diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000000..e9ce865bf6 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,24 @@ +--- +engines: + duplication: + enabled: true + config: + languages: + - ruby + - javascript + - python + - php + fixme: + enabled: true + rubocop: + enabled: true +ratings: + paths: + - "**.inc" + - "**.js" + - "**.jsx" + - "**.module" + - "**.php" + - "**.py" + - "**.rb" +exclude_paths: [] diff --git a/.github/workflows/build_publish.yml b/.github/workflows/build_publish.yml new file mode 100644 index 0000000000..0d65180b02 --- /dev/null +++ b/.github/workflows/build_publish.yml @@ -0,0 +1,39 @@ +name: Build and Publish package +on: + push: + branches: [ master ] + workflow_dispatch: + +jobs: + build-publish-package: + name: Build and Publish package + runs-on: macos-11 + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + server-id: nexus-sonatype + server-username: NEXUS_USERNAME + server-password: NEXUS_PASSWORD + - name: Cache Maven packages + uses: actions/cache@v3 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Install compass + run: | + sudo gem install compass -v 1.0.3 + - name: Build and deploy with Maven + run: ./mvnw --no-transfer-progress clean -U deploy + env: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + diff --git a/.github/workflows/validate_pr.yml b/.github/workflows/validate_pr.yml new file mode 100644 index 0000000000..9049223614 --- /dev/null +++ b/.github/workflows/validate_pr.yml @@ -0,0 +1,33 @@ +name: Validate PR +on: + pull_request: + branches: [ master ] + +jobs: + build: + name: Build + runs-on: macos-11 + 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@v3 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Install compass + run: | + sudo gem install compass -v 1.0.3 + - name: Build with Maven + run: | + ./mvnw install -U -Dmaven.javadoc.skip=true -V -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + ./mvnw verify -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn diff --git a/.gitignore b/.gitignore index e08c79410a..ac7e5e5d4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,20 @@ target/ .DS_Store +.idea +*.iml +*/logs/* +logs/* +classes/ +.sass-cache +.rubygems-provided +.rubygems +sass-external +bahmnicore-omod/src/main/webapp/resources/styles/bahmnicore.css +.mvn/wrapper/*.jar +.vscode + + +# Eclipse project files +.settings +.classpath +.project diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..8c79a83ae4 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000000..3f1d2224ad --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,1156 @@ +AllCops: + DisabledByDefault: true + +#################### Lint ################################ + +Lint/AmbiguousOperator: + Description: >- + Checks for ambiguous operators in the first argument of a + method invocation without parentheses. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-as-args' + Enabled: true + +Lint/AmbiguousRegexpLiteral: + Description: >- + Checks for ambiguous regexp literals in the first argument of + a method invocation without parenthesis. + Enabled: true + +Lint/AssignmentInCondition: + Description: "Don't use assignment in conditions." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition' + Enabled: true + +Lint/BlockAlignment: + Description: 'Align block ends correctly.' + Enabled: true + +Lint/CircularArgumentReference: + Description: "Don't refer to the keyword argument in the default value." + Enabled: true + +Lint/ConditionPosition: + Description: >- + Checks for condition placed in a confusing position relative to + the keyword. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition' + Enabled: true + +Lint/Debugger: + Description: 'Check for debugger calls.' + Enabled: true + +Lint/DefEndAlignment: + Description: 'Align ends corresponding to defs correctly.' + Enabled: true + +Lint/DeprecatedClassMethods: + Description: 'Check for deprecated class method calls.' + Enabled: true + +Lint/DuplicateMethods: + Description: 'Check for duplicate methods calls.' + Enabled: true + +Lint/EachWithObjectArgument: + Description: 'Check for immutable argument given to each_with_object.' + Enabled: true + +Lint/ElseLayout: + Description: 'Check for odd code arrangement in an else block.' + Enabled: true + +Lint/EmptyEnsure: + Description: 'Checks for empty ensure block.' + Enabled: true + +Lint/EmptyInterpolation: + Description: 'Checks for empty string interpolation.' + Enabled: true + +Lint/EndAlignment: + Description: 'Align ends correctly.' + Enabled: true + +Lint/EndInMethod: + Description: 'END blocks should not be placed inside method definitions.' + Enabled: true + +Lint/EnsureReturn: + Description: 'Do not use return in an ensure block.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-return-ensure' + Enabled: true + +Lint/Eval: + Description: 'The use of eval represents a serious security risk.' + Enabled: true + +Lint/FormatParameterMismatch: + Description: 'The number of parameters to format/sprint must match the fields.' + Enabled: true + +Lint/HandleExceptions: + Description: "Don't suppress exception." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions' + Enabled: true + +Lint/InvalidCharacterLiteral: + Description: >- + Checks for invalid character literals with a non-escaped + whitespace character. + Enabled: true + +Lint/LiteralInCondition: + Description: 'Checks of literals used in conditions.' + Enabled: true + +Lint/LiteralInInterpolation: + Description: 'Checks for literals used in interpolation.' + Enabled: true + +Lint/Loop: + Description: >- + Use Kernel#loop with break rather than begin/end/until or + begin/end/while for post-loop tests. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#loop-with-break' + Enabled: true + +Lint/NestedMethodDefinition: + Description: 'Do not use nested method definitions.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-methods' + Enabled: true + +Lint/NonLocalExitFromIterator: + Description: 'Do not use return in iterator to cause non-local exit.' + Enabled: true + +Lint/ParenthesesAsGroupedExpression: + Description: >- + Checks for method calls with a space before the opening + parenthesis. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces' + Enabled: true + +Lint/RequireParentheses: + Description: >- + Use parentheses in the method call to avoid confusion + about precedence. + Enabled: true + +Lint/RescueException: + Description: 'Avoid rescuing the Exception class.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-blind-rescues' + Enabled: true + +Lint/ShadowingOuterLocalVariable: + Description: >- + Do not use the same name as outer local variable + for block arguments or block local variables. + Enabled: true + +Lint/StringConversionInInterpolation: + Description: 'Checks for Object#to_s usage in string interpolation.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-to-s' + Enabled: true + +Lint/UnderscorePrefixedVariableName: + Description: 'Do not use prefix `_` for a variable that is used.' + Enabled: true + +Lint/UnneededDisable: + Description: >- + Checks for rubocop:disable comments that can be removed. + Note: this cop is not disabled when disabling all cops. + It must be explicitly disabled. + Enabled: true + +Lint/UnusedBlockArgument: + Description: 'Checks for unused block arguments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars' + Enabled: true + +Lint/UnusedMethodArgument: + Description: 'Checks for unused method arguments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars' + Enabled: true + +Lint/UnreachableCode: + Description: 'Unreachable code.' + Enabled: true + +Lint/UselessAccessModifier: + Description: 'Checks for useless access modifiers.' + Enabled: true + +Lint/UselessAssignment: + Description: 'Checks for useless assignment to a local variable.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars' + Enabled: true + +Lint/UselessComparison: + Description: 'Checks for comparison of something with itself.' + Enabled: true + +Lint/UselessElseWithoutRescue: + Description: 'Checks for useless `else` in `begin..end` without `rescue`.' + Enabled: true + +Lint/UselessSetterCall: + Description: 'Checks for useless setter call to a local variable.' + Enabled: true + +Lint/Void: + Description: 'Possible use of operator/literal/variable in void context.' + Enabled: true + +###################### Metrics #################################### + +Metrics/AbcSize: + Description: >- + A calculated magnitude based on number of assignments, + branches, and conditions. + Reference: 'http://c2.com/cgi/wiki?AbcMetric' + Enabled: false + Max: 20 + +Metrics/BlockNesting: + Description: 'Avoid excessive block nesting' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count' + Enabled: true + Max: 4 + +Metrics/ClassLength: + Description: 'Avoid classes longer than 250 lines of code.' + Enabled: true + Max: 250 + +Metrics/CyclomaticComplexity: + Description: >- + A complexity metric that is strongly correlated to the number + of test cases needed to validate a method. + Enabled: true + +Metrics/LineLength: + Description: 'Limit lines to 80 characters.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits' + Enabled: false + +Metrics/MethodLength: + Description: 'Avoid methods longer than 30 lines of code.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods' + Enabled: true + Max: 30 + +Metrics/ModuleLength: + Description: 'Avoid modules longer than 250 lines of code.' + Enabled: true + Max: 250 + +Metrics/ParameterLists: + Description: 'Avoid parameter lists longer than three or four parameters.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#too-many-params' + Enabled: true + +Metrics/PerceivedComplexity: + Description: >- + A complexity metric geared towards measuring complexity for a + human reader. + Enabled: false + +##################### Performance ############################# + +Performance/Count: + Description: >- + Use `count` instead of `select...size`, `reject...size`, + `select...count`, `reject...count`, `select...length`, + and `reject...length`. + Enabled: true + +Performance/Detect: + Description: >- + Use `detect` instead of `select.first`, `find_all.first`, + `select.last`, and `find_all.last`. + Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerabledetect-vs-enumerableselectfirst-code' + Enabled: true + +Performance/FlatMap: + Description: >- + Use `Enumerable#flat_map` + instead of `Enumerable#map...Array#flatten(1)` + or `Enumberable#collect..Array#flatten(1)` + Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablemaparrayflatten-vs-enumerableflat_map-code' + Enabled: true + EnabledForFlattenWithoutParams: false + # If enabled, this cop will warn about usages of + # `flatten` being called without any parameters. + # This can be dangerous since `flat_map` will only flatten 1 level, and + # `flatten` without any parameters can flatten multiple levels. + +Performance/ReverseEach: + Description: 'Use `reverse_each` instead of `reverse.each`.' + Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablereverseeach-vs-enumerablereverse_each-code' + Enabled: true + +Performance/Sample: + Description: >- + Use `sample` instead of `shuffle.first`, + `shuffle.last`, and `shuffle[Fixnum]`. + Reference: 'https://github.com/JuanitoFatas/fast-ruby#arrayshufflefirst-vs-arraysample-code' + Enabled: true + +Performance/Size: + Description: >- + Use `size` instead of `count` for counting + the number of elements in `Array` and `Hash`. + Reference: 'https://github.com/JuanitoFatas/fast-ruby#arraycount-vs-arraysize-code' + Enabled: true + +Performance/StringReplacement: + Description: >- + Use `tr` instead of `gsub` when you are replacing the same + number of characters. Use `delete` instead of `gsub` when + you are deleting characters. + Reference: 'https://github.com/JuanitoFatas/fast-ruby#stringgsub-vs-stringtr-code' + Enabled: true + +##################### Rails ################################## + +Rails/ActionFilter: + Description: 'Enforces consistent use of action filter methods.' + Enabled: false + +Rails/Date: + Description: >- + Checks the correct usage of date aware methods, + such as Date.today, Date.current etc. + Enabled: false + +Rails/Delegate: + Description: 'Prefer delegate method for delegations.' + Enabled: false + +Rails/FindBy: + Description: 'Prefer find_by over where.first.' + Enabled: false + +Rails/FindEach: + Description: 'Prefer all.find_each over all.find.' + Enabled: false + +Rails/HasAndBelongsToMany: + Description: 'Prefer has_many :through to has_and_belongs_to_many.' + Enabled: false + +Rails/Output: + Description: 'Checks for calls to puts, print, etc.' + Enabled: false + +Rails/ReadWriteAttribute: + Description: >- + Checks for read_attribute(:attr) and + write_attribute(:attr, val). + Enabled: false + +Rails/ScopeArgs: + Description: 'Checks the arguments of ActiveRecord scopes.' + Enabled: false + +Rails/TimeZone: + Description: 'Checks the correct usage of time zone aware methods.' + StyleGuide: 'https://github.com/bbatsov/rails-style-guide#time' + Reference: 'http://danilenko.org/2012/7/6/rails_timezones' + Enabled: false + +Rails/Validation: + Description: 'Use validates :attribute, hash of validations.' + Enabled: false + +################## Style ################################# + +Style/AccessModifierIndentation: + Description: Check indentation of private/protected visibility modifiers. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected' + Enabled: false + +Style/AccessorMethodName: + Description: Check the naming of accessor methods for get_/set_. + Enabled: false + +Style/Alias: + Description: 'Use alias_method instead of alias.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#alias-method' + Enabled: false + +Style/AlignArray: + Description: >- + Align the elements of an array literal if they span more than + one line. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays' + Enabled: false + +Style/AlignHash: + Description: >- + Align the elements of a hash literal if they span more than + one line. + Enabled: false + +Style/AlignParameters: + Description: >- + Align the parameters of a method call if they span more + than one line. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent' + Enabled: false + +Style/AndOr: + Description: 'Use &&/|| instead of and/or.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-and-or-or' + Enabled: false + +Style/ArrayJoin: + Description: 'Use Array#join instead of Array#*.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#array-join' + Enabled: false + +Style/AsciiComments: + Description: 'Use only ascii symbols in comments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments' + Enabled: false + +Style/AsciiIdentifiers: + Description: 'Use only ascii symbols in identifiers.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-identifiers' + Enabled: false + +Style/Attr: + Description: 'Checks for uses of Module#attr.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr' + Enabled: false + +Style/BeginBlock: + Description: 'Avoid the use of BEGIN blocks.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-BEGIN-blocks' + Enabled: false + +Style/BarePercentLiterals: + Description: 'Checks if usage of %() or %Q() matches configuration.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q-shorthand' + Enabled: false + +Style/BlockComments: + Description: 'Do not use block comments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-block-comments' + Enabled: false + +Style/BlockEndNewline: + Description: 'Put end statement of multiline block on its own line.' + Enabled: false + +Style/BlockDelimiters: + Description: >- + Avoid using {...} for multi-line blocks (multiline chaining is + always ugly). + Prefer {...} over do...end for single-line blocks. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks' + Enabled: false + +Style/BracesAroundHashParameters: + Description: 'Enforce braces style around hash parameters.' + Enabled: false + +Style/CaseEquality: + Description: 'Avoid explicit use of the case equality operator(===).' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-case-equality' + Enabled: false + +Style/CaseIndentation: + Description: 'Indentation of when in a case/when/[else/]end.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-when-to-case' + Enabled: false + +Style/CharacterLiteral: + Description: 'Checks for uses of character literals.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-character-literals' + Enabled: false + +Style/ClassAndModuleCamelCase: + Description: 'Use CamelCase for classes and modules.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#camelcase-classes' + Enabled: false + +Style/ClassAndModuleChildren: + Description: 'Checks style of children classes and modules.' + Enabled: false + +Style/ClassCheck: + Description: 'Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.' + Enabled: false + +Style/ClassMethods: + Description: 'Use self when defining module/class methods.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#def-self-class-methods' + Enabled: false + +Style/ClassVars: + Description: 'Avoid the use of class variables.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-class-vars' + Enabled: false + +Style/ClosingParenthesisIndentation: + Description: 'Checks the indentation of hanging closing parentheses.' + Enabled: false + +Style/ColonMethodCall: + Description: 'Do not use :: for method call.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#double-colons' + Enabled: false + +Style/CommandLiteral: + Description: 'Use `` or %x around command literals.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-x' + Enabled: false + +Style/CommentAnnotation: + Description: 'Checks formatting of annotation comments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#annotate-keywords' + Enabled: false + +Style/CommentIndentation: + Description: 'Indentation of comments.' + Enabled: false + +Style/ConstantName: + Description: 'Constants should use SCREAMING_SNAKE_CASE.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#screaming-snake-case' + Enabled: false + +Style/DefWithParentheses: + Description: 'Use def with parentheses when there are arguments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens' + Enabled: false + +Style/DeprecatedHashMethods: + Description: 'Checks for use of deprecated Hash methods.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-key' + Enabled: false + +Style/Documentation: + Description: 'Document classes and non-namespace modules.' + Enabled: false + +Style/DotPosition: + Description: 'Checks the position of the dot in multi-line method calls.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains' + Enabled: false + +Style/DoubleNegation: + Description: 'Checks for uses of double negation (!!).' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-bang-bang' + Enabled: false + +Style/EachWithObject: + Description: 'Prefer `each_with_object` over `inject` or `reduce`.' + Enabled: false + +Style/ElseAlignment: + Description: 'Align elses and elsifs correctly.' + Enabled: false + +Style/EmptyElse: + Description: 'Avoid empty else-clauses.' + Enabled: false + +Style/EmptyLineBetweenDefs: + Description: 'Use empty lines between defs.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods' + Enabled: false + +Style/EmptyLines: + Description: "Don't use several empty lines in a row." + Enabled: false + +Style/EmptyLinesAroundAccessModifier: + Description: "Keep blank lines around access modifiers." + Enabled: false + +Style/EmptyLinesAroundBlockBody: + Description: "Keeps track of empty lines around block bodies." + Enabled: false + +Style/EmptyLinesAroundClassBody: + Description: "Keeps track of empty lines around class bodies." + Enabled: false + +Style/EmptyLinesAroundModuleBody: + Description: "Keeps track of empty lines around module bodies." + Enabled: false + +Style/EmptyLinesAroundMethodBody: + Description: "Keeps track of empty lines around method bodies." + Enabled: false + +Style/EmptyLiteral: + Description: 'Prefer literals to Array.new/Hash.new/String.new.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#literal-array-hash' + Enabled: false + +Style/EndBlock: + Description: 'Avoid the use of END blocks.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-END-blocks' + Enabled: false + +Style/EndOfLine: + Description: 'Use Unix-style line endings.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#crlf' + Enabled: false + +Style/EvenOdd: + Description: 'Favor the use of Fixnum#even? && Fixnum#odd?' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods' + Enabled: false + +Style/ExtraSpacing: + Description: 'Do not use unnecessary spacing.' + Enabled: false + +Style/FileName: + Description: 'Use snake_case for source file names.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files' + Enabled: false + +Style/InitialIndentation: + Description: >- + Checks the indentation of the first non-blank non-comment line in a file. + Enabled: false + +Style/FirstParameterIndentation: + Description: 'Checks the indentation of the first parameter in a method call.' + Enabled: false + +Style/FlipFlop: + Description: 'Checks for flip flops' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-flip-flops' + Enabled: false + +Style/For: + Description: 'Checks use of for or each in multiline loops.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-for-loops' + Enabled: false + +Style/FormatString: + Description: 'Enforce the use of Kernel#sprintf, Kernel#format or String#%.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#sprintf' + Enabled: false + +Style/GlobalVars: + Description: 'Do not introduce global variables.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#instance-vars' + Reference: 'http://www.zenspider.com/Languages/Ruby/QuickRef.html' + Enabled: false + +Style/GuardClause: + Description: 'Check for conditionals that can be replaced with guard clauses' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals' + Enabled: false + +Style/HashSyntax: + Description: >- + Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax + { :a => 1, :b => 2 }. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-literals' + Enabled: false + +Style/IfUnlessModifier: + Description: >- + Favor modifier if/unless usage when you have a + single-line body. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier' + Enabled: false + +Style/IfWithSemicolon: + Description: 'Do not use if x; .... Use the ternary operator instead.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs' + Enabled: false + +Style/IndentationConsistency: + Description: 'Keep indentation straight.' + Enabled: false + +Style/IndentationWidth: + Description: 'Use 2 spaces for indentation.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation' + Enabled: false + +Style/IndentArray: + Description: >- + Checks the indentation of the first element in an array + literal. + Enabled: false + +Style/IndentHash: + Description: 'Checks the indentation of the first key in a hash literal.' + Enabled: false + +Style/InfiniteLoop: + Description: 'Use Kernel#loop for infinite loops.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#infinite-loop' + Enabled: false + +Style/Lambda: + Description: 'Use the new lambda literal syntax for single-line blocks.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#lambda-multi-line' + Enabled: false + +Style/LambdaCall: + Description: 'Use lambda.call(...) instead of lambda.(...).' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc-call' + Enabled: false + +Style/LeadingCommentSpace: + Description: 'Comments should start with a space.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-space' + Enabled: false + +Style/LineEndConcatenation: + Description: >- + Use \ instead of + or << to concatenate two string literals at + line end. + Enabled: false + +Style/MethodCallParentheses: + Description: 'Do not use parentheses for method calls with no arguments.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens' + Enabled: false + +Style/MethodDefParentheses: + Description: >- + Checks if the method definitions have or don't have + parentheses. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens' + Enabled: false + +Style/MethodName: + Description: 'Use the configured style when naming methods.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars' + Enabled: false + +Style/ModuleFunction: + Description: 'Checks for usage of `extend self` in modules.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#module-function' + Enabled: false + +Style/MultilineBlockChain: + Description: 'Avoid multi-line chains of blocks.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks' + Enabled: false + +Style/MultilineBlockLayout: + Description: 'Ensures newlines after multiline block do statements.' + Enabled: false + +Style/MultilineIfThen: + Description: 'Do not use then for multi-line if/unless.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-then' + Enabled: false + +Style/MultilineOperationIndentation: + Description: >- + Checks indentation of binary operations that span more than + one line. + Enabled: false + +Style/MultilineTernaryOperator: + Description: >- + Avoid multi-line ?: (the ternary operator); + use if/unless instead. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-multiline-ternary' + Enabled: false + +Style/NegatedIf: + Description: >- + Favor unless over if for negative conditions + (or control flow or). + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#unless-for-negatives' + Enabled: false + +Style/NegatedWhile: + Description: 'Favor until over while for negative conditions.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#until-for-negatives' + Enabled: false + +Style/NestedTernaryOperator: + Description: 'Use one expression per branch in a ternary operator.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-ternary' + Enabled: false + +Style/Next: + Description: 'Use `next` to skip iteration instead of a condition at the end.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals' + Enabled: false + +Style/NilComparison: + Description: 'Prefer x.nil? to x == nil.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods' + Enabled: false + +Style/NonNilCheck: + Description: 'Checks for redundant nil checks.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks' + Enabled: false + +Style/Not: + Description: 'Use ! instead of not.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bang-not-not' + Enabled: false + +Style/NumericLiterals: + Description: >- + Add underscores to large numeric literals to improve their + readability. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics' + Enabled: false + +Style/OneLineConditional: + Description: >- + Favor the ternary operator(?:) over + if/then/else/end constructs. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator' + Enabled: false + +Style/OpMethod: + Description: 'When defining binary operators, name the argument other.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg' + Enabled: false + +Style/OptionalArguments: + Description: >- + Checks for optional arguments that do not appear at the end + of the argument list + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#optional-arguments' + Enabled: false + +Style/ParallelAssignment: + Description: >- + Check for simple usages of parallel assignment. + It will only warn when the number of variables + matches on both sides of the assignment. + This also provides performance benefits + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parallel-assignment' + Enabled: false + +Style/ParenthesesAroundCondition: + Description: >- + Don't use parentheses around the condition of an + if/unless/while. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-parens-if' + Enabled: false + +Style/PercentLiteralDelimiters: + Description: 'Use `%`-literal delimiters consistently' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-literal-braces' + Enabled: false + +Style/PercentQLiterals: + Description: 'Checks if uses of %Q/%q match the configured preference.' + Enabled: false + +Style/PerlBackrefs: + Description: 'Avoid Perl-style regex back references.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers' + Enabled: false + +Style/PredicateName: + Description: 'Check the names of predicate methods.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark' + Enabled: false + +Style/Proc: + Description: 'Use proc instead of Proc.new.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc' + Enabled: false + +Style/RaiseArgs: + Description: 'Checks the arguments passed to raise/fail.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#exception-class-messages' + Enabled: false + +Style/RedundantBegin: + Description: "Don't use begin blocks when they are not needed." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#begin-implicit' + Enabled: false + +Style/RedundantException: + Description: "Checks for an obsolete RuntimeException argument in raise/fail." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror' + Enabled: false + +Style/RedundantReturn: + Description: "Don't use return where it's not required." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-return' + Enabled: false + +Style/RedundantSelf: + Description: "Don't use self where it's not needed." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-self-unless-required' + Enabled: false + +Style/RegexpLiteral: + Description: 'Use / or %r around regular expressions.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r' + Enabled: false + +Style/RescueEnsureAlignment: + Description: 'Align rescues and ensures correctly.' + Enabled: false + +Style/RescueModifier: + Description: 'Avoid using rescue in its modifier form.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers' + Enabled: false + +Style/SelfAssignment: + Description: >- + Checks for places where self-assignment shorthand should have + been used. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#self-assignment' + Enabled: false + +Style/Semicolon: + Description: "Don't use semicolons to terminate expressions." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon' + Enabled: false + +Style/SignalException: + Description: 'Checks for proper usage of fail and raise.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#fail-method' + Enabled: false + +Style/SingleLineBlockParams: + Description: 'Enforces the names of some block params.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#reduce-blocks' + Enabled: false + +Style/SingleLineMethods: + Description: 'Avoid single-line methods.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-single-line-methods' + Enabled: false + +Style/SpaceBeforeFirstArg: + Description: >- + Checks that exactly one space is used between a method name + and the first argument for method calls without parentheses. + Enabled: true + +Style/SpaceAfterColon: + Description: 'Use spaces after colons.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' + Enabled: false + +Style/SpaceAfterComma: + Description: 'Use spaces after commas.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' + Enabled: false + +Style/SpaceAroundKeyword: + Description: 'Use spaces around keywords.' + Enabled: false + +Style/SpaceAfterMethodName: + Description: >- + Do not put a space between a method name and the opening + parenthesis in a method definition. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces' + Enabled: false + +Style/SpaceAfterNot: + Description: Tracks redundant space after the ! operator. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-bang' + Enabled: false + +Style/SpaceAfterSemicolon: + Description: 'Use spaces after semicolons.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' + Enabled: false + +Style/SpaceBeforeBlockBraces: + Description: >- + Checks that the left block brace has or doesn't have space + before it. + Enabled: false + +Style/SpaceBeforeComma: + Description: 'No spaces before commas.' + Enabled: false + +Style/SpaceBeforeComment: + Description: >- + Checks for missing space between code and a comment on the + same line. + Enabled: false + +Style/SpaceBeforeSemicolon: + Description: 'No spaces before semicolons.' + Enabled: false + +Style/SpaceInsideBlockBraces: + Description: >- + Checks that block braces have or don't have surrounding space. + For blocks taking parameters, checks that the left brace has + or doesn't have trailing space. + Enabled: false + +Style/SpaceAroundBlockParameters: + Description: 'Checks the spacing inside and after block parameters pipes.' + Enabled: false + +Style/SpaceAroundEqualsInParameterDefault: + Description: >- + Checks that the equals signs in parameter default assignments + have or don't have surrounding space depending on + configuration. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-around-equals' + Enabled: false + +Style/SpaceAroundOperators: + Description: 'Use a single space around operators.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' + Enabled: false + +Style/SpaceInsideBrackets: + Description: 'No spaces after [ or before ].' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces' + Enabled: false + +Style/SpaceInsideHashLiteralBraces: + Description: "Use spaces inside hash literal braces - or don't." + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' + Enabled: false + +Style/SpaceInsideParens: + Description: 'No spaces after ( or before ).' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces' + Enabled: false + +Style/SpaceInsideRangeLiteral: + Description: 'No spaces inside range literals.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals' + Enabled: false + +Style/SpaceInsideStringInterpolation: + Description: 'Checks for padding/surrounding spaces inside string interpolation.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#string-interpolation' + Enabled: false + +Style/SpecialGlobalVars: + Description: 'Avoid Perl-style global variables.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms' + Enabled: false + +Style/StringLiterals: + Description: 'Checks if uses of quotes match the configured preference.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals' + Enabled: false + +Style/StringLiteralsInInterpolation: + Description: >- + Checks if uses of quotes inside expressions in interpolated + strings match the configured preference. + Enabled: false + +Style/StructInheritance: + Description: 'Checks for inheritance from Struct.new.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-extend-struct-new' + Enabled: false + +Style/SymbolLiteral: + Description: 'Use plain symbols instead of string symbols when possible.' + Enabled: false + +Style/SymbolProc: + Description: 'Use symbols as procs instead of blocks when possible.' + Enabled: false + +Style/Tab: + Description: 'No hard tabs.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation' + Enabled: false + +Style/TrailingBlankLines: + Description: 'Checks trailing blank lines and final newline.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#newline-eof' + Enabled: false + +Style/TrailingCommaInArguments: + Description: 'Checks for trailing comma in parameter lists.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-params-comma' + Enabled: false + +Style/TrailingCommaInLiteral: + Description: 'Checks for trailing comma in literals.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas' + Enabled: false + +Style/TrailingWhitespace: + Description: 'Avoid trailing whitespace.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace' + Enabled: false + +Style/TrivialAccessors: + Description: 'Prefer attr_* methods to trivial readers/writers.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr_family' + Enabled: false + +Style/UnlessElse: + Description: >- + Do not use unless with else. Rewrite these with the positive + case first. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-else-with-unless' + Enabled: false + +Style/UnneededCapitalW: + Description: 'Checks for %W when interpolation is not needed.' + Enabled: false + +Style/UnneededPercentQ: + Description: 'Checks for %q/%Q when single quotes or double quotes would do.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q' + Enabled: false + +Style/TrailingUnderscoreVariable: + Description: >- + Checks for the usage of unneeded trailing underscores at the + end of parallel variable assignment. + Enabled: false + +Style/VariableInterpolation: + Description: >- + Don't interpolate global, instance and class variables + directly in strings. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#curlies-interpolate' + Enabled: false + +Style/VariableName: + Description: 'Use the configured style when naming variables.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars' + Enabled: false + +Style/WhenThen: + Description: 'Use when x then ... for one-line cases.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#one-line-cases' + Enabled: false + +Style/WhileUntilDo: + Description: 'Checks for redundant do after while or until.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-multiline-while-do' + Enabled: false + +Style/WhileUntilModifier: + Description: >- + Favor modifier while/until usage when you have a + single-line body. + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier' + Enabled: false + +Style/WordArray: + Description: 'Use %w or %W for arrays of words.' + StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-w' + Enabled: false diff --git a/DrugInventory.java b/DrugInventory.java deleted file mode 100644 index 92c2c6de44..0000000000 --- a/DrugInventory.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.io.Serializable; -import java.util.Date; - -import org.openmrs.BaseOpenmrsMetadata; - -public class DrugInventory extends BaseOpenmrsMetadata implements Serializable { - - private Integer drugInventoryId; - - private String drugInventoryName; - - private String drugInventoryDescription; - - private Integer drugId; - - private Integer quantity; - - private Date expiryDate; - - private String batch; - - private Integer value; - - private String status; - - private Integer providerId; - - private Integer locationId; - - private Integer drugPurchaseOrderId; - - public DrugInventory() { - - } - - public Integer getId() { - // TODO Auto-generated method stub - return getDrugInventoryId(); - } - - public void setId(Integer arg0) { - // TODO Auto-generated method stub - setDrugInventoryId(arg0); - } - - public Integer getDrugInventoryId() { - return drugInventoryId; - } - - public void setDrugInventoryId(Integer drugInventoryId) { - this.drugInventoryId = drugInventoryId; - } - - public String getDrugInventoryName() { - return drugInventoryName; - } - - public void setDrugInventoryName(String drugInventoryName) { - this.drugInventoryName = drugInventoryName; - } - - public String getDrugInventoryDescription() { - return drugInventoryDescription; - } - - public void setDrugInventoryDescription(String drugInventoryDescription) { - this.drugInventoryDescription = drugInventoryDescription; - } - - public Integer getDrugId() { - return drugId; - } - - public void setDrugId(Integer drugd) { - this.drugId = drugId; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } - - public Date getExpiryDate() { - return expiryDate; - } - - public void setExpiryDate(Date expiryDate) { - this.expiryDate = expiryDate; - } - - public String getBatch() { - return batch; - } - - public void setBatch(String batch) { - this.batch = batch; - } - - public Integer getValue() { - return value; - } - - public void setValue(Integer value) { - this.value = value; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Integer getProviderId() { - return providerId; - } - - public void setProviderId(Integer providerId) { - this.providerId = providerId; - } - - public Integer getLocationId() { - return locationId; - } - - public void setLocationId(Integer locationId) { - this.locationId = locationId; - } - - public Integer getDrugPurchaseOrderId() { - return drugPurchaseOrderId; - } - - public void setDrugPurchaseOrderId(Integer drugPurchaseOrderId) { - this.drugPurchaseOrderId = drugPurchaseOrderId; - } - -} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..0ad25db4bd --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..0d40080504 --- /dev/null +++ b/NOTICE @@ -0,0 +1,7 @@ +Copyright (C) 2018 OpenMRS, Inc + +This product includes software developed under the stewardship of the Bahmni Coalition, under fiscal sponsorship of OpenMRS, Inc. (http://www.openmrs.org/) + +This product includes software developed at ThoughtWorks, Inc (http://www.thoughtworks.com/) + +This software contains code derived from the RAXA-Core (https://github.com/Raxa/raxacore) \ No newline at end of file diff --git a/OpenMRSFormatter.xml b/OpenMRSFormatter.xml deleted file mode 100644 index 35c5cdf8e3..0000000000 --- a/OpenMRSFormatter.xml +++ /dev/null @@ -1,267 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/README.md b/README.md index 4b057d34d3..69d2ff937e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,25 @@ -raxacore -======== +Tracing from raxacore to bahmni-core -The raxacore is an OpenMRS module that hosts all the services that are required by the RaxaEMR on-top of the OpenMRS installation. -The module provides core REST services required for core RaxaEMR management -RaxaEMR modules may have their own backend services provided by other OpenMRS modules -This module should only depend on the OpenMRS core and webservices.rest module +# OpenMRS module bahmnicore -The raxacore module provides the following services -- PatientListService \ No newline at end of file +This module provides necessary services for running Bahmni + +## Build + +[![BahmniCore-master Actions Status](https://github.com/Bahmni/bahmni-core/workflows/Java%20CI%20with%20Maven/badge.svg)](https://github.com/Bahmni/bahmni-core/actions) + +### Prerequisite + JDK 1.8 + ruby 2.2+ + RubyGems + Compass 1.0.3 (gem install compass) + +### Clone the repository and build the omod + + git clone https://github.com/bahmni/bahmni-core + cd bahmni-core + ./mvnw clean install + +## Deploy + +Copy ```bahmni-core/bahmnicore-omod/target/bahmnicore-omod-VERSION-SNAPSHOT.omod``` into OpenMRS modules directory and restart OpenMRS diff --git a/admin/pom.xml b/admin/pom.xml new file mode 100644 index 0000000000..66185a5bf6 --- /dev/null +++ b/admin/pom.xml @@ -0,0 +1,290 @@ + + + 4.0.0 + + bahmni + org.bahmni.module + 1.2.0-SNAPSHOT + + + admin + Admin + + + + + org.bahmni.module + bahmni-migrator + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + common + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + auditlog-api + provided + + + org.bahmni.module + bahmni-commons-api + + + net.sf.opencsv + opencsv + 2.0 + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + org.openmrs.test + openmrs-test + pom + test + + + junit + junit + test + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + + + org.bahmni.module + bahmni-emr-api + ${project.parent.version} + + + org.openmrs.module + reporting-api + + + org.openmrs.module + calculation-api + + + org.openmrs.module + serialization.xstream-api-2.0 + + + org.openmrs.module + providermanagement-api + + + org.openmrs.module + appframework-api + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + jar + + + org.bahmni.module + bahmnicore-api + ${project.parent.version} + jar + + + org.bahmni.module + bahmnicore-api + ${project.parent.version} + test-jar + test + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + provided + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + provided + + + org.apache.httpcomponents + httpclient + 4.2.5 + provided + + + org.bahmni.module + reference-data-api + ${project.parent.version} + provided + + + org.bahmni.module + episodes-api + ${episodes.version} + provided + + + org.bahmni.module + form2-utils + ${bahmniJavaUtilsVersion} + + + org.openmrs.web + openmrs-web + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + javax.servlet + javax.servlet-api + test + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test-jar + test + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + test-jar + test + + + javax.servlet + servlet-api + + + + + org.openmrs.module + addresshierarchy-api + ${addressHierarchyVersion} + provided + + + org.openmrs.module + addresshierarchy-omod + ${addressHierarchyVersion} + provided + + + org.openmrs.module + legacyui-omod + + + org.openmrs.module + webservices.rest-omod + ${openMRSWebServicesVersion} + jar + test + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + tests + test + + + com.google.code.gson + gson + 2.3.1 + + + org.ict4h.openmrs + openmrs-atomfeed-api + ${openmrsAtomfeedVersion} + test + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + test + + + + + + + src/main/resources + true + + + + + + src/test/resources + true + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.35 + + + BRANCH + COVEREDRATIO + 0.36 + + + + + + + + + + + + diff --git a/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/ConceptMapper.java b/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/ConceptMapper.java new file mode 100644 index 0000000000..3c6a8b4570 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/ConceptMapper.java @@ -0,0 +1,118 @@ +package org.bahmni.module.admin.concepts.mapper; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getKeyValueList; + +public class ConceptMapper { + + public Concept map(ConceptRow conceptRow) { + Concept concept = new Concept(); + concept.setUuid(conceptRow.getUuid()); + concept.setClassName(conceptRow.conceptClass); + concept.setDataType(conceptRow.getDataType()); + concept.setDescription(conceptRow.getDescription()); + concept.setUniqueName(conceptRow.getName()); + concept.setDisplayName(conceptRow.getShortName()); + concept.setUnits(conceptRow.getUnits()); + concept.setHiNormal(conceptRow.getHiNormal()); + concept.setLowNormal(conceptRow.getLowNormal()); + if (Objects.equals(conceptRow.getAllowDecimal(), "") || conceptRow.getAllowDecimal() == null) { + concept.setAllowDecimal("true"); + } else { + concept.setAllowDecimal(conceptRow.getAllowDecimal()); + } + concept.setLocale(conceptRow.getLocale()); + addSynonyms(conceptRow, concept); + addAnswers(conceptRow, concept); + addConceptReferenceTerms(conceptRow, concept); + + return concept; + } + + private void addSynonyms(ConceptRow conceptRow, Concept concept) { + List synonyms = new ArrayList<>(); + for (KeyValue synonym : conceptRow.getSynonyms()) { + if (!StringUtils.isEmpty(synonym.getValue())) { + synonyms.add(synonym.getValue()); + } + } + concept.setSynonyms(synonyms); + } + + private void addAnswers(ConceptRow conceptRow, Concept concept) { + List answers = new ArrayList<>(); + List> sortedAnswers = sortAnswersAccordingToNumericValueOfKey(conceptRow.getAnswers()); + for (Map.Entry answer : sortedAnswers) { + if (!StringUtils.isEmpty(answer.getValue())) { + answers.add(answer.getValue()); + } + } + concept.setAnswers(answers); + } + + private List> sortAnswersAccordingToNumericValueOfKey(List answers) { + HashMap answersMap = new HashMap(); + for (KeyValue answer : answers) { + answersMap.put(Integer.parseInt(answer.getKey()), answer.getValue()); + } + List> sortedAnswers = new ArrayList>( + answersMap.entrySet() + ); + Collections.sort( + sortedAnswers + , new Comparator>() { + public int compare(Map.Entry a, Map.Entry b) { + return Integer.compare(a.getKey(), b.getKey()); + } + } + ); + return sortedAnswers; + } + + + private void addConceptReferenceTerms(ConceptRow conceptRow, Concept concept) { + ConceptReferenceTerm conceptReferenceTerm; + for (ConceptReferenceTermRow referenceTerm : conceptRow.getReferenceTerms()) { + conceptReferenceTerm = new ConceptReferenceTerm(referenceTerm.getReferenceTermCode(), referenceTerm.getReferenceTermRelationship(), referenceTerm.getReferenceTermSource()); + concept.getConceptReferenceTermsList().add(conceptReferenceTerm); + } + } + + //TODO need to change + public ConceptRow map(Concept concept) { + String name = concept.getUniqueName(); + String description = concept.getDescription(); + String shortName = concept.getDisplayName(); + String conceptClass = concept.getClassName(); + String conceptDatatype = concept.getDataType(); + String locale = concept.getLocale(); + List conceptSynonyms = getKeyValueList("synonym", concept.getSynonyms()); + List conceptAnswers = getKeyValueList("answer", concept.getAnswers()); + + List referenceTermRows = new ArrayList<>(); + for (ConceptReferenceTerm term : concept.getConceptReferenceTermsList()) { + referenceTermRows.add(new ConceptReferenceTermRow(term.getReferenceTermSource(), term.getReferenceTermCode(), term.getReferenceTermRelationship())); + } + String uuid = concept.getUuid(); + String units = concept.getUnits(); + String hiNormal = concept.getHiNormal(); + String lowNormal = concept.getLowNormal(); + String allowDecimal = concept.getAllowDecimal(); + return new ConceptRow(uuid, name, description, conceptClass, shortName, conceptDatatype, units, hiNormal, + lowNormal, allowDecimal, referenceTermRows, conceptSynonyms, conceptAnswers, locale); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/ConceptSetMapper.java b/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/ConceptSetMapper.java new file mode 100644 index 0000000000..03c39cc31a --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/ConceptSetMapper.java @@ -0,0 +1,117 @@ +package org.bahmni.module.admin.concepts.mapper; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.admin.csv.models.ConceptRows; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.contract.Concepts; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getKeyValueList; + +public class ConceptSetMapper { + + private ConceptMapper conceptMapper; + + public ConceptSetMapper() { + conceptMapper = new ConceptMapper(); + } + + public ConceptSet map(ConceptSetRow conceptSetRow) { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setUuid(conceptSetRow.getUuid()); + conceptSet.setUniqueName(conceptSetRow.getName()); + conceptSet.setDisplayName(conceptSetRow.getShortName()); + conceptSet.setClassName(conceptSetRow.conceptClass); + conceptSet.setDescription(conceptSetRow.description); + conceptSet.setChildren(getChildren(conceptSetRow)); + + List conceptReferenceTerms = new ArrayList<>(); + for (ConceptReferenceTermRow term : conceptSetRow.referenceTerms) { + conceptReferenceTerms.add(new ConceptReferenceTerm(term.getReferenceTermCode(), term.getReferenceTermRelationship(), term.getReferenceTermSource())); + } + + conceptSet.setConceptReferenceTermsList(conceptReferenceTerms); + return conceptSet; + } + + private List getChildren(ConceptSetRow conceptSetRow) { + List children = new ArrayList<>(); + List> sortedChildren = sortChildrenAccordingToNumericValueOfKey(conceptSetRow.getChildren()); + for (Map.Entry child : sortedChildren) { + if(!StringUtils.isEmpty(child.getValue())) { + children.add(child.getValue()); + } + } + return children; + } + + private List> sortChildrenAccordingToNumericValueOfKey(List children) { + HashMap childrenMap = new HashMap(); + for (KeyValue child : children) { + childrenMap.put(Integer.parseInt(child.getKey()), child.getValue()); + } + List> sortedChildren = new ArrayList>( + childrenMap.entrySet() + ); + Collections.sort( + sortedChildren + , new Comparator>() { + public int compare(Map.Entry a, Map.Entry b) { + return Integer.compare(a.getKey(), b.getKey()); + } + } + ); + return sortedChildren; + } + + + // private ConceptReferenceTerm getConceptReferenceTerm(ConceptSetRow conceptSetRow) { +// ConceptReferenceTerm conceptReferenceTerm = new ConceptReferenceTerm(); +// conceptReferenceTerm.setReferenceTermCode(conceptSetRow.referenceTermCode); +// conceptReferenceTerm.setReferenceTermRelationship(conceptSetRow.referenceTermRelationship); +// conceptReferenceTerm.setReferenceTermSource(conceptSetRow.referenceTermSource); +// return conceptReferenceTerm; +// } +// + public ConceptSetRow map(ConceptSet conceptSet) { + String name = conceptSet.getUniqueName(); + String description = conceptSet.getDescription(); + String shortName = conceptSet.getDisplayName(); + String conceptClass = conceptSet.getClassName(); + List children = getKeyValueList("child", conceptSet.getChildren()); + + List referenceTermRows = new ArrayList<>(); + for (ConceptReferenceTerm term : conceptSet.getConceptReferenceTermsList()) { + referenceTermRows.add(new ConceptReferenceTermRow(term.getReferenceTermSource(), term.getReferenceTermCode(), term.getReferenceTermRelationship())); + } + String uuid = conceptSet.getUuid(); + return new ConceptSetRow(uuid, name, description, conceptClass, shortName, referenceTermRows, children); + } + + + public ConceptRows mapAll(Concepts concepts) { + ConceptRows conceptRows = new ConceptRows(); + List conceptRowList = new ArrayList<>(); + List conceptSetRowList = new ArrayList<>(); + for (org.bahmni.module.referencedata.labconcepts.contract.Concept concept : concepts.getConceptList()) { + conceptRowList.add(conceptMapper.map(concept)); + } + for (ConceptSet conceptSet : concepts.getConceptSetList()) { + conceptSetRowList.add(map(conceptSet)); + } + conceptRows.setConceptRows(conceptRowList); + conceptRows.setConceptSetRows(conceptSetRowList); + return conceptRows; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/DrugMapper.java b/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/DrugMapper.java new file mode 100644 index 0000000000..8391e6013d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/concepts/mapper/DrugMapper.java @@ -0,0 +1,19 @@ +package org.bahmni.module.admin.concepts.mapper; + +import org.bahmni.module.admin.csv.models.DrugRow; +import org.bahmni.module.referencedata.labconcepts.contract.Drug; + +public class DrugMapper { + public Drug map(DrugRow drugRow) { + Drug drug = new Drug(); + drug.setUuid(drugRow.getUuid()); + drug.setName(drugRow.getName()); + drug.setGenericName(drugRow.getGenericName()); + drug.setDosageForm(drugRow.getDosageForm()); + drug.setStrength(drugRow.getStrength()); + drug.setMinimumDose(drugRow.getMinimumDose()); + drug.setMaximumDose(drugRow.getMaximumDose()); + drug.setCombination(drugRow.getCombination()); + return drug; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/config/dao/BahmniConfigDao.java b/admin/src/main/java/org/bahmni/module/admin/config/dao/BahmniConfigDao.java new file mode 100644 index 0000000000..df2e2eaf3d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/config/dao/BahmniConfigDao.java @@ -0,0 +1,19 @@ +package org.bahmni.module.admin.config.dao; + +import org.bahmni.module.admin.config.model.BahmniConfig; + +import java.util.List; + +public interface BahmniConfigDao { + BahmniConfig get(String appName, String configName); + + BahmniConfig get(String uuid); + + List getAllFor(String appName); + + BahmniConfig save(BahmniConfig bahmniConfig); + + BahmniConfig update(BahmniConfig existingConfig); + + List getAll(); +} diff --git a/admin/src/main/java/org/bahmni/module/admin/config/dao/impl/BahmniConfigDaoImpl.java b/admin/src/main/java/org/bahmni/module/admin/config/dao/impl/BahmniConfigDaoImpl.java new file mode 100644 index 0000000000..293af614f9 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/config/dao/impl/BahmniConfigDaoImpl.java @@ -0,0 +1,87 @@ +package org.bahmni.module.admin.config.dao.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.admin.config.dao.BahmniConfigDao; +import org.bahmni.module.admin.config.model.BahmniConfig; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class BahmniConfigDaoImpl implements BahmniConfigDao { + + @Autowired + private SessionFactory sessionFactory; + + @Override + public BahmniConfig get(String appName, String configName) { + List appConfig = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select config from BahmniConfig config " + + " where config.appName = :appName and config.configName = :configName"); + query.setParameter("appName", appName); + query.setParameter("configName", configName); + appConfig.addAll(query.list()); + return CollectionUtils.isEmpty(appConfig) ? null : appConfig.get(0); + } + + @Override + public BahmniConfig get(String uuid) { + List appConfig = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select config from BahmniConfig config " + + " where config.uuid = :uuid "); + query.setParameter("uuid", uuid); + appConfig.addAll(query.list()); + return CollectionUtils.isEmpty(appConfig) ? null : appConfig.get(0); + } + + //Mihir: Don't try to the merge the top one and this method together, since we are using a CLOB in MYSQL + //its a streaming Datatype, so best not to load things we don't require in the memory. + @Override + public List getAllFor(String appName) { + List appConfigs = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select config from BahmniConfig config " + + " where config.appName = :appName "); + query.setParameter("appName", appName); + appConfigs.addAll(query.list()); + for (BahmniConfig bahmniConfig : appConfigs) { + bahmniConfig.setConfig(null); + } + return appConfigs; + } + + @Override + public List getAll() { + List appConfigs = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select distinct config.appName from BahmniConfig config "); + appConfigs.addAll(query.list()); + return appConfigs; + } + + @Override + @Transactional + public BahmniConfig save(BahmniConfig bahmniConfig) { + sessionFactory.getCurrentSession().save(bahmniConfig); + return get(bahmniConfig.getAppName(), bahmniConfig.getConfigName()); + } + + @Override + @Transactional + public BahmniConfig update(BahmniConfig bahmniConfig) { + sessionFactory.getCurrentSession().update(bahmniConfig); + return bahmniConfig; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/config/model/BahmniConfig.java b/admin/src/main/java/org/bahmni/module/admin/config/model/BahmniConfig.java new file mode 100644 index 0000000000..4f00a11062 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/config/model/BahmniConfig.java @@ -0,0 +1,111 @@ +package org.bahmni.module.admin.config.model; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.openmrs.Auditable; +import org.openmrs.BaseOpenmrsObject; +import org.openmrs.User; + +import java.io.Serializable; +import java.util.Date; + +public class BahmniConfig extends BaseOpenmrsObject implements Auditable, Serializable { + private Integer configId; + + private String appName; + + private String configName; + + private User creator; + + private Date dateCreated; + + private User changedBy; + + private Date dateChanged; + + private String config; + + public Integer getConfigId() { + return configId; + } + + public void setConfigId(Integer configId) { + this.configId = configId; + } + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getConfigName() { + return configName; + } + + public void setConfigName(String configName) { + this.configName = configName; + } + + @Override + public Integer getId() { + return getConfigId(); + } + + @Override + public void setId(Integer id) { + setConfigId(id); + } + + @Override + @JsonIgnore + public User getCreator() { + return creator; + } + + @Override + public void setCreator(User creator) { + this.creator = creator; + } + + @Override + public Date getDateCreated() { + return dateCreated; + } + + @Override + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + @Override + @JsonIgnore + public User getChangedBy() { + return changedBy; + } + + @Override + public void setChangedBy(User changedBy) { + this.changedBy = changedBy; + } + + @Override + public Date getDateChanged() { + return dateChanged; + } + + @Override + public void setDateChanged(Date dateChanged) { + this.dateChanged = dateChanged; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/config/service/BahmniConfigService.java b/admin/src/main/java/org/bahmni/module/admin/config/service/BahmniConfigService.java new file mode 100644 index 0000000000..44d6534cb1 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/config/service/BahmniConfigService.java @@ -0,0 +1,17 @@ +package org.bahmni.module.admin.config.service; + +import org.bahmni.module.admin.config.model.BahmniConfig; + +import java.util.List; + +public interface BahmniConfigService { + BahmniConfig get(String appName, String configName); + + List getAllFor(String appName); + + BahmniConfig save(BahmniConfig bahmniConfig); + + BahmniConfig update(BahmniConfig bahmniConfig); + + List getAll(); +} diff --git a/admin/src/main/java/org/bahmni/module/admin/config/service/impl/BahmniConfigServiceImpl.java b/admin/src/main/java/org/bahmni/module/admin/config/service/impl/BahmniConfigServiceImpl.java new file mode 100644 index 0000000000..74e808ac5d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/config/service/impl/BahmniConfigServiceImpl.java @@ -0,0 +1,64 @@ +package org.bahmni.module.admin.config.service.impl; + +import org.bahmni.module.admin.config.dao.BahmniConfigDao; +import org.bahmni.module.admin.config.model.BahmniConfig; +import org.bahmni.module.admin.config.service.BahmniConfigService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@Service +public class BahmniConfigServiceImpl implements BahmniConfigService { + private BahmniConfigDao bahmniConfigDao; + + @Autowired + public BahmniConfigServiceImpl(BahmniConfigDao bahmniConfigDao) { + this.bahmniConfigDao = bahmniConfigDao; + } + + @Override + public BahmniConfig get(String appName, String configName) { + return bahmniConfigDao.get(appName, configName); + } + + @Override + public List getAllFor(String appName) { + return bahmniConfigDao.getAllFor(appName); + } + + @Override + public BahmniConfig save(BahmniConfig bahmniConfig) { + createNewConfig(bahmniConfig); + return bahmniConfigDao.save(bahmniConfig); + } + + @Override + public BahmniConfig update(BahmniConfig configUpdate) { + BahmniConfig existingConfig = bahmniConfigDao.get(configUpdate.getUuid()); + updateExistingConfig(configUpdate, existingConfig); + BahmniConfig updatedConfig = bahmniConfigDao.update(existingConfig); + return bahmniConfigDao.get(updatedConfig.getUuid()); + } + + @Override + public List getAll() { + return bahmniConfigDao.getAll(); + } + + private void createNewConfig(BahmniConfig bahmniConfig) { + bahmniConfig.setDateCreated(new Date()); + bahmniConfig.setCreator(Context.getAuthenticatedUser()); + bahmniConfig.setUuid(UUID.randomUUID().toString()); + bahmniConfig.setConfigId(null); + } + + private void updateExistingConfig(BahmniConfig updatedConfig, BahmniConfig existingConfig) { + existingConfig.setConfig(updatedConfig.getConfig()); + existingConfig.setChangedBy(Context.getAuthenticatedUser()); + existingConfig.setDateChanged(new Date()); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/exporter/ConceptSetExporter.java b/admin/src/main/java/org/bahmni/module/admin/csv/exporter/ConceptSetExporter.java new file mode 100644 index 0000000000..1c121ca0b8 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/exporter/ConceptSetExporter.java @@ -0,0 +1,31 @@ +package org.bahmni.module.admin.csv.exporter; + +import org.bahmni.module.admin.concepts.mapper.ConceptSetMapper; +import org.bahmni.module.admin.csv.models.ConceptRows; +import org.bahmni.module.referencedata.labconcepts.contract.Concepts; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.openmrs.api.APIException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ConceptSetExporter { + + @Autowired + private ReferenceDataConceptService conceptService; + private final ConceptSetMapper conceptSetMapper; + + public ConceptSetExporter() { + conceptSetMapper = new ConceptSetMapper(); + } + + public ConceptRows exportConcepts(String conceptName) { + Concepts conceptSet = conceptService.getConcept(conceptName); + if (conceptSet == null) { + throw new APIException("Concept " + conceptName + " not found"); + } + ConceptRows conceptRows = conceptSetMapper.mapAll(conceptSet); + conceptRows.makeCSVReady(); + return conceptRows; + } +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptReferenceTermRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptReferenceTermRow.java new file mode 100644 index 0000000000..98b47fca6c --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptReferenceTermRow.java @@ -0,0 +1,61 @@ +package org.bahmni.module.admin.csv.models; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.csv.annotation.CSVHeader; + +public class ConceptReferenceTermRow { + @CSVHeader(name = "reference-term-source") + private String referenceTermSource; + + @CSVHeader(name = "reference-term-code") + private String referenceTermCode; + + @CSVHeader(name = "reference-term-relationship") + private String referenceTermRelationship; + + public String getReferenceTermSource() { + return referenceTermSource; + } + + public void setReferenceTermSource(String referenceTermSource) { + this.referenceTermSource = referenceTermSource; + } + + public String getReferenceTermCode() { + return referenceTermCode; + } + + public void setReferenceTermCode(String referenceTermCode) { + this.referenceTermCode = referenceTermCode; + } + + public String getReferenceTermRelationship() { + return referenceTermRelationship; + } + + public void setReferenceTermRelationship(String referenceTermRelationship) { + this.referenceTermRelationship = referenceTermRelationship; + } + + public ConceptReferenceTermRow() { + + } + + public ConceptReferenceTermRow(String referenceTermSource, String referenceTermCode, String referenceTermRelationship) { + this.referenceTermSource = referenceTermSource; + this.referenceTermCode = referenceTermCode; + this.referenceTermRelationship = referenceTermRelationship; + } + + public boolean isEmpty() { + return StringUtils.isBlank(referenceTermSource) && StringUtils.isBlank(referenceTermCode) && StringUtils.isBlank(referenceTermRelationship); + } + + public String[] getRowValues() { + return new String[]{referenceTermSource, referenceTermCode, referenceTermRelationship}; + } + + public ConceptReferenceTermRow getHeaders() { + return new ConceptReferenceTermRow("reference-term-source", "reference-term-code", "reference-term-relationship"); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptRow.java new file mode 100644 index 0000000000..d7426d9d00 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptRow.java @@ -0,0 +1,232 @@ +package org.bahmni.module.admin.csv.models; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; +import org.bahmni.csv.annotation.CSVRepeatingHeaders; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getStringArray; + +public class ConceptRow extends CSVEntity { + @CSVHeader(name = "uuid", optional = true) + public String uuid; + + @CSVHeader(name = "name") + public String name; + + @CSVHeader(name = "description", optional = true) + public String description; + + @CSVHeader(name = "class") + public String conceptClass; + + @CSVHeader(name = "shortname") + public String shortName; + + @CSVRepeatingHeaders(names = {"reference-term-source", "reference-term-code", "reference-term-relationship"}, type = ConceptReferenceTermRow.class) + public List referenceTerms = new ArrayList<>(); + + @CSVHeader(name = "datatype") + public String dataType; + + @CSVRegexHeader(pattern = "synonym.*") + public List synonyms; + + @CSVRegexHeader(pattern = "answer.*") + public List answers; + + @CSVHeader(name = "units", optional = true) + public String units; + + @CSVHeader(name = "High Normal", optional = true) + public String hiNormal; + + @CSVHeader(name = "Low Normal", optional = true) + public String lowNormal; + + @CSVHeader(name = "Allow Decimal", optional = true) + public String allowDecimal; + + @CSVHeader(name = "locale", optional = true) + public String locale; + + public ConceptRow(String uuid, String name, String description, String conceptClass, String shortName, String dataType, + String units, String hiNormal, String lowNormal, String allowDecimal, List referenceTermRows, + List synonyms, List answers, String locale) { + this.uuid = uuid; + this.name = name; + this.description = description; + this.conceptClass = conceptClass; + this.shortName = shortName; + this.dataType = dataType; + this.synonyms = synonyms; + this.answers = answers; + this.units = units; + this.hiNormal = hiNormal; + this.lowNormal = lowNormal; + this.allowDecimal = allowDecimal; + this.referenceTerms = referenceTermRows; + this.locale = locale; + String[] aRow = {uuid, name, description, conceptClass, shortName, dataType, units, hiNormal, lowNormal, allowDecimal,locale}; + String[] synonymsRow = getStringArray(synonyms); + String[] answersRow = getStringArray(answers); + aRow = ArrayUtils.addAll(aRow, ArrayUtils.addAll(synonymsRow, answersRow)); + aRow = ArrayUtils.addAll(aRow, getReferenceTermRowValues()); + originalRow(aRow); + } + + public ConceptRow getHeaders() { + List synonymHeaders = new ArrayList<>(); + List answerHeaders = new ArrayList<>(); + List referenceTermHeaders = new ArrayList<>(); + for (int count = 1; count <= synonyms.size(); count++) { + synonymHeaders.add(new KeyValue("synonymHeader", "synonym." + count)); + } + for (int count = 1; count <= answers.size(); count++) { + answerHeaders.add(new KeyValue("answerHeader", "answer." + count)); + } + for (ConceptReferenceTermRow referenceTerm : referenceTerms) { + referenceTermHeaders.add(referenceTerm.getHeaders()); + } + + //TODO FIX reference terms + return new ConceptRow("uuid", "name", "description", "class", "shortname", "datatype", "units", "High Normal", "Low Normal","Allow Decimal", referenceTermHeaders, synonymHeaders, answerHeaders,"locale"); + } + + public ConceptRow() { + } + + public List getSynonyms() { + return synonyms == null ? new ArrayList() : synonyms; + } + + public List getAnswers() { + return answers == null ? new ArrayList() : answers; + } + + public String getName() { + return name == null ? null : name.trim(); + } + + public String getConceptClass() { + return conceptClass == null ? null : conceptClass.trim(); + } + + public String getUuid() { + try { + UUID uuid = UUID.fromString(this.uuid.trim()); + return uuid.toString(); + } catch (Exception e) { + return null; + } + } + + public String getDataType() { + return StringUtils.isEmpty(dataType) ? "N/A" : dataType; + } + + public String getDescription() { + return StringUtils.isEmpty(description) ? null : description; + } + + public String getShortName() { + return StringUtils.isEmpty(shortName) ? null : shortName; + } + + public List getReferenceTerms() { + return referenceTerms; + } + + public void setReferenceTerms(List referenceTerms) { + this.referenceTerms = referenceTerms; + } + + public String getUnits() { + return units; + } + + public void setUnits(String units) { + this.units = units; + } + + public String getHiNormal() { + return hiNormal; + } + + public void setHiNormal(String hiNormal) { + this.hiNormal = hiNormal; + } + + public String getLowNormal() { + return lowNormal; + } + + public void setLowNormal(String lowNormal) { + this.lowNormal = lowNormal; + } + + public String getAllowDecimal() { return allowDecimal; } + + public void setAllowDecimal(String allowDecimal) { this.allowDecimal = allowDecimal; } + + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + + public void adjust(int maxSynonyms, int maxAnswers, int maxReferenceTerms) { + addBlankSynonyms(maxSynonyms); + addBlankAnswers(maxAnswers); + addBlankReferenceTerms(maxReferenceTerms); + String[] aRow = {uuid, name, description, conceptClass, shortName, dataType, units, hiNormal, lowNormal, allowDecimal, locale}; + String[] synonymsRow = getStringArray(synonyms); + String[] answersRow = getStringArray(answers); + aRow = ArrayUtils.addAll(aRow, ArrayUtils.addAll(synonymsRow, answersRow)); + aRow = ArrayUtils.addAll(aRow, getReferenceTermRowValues()); + originalRow(aRow); + } + + private String[] getReferenceTermRowValues() { + String[] aRow = new String[0]; + for (ConceptReferenceTermRow referenceTerm : referenceTerms) { + aRow = ArrayUtils.addAll(aRow, referenceTerm.getRowValues()); + } + return aRow; + } + + private void addBlankReferenceTerms(int maxReferenceTerms) { + int counter = this.getReferenceTerms().size(); + while (counter <= maxReferenceTerms) { + this.referenceTerms.add(new ConceptReferenceTermRow(null, null, null)); + counter++; + } + } + + private void addBlankAnswers(int maxAnswers) { + int counter = this.getAnswers().size(); + this.answers = this.getAnswers(); + while (counter <= maxAnswers) { + this.answers.add(new KeyValue("answer", "")); + counter++; + } + } + + private void addBlankSynonyms(int maxSynonyms) { + int counter = this.getSynonyms().size(); + this.synonyms = this.getSynonyms(); + while (counter <= maxSynonyms) { + this.synonyms.add(new KeyValue("synonym", "")); + counter++; + } + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptRows.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptRows.java new file mode 100644 index 0000000000..07075c18f3 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptRows.java @@ -0,0 +1,94 @@ +package org.bahmni.module.admin.csv.models; + +import java.util.ArrayList; +import java.util.List; + +public class ConceptRows { + private List conceptRows; + private List conceptSetRows; + + public List getConceptRows() { + return conceptRows == null ? new ArrayList() : conceptRows; + } + + public void setConceptRows(List conceptRows) { + this.conceptRows = conceptRows; + } + + public List getConceptSetRows() { + return conceptSetRows == null ? new ArrayList() : conceptSetRows; + } + + public void setConceptSetRows(List conceptSetRows) { + this.conceptSetRows = conceptSetRows; + } + + public ConceptRows makeCSVReady() { + int maxSynonyms = getMaxSynonyms(); + int maxAnswers = getMaxAnswers(); + int maxReferenceTerms = getMaxReferenceTerms(); + int maxConceptSetReferenceTerms = getMaxConceptSetReferenceTerms(); + int maxSetMembers = getMaxSetMembers(); + conceptRows.add(0, new ConceptRow()); + conceptSetRows.add(0, new ConceptSetRow()); + for (ConceptRow conceptRow : getConceptRows()) { + conceptRow.adjust(maxSynonyms, maxAnswers, maxReferenceTerms); + } + for (ConceptSetRow conceptSetRow : getConceptSetRows()) { + conceptSetRow.adjust(maxSetMembers, maxConceptSetReferenceTerms); + } + conceptRows.set(0, conceptRows.get(0).getHeaders()); + conceptSetRows.set(0, conceptSetRows.get(0).getHeaders()); + return this; + } + + private int getMaxSetMembers() { + int maxSetMembers = 0; + for (ConceptSetRow conceptSetRow : getConceptSetRows()) { + if (conceptSetRow.getChildren().size() > maxSetMembers) { + maxSetMembers = conceptSetRow.getChildren().size(); + } + } + return maxSetMembers; + } + + private int getMaxSynonyms() { + int maxSynonyms = 0; + for (ConceptRow conceptRow : getConceptRows()) { + if (conceptRow.getSynonyms().size() > maxSynonyms) { + maxSynonyms = conceptRow.getSynonyms().size(); + } + } + return maxSynonyms; + } + + private int getMaxAnswers() { + int maxAnswers = 0; + for (ConceptRow conceptRow : getConceptRows()) { + if (conceptRow.getAnswers().size() > maxAnswers) { + maxAnswers = conceptRow.getAnswers().size(); + } + } + return maxAnswers; + } + + private int getMaxReferenceTerms() { + int maxReferenceTerms = 0; + for (ConceptRow conceptRow : getConceptRows()) { + if (conceptRow.getReferenceTerms().size() > maxReferenceTerms) { + maxReferenceTerms = conceptRow.getReferenceTerms().size(); + } + } + return maxReferenceTerms; + } + + private int getMaxConceptSetReferenceTerms() { + int maxReferenceTerms = 0; + for (ConceptSetRow conceptSetRow : getConceptSetRows()) { + if (conceptSetRow.referenceTerms.size() > maxReferenceTerms) { + maxReferenceTerms = conceptSetRow.referenceTerms.size(); + } + } + return maxReferenceTerms; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptSetRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptSetRow.java new file mode 100644 index 0000000000..83657b4fb7 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/ConceptSetRow.java @@ -0,0 +1,129 @@ +package org.bahmni.module.admin.csv.models; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; +import org.bahmni.csv.annotation.CSVRepeatingHeaders; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getStringArray; + +public class ConceptSetRow extends CSVEntity { + @CSVHeader(name = "uuid", optional = true) + public String uuid; + + @CSVHeader(name = "name") + public String name; + + @CSVHeader(name = "description", optional = true) + public String description; + + @CSVHeader(name = "class") + public String conceptClass; + + @CSVHeader(name = "shortname") + public String shortName; + + @CSVRepeatingHeaders(names = {"reference-term-source", "reference-term-code", "reference-term-relationship"}, type = ConceptReferenceTermRow.class) + public List referenceTerms = new ArrayList<>(); + + @CSVRegexHeader(pattern = "child.*") + public List children; + + public List getChildren() { + return children == null ? new ArrayList() : children; + } + + public String getShortName() { + return (shortName != null && StringUtils.isEmpty(shortName.trim())) ? null : shortName; + } + + public String getName() { + return name == null ? null : name.trim(); + } + + public String getConceptClass() { + return conceptClass == null ? null : conceptClass.trim(); + } + + public String getUuid() { + try { + UUID uuid = UUID.fromString(this.uuid.trim()); + return uuid.toString(); + } catch (Exception e) { + return null; + } + } + + public ConceptSetRow getHeaders() { + List childHeaders = new ArrayList<>(); + for (int childCount = 1; childCount <= children.size(); childCount++) { + childHeaders.add(new KeyValue("childHeader", "child." + childCount)); + } + + List referenceTermHeaders = new ArrayList<>(); + for (ConceptReferenceTermRow referenceTerm : referenceTerms) { + referenceTermHeaders.add(referenceTerm.getHeaders()); + } + return new ConceptSetRow("uuid", "name", "description", "class", "shortname", referenceTermHeaders, childHeaders); + } + + public ConceptSetRow(String uuid, String name, String description, String conceptClass, String shortName, List referenceTerms, List children) { + this.uuid = uuid; + this.name = name; + this.description = description; + this.conceptClass = conceptClass; + this.shortName = shortName; + this.children = children; + this.referenceTerms = referenceTerms; + String[] aRow = {uuid, name, description, conceptClass, shortName}; + String[] childrenRow = getStringArray(children); + aRow = ArrayUtils.addAll(aRow, childrenRow); + aRow = ArrayUtils.addAll(aRow, getReferenceTermRowValues()); + originalRow(aRow); + } + + public ConceptSetRow() { + } + + public void adjust(int maxSetMembers, int maxConceptSetReferenceTerms) { + addBlankChildren(maxSetMembers); + addBlankReferenceTerms(maxConceptSetReferenceTerms); + String[] aRow = {uuid, name, description, conceptClass, shortName}; + String[] childrenRow = getStringArray(children); + aRow = ArrayUtils.addAll(aRow, childrenRow); + aRow = ArrayUtils.addAll(aRow, getReferenceTermRowValues()); + originalRow(aRow); + } + + private void addBlankChildren(int maxSetMembers) { + int counter = this.getChildren().size(); + this.children = this.getChildren(); + while (counter <= maxSetMembers) { + this.children.add(new KeyValue("child", "")); + counter++; + } + } + + private void addBlankReferenceTerms(int maxReferenceTerms) { + int counter = this.referenceTerms.size(); + while (counter <= maxReferenceTerms) { + this.referenceTerms.add(new ConceptReferenceTermRow(null, null, null)); + counter++; + } + } + + private String[] getReferenceTermRowValues() { + String[] aRow = new String[0]; + for (ConceptReferenceTermRow referenceTerm : referenceTerms) { + aRow = ArrayUtils.addAll(aRow, referenceTerm.getRowValues()); + } + return aRow; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/DrugRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/DrugRow.java new file mode 100644 index 0000000000..b0fa2b597b --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/DrugRow.java @@ -0,0 +1,95 @@ +package org.bahmni.module.admin.csv.models; + +import org.apache.commons.lang3.BooleanUtils; +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.annotation.CSVHeader; + +public class DrugRow extends CSVEntity { + @CSVHeader(name = "uuid", optional = true) + private String uuid; + + @CSVHeader(name = "Name") + private String name; + + @CSVHeader(name = "Generic Name") + private String genericName; + + @CSVHeader(name = "Combination", optional = true) + private String combination; + + @CSVHeader(name = "Strength", optional = true) + private String strength; + + @CSVHeader(name = "Dosage Form") + private String dosageForm; + + @CSVHeader(name = "Minimum Dose", optional = true) + private String minimumDose; + + @CSVHeader(name = "Maximum Dose", optional = true) + private String maximumDose; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGenericName() { + return genericName; + } + + public void setGenericName(String genericName) { + this.genericName = genericName; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getStrength() { + return strength; + } + + public void setDosageForm(String dosageForm) { + this.dosageForm = dosageForm; + } + + public String getDosageForm() { + return dosageForm; + } + + public void setMinimumDose(String minimumDose) { + this.minimumDose = minimumDose; + } + + public String getMinimumDose() { + return minimumDose; + } + + public void setMaximumDose(String maximumDose) { + this.maximumDose = maximumDose; + } + + public String getMaximumDose() { + return maximumDose; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Boolean getCombination() { + return BooleanUtils.toBoolean(combination); + } + + public void setCombination(String combination) { + this.combination = combination; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/EncounterRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/EncounterRow.java new file mode 100644 index 0000000000..a9d6cdc46d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/EncounterRow.java @@ -0,0 +1,71 @@ +package org.bahmni.module.admin.csv.models; + +import org.apache.commons.lang.StringUtils; +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; + +import java.text.ParseException; +import java.util.Date; +import java.util.List; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; + +public class EncounterRow extends CSVEntity { + + @CSVHeader(name = "EncounterDate") + public String encounterDateTime; + + @CSVRegexHeader(pattern = "Obs.*") + public List obsRows; + + @CSVRegexHeader(pattern = "Diagnosis.*") + public List diagnosesRows; + + public Date getEncounterDate() throws ParseException { + return getDateFromString(encounterDateTime); + } + + public boolean hasObservations() { + return obsRows != null && !obsRows.isEmpty(); + } + + public boolean hasDiagnoses() { + return diagnosesRows != null && !diagnosesRows.isEmpty(); + } + + public boolean isEmpty() { + return areObservationsEmpty() && areDiagnosesEmpty() && noEncounterDate(); + } + + private boolean areDiagnosesEmpty() { + if (diagnosesRows == null || diagnosesRows.isEmpty()) + return true; + + for (KeyValue diagnosisRow : diagnosesRows) { + if (StringUtils.isNotBlank(diagnosisRow.getValue())) { + return false; + } + } + + return true; + } + + private boolean areObservationsEmpty() { + if (obsRows == null || obsRows.isEmpty()) + return true; + + for (KeyValue obsRow : obsRows) { + if (StringUtils.isNotBlank(obsRow.getValue())) { + return false; + } + } + + return true; + } + + private boolean noEncounterDate() { + return StringUtils.isBlank(encounterDateTime); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/FormerConceptReferenceRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/FormerConceptReferenceRow.java new file mode 100644 index 0000000000..b3fa16b895 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/FormerConceptReferenceRow.java @@ -0,0 +1,33 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRepeatingHeaders; + +import java.util.ArrayList; +import java.util.List; + +public class FormerConceptReferenceRow extends CSVEntity { + @CSVHeader(name = "concept-name") + private String conceptName; + + @CSVRepeatingHeaders(names = {"reference-term-source", "reference-term-code", "reference-term-relationship"}, type = ConceptReferenceTermRow.class) + private List referenceTerms = new ArrayList<>(); + + + public String getConceptName() { + return conceptName; + } + + public void setConceptName(String conceptName) { + this.conceptName = conceptName; + } + + public List getReferenceTerms() { + return referenceTerms; + } + + public void setReferenceTerms(List referenceTerms) { + this.referenceTerms = referenceTerms; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/LabResultRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/LabResultRow.java new file mode 100644 index 0000000000..8bae6e0fad --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/LabResultRow.java @@ -0,0 +1,38 @@ +package org.bahmni.module.admin.csv.models; + +import org.apache.commons.lang3.StringUtils; + +public class LabResultRow { + private String test; + private String result; + + public LabResultRow() { + } + + public LabResultRow(String test, String result) { + this.test = test; + this.result = result; + } + + public String getTest() { + return test; + } + + public LabResultRow setTest(String test) { + this.test = test; + return this; + } + + public String getResult() { + return result; + } + + public LabResultRow setResult(String result) { + this.result = result; + return this; + } + + public boolean isEmpty() { + return StringUtils.isBlank(test) && StringUtils.isBlank(result); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/LabResultsRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/LabResultsRow.java new file mode 100644 index 0000000000..b9757bcc17 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/LabResultsRow.java @@ -0,0 +1,83 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; +import org.bahmni.csv.annotation.CSVRepeatingHeaders; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; + +public class LabResultsRow extends CSVEntity { + @CSVHeader(name = "Registration Number") + private String patientIdentifier; + + @CSVRegexHeader(pattern = "Patient.*") + private List patientAttributes; + + @CSVHeader(name = "Date") + private String testDateString; + + @CSVHeader(name = "Visit Type") + private String visitType; + + @CSVRepeatingHeaders(names = {"Test", "Result"}, type = LabResultRow.class) + private List testResults; + + public List getTestResults() { + List labResultRows = new ArrayList<>(); + for (LabResultRow testResult : testResults) { + if (!testResult.isEmpty()) { + labResultRows.add(testResult); + } + } + return labResultRows; + } + + public LabResultsRow setTestResults(List testResults) { + this.testResults = testResults; + return this; + } + + public Date getTestDate() throws ParseException { + return getDateFromString(this.testDateString); + } + + public List getPatientAttributes() { + return patientAttributes; + } + + public LabResultsRow setPatientAttributes(List patientAttributes) { + this.patientAttributes = patientAttributes; + return this; + } + + public String getPatientIdentifier() { + return patientIdentifier; + } + + public LabResultsRow setPatientIdentifier(String patientIdentifier) { + this.patientIdentifier = patientIdentifier; + return this; + } + + public LabResultsRow setTestDateString(String testDateString) { + this.testDateString = testDateString; + return this; + } + + public String getVisitType() { + return visitType; + } + + public LabResultsRow setVisitType(String visitType) { + this.visitType = visitType; + return this; + } +} + diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/MultipleEncounterRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/MultipleEncounterRow.java new file mode 100644 index 0000000000..329b51e253 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/MultipleEncounterRow.java @@ -0,0 +1,67 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; +import org.bahmni.csv.annotation.CSVRepeatingRegexHeaders; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; + +public class MultipleEncounterRow extends CSVEntity { + + @CSVHeader(name = "Registration Number") + public String patientIdentifier; + + @CSVHeader(name = "encounterType") + public String encounterType; + + @CSVHeader(name = "visitType") + public String visitType; + + @CSVHeader(name = "providerName", optional = true) + public String providerName; + + @CSVHeader(name = "Visit Start Date", optional = true) + public String visitStartDate; + + @CSVHeader(name = "Visit End Date", optional = true) + public String visitEndDate; + + @CSVRegexHeader(pattern = "Patient.*") + public List patientAttributes; + + @CSVRepeatingRegexHeaders(type = EncounterRow.class) + public List encounterRows; + + public List getNonEmptyEncounterRows() { + List nonEmptyEncounters = new ArrayList<>(); + if (encounterRows == null) + return nonEmptyEncounters; + + for (EncounterRow encounterRow : encounterRows) { + if (!encounterRow.isEmpty()) { + nonEmptyEncounters.add(encounterRow); + } + } + return nonEmptyEncounters; + } + + public Date getVisitStartDate() throws ParseException { + if (visitStartDate == null) + return null; + return getDateFromString(visitStartDate); + } + + public Date getVisitEndDate() throws ParseException { + if (visitEndDate == null) + return null; + return getDateFromString(visitEndDate); + } +} + diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/PatientProgramRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/PatientProgramRow.java new file mode 100644 index 0000000000..81b26fcc48 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/PatientProgramRow.java @@ -0,0 +1,30 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; + +import java.text.ParseException; +import java.util.Date; +import java.util.List; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; + +public class PatientProgramRow extends CSVEntity { + @CSVHeader(name = "Registration Number") + public String patientIdentifier; + + @CSVRegexHeader(pattern = "Patient.*") + public List patientAttributes; + + @CSVHeader(name = "Program") + public String programName; + + @CSVHeader(name = "EnrollmentDate") + public String enrollmentDateTime; + + public Date getEnrollmentDate() throws ParseException { + return getDateFromString(enrollmentDateTime); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/PatientRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/PatientRow.java new file mode 100644 index 0000000000..8afd830965 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/PatientRow.java @@ -0,0 +1,44 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.annotation.CSVHeader; +import org.bahmni.csv.annotation.CSVRegexHeader; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; + +public class PatientRow extends CSVEntity { + @CSVHeader(name = "First Name") + public String firstName; + @CSVHeader(name = "Middle Name") + public String middleName; + @CSVHeader(name = "Last Name") + public String lastName; + @CSVHeader(name = "Registration Number") + public String registrationNumber; + @CSVHeader(name = "Gender") + public String gender; + @CSVHeader(name = "Age", optional = true) + public String age; + @CSVHeader(name = "Birth Date", optional = true) + public String birthdate; + @CSVHeader(name = "Registration Date", optional = true) + public String registrationDate; + + @CSVRegexHeader(pattern = "Address.*") + public List addressParts; + + @CSVRegexHeader(pattern = "Attribute.*") + public List attributes = new ArrayList<>(); + + public Date getRegistrationDate() throws ParseException { + if (registrationDate == null) + return null; + return getDateFromString(registrationDate); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/ReferenceTermRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/ReferenceTermRow.java new file mode 100644 index 0000000000..2ed05a2b57 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/ReferenceTermRow.java @@ -0,0 +1,72 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.annotation.CSVHeader; + +public class ReferenceTermRow extends CSVEntity { + @CSVHeader(name = "Code") + private String code; + + @CSVHeader(name = "Source") + private String source; + + @CSVHeader(name = "Name") + private String name; + + @CSVHeader(name = "Description", optional = true) + private String description; + + @CSVHeader(name = "Version", optional = true) + private String version; + + public ReferenceTermRow() { + } + + public ReferenceTermRow(String code, String source, String name, String description, String version) { + this.code = code; + this.source = source; + this.name = name; + this.description = description; + this.version = version; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/RelationshipRow.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/RelationshipRow.java new file mode 100644 index 0000000000..b9ffce0144 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/RelationshipRow.java @@ -0,0 +1,85 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.annotation.CSVHeader; + +public class RelationshipRow extends CSVEntity { + + @CSVHeader(name = "Registration_Number") + private String patientIdentifier; + + @CSVHeader(name = "Relationship_Type") + private String relationshipType; + + @CSVHeader(name = "Related_To_Registration_Number") + private String patientRelationIdentifier; + + @CSVHeader(name = "Provider_Name") + private String providerName; + + @CSVHeader(name = "Relationship_StartDate") + private String startDate; + + @CSVHeader(name = "Relationship_EndDate") + private String endDate; + + public RelationshipRow(String patientIdentifier, String patientRelationIdentifier, String providerName, String relationshipType, String startDate, String endDate) { + this.patientIdentifier = patientIdentifier; + this.patientRelationIdentifier = patientRelationIdentifier; + this.providerName = providerName; + this.relationshipType = relationshipType; + this.startDate = startDate; + this.endDate = endDate; + } + + public RelationshipRow() { + } + + public String getPatientIdentifier() { + return patientIdentifier; + } + + public void setPatientIdentifier(String patientIdentifier) { + this.patientIdentifier = patientIdentifier; + } + + public String getPatientRelationIdentifier() { + return patientRelationIdentifier; + } + + public void setPatientRelationIdentifier(String patientRelationIdentifier) { + this.patientRelationIdentifier = patientRelationIdentifier; + } + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public String getRelationshipType() { + return relationshipType; + } + + public void setRelationshipType(String relationshipType) { + this.relationshipType = relationshipType; + } + + public String getStartDate() { + return startDate; + } + + public void setStartDate(String startDate) { + this.startDate = startDate; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(String endDate) { + this.endDate = endDate; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/models/SectionPositionValue.java b/admin/src/main/java/org/bahmni/module/admin/csv/models/SectionPositionValue.java new file mode 100644 index 0000000000..58823c66b9 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/models/SectionPositionValue.java @@ -0,0 +1,60 @@ +package org.bahmni.module.admin.csv.models; + +public class SectionPositionValue { + + private String value; + private String sectionIndex; + private int valueIndex; + + private int multiSelectIndex; + private int addmoreIndex; + + public SectionPositionValue(String value, String sectionIndex, int valueIndex, int multiSelectIndex, int addmoreIndex) { + this.value = value; + this.sectionIndex = sectionIndex; + this.valueIndex = valueIndex; + this.multiSelectIndex = multiSelectIndex; + this.addmoreIndex = addmoreIndex; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getSectionIndex() { + return sectionIndex; + } + + public void setSectionIndex(String sectionIndex) { + this.sectionIndex = sectionIndex; + } + + public int getValueIndex() { + return valueIndex; + } + + public void setValueIndex(int valueIndex) { + this.valueIndex = valueIndex; + } + + public int getMultiSelectIndex() { + return multiSelectIndex; + } + + public void setMultiSelectIndex(int multiSelectIndex) { + this.multiSelectIndex = multiSelectIndex; + } + + public int getAddmoreIndex() { + return addmoreIndex; + } + + public void setAddmoreIndex(int addmoreIndex) { + this.addmoreIndex = addmoreIndex; + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/BahmniPatientMatchingAlgorithm.java b/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/BahmniPatientMatchingAlgorithm.java new file mode 100644 index 0000000000..5febe0a13b --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/BahmniPatientMatchingAlgorithm.java @@ -0,0 +1,13 @@ +package org.bahmni.module.admin.csv.patientmatchingalgorithm; + +import org.bahmni.csv.KeyValue; +import org.openmrs.Patient; + +import java.util.List; + +public class BahmniPatientMatchingAlgorithm extends PatientMatchingAlgorithm { + @Override + public Patient run(List patientList, List patientAttributes) { + return patientList.size() > 0 ? patientList.get(0) : null; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/PatientMatchingAlgorithm.java b/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/PatientMatchingAlgorithm.java new file mode 100644 index 0000000000..e7a9ada377 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/PatientMatchingAlgorithm.java @@ -0,0 +1,20 @@ +package org.bahmni.module.admin.csv.patientmatchingalgorithm; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.patientmatchingalgorithm.exception.CannotMatchPatientException; +import org.openmrs.Patient; + +import java.util.List; + +public abstract class PatientMatchingAlgorithm { + public String valueFor(String keyToSearch, List patientAttributes) { + for (KeyValue patientAttributeKeyValue : patientAttributes) { + if (patientAttributeKeyValue.getKey().equalsIgnoreCase(keyToSearch)) { + return patientAttributeKeyValue.getValue(); + } + } + return null; + } + + public abstract Patient run(List patientList, List patientAttributes) throws CannotMatchPatientException; +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/exception/CannotMatchPatientException.java b/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/exception/CannotMatchPatientException.java new file mode 100644 index 0000000000..0f13c6a958 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/patientmatchingalgorithm/exception/CannotMatchPatientException.java @@ -0,0 +1,37 @@ +package org.bahmni.module.admin.csv.patientmatchingalgorithm.exception; + +import org.openmrs.Patient; + +import java.util.List; + +public class CannotMatchPatientException extends Exception { + private String patientIds = ""; + + public CannotMatchPatientException() { + } + + public CannotMatchPatientException(List patients) { + this.patientIds = getPatientIds(patients); + } + + @Override + public String getMessage() { + return "No matching patients found. Potential matches:'" + patientIds + "'"; + } + + @Override + public String toString() { + return "CannotMatchPatientException{Potential matches patientIds='" + patientIds + "'}"; + } + + private String getPatientIds(List patients) { + if (patients == null) + return ""; + + StringBuffer patientIdsBuffer = new StringBuffer(); + for (Patient patient : patients) { + patientIdsBuffer.append(patient.getPatientIdentifier().getIdentifier()).append(", "); + } + return patientIdsBuffer.toString(); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptPersister.java new file mode 100644 index 0000000000..392aa9cf69 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptPersister.java @@ -0,0 +1,37 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang.StringUtils; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.concepts.mapper.ConceptMapper; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ConceptPersister implements EntityPersister { + + @Autowired + private ReferenceDataConceptService referenceDataConceptService; + + @Override + public Messages validate(ConceptRow conceptRow) { + Messages messages = new Messages(); + if (StringUtils.isEmpty(conceptRow.name)) { + messages.add("Concept Name not specified\n"); + } + if (StringUtils.isEmpty(conceptRow.conceptClass)) { + messages.add("Concept Class not specified\n"); + } + return messages; + } + + @Override + public Messages persist(ConceptRow conceptRow) { + Concept concept = new ConceptMapper().map(conceptRow); + referenceDataConceptService.saveConcept(concept); + return new Messages(); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptReferenceTermPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptReferenceTermPersister.java new file mode 100644 index 0000000000..3527e0f975 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptReferenceTermPersister.java @@ -0,0 +1,96 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.FormerConceptReferenceRow; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptReferenceTermService; +import org.openmrs.Concept; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.Objects.isNull; + +@Service +public class ConceptReferenceTermPersister implements EntityPersister { + private static final Logger log = LogManager.getLogger(ConceptReferenceTermPersister.class); + + @Autowired + private ReferenceDataConceptReferenceTermService referenceTermService; + + @Autowired + private ConceptService conceptService; + + + private UserContext userContext; + + public void init(UserContext userContext) { + this.userContext = userContext; + } + + @Override + public Messages persist(FormerConceptReferenceRow formerConceptReferenceRow) { + Concept concept = conceptService.getConceptByName(formerConceptReferenceRow.getConceptName()); + concept.getConceptMappings().addAll(getNewConceptMappings(formerConceptReferenceRow.getReferenceTerms(), concept)); + conceptService.saveConcept(concept); + + return new Messages(); + } + + private List getNewConceptMappings(List referenceTerms, Concept concept) { + return referenceTerms.stream().map(termRow -> getConceptMap(concept, termRow)).collect(Collectors.toList()); + } + + private ConceptMap getConceptMap(Concept concept, ConceptReferenceTermRow termRow) { + String code = termRow.getReferenceTermCode(); + String source = termRow.getReferenceTermSource(); + + ConceptReferenceTerm conceptReferenceTerm = referenceTermService.getConceptReferenceTerm(code, source); + ConceptMap conceptMap = new ConceptMap(); + conceptMap.setConceptReferenceTerm(conceptReferenceTerm); + conceptMap.setConcept(concept); + conceptMap.setConceptMapType(conceptService.getConceptMapTypeByName(termRow.getReferenceTermRelationship())); + return conceptMap; + } + + @Override + public Messages validate(FormerConceptReferenceRow formerConceptReferenceRow) { + Messages messages = new Messages(); + Context.openSession(); + Context.setUserContext(userContext); + + String conceptName = formerConceptReferenceRow.getConceptName(); + if (isNull(conceptService.getConceptByName(conceptName))) + messages.add(String.format("%s concept is not present", conceptName)); + + formerConceptReferenceRow.getReferenceTerms().forEach(termRow -> { + String code = termRow.getReferenceTermCode(); + String source = termRow.getReferenceTermSource(); + + try { + referenceTermService.getConceptReferenceTerm(code, source); + } catch (Exception e) { + log.error(e.getMessage(), e); + messages.add(String.format("%s reference term code is not present in %s source", code, source)); + } + if (isNull(conceptService.getConceptMapTypeByName(termRow.getReferenceTermRelationship()))) + messages.add(String.format("%s concept map type is not present", termRow.getReferenceTermRelationship())); + + }); + + Context.flushSession(); + Context.closeSession(); + + return messages; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptSetPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptSetPersister.java new file mode 100644 index 0000000000..c142cd8b9e --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ConceptSetPersister.java @@ -0,0 +1,88 @@ +package org.bahmni.module.admin.csv.persister; + + +import org.apache.commons.lang.StringUtils; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.concepts.mapper.ConceptSetMapper; +import org.bahmni.module.admin.csv.models.ConceptRows; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ConceptSetPersister implements EntityPersister { + + @Autowired + private ReferenceDataConceptService referenceDataConceptService; + + + + @Override + public Messages validate(ConceptSetRow conceptSetRow) { + Messages messages = new Messages(); + if (StringUtils.isEmpty(conceptSetRow.name)) { + messages.add("Concept Name not specified\n"); + } + if (StringUtils.isEmpty(conceptSetRow.conceptClass)) { + messages.add("Concept Class not specified\n"); + } + for (KeyValue conceptKeyValue: conceptSetRow.getChildren()) { + if(conceptKeyValue.getValue().equals(conceptSetRow.getName())){ + messages.add("Concept introduces cycle\n"); + } + } + + return messages; + + } + + private boolean createsCycle(ConceptSetRow newConceptSetRow){ + + List descendantNames = getAllDescendantsNames(newConceptSetRow); + for (String descendantName: descendantNames) { + if(descendantName.equals(newConceptSetRow.getName())){ + return true; + } + } + return false; + } + + private List getAllDescendantsNames(ConceptSetRow newConceptSetRow) { + List descendants = new ArrayList<>(); + + List conceptRowsCollection = new ArrayList<>(); + for (KeyValue concept: newConceptSetRow.getChildren()) { + if(StringUtils.isNotEmpty(concept.getValue())) { + conceptRowsCollection.add(new ConceptSetMapper().mapAll(referenceDataConceptService.getConcept(concept.getValue()))); + } + } + for (ConceptRows conceptRows: conceptRowsCollection) { + for (ConceptSetRow conceptSetRow: conceptRows.getConceptSetRows()) { + descendants.add(conceptSetRow.getName()); + } + } + return descendants; + } + + + @Override + public Messages persist(ConceptSetRow conceptSetRow) { + Messages messages = new Messages(); + if(createsCycle(conceptSetRow)){ + messages.add("Concept Set introduces cycle\n"); + return messages; + } + + ConceptSet concept = new ConceptSetMapper().map(conceptSetRow); + referenceDataConceptService.saveConcept(concept); + return new Messages(); + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/DatabasePersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/DatabasePersister.java new file mode 100644 index 0000000000..09fc0e553c --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/DatabasePersister.java @@ -0,0 +1,41 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; + +public class DatabasePersister implements EntityPersister { + private final EntityPersister persister; + private final UserContext userContext; + private static final Logger log = LogManager.getLogger(DatabasePersister.class); + + public DatabasePersister(EntityPersister persister) { + this.persister = persister; + userContext = Context.getUserContext(); + } + + @Override + public Messages persist(T csvEntity) { + try { + Context.openSession(); + Context.setUserContext(userContext); + return persister.persist(csvEntity); + } catch (Throwable e) { + log.error(e.getMessage(), e); + Context.clearSession(); + return new Messages(e); + } finally { + Context.flushSession(); + Context.closeSession(); + } + } + + @Override + public Messages validate(T csvEntity) { + return persister.validate(csvEntity); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/DrugPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/DrugPersister.java new file mode 100644 index 0000000000..bbb4bc440d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/DrugPersister.java @@ -0,0 +1,36 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang.StringUtils; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.concepts.mapper.DrugMapper; +import org.bahmni.module.admin.csv.models.DrugRow; +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataDrugService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DrugPersister implements EntityPersister { + @Autowired + private ReferenceDataDrugService referenceDataDrugService; + + @Override + public Messages validate(DrugRow drugRow) { + Messages messages = new Messages(); + if (StringUtils.isEmpty(drugRow.getName())) { + messages.add("Drug name not specified\n"); + } + if (StringUtils.isEmpty(drugRow.getGenericName())) { + messages.add("Drug generic name not specified\n"); + } + return messages; + } + + @Override + public Messages persist(DrugRow drugRow) { + Drug drug = new DrugMapper().map(drugRow); + referenceDataDrugService.saveDrug(drug); + return new Messages(); + } +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/EncounterPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/EncounterPersister.java new file mode 100644 index 0000000000..22a3da5124 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/EncounterPersister.java @@ -0,0 +1,154 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.MultipleEncounterRow; +import org.bahmni.module.admin.csv.service.PatientMatchService; +import org.bahmni.module.admin.encounter.BahmniEncounterTransactionImportService; +import org.bahmni.module.admin.retrospectiveEncounter.service.DuplicateObservationService; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.auditlog.service.AuditLogService; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniProviderMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Component +public class EncounterPersister implements EntityPersister { + public static final String IMPORT_ID = "IMPORT_ID_"; + @Autowired + private PatientMatchService patientMatchService; + @Autowired + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + @Autowired + private DuplicateObservationService duplicateObservationService; + @Autowired + private BahmniEncounterTransactionImportService bahmniEncounterTransactionImportService; + @Autowired + private AuditLogService auditLogService; + + private UserContext userContext; + private String patientMatchingAlgorithmClassName; + private boolean shouldMatchExactPatientId; + private String loginUuid; + private boolean shouldPerformForm2Validations; + + private static final Logger log = LogManager.getLogger(EncounterPersister.class); + + public void init(UserContext userContext, String patientMatchingAlgorithmClassName, boolean shouldMatchExactPatientId, String loginUuid, boolean shouldPerformForm2Validations) { + this.userContext = userContext; + this.patientMatchingAlgorithmClassName = patientMatchingAlgorithmClassName; + this.shouldMatchExactPatientId = shouldMatchExactPatientId; + this.loginUuid = loginUuid; + this.shouldPerformForm2Validations = shouldPerformForm2Validations; + } + + @Override + public Messages validate(MultipleEncounterRow multipleEncounterRow) { + return new Messages(); + } + + @Override + public Messages persist(MultipleEncounterRow multipleEncounterRow) { + // This validation is needed as patientservice toString returns all patients for empty patient identifier + if (StringUtils.isEmpty(multipleEncounterRow.patientIdentifier)) { + return noMatchingPatients(multipleEncounterRow); + } + synchronized ((IMPORT_ID + multipleEncounterRow.patientIdentifier).intern()) { + try { + Context.openSession(); + Context.setUserContext(userContext); + + Patient patient = patientMatchService.getPatient(patientMatchingAlgorithmClassName, multipleEncounterRow.patientAttributes, + multipleEncounterRow.patientIdentifier, shouldMatchExactPatientId); + if (patient == null) { + return noMatchingPatients(multipleEncounterRow); + } + + Set providers = getProviders(multipleEncounterRow.providerName); + + if(providers.isEmpty()) { + return noMatchingProviders(multipleEncounterRow); + } + + List bahmniEncounterTransactions = bahmniEncounterTransactionImportService.getBahmniEncounterTransaction(multipleEncounterRow, patient, shouldPerformForm2Validations); + + for (BahmniEncounterTransaction bahmniEncounterTransaction : bahmniEncounterTransactions) { + bahmniEncounterTransaction.setLocationUuid(loginUuid); + bahmniEncounterTransaction.setProviders(providers); + duplicateObservationService.filter(bahmniEncounterTransaction, patient, multipleEncounterRow.getVisitStartDate(), multipleEncounterRow.getVisitEndDate()); + } + Boolean isAuditLogEnabled = Boolean.valueOf(Context.getAdministrationService().getGlobalProperty("bahmni.enableAuditLog")); + for (BahmniEncounterTransaction bahmniEncounterTransaction : bahmniEncounterTransactions) { + BahmniEncounterTransaction updatedBahmniEncounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction, patient, multipleEncounterRow.getVisitStartDate(), multipleEncounterRow.getVisitEndDate()); + if (isAuditLogEnabled) { + Map params = new HashMap<>(); + params.put("encounterUuid", updatedBahmniEncounterTransaction.getEncounterUuid()); + params.put("encounterType", updatedBahmniEncounterTransaction.getEncounterType()); + auditLogService.createAuditLog(patient.getUuid(), "EDIT_ENCOUNTER", "EDIT_ENCOUNTER_MESSAGE", params, "MODULE_LABEL_ADMIN_KEY"); + } + } + + return new Messages(); + } catch (Exception e) { + log.error(e.getMessage(), e); + Context.clearSession(); + return new Messages(e); + } finally { + Context.flushSession(); + Context.closeSession(); + } + } + } + + private Set getProviders(String providerName) { + Set encounterTransactionProviders = new HashSet<>(); + + if (StringUtils.isEmpty(providerName)) { + providerName = userContext.getAuthenticatedUser().getUsername(); + } + + User user = Context.getUserService().getUserByUsername(providerName); + + if (user == null){ + return encounterTransactionProviders; + } + + Collection providers = Context.getProviderService().getProvidersByPerson(user.getPerson()); + + Set providerSet = new HashSet<>(providers); + + BahmniProviderMapper bahmniProviderMapper = new BahmniProviderMapper(); + + Iterator iterator = providerSet.iterator(); + while (iterator.hasNext()) { + encounterTransactionProviders.add(bahmniProviderMapper.map((Provider) iterator.next())); + } + + return encounterTransactionProviders; + } + + private Messages noMatchingPatients(MultipleEncounterRow multipleEncounterRow) { + return new Messages("No matching patients found with ID:'" + multipleEncounterRow.patientIdentifier + "'"); + } + + private Messages noMatchingProviders(MultipleEncounterRow multipleEncounterRow) { + return new Messages("No matching providers found with username:'" + multipleEncounterRow.providerName + "'"); + } +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/LabResultPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/LabResultPersister.java new file mode 100644 index 0000000000..648bda52df --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/LabResultPersister.java @@ -0,0 +1,163 @@ +package org.bahmni.module.admin.csv.persister; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.LabResultRow; +import org.bahmni.module.admin.csv.models.LabResultsRow; +import org.bahmni.module.admin.csv.service.PatientMatchService; +import org.openmrs.CareSetting; +import org.openmrs.Concept; +import org.openmrs.ConceptNumeric; +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.auditlog.service.AuditLogService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitIdentificationHelper; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.mapper.LabOrderResultMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; + +@Component +public class LabResultPersister implements EntityPersister { + private static final Log log = LogFactory.getLog(LabResultPersister.class); + public static final String LAB_RESULT_ENCOUNTER_TYPE = "LAB_RESULT"; + public static final String LAB_ORDER_TYPE = "Lab Order"; + private String patientMatchingAlgorithmClassName; + private boolean shouldMatchExactPatientId; + + @Autowired + private PatientMatchService patientMatchService; + @Autowired + private ConceptService conceptService; + @Autowired + private OrderService orderService; + @Autowired + private ProviderService providerService; + @Autowired + private EncounterService encounterService; + @Autowired + private VisitIdentificationHelper visitIdentificationHelper; + @Autowired + private LabOrderResultMapper labOrderResultMapper; + @Autowired + private BahmniVisitAttributeService bahmniVisitAttributeSaveCommand; + @Autowired + private AuditLogService auditLogService; + private UserContext userContext; + private String loginLocationUuid; + + public void init(UserContext userContext, String patientMatchingAlgorithmClassName, boolean shouldMatchExactPatientId, String loginLocationUuid) { + this.userContext = userContext; + this.patientMatchingAlgorithmClassName = patientMatchingAlgorithmClassName; + this.shouldMatchExactPatientId = shouldMatchExactPatientId; + this.loginLocationUuid = loginLocationUuid; + } + + @Override + public Messages persist(LabResultsRow labResultsRow) { + try { + Patient patient = patientMatchService.getPatient(patientMatchingAlgorithmClassName, labResultsRow.getPatientAttributes(), labResultsRow.getPatientIdentifier(), shouldMatchExactPatientId); + Visit visit = visitIdentificationHelper.getVisitFor(patient, labResultsRow.getVisitType(), labResultsRow.getTestDate(), labResultsRow.getTestDate(), labResultsRow.getTestDate(), loginLocationUuid); + Encounter encounter = new Encounter(); + encounter.setPatient(patient); + encounter.setEncounterDatetime(labResultsRow.getTestDate()); + encounter.setEncounterType(encounterService.getEncounterType(LAB_RESULT_ENCOUNTER_TYPE)); + encounter.addProvider(encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID), getProvider()); + HashSet resultObservations = new HashSet<>(); + for (LabResultRow labResultRow : labResultsRow.getTestResults()) { + org.openmrs.Concept concept = conceptService.getConceptByName(labResultRow.getTest()); + if (concept.isNumeric()) { + ConceptNumeric cn = (ConceptNumeric) concept; + if (!cn.isAllowDecimal() && labResultRow.getResult().contains(".")) { + throw new APIException("Decimal is not allowed for " + cn.getName() + " concept"); + } + } + Order testOrder = getTestOrder(patient, labResultRow, labResultsRow.getTestDate()); + encounter.addOrder(testOrder); + resultObservations.add(getResultObs(labResultRow.getResult(), testOrder, concept)); + } + visit.addEncounter(encounter); + Encounter savedEncounter = encounterService.saveEncounter(encounter); + bahmniVisitAttributeSaveCommand.save(savedEncounter); + Boolean isAuditLogEnabled = Boolean.valueOf(Context.getAdministrationService().getGlobalProperty("bahmni.enableAuditLog")); + if (isAuditLogEnabled) { + Map params = new HashMap<>(); + params.put("encounterUuid", savedEncounter.getUuid()); + params.put("encounterType", savedEncounter.getEncounterType().getName()); + auditLogService.createAuditLog(patient.getUuid(), "EDIT_ENCOUNTER", "EDIT_ENCOUNTER_MESSAGE", params, "MODULE_LABEL_ADMIN_KEY"); + } + saveResults(encounter, resultObservations); + return new Messages(); + } catch (Exception e) { + throw new APIException(e.getMessage(), e); + } + } + + // Hack: OpenMRS doesn't allow saving order and its associated observations in single call + // throws error object references an unsaved transient instance - save the transient instance before flushing + private void saveResults(Encounter encounter, HashSet resultObservations) { + for (Obs obs : resultObservations) { + encounter.addObs(obs); + } + encounterService.saveEncounter(encounter); + } + + private Order getTestOrder(Patient patient, LabResultRow labResultRow, Date testDate) throws ParseException { + Order order = new Order(); + order.setConcept(conceptService.getConceptByName(labResultRow.getTest())); + order.setDateActivated(testDate); + order.setAutoExpireDate(testDate); + order.setPatient(patient); + order.setOrderType(orderService.getOrderTypeByName(LAB_ORDER_TYPE)); + order.setCareSetting(orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString())); + order.setOrderer(getProvider()); + return order; + } + + private Obs getResultObs(String labResult, Order testOrder, Concept concept) { + LabOrderResult labOrderResult = new LabOrderResult(); + labOrderResult.setResult(labResult); + labOrderResult.setResultDateTime(testOrder.getDateActivated()); + if (concept.getDatatype().getHl7Abbreviation().equals(org.openmrs.ConceptDatatype.CODED)) { + Concept resultConcept = conceptService.getConceptByName(labResult); + if (resultConcept != null) + labOrderResult.setResultUuid(resultConcept.getUuid()); + else + log.warn(String.format("Concept is not available in OpenMRS for concept name: %s", labResult)); + } + return labOrderResultMapper.map(labOrderResult, testOrder, testOrder.getConcept()); + } + + private Provider getProvider() { + Collection providers = providerService.getProvidersByPerson(userContext.getAuthenticatedUser().getPerson()); + return providers.size() > 0 ? providers.iterator().next() : null; + } + + @Override + public Messages validate(LabResultsRow labResultsRow) { + return new Messages(); + } +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/PatientPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/PatientPersister.java new file mode 100644 index 0000000000..d8865873eb --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/PatientPersister.java @@ -0,0 +1,86 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.common.config.registration.service.RegistrationPageReaderService; +import org.bahmni.common.config.registration.service.RegistrationPageService; +import org.bahmni.common.config.registration.service.impl.RegistrationPageReaderServiceImpl; +import org.bahmni.common.config.registration.service.impl.RegistrationPageServiceImpl; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.PatientRow; +import org.bahmni.module.admin.csv.service.CSVAddressService; +import org.bahmni.module.admin.csv.service.CSVPatientService; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.addresshierarchy.service.AddressHierarchyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +public class PatientPersister implements EntityPersister { + private UserContext userContext; + + @Autowired + private PatientService patientService; + + @Autowired + private PersonService personService; + + @Autowired + private ConceptService conceptService; + + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + + private CSVAddressService csvAddressService; + + private static final Logger log = LogManager.getLogger(PatientPersister.class); + + private RegistrationPageReaderService registrationPageReaderService = new RegistrationPageReaderServiceImpl(); + + private RegistrationPageService registrationPageService = new RegistrationPageServiceImpl(registrationPageReaderService); + + + public void init(UserContext userContext) { + this.userContext = userContext; + } + + @Override + public Messages persist(PatientRow patientRow) { + try { + Context.openSession(); + Context.setUserContext(userContext); + + new CSVPatientService(patientService, personService, conceptService, administrationService, getAddressHierarchyService(), registrationPageService).save(patientRow); + + return new Messages(); + } catch (Throwable e) { + log.error(e.getMessage(), e); + Context.clearSession(); + return new Messages(e); + } finally { + Context.flushSession(); + Context.closeSession(); + } + } + + private CSVAddressService getAddressHierarchyService() { + if (csvAddressService == null) { + AddressHierarchyService addressHierarchyService = Context.getService(AddressHierarchyService.class); + this.csvAddressService = new CSVAddressService(addressHierarchyService); + } + return csvAddressService; + } + + @Override + public Messages validate(PatientRow csvEntity) { + return new Messages(); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/PatientProgramPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/PatientProgramPersister.java new file mode 100644 index 0000000000..3aff82d3db --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/PatientProgramPersister.java @@ -0,0 +1,114 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.PatientProgramRow; +import org.bahmni.module.admin.csv.service.PatientMatchService; +import org.openmrs.ConceptName; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Program; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class PatientProgramPersister implements EntityPersister { + @Autowired + private PatientMatchService patientMatchService; + @Autowired + private ProgramWorkflowService programWorkflowService; + + private UserContext userContext; + + private static final Logger log = LogManager.getLogger(PatientProgramPersister.class); + private String patientMatchingAlgorithmClassName; + + public void init(UserContext userContext, String patientMatchingAlgorithmClassName) { + this.userContext = userContext; + this.patientMatchingAlgorithmClassName = patientMatchingAlgorithmClassName; + } + + @Override + public Messages validate(PatientProgramRow patientProgramRow) { + return new Messages(); + } + + @Override + public Messages persist(PatientProgramRow patientProgramRow) { + // This validation is needed as patientservice toString returns all patients for empty patient identifier + if (StringUtils.isEmpty(patientProgramRow.patientIdentifier)) { + return noMatchingPatients(patientProgramRow); + } + + try { + Context.openSession(); + Context.setUserContext(userContext); + + boolean shouldMatchExactPatientId = false; //Mujir - defaulting to false for now. Not sure if we have program data for migration that does not have exact patient identifiers. + + Patient patient = patientMatchService.getPatient(patientMatchingAlgorithmClassName, patientProgramRow.patientAttributes, patientProgramRow.patientIdentifier, shouldMatchExactPatientId); + if (patient == null) { + return noMatchingPatients(patientProgramRow); + } + + Program program = getProgramByName(patientProgramRow.programName); + List existingEnrolledPrograms = programWorkflowService.getPatientPrograms(patient, program, null, null, null, null, false); + if (existingEnrolledPrograms != null && !existingEnrolledPrograms.isEmpty()) { + return new Messages(getErrorMessage(existingEnrolledPrograms)); + } + + PatientProgram patientProgram = new PatientProgram(); + patientProgram.setPatient(patient); + patientProgram.setProgram(program); + patientProgram.setDateEnrolled(patientProgramRow.getEnrollmentDate()); + + programWorkflowService.savePatientProgram(patientProgram); + + } catch (Exception e) { + log.error(e.getMessage(), e); + Context.clearSession(); + return new Messages(e); + } finally { + Context.flushSession(); + Context.closeSession(); + } + return new Messages(); + } + + private String getErrorMessage(List patientPrograms) { + PatientProgram existingProgram = patientPrograms.get(0); + String errorMessage = "Patient already enrolled in " + existingProgram.getProgram().getName() + " from " + existingProgram.getDateEnrolled(); + errorMessage += existingProgram.getDateCompleted() == null ? "" : " to " + existingProgram.getDateCompleted(); + return errorMessage; + } + + private Messages noMatchingPatients(PatientProgramRow patientProgramRow) { + return new Messages("No matching patients found with ID:'" + patientProgramRow.patientIdentifier + "'"); + } + + private Program getProgramByName(String programName) { + for (Program program : programWorkflowService.getAllPrograms()) { + if (isNamed(program, programName)) { + return program; + } + } + throw new RuntimeException("No matching Program found with name: " + programName); + } + + private boolean isNamed(Program program, String programName) { + for (ConceptName conceptName : program.getConcept().getNames()) { + if (programName.equalsIgnoreCase(conceptName.getName())) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/ReferenceTermPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ReferenceTermPersister.java new file mode 100644 index 0000000000..76c63454dc --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/ReferenceTermPersister.java @@ -0,0 +1,60 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.ReferenceTermRow; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptReferenceTermService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ReferenceTermPersister implements EntityPersister { + + private UserContext userContext; + private static final Logger log = LogManager.getLogger(PatientPersister.class); + + @Autowired + private ReferenceDataConceptReferenceTermService referenceDataConceptReferenceTermService; + + public void init(UserContext userContext) { + this.userContext = userContext; + } + + @Override + public Messages persist(ReferenceTermRow referenceTermRow) { + try { + Context.openSession(); + Context.setUserContext(userContext); + + referenceDataConceptReferenceTermService.saveOrUpdate(getConceptReferenceTerm(referenceTermRow)); + } catch (Throwable e) { + log.error(e.getMessage(), e); + Context.clearSession(); + return new Messages(e); + } finally { + Context.flushSession(); + Context.closeSession(); + } + return new Messages(); + } + + private org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm getConceptReferenceTerm(ReferenceTermRow referenceTermRow) { + return new org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm( + referenceTermRow.getCode(), + referenceTermRow.getName(), + null, + referenceTermRow.getSource(), + referenceTermRow.getDescription(), + referenceTermRow.getVersion() + ); + } + + @Override + public Messages validate(ReferenceTermRow referenceTermRow) { + return new Messages(); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/persister/RelationshipPersister.java b/admin/src/main/java/org/bahmni/module/admin/csv/persister/RelationshipPersister.java new file mode 100644 index 0000000000..14dac8869d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/persister/RelationshipPersister.java @@ -0,0 +1,96 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.RelationshipRow; +import org.bahmni.module.admin.csv.service.CSVRelationshipService; +import org.bahmni.module.admin.csv.utils.CSVUtils; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PersonService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.text.ParseException; + +@Component +public class RelationshipPersister implements EntityPersister { + + @Autowired + private BahmniPatientService patientService; + + @Autowired + private ProviderService providerService; + + @Autowired + private PersonService personService; + + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + + private static final Logger log = LogManager.getLogger(RelationshipPersister.class); + private UserContext userContext; + + public void init(UserContext userContext) { + this.userContext = userContext; + } + + @Override + public Messages validate(RelationshipRow relationshipRow) { + return new Messages(); + } + + void validateRow(RelationshipRow relationshipRow){ + if (StringUtils.isEmpty(relationshipRow.getPatientIdentifier())) { + throw new RuntimeException("Patient unique identifier not specified."); + } + + if (StringUtils.isEmpty(relationshipRow.getPatientRelationIdentifier()) && StringUtils.isEmpty(relationshipRow.getProviderName())) { + throw new RuntimeException("Both Provider Name and Relation Identifier cannot be null."); + } + + if (StringUtils.isEmpty(relationshipRow.getRelationshipType())) { + throw new RuntimeException("Relationship type is not specified."); + } + + if ((!StringUtils.isEmpty(relationshipRow.getStartDate()) && !StringUtils.isEmpty(relationshipRow.getEndDate()))) { + try { + if (CSVUtils.getDateFromString(relationshipRow.getStartDate()).after(CSVUtils.getDateFromString(relationshipRow.getEndDate()))){ + throw new RuntimeException("Start date should be before end date."); + } + } catch (ParseException e) { + throw new RuntimeException("Could not parse provided dates. Please provide date in format yyyy-mm-dd"); + } + } + } + + @Override + public Messages persist(RelationshipRow relationshipRow) { + try { + Context.openSession(); + Context.setUserContext(userContext); + validateRow(relationshipRow); + new CSVRelationshipService(patientService, personService, providerService, administrationService).save(relationshipRow); + + return new Messages(); + } catch (Throwable e) { + log.error(e.getMessage(), e); + Context.clearSession(); + return new Messages(e); + } finally { + Context.flushSession(); + Context.closeSession(); + } + + } + +} + diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVAddressService.java b/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVAddressService.java new file mode 100644 index 0000000000..c87eb6f44f --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVAddressService.java @@ -0,0 +1,55 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.csv.KeyValue; +import org.openmrs.PersonAddress; +import org.openmrs.module.addresshierarchy.AddressHierarchyLevel; +import org.openmrs.module.addresshierarchy.service.AddressHierarchyService; +import org.openmrs.module.addresshierarchy.util.AddressHierarchyUtil; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class CSVAddressService { + + private AddressHierarchyService addressHierarchyService; + private List addressHierarchyLevels; + + public CSVAddressService() { + } + + public CSVAddressService(AddressHierarchyService addressHierarchyService) { + this.addressHierarchyService = addressHierarchyService; + } + + public PersonAddress getPersonAddress(List addressParts) { + if (addressHierarchyLevels == null) { + addressHierarchyLevels = addressHierarchyService.getAddressHierarchyLevels(); + } + + return mapPersonAddressFields(addressParts, addressHierarchyLevels); + } + + private PersonAddress mapPersonAddressFields(List addressParts, List addressHierarchyLevels) { + Map addressFieldToValueMap = new HashMap<>(); + for (KeyValue addressPart : addressParts) { + AddressHierarchyLevel addressHierarchyLevel = findAddressHierarchyLevel(addressPart.getKey(), addressHierarchyLevels); + addressFieldToValueMap.put(addressHierarchyLevel.getAddressField().getName(), addressPart.getValue()); + } + return AddressHierarchyUtil.convertAddressMapToPersonAddress(addressFieldToValueMap); + } + + private AddressHierarchyLevel findAddressHierarchyLevel(String key, List addressHierarchyLevels) { + for (AddressHierarchyLevel addressHierarchyLevel : addressHierarchyLevels) { + if (addressHierarchyLevel.getName().equals(key)) { + return addressHierarchyLevel; + } + } + throw new RuntimeException(String.format("Address Hierarchy level {0} does not exist.", key)); + } + + +} + diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVPatientService.java b/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVPatientService.java new file mode 100644 index 0000000000..455eff5b29 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVPatientService.java @@ -0,0 +1,158 @@ +package org.bahmni.module.admin.csv.service; + +import org.apache.commons.lang.StringUtils; +import org.bahmni.common.config.registration.service.RegistrationPageService; +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.PatientRow; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.PersonAddress; +import org.openmrs.PersonAttribute; +import org.openmrs.PersonAttributeType; +import org.openmrs.PersonName; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; + +import java.text.ParseException; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateStringInSupportedFormat; +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; + +public class CSVPatientService { + + private static final String BAHMNI_PRIMARY_IDENTIFIER_TYPE = "bahmni.primaryIdentifierType"; + private static final String REGISTRATION_PAGE_VALIDATION_MANDATORY_FIELD = "bahmni.registration.validation.mandatoryField"; + private boolean DEFAULT_MANDATORY_FIELD_VALIDATION = true; + + private PatientService patientService; + private PersonService personService; + private ConceptService conceptService; + private AdministrationService administrationService; + private CSVAddressService csvAddressService; + private RegistrationPageService registrationPageService; + + public CSVPatientService(PatientService patientService, PersonService personService, ConceptService conceptService, AdministrationService administrationService, CSVAddressService csvAddressService, RegistrationPageService registrationPageService) { + this.patientService = patientService; + this.personService = personService; + this.conceptService = conceptService; + this.administrationService = administrationService; + this.csvAddressService = csvAddressService; + this.registrationPageService = registrationPageService; + } + + public Patient save(PatientRow patientRow) throws ParseException { + Patient patient = new Patient(); + PersonName personName = new PersonName(patientRow.firstName, patientRow.middleName, patientRow.lastName); + personName.setPreferred(true); + patient.addName(personName); + + addPersonAttributes(patient, patientRow); + + if (!StringUtils.isBlank(patientRow.birthdate)) { + patient.setBirthdate(getDateFromString(patientRow.birthdate)); + } else if (!StringUtils.isBlank(patientRow.age)) { + patient.setBirthdateFromAge(Integer.parseInt(patientRow.age), new Date()); + } + patient.setGender(patientRow.gender); + patient.addIdentifier(new PatientIdentifier(patientRow.registrationNumber, getPatientIdentifierType(), null)); + + List addressParts = patientRow.addressParts; + PersonAddress personAddress = csvAddressService.getPersonAddress(addressParts); + if (personAddress != null) { + patient.addAddress(personAddress); + } + + patient.setPersonDateCreated(patientRow.getRegistrationDate()); + + patientService.savePatient(patient); + + return patient; + } + + private void addPersonAttributes(Patient patient, PatientRow patientRow) throws ParseException { + final List mandatoryAttributes = registrationPageService.getMandatoryAttributes(); + for (KeyValue attribute : patientRow.attributes) { + if (validateForMandatoryAttribute(mandatoryAttributes, attribute)) + continue; + PersonAttributeType personAttributeType = findAttributeType(attribute.getKey()); + if (personAttributeType.getFormat().equalsIgnoreCase("org.openmrs.Concept")) { + Concept concept = getConceptByName(attribute.getValue()); + if (concept != null) { + patient.addAttribute(new PersonAttribute(personAttributeType, concept.getId().toString())); + } else { + throw new RuntimeException("Invalid value for Attribute." + attribute.getKey()); + } + } else if (personAttributeType.getFormat().startsWith("java.lang.")) { + patient.addAttribute(new PersonAttribute(findAttributeType(attribute.getKey()), attribute.getValue())); + } else if (personAttributeType.getFormat().startsWith("org.openmrs.util.AttributableDate")) { + + String dateString = attribute.getValue(); + //Validating the Date format + getDateFromString(dateString); + String supportedDateString = getDateStringInSupportedFormat(dateString); + patient.addAttribute(new PersonAttribute(findAttributeType(attribute.getKey()),supportedDateString)); + } + } + } + + private boolean validateForMandatoryAttribute(List mandatoryAttributes, KeyValue attribute) { + boolean skipCurrentAttribute = false; + final boolean mandatoryFieldValidationRequired = isMandatoryFieldValidationRequired(); + if(StringUtils.isBlank(attribute.getValue())) { + if(mandatoryFieldValidationRequired) { + if(mandatoryAttributes == null) + throw new RuntimeException("Error in reading patient registration config"); + else if(mandatoryAttributes.contains(attribute.getKey())) + throw new RuntimeException(String.format("Missing value for mandatory attribute \"%s\"", attribute.getKey())); + else + skipCurrentAttribute = true; + } else + skipCurrentAttribute = true; + } + return skipCurrentAttribute; + } + + private Concept getConceptByName(String name) { + List concepts = conceptService.getConceptsByName(name); + if (concepts != null) { + for (Concept concept : concepts) { + Collection nameCollection = concept.getNames(); + for (ConceptName conceptName : nameCollection) { + if (conceptName.getName().equalsIgnoreCase(name) && (conceptName.isPreferred() || conceptName.isFullySpecifiedName() || conceptName.isShort())) { + return concept; + } + } + } + } + return null; + } + + private PersonAttributeType findAttributeType(String key) { + for (PersonAttributeType personAttributeType : personService.getAllPersonAttributeTypes(false)) { + if (key.equalsIgnoreCase(personAttributeType.getName())) { + return personAttributeType; + } + } + + throw new RuntimeException(String.format("Person Attribute %s not found", key)); + } + + private PatientIdentifierType getPatientIdentifierType() { + String globalProperty = administrationService.getGlobalProperty(BAHMNI_PRIMARY_IDENTIFIER_TYPE); + return patientService.getPatientIdentifierTypeByUuid(globalProperty); + } + + private boolean isMandatoryFieldValidationRequired() { + String mandatoryFieldValidationGlobalProperty = administrationService.getGlobalProperty(REGISTRATION_PAGE_VALIDATION_MANDATORY_FIELD); + return StringUtils.isNotBlank(mandatoryFieldValidationGlobalProperty) ? Boolean.valueOf(mandatoryFieldValidationGlobalProperty) : DEFAULT_MANDATORY_FIELD_VALIDATION; + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVRelationshipService.java b/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVRelationshipService.java new file mode 100644 index 0000000000..cf46580a72 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/service/CSVRelationshipService.java @@ -0,0 +1,165 @@ +package org.bahmni.module.admin.csv.service; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.bahmni.module.admin.csv.models.RelationshipRow; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Provider; +import org.openmrs.Relationship; +import org.openmrs.RelationshipType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PersonService; +import org.openmrs.api.ProviderService; + +import java.text.ParseException; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateFromString; +import static org.bahmni.module.admin.csv.utils.CSVUtils.getTodayDate; + +public class CSVRelationshipService { + + private static final String BAHMNI_RELATIONSHIP_TYPE_MAP_PROPERTY = "bahmni.relationshipTypeMap"; + private static final String PATIENT_RELATIONSHIP = "patient"; + private static final String PROVIDER_RELATIONSHIP = "provider"; + + private BahmniPatientService patientService; + private PersonService personService; + private ProviderService providerService; + private AdministrationService administrationService; + + + public CSVRelationshipService(BahmniPatientService patientService, PersonService personService, ProviderService providerService, AdministrationService administrationService) { + this.patientService = patientService; + this.personService = personService; + this.providerService = providerService; + this.administrationService = administrationService; + } + + public Relationship save(RelationshipRow relationshipRow) throws ParseException { + List patientList = patientService.get(relationshipRow.getPatientIdentifier(), true); + if (null == patientList || patientList.size() == 0) { + throw new RuntimeException("No matching patients found with ID:'" + relationshipRow.getPatientIdentifier() + "'"); + } else { + Patient patient = patientList.get(0); + Relationship relationship = createRelationship(relationshipRow, patient); + return personService.saveRelationship(relationship); + } + } + + private Relationship createRelationship(RelationshipRow relationshipRow, Patient patient) throws ParseException { + + RelationshipType relationshipType = getMatchingRelationship(relationshipRow.getRelationshipType()); + Person personB = getRelatedPerson(relationshipRow); + Relationship relationship = checkForExistingRelationship(patient, relationshipType, personB); + + if (relationship == null){ + relationship = new Relationship(); + relationship.setPersonA(patient); + relationship.setPersonB(personB); + relationship.setRelationshipType(relationshipType); + } + + relationship.setStartDate(getStartDate(relationshipRow)); + relationship.setEndDate(getEndDate(relationshipRow)); + return relationship; + } + + private Person getRelatedPerson(RelationshipRow relationshipRow) { + String relationshipMapProperty = administrationService.getGlobalProperty(BAHMNI_RELATIONSHIP_TYPE_MAP_PROPERTY); + Map relationshipMap = new Gson().fromJson(relationshipMapProperty, new TypeToken>() { + }.getType()); + + if (isProviderRelationship(relationshipMap, relationshipRow.getRelationshipType())) { + return getProvider(relationshipRow); + + } else if (isPatientRelationship(relationshipMap, relationshipRow.getRelationshipType())) { + return getPatient(relationshipRow); + + } else { + throw new RuntimeException("Relationship not found " + relationshipRow.getProviderName()); + } + } + + private Person getProvider(RelationshipRow relationshipRow) { + if (StringUtils.isEmpty(relationshipRow.getProviderName())) { + throw new RuntimeException("Provider name not found"); + } + List matchedProvider = providerService.getProviders(relationshipRow.getProviderName(), null, null, null); + if (CollectionUtils.isEmpty(matchedProvider)) { + throw new RuntimeException("No matching provider found with ID:'" + relationshipRow.getProviderName() + "'"); + } + return matchedProvider.get(0).getPerson(); + } + + private Person getPatient(RelationshipRow relationshipRow) { + List matchedPatient = patientService.get(relationshipRow.getPatientRelationIdentifier(), true); + + if (CollectionUtils.isEmpty(matchedPatient)) { + throw new RuntimeException("No matching patients found with ID:'" + relationshipRow.getPatientRelationIdentifier() + "'"); + } + return matchedPatient.get(0); + } + + private Relationship checkForExistingRelationship(Patient patient, RelationshipType relationshipType, Person matchedPerson) { + List existingRelationship = personService.getRelationships(patient, matchedPerson, relationshipType); + if (CollectionUtils.isNotEmpty(existingRelationship)) { + return existingRelationship.get(0); + } + return null; + } + + private RelationshipType getMatchingRelationship(String relationshipType) { + List relationshipTypes = patientService.getByAIsToB(relationshipType); + + if (CollectionUtils.isEmpty(relationshipTypes)) { + throw new RuntimeException("No matching relationship type found with relationship type name:'" + relationshipType + "'"); + } + return relationshipTypes.get(0); + } + + private List getRelationshipTypes(Map relationshipMap, String relationship) { + return relationshipMap != null ? (List) relationshipMap.get(relationship) : null; + } + + private boolean isProviderRelationship(Map relationshipMap, String relationshipType) { + List relationshipTypes = getRelationshipTypes(relationshipMap, PROVIDER_RELATIONSHIP); + return relationshipTypes != null && containsIgnoreCase(relationshipTypes, relationshipType); + } + + private boolean isPatientRelationship(Map relationshipMap, String relationshipType) { + List relationshipTypes = getRelationshipTypes(relationshipMap, PATIENT_RELATIONSHIP); + return relationshipTypes != null && containsIgnoreCase(relationshipTypes, relationshipType); + } + + private Date getStartDate(RelationshipRow relationshipRow) throws ParseException { + if (!StringUtils.isEmpty(relationshipRow.getStartDate())) { + return getDateFromString(relationshipRow.getStartDate()); + } + return getTodayDate(); + } + + private Date getEndDate(RelationshipRow relationshipRow) throws ParseException { + if (!StringUtils.isEmpty(relationshipRow.getEndDate())) { + return getDateFromString(relationshipRow.getEndDate()); + } + return null; + } + + private boolean containsIgnoreCase(List relationshipTypes, String relationshipType) { + for (String relType : relationshipTypes) { + if(relationshipType.equalsIgnoreCase(relType)){ + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/service/FormFieldPathGeneratorService.java b/admin/src/main/java/org/bahmni/module/admin/csv/service/FormFieldPathGeneratorService.java new file mode 100644 index 0000000000..46e68d8d7d --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/service/FormFieldPathGeneratorService.java @@ -0,0 +1,146 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.csv.KeyValue; +import org.bahmni.form2.service.FormFieldPathService; +import org.bahmni.module.admin.csv.models.SectionPositionValue; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.bahmni.module.admin.observation.CSVObservationHelper.getLastItem; +import static org.springframework.util.CollectionUtils.isEmpty; + +@Component +public class FormFieldPathGeneratorService { + + private static final String FORM_NAMESPACE = "Bahmni"; + private static final String FORM_FIELD_PATH_SEPARATOR = "/"; + private Map formFieldPathAddmoreAttribute = new HashMap<>(); + private Map> addmoreSectionIndices = new HashMap<>(); + + private FormFieldPathService formFieldPathService; + + @Autowired + public FormFieldPathGeneratorService(FormFieldPathService formFieldPathService) { + this.formFieldPathService = formFieldPathService; + } + + public void setFormNamespaceAndFieldPath(List form2Observations, List form2CSVHeaderParts) { + if (isEmpty(form2Observations)) { + return; + } + final EncounterTransaction.Observation observation = getLastItem(form2Observations); + final String formFieldPath = formFieldPathService.getFormFieldPath(form2CSVHeaderParts); + observation.setFormFieldPath(formFieldPath); + observation.setFormNamespace(FORM_NAMESPACE); + } + + public void setFormNamespaceAndFieldPathForMultiSelectObs(List form2Observations, List form2CSVHeaderParts, List multiSelectForm2CSVObservations) { + if (isEmpty(form2Observations)) { + return; + } + int prevObsCount = form2Observations.size() - multiSelectForm2CSVObservations.size(); + for(int i = 0; i < multiSelectForm2CSVObservations.size(); i++) { + final EncounterTransaction.Observation observation = form2Observations.get(prevObsCount + i); + final String formFieldPath = formFieldPathService.getFormFieldPath(form2CSVHeaderParts); + observation.setFormFieldPath(formFieldPath); + observation.setFormNamespace(FORM_NAMESPACE); + } + } + + public void setFormNamespaceAndFieldPathForAddmoreObs(List form2Observations, List form2CSVHeaderParts, List addmoreForm2CSVObservations) { + if (isEmpty(form2Observations)) { + return; + } + int prevObsCount = form2Observations.size() - addmoreForm2CSVObservations.size(); + final String formFieldPath = formFieldPathService.getFormFieldPath(form2CSVHeaderParts); + String[] tokens = formFieldPath.split(FORM_FIELD_PATH_SEPARATOR); + int formFieldPathPosition = tokens.length - 1; + String path = tokens[formFieldPathPosition]; + String controlIdPrefix = path.split("-")[0]; + + for(int i = 0; i < addmoreForm2CSVObservations.size(); i++) { + final EncounterTransaction.Observation observation = form2Observations.get(prevObsCount + i); + tokens[formFieldPathPosition] = controlIdPrefix + "-" + i; + observation.setFormFieldPath(String.join(FORM_FIELD_PATH_SEPARATOR, tokens)); + observation.setFormNamespace(FORM_NAMESPACE); + } + } + + public void setFormNamespaceAndFieldPathForJsonValue(List form2Observations, List form2CSVHeaderParts, List addmoreSectionCSVObservations, List sectionPositionValues) { + if (isEmpty(form2Observations)) { + return; + } + + updateFormFieldPathWithAddmoreAttribute(form2CSVHeaderParts); + + int prevObsCount = form2Observations.size() - addmoreSectionCSVObservations.size(); + final String formFieldPath = formFieldPathService.getFormFieldPath(form2CSVHeaderParts); + + for(int i = 0; i < addmoreSectionCSVObservations.size(); i++) { + final EncounterTransaction.Observation observation = form2Observations.get(prevObsCount + i); + updateObsWithFormFieldPath(observation, form2CSVHeaderParts, sectionPositionValues, prevObsCount, formFieldPath, i); + } + } + + private void updateObsWithFormFieldPath(EncounterTransaction.Observation observation, List form2CSVHeaderParts, List sectionPositionValues, int prevObsCount, String formFieldPath, int csvObservationIndex) { + String[] tokens = formFieldPath.split(FORM_FIELD_PATH_SEPARATOR); + List indicesInJson = addmoreSectionIndices.get(form2CSVHeaderParts.toString()); + String sectionPositionIndex = sectionPositionValues.get(csvObservationIndex).getSectionIndex(); + + // update form field path for sections based on JSON value + for(int j = 0; j < indicesInJson.size() - 1; j++) { + int addmoreSectionIndex = 0; + int sectionIndexPosition = indicesInJson.get(j); + String partialFormFieldPath = tokens[sectionIndexPosition]; + String controlIdPrefix = partialFormFieldPath.split("-")[0]; + if(sectionPositionIndex.contains(FORM_FIELD_PATH_SEPARATOR)) { + String[] indices = sectionPositionIndex.split(FORM_FIELD_PATH_SEPARATOR); + addmoreSectionIndex = Integer.parseInt(indices[j+1]); + } else { + addmoreSectionIndex = Integer.parseInt(sectionPositionIndex); + } + tokens[sectionIndexPosition] = controlIdPrefix + "-" + addmoreSectionIndex; + } + + // update form field path for section having observation. + int sectionWithObsIndexPosition = indicesInJson.get(indicesInJson.size() - 1); + String partialFormFieldPath = tokens[sectionWithObsIndexPosition]; + String controlIdPrefix = partialFormFieldPath.split("-")[0]; + tokens[sectionWithObsIndexPosition] = controlIdPrefix + "-" + sectionPositionValues.get(csvObservationIndex).getValueIndex(); + + if(sectionPositionValues.get(csvObservationIndex).getAddmoreIndex() != -1) { + int obsAddmoreIndex = sectionPositionValues.get(csvObservationIndex).getAddmoreIndex(); + String addmoreFormControlId = tokens[tokens.length - 1]; + String addmoreControlIdPrefix = addmoreFormControlId.split("-")[0]; + tokens[tokens.length - 1] = addmoreControlIdPrefix + "-" + obsAddmoreIndex; + } + observation.setFormFieldPath(String.join(FORM_FIELD_PATH_SEPARATOR, tokens)); + observation.setFormNamespace(FORM_NAMESPACE); + } + + private void updateFormFieldPathWithAddmoreAttribute(List form2CSVHeaderParts) { + if(formFieldPathAddmoreAttribute.get(form2CSVHeaderParts.toString()) == null) { + List indices = new ArrayList<>(); + boolean isFirstAddmoreIdentified = false; + int intialSectionsWithoutAddmore = 0; + for (int i = 1; i < form2CSVHeaderParts.size(); i++) { + List headerPartsList = form2CSVHeaderParts.subList(0, i + 1); + boolean addmore = formFieldPathService.isAddmore(headerPartsList); + if(!addmore && !isFirstAddmoreIdentified) { + isFirstAddmoreIdentified = true; + intialSectionsWithoutAddmore++; + } + formFieldPathAddmoreAttribute.put(headerPartsList.toString(), addmore); + if(addmore) + indices.add(i - intialSectionsWithoutAddmore); + } + addmoreSectionIndices.put(form2CSVHeaderParts.toString(), indices); + } + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/service/PatientMatchService.java b/admin/src/main/java/org/bahmni/module/admin/csv/service/PatientMatchService.java new file mode 100644 index 0000000000..c10a94e696 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/service/PatientMatchService.java @@ -0,0 +1,62 @@ +package org.bahmni.module.admin.csv.service; + +import groovy.lang.GroovyClassLoader; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.patientmatchingalgorithm.BahmniPatientMatchingAlgorithm; +import org.bahmni.module.admin.csv.patientmatchingalgorithm.PatientMatchingAlgorithm; +import org.bahmni.module.admin.csv.patientmatchingalgorithm.exception.CannotMatchPatientException; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.openmrs.Patient; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class PatientMatchService { + @Autowired + private BahmniPatientService patientService; + + private static final String PATIENT_MATCHING_ALGORITHM_DIRECTORY = "/patientMatchingAlgorithm/"; + private static final Logger log = LogManager.getLogger(PatientMatchService.class); + + // Mujir - an implementation could use multiple patient matching algorithms + protected Map patientMatchingAlgorithms = new HashMap<>(); + + public Patient getPatient(String matchingAlgorithmClassName, List patientAttributes, String patientIdentifier, boolean shouldMatchExactPatientId) throws IOException, IllegalAccessException, InstantiationException, CannotMatchPatientException { + List matchingPatients = patientService.get(patientIdentifier, shouldMatchExactPatientId); + return matchPatients(matchingPatients, patientAttributes, matchingAlgorithmClassName); + } + + private Patient matchPatients(List matchingPatients, List patientAttributes, String matchingAlgorithmClassName) throws IOException, IllegalAccessException, InstantiationException, CannotMatchPatientException { + if (StringUtils.isEmpty(matchingAlgorithmClassName)) { + return new BahmniPatientMatchingAlgorithm().run(matchingPatients, patientAttributes); + } + PatientMatchingAlgorithm patientMatchingAlgorithm = getPatientMatchingAlgorithm(matchingAlgorithmClassName); + log.debug("PatientMatching : Using Algorithm in " + patientMatchingAlgorithm.getClass().getName()); + return patientMatchingAlgorithm.run(matchingPatients, patientAttributes); + } + + private PatientMatchingAlgorithm getPatientMatchingAlgorithm(String matchingAlgorithmClassName) throws IOException, InstantiationException, IllegalAccessException { + PatientMatchingAlgorithm patientMatchingAlgorithm = patientMatchingAlgorithms.get(matchingAlgorithmClassName); + if (patientMatchingAlgorithm == null) { + Class clazz = new GroovyClassLoader().parseClass(new File(getAlgorithmClassPath(matchingAlgorithmClassName))); + patientMatchingAlgorithms.put(matchingAlgorithmClassName, (PatientMatchingAlgorithm) clazz.newInstance()); + } + + return patientMatchingAlgorithms.get(matchingAlgorithmClassName); + } + + private String getAlgorithmClassPath(String matchingAlgorithmClassName) { + return OpenmrsUtil.getApplicationDataDirectory() + PATIENT_MATCHING_ALGORITHM_DIRECTORY + matchingAlgorithmClassName; + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/csv/utils/CSVUtils.java b/admin/src/main/java/org/bahmni/module/admin/csv/utils/CSVUtils.java new file mode 100644 index 0000000000..e1896b181f --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/csv/utils/CSVUtils.java @@ -0,0 +1,79 @@ +package org.bahmni.module.admin.csv.utils; + +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.exception.MigrationException; +import org.openmrs.api.context.Context; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class CSVUtils { + + public static final String ENCOUNTER_DATE_PATTERN = "yyyy-M-d"; + private final static String GLOBAL_DATE_FORMAT = "bahmni.admin.csv.upload.dateFormat"; + + public static String getCsvGlobalDateFormat(){ + return Context.getAdministrationService().getGlobalProperty(GLOBAL_DATE_FORMAT); + }; + + public static String[] getStringArray(List keyValueList) { + List stringList = new ArrayList<>(); + for (KeyValue keyValue : keyValueList) { + stringList.add(keyValue.getValue()); + } + return stringList.toArray(new String[]{}); + } + + public static List getKeyValueList(String key, List stringList) { + List keyValueList = new ArrayList<>(); + for (String string : stringList) { + keyValueList.add(new KeyValue(key, string)); + } + return keyValueList; + } + + public static String getDateStringInSupportedFormat(String dateString) throws ParseException { + String dateGlobalProperty = getCsvGlobalDateFormat(); + SimpleDateFormat simpleDateFormat; + if( dateGlobalProperty != null) { + simpleDateFormat = new SimpleDateFormat(dateGlobalProperty); + simpleDateFormat.setLenient(false); + Date date = new Date(simpleDateFormat.parse(dateString).getTime()); + + SimpleDateFormat defaultDateFormat = new SimpleDateFormat(ENCOUNTER_DATE_PATTERN); + return defaultDateFormat.format(date); + }else{ + return dateString; + } + }; + + public static Date getDateFromString(String dateString) throws ParseException { + // All csv imports use the date format from global properties + SimpleDateFormat simpleDateFormat; + String dateGlobalProperty = getCsvGlobalDateFormat(); + String expectedDateFormat = dateGlobalProperty != null ? dateGlobalProperty : ENCOUNTER_DATE_PATTERN; + try { + if (dateGlobalProperty != null) { + dateString = getDateStringInSupportedFormat(dateString); + } + simpleDateFormat = new SimpleDateFormat(ENCOUNTER_DATE_PATTERN); + simpleDateFormat.setLenient(false); + return simpleDateFormat.parse(dateString); + } + catch (ParseException e){ + throw new MigrationException("Date format " + dateString + " doesn't match `bahmni.admin.csv.upload.dateFormat` global property, expected format " + expectedDateFormat ); + } + }; + + public static Date getTodayDate() throws ParseException { + DateFormat dateFormat = new SimpleDateFormat(ENCOUNTER_DATE_PATTERN); + Date date = new Date(); + String dateString = dateFormat.format(date); + return getDateFromString(dateString); + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/encounter/BahmniEncounterTransactionImportService.java b/admin/src/main/java/org/bahmni/module/admin/encounter/BahmniEncounterTransactionImportService.java new file mode 100644 index 0000000000..4a8a1168c9 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/encounter/BahmniEncounterTransactionImportService.java @@ -0,0 +1,73 @@ +package org.bahmni.module.admin.encounter; + +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.csv.models.MultipleEncounterRow; +import org.bahmni.module.admin.observation.DiagnosisMapper; +import org.bahmni.module.admin.observation.ObservationMapper; +import org.openmrs.EncounterType; +import org.openmrs.Patient; +import org.openmrs.api.EncounterService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.ETObsToBahmniObsMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +@Component +public class BahmniEncounterTransactionImportService { + + private EncounterService encounterService; + private ObservationMapper observationMapper; + private DiagnosisMapper diagnosisMapper; + private ETObsToBahmniObsMapper fromETObsToBahmniObs; + + @Autowired + public BahmniEncounterTransactionImportService(EncounterService encounterService, + ObservationMapper observationMapper, DiagnosisMapper diagnosisMapper, + ETObsToBahmniObsMapper fromETObsToBahmniObs) { + this.encounterService = encounterService; + this.observationMapper = observationMapper; + this.diagnosisMapper = diagnosisMapper; + this.fromETObsToBahmniObs = fromETObsToBahmniObs; + } + + public List getBahmniEncounterTransaction(MultipleEncounterRow multipleEncounterRow, Patient patient, boolean shouldPerformForm2Validations) throws ParseException { + if (multipleEncounterRow.encounterRows == null || multipleEncounterRow.encounterRows.isEmpty()) + return new ArrayList<>(); + + List bahmniEncounterTransactions = new ArrayList<>(); + + EncounterType requestedEncounterType = encounterService.getEncounterType(multipleEncounterRow.encounterType); + if (requestedEncounterType == null) { + throw new RuntimeException("Encounter type:'" + multipleEncounterRow.encounterType + "' not found."); + } + String encounterType = multipleEncounterRow.encounterType; + String visitType = multipleEncounterRow.visitType; + + for (EncounterRow encounterRow : multipleEncounterRow.getNonEmptyEncounterRows()) { + List allObservations = observationMapper.getObservations(encounterRow, shouldPerformForm2Validations); + List allDiagnosis = diagnosisMapper.getBahmniDiagnosis(encounterRow); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setPatientUuid(patient.getUuid()); + bahmniEncounterTransaction.setBahmniDiagnoses(allDiagnosis); + bahmniEncounterTransaction.setObservations(fromETObsToBahmniObs.create(allObservations, new AdditionalBahmniObservationFields(null, encounterRow.getEncounterDate(), null, null))); + + bahmniEncounterTransaction.setEncounterDateTime(encounterRow.getEncounterDate()); + bahmniEncounterTransaction.setEncounterType(encounterType); + bahmniEncounterTransaction.setVisitType(visitType); + + bahmniEncounterTransactions.add(bahmniEncounterTransaction); + } + + + return bahmniEncounterTransactions; + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/CSVObservationHelper.java b/admin/src/main/java/org/bahmni/module/admin/observation/CSVObservationHelper.java new file mode 100644 index 0000000000..0236e868d9 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/CSVObservationHelper.java @@ -0,0 +1,249 @@ +package org.bahmni.module.admin.observation; + +import org.apache.commons.lang.StringUtils; +import org.bahmni.csv.KeyValue; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; +import org.openmrs.Obs; +import org.openmrs.api.APIException; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction.Observation; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.security.InvalidParameterException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; +import static java.util.Objects.nonNull; +import static org.apache.commons.lang.StringUtils.isNotBlank; +import static org.springframework.util.CollectionUtils.isEmpty; +import static org.bahmni.module.admin.csv.utils.CSVUtils.getDateStringInSupportedFormat; + +@Component +public class CSVObservationHelper { + private static final String FORM2_TYPE = "form2"; + private static final String OBS_PATH_SPLITTER_PROPERTY = "bahmni.admin.csv.upload.obsPath.splitter"; + private static final String DEFAULT_OBSPATH_SPLITTER = "."; + private static final String MULTI_SELECT_OBS_SPLITTER_PROPERTY = "bahmni.admin.csv.upload.obs.multiSelect.splitter"; + private static final String DEFAULT_MULTI_SELECT_OBS_SPLITTER = "|"; + private static final String ADDMORE_OBS_SPLITTER_PROPERTY = "bahmni.admin.csv.upload.obs.addmore.splitter"; + private static final String DEFAULT_ADDMORE_OBS_SPLITTER = "|"; + private static final String DATE = "Date"; + private final ConceptCache conceptCache; + private final ConceptService conceptService; + private AdministrationService administrationService; + + @Autowired + CSVObservationHelper(ConceptService conceptService, + @Qualifier("adminService") AdministrationService administrationService) { + this.conceptCache = new ConceptCache(conceptService); + this.conceptService = conceptService; + this.administrationService = administrationService; + } + + public static T getLastItem(List items) { + if (isEmpty(items)) { + throw new InvalidParameterException("Empty items"); + } + return items.get(items.size() - 1); + } + + protected Concept getConcept(String conceptName) { + return conceptCache.getConcept(conceptName); + } + + public void createObservations(List observations, Date encounterDate, + List obsRows, List conceptNames) throws ParseException { + Observation existingObservation = getRootObservationIfExists(observations, conceptNames, null); + if (existingObservation == null) { + for(KeyValue obsRow : obsRows) + observations.add(createObservation(conceptNames, encounterDate, obsRow)); + } else { + for(KeyValue obsRow : obsRows) + updateObservation(conceptNames, existingObservation, encounterDate, obsRow); + } + } + + public void createObservations(List observations, Date encounterDate, + KeyValue obsRow, List conceptNames) throws ParseException { + Observation existingObservation = getRootObservationIfExists(observations, conceptNames, null); + if (existingObservation == null) { + observations.add(createObservation(conceptNames, encounterDate, obsRow)); + } else { + updateObservation(conceptNames, existingObservation, encounterDate, obsRow); + + } + } + + public void verifyNumericConceptValue(KeyValue obsRow, List conceptNames) { + String lastConceptName = getLastItem(conceptNames); + Concept lastConcept = conceptService.getConceptByName(lastConceptName); + if (lastConcept != null && lastConcept.isNumeric()) { + ConceptNumeric cn = (ConceptNumeric) lastConcept; + if (!cn.getAllowDecimal() && obsRow.getValue().contains(".")) { + throw new APIException("Decimal is not allowed for " + cn.getName() + " concept"); + } + } + } + + private void updateObservation(List conceptNames, Observation existingObservation, + Date encounterDate, KeyValue obsRow) throws ParseException { + existingObservation.addGroupMember(createObservation(conceptNames, encounterDate, obsRow)); + } + + private Observation getRootObservationIfExists(List observations, List conceptNames, + Observation existingObservation) { + for (Observation observation : observations) { + if (observation.getConcept().getName().equals(conceptNames.get(0))) { + conceptNames.remove(0); + if (conceptNames.size() == 0) { + conceptNames.add(observation.getConcept().getName()); + return existingObservation; + } + existingObservation = observation; + return getRootObservationIfExists(observation.getGroupMembers(), conceptNames, existingObservation); + } + } + return existingObservation; + } + + private Observation createObservation(List conceptNames, Date encounterDate, KeyValue obsRow) throws ParseException { + Concept obsConcept = conceptCache.getConcept(conceptNames.get(0)); + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(obsConcept.getUuid(), + obsConcept.getName().getName()); + + Observation observation = new Observation(); + observation.setConcept(concept); + observation.setObservationDateTime(encounterDate); + if (conceptNames.size() == 1) { + observation.setValue(getValue(obsRow, obsConcept)); + if (obsConcept.getDatatype().isNumeric()) { + validateAndUpdateObservationInterpretation(obsRow, obsConcept, observation); + } else if(obsConcept.getDatatype().isDate()) { + observation.getConcept().setDataType(DATE); + } + } else { + conceptNames.remove(0); + observation.addGroupMember(createObservation(conceptNames, encounterDate, obsRow)); + } + return observation; + } + + private void validateAndUpdateObservationInterpretation(KeyValue obsRow, Concept obsConcept, Observation observation) { + verifyNumericConceptValue(obsRow, Collections.singletonList(obsConcept.getName().getName())); + Double recordedObsValue = Double.parseDouble(obsRow.getValue()); + Double hiNormal = ((ConceptNumeric) obsConcept).getHiNormal(); + Double lowNormal = ((ConceptNumeric) obsConcept).getLowNormal(); + if (nonNull(recordedObsValue) && ((nonNull(hiNormal) && recordedObsValue.compareTo(hiNormal) > 0) || (nonNull(lowNormal) && recordedObsValue.compareTo(lowNormal) < 0))) { + observation.setInterpretation(String.valueOf(Obs.Interpretation.ABNORMAL)); + } + }; + + private Object getValue(KeyValue obsRow, Concept obsConcept) throws ParseException { + Map valueConcept = null; + if(obsConcept.getDatatype().isDate()) { + String dateString = obsRow.getValue(); + return getDateStringInSupportedFormat(dateString); + } + if (obsConcept.getDatatype().isCoded()) { + List valueConcepts = conceptService.getConceptsByName(obsRow.getValue()); + for (Concept concept : valueConcepts) { + ConceptName name = concept.getFullySpecifiedName(Context.getLocale()) != null ? + concept.getFullySpecifiedName(Context.getLocale()) : concept.getName(); + if (name.getName().equalsIgnoreCase(obsRow.getValue())) { + valueConcept = new LinkedHashMap<>(); + Map conceptNameDetails = new HashMap<>(); + conceptNameDetails.put("name", concept.getName().getName()); + conceptNameDetails.put("uuid", concept.getName().getUuid()); + conceptNameDetails.put("display", concept.getDisplayString()); + conceptNameDetails.put("locale", concept.getName().getLocale()); + conceptNameDetails.put("localePreferred", concept.getName().getLocalePreferred()); + conceptNameDetails.put("conceptNameType", concept.getName().getConceptNameType()); + valueConcept.put("uuid", concept.getUuid()); + valueConcept.put("name", conceptNameDetails); + valueConcept.put("names", concept.getNames()); + valueConcept.put("displayString", concept.getDisplayString()); + valueConcept.put("translationKey", concept.getName()); + break; + } + } + if (valueConcept == null) + throw new ConceptNotFoundException(obsRow.getValue() + " not found"); + return valueConcept; + } + return obsRow.getValue(); + } + + public List getCSVHeaderParts(KeyValue csvObservation) { + String key = csvObservation.getKey(); + return isNotBlank(key) ? new ArrayList<>(asList(key.split(String.format("\\%s", getObsPathSplitter())))) + : new ArrayList<>(); + } + + private String getObsPathSplitter() { + final String obsPathSplitter = administrationService.getGlobalProperty(OBS_PATH_SPLITTER_PROPERTY); + return isNotBlank(obsPathSplitter) ? obsPathSplitter : DEFAULT_OBSPATH_SPLITTER; + } + + public List getMultiSelectObs(KeyValue csvObservation) { + String multiSelectRawValue = csvObservation.getValue(); + return isNotBlank(multiSelectRawValue) ? new ArrayList<>(asList(multiSelectRawValue.split(String.format("\\%s", getMultiSelectObsSplitter())))) + : new ArrayList<>(); + } + + public List getAddmoreObs(KeyValue csvObservation) { + String addmoreRawValue = csvObservation.getValue(); + return isNotBlank(addmoreRawValue) ? new ArrayList<>(asList(addmoreRawValue.split(String.format("\\%s", getAddmoreObsSplitter())))) + : new ArrayList<>(); + } + + private String getMultiSelectObsSplitter() { + final String multiSelectObsSplitter = administrationService.getGlobalProperty(MULTI_SELECT_OBS_SPLITTER_PROPERTY); + return isNotBlank(multiSelectObsSplitter) ? multiSelectObsSplitter : DEFAULT_MULTI_SELECT_OBS_SPLITTER; + } + + private String getAddmoreObsSplitter() { + final String addmoreObsSplitter = administrationService.getGlobalProperty(ADDMORE_OBS_SPLITTER_PROPERTY); + return isNotBlank(addmoreObsSplitter) ? addmoreObsSplitter : DEFAULT_ADDMORE_OBS_SPLITTER; + } + + public List getMultiSelectObsForJsonValue(String jsonValue) { + List multiSelectValues = new ArrayList<>(); + if(isNotBlank(jsonValue)) + multiSelectValues.addAll(asList(jsonValue.split(String.format("\\%s", getMultiSelectObsSplitter())))); + return multiSelectValues; + } + + public List getAddmoreObsForJsonValue(String jsonValue) { + List addmoreValues = new ArrayList<>(); + if(isNotBlank(jsonValue)) + addmoreValues.addAll(asList(jsonValue.split(String.format("\\%s", getAddmoreObsSplitter())))); + return addmoreValues; + } + public boolean isForm2Type(KeyValue obsRow) { + String key = obsRow.getKey(); + if (StringUtils.isNotBlank(key)) { + String[] csvHeaderParts = key.split((String.format("\\%s", getObsPathSplitter()))); + return csvHeaderParts[0].equalsIgnoreCase(FORM2_TYPE); + } + return false; + } + + public boolean isForm1Type(KeyValue keyValue) { + return !isForm2Type(keyValue); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/ConceptCache.java b/admin/src/main/java/org/bahmni/module/admin/observation/ConceptCache.java new file mode 100644 index 0000000000..434430655c --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/ConceptCache.java @@ -0,0 +1,32 @@ +package org.bahmni.module.admin.observation; + +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; + +import java.util.HashMap; +import java.util.Map; + +public class ConceptCache { + private Map cachedConcepts = new HashMap<>(); + private ConceptService conceptService; + + public ConceptCache(ConceptService conceptService) { + this.conceptService = conceptService; + } + + public Concept getConcept(String conceptName) { + if (!cachedConcepts.containsKey(conceptName)) { + cachedConcepts.put(conceptName, fetchConcept(conceptName)); + } + return cachedConcepts.get(conceptName); + } + + private Concept fetchConcept(String conceptName) { + Concept obsConcept = conceptService.getConceptByName(conceptName); + if (obsConcept == null) + throw new ConceptNotFoundException("Concept '" + conceptName + "' not found"); + + return obsConcept; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/DiagnosisMapper.java b/admin/src/main/java/org/bahmni/module/admin/observation/DiagnosisMapper.java new file mode 100644 index 0000000000..0617b5ffe4 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/DiagnosisMapper.java @@ -0,0 +1,75 @@ +package org.bahmni.module.admin.observation; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.emrapi.diagnosis.Diagnosis; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Component(value = "adminDiagnosisMapper") +public class DiagnosisMapper { + + private static final Logger log = LogManager.getLogger(DiagnosisMapper.class); + + private final ConceptCache conceptCache; + + @Autowired + public DiagnosisMapper(ConceptService conceptService) { + this.conceptCache = new ConceptCache(conceptService); + } + + public List getBahmniDiagnosis(EncounterRow encounterRow) throws ParseException { + List bahmniDiagnoses = new ArrayList<>(); + if (encounterRow.hasDiagnoses()) { + Date encounterDate = encounterRow.getEncounterDate(); + for (KeyValue uniqueDiagnosisKeyValue : encounterRow.diagnosesRows) { + String diagnosis = uniqueDiagnosisKeyValue.getValue(); + if (StringUtils.isNotBlank(diagnosis)) { + BahmniDiagnosisRequest bahmniDiagnosisRequest = createDiagnosis(encounterDate, diagnosis); + bahmniDiagnoses.add(bahmniDiagnosisRequest); + } + } + } + return bahmniDiagnoses; + } + + private BahmniDiagnosisRequest createDiagnosis(Date encounterDate, String diagnosis) throws ParseException { + Concept obsConcept = getConcept(diagnosis); + + BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + bahmniDiagnosisRequest.setOrder(String.valueOf(Diagnosis.Order.PRIMARY)); + bahmniDiagnosisRequest.setCertainty(String.valueOf(Diagnosis.Certainty.CONFIRMED)); + bahmniDiagnosisRequest.setDiagnosisDateTime(encounterDate); + + if (obsConcept == null) { + bahmniDiagnosisRequest.setFreeTextAnswer(diagnosis); + } else { + EncounterTransaction.Concept diagnosisConcept = new EncounterTransaction.Concept(obsConcept.getUuid(), obsConcept.getName().getName()); + bahmniDiagnosisRequest.setCodedAnswer(diagnosisConcept); + } + + return bahmniDiagnosisRequest; + } + + protected Concept getConcept(String diagnosis) { + try { + return conceptCache.getConcept(diagnosis); + } catch (ConceptNotFoundException cnfe) { + log.error(cnfe.getMessage() + " Setting it as free text answer", cnfe); + return null; + } + } +} \ No newline at end of file diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/ObservationMapper.java b/admin/src/main/java/org/bahmni/module/admin/observation/ObservationMapper.java new file mode 100644 index 0000000000..9b98944513 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/ObservationMapper.java @@ -0,0 +1,42 @@ +package org.bahmni.module.admin.observation; + +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.observation.handler.CSVObsHandler; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +@Component(value = "adminObservationMapper") +public class ObservationMapper { + + @Autowired + private List csvObsHandlers; + + @Autowired + @Deprecated + public ObservationMapper(ConceptService conceptService) { + } + + public List getObservations(EncounterRow encounterRow) throws ParseException { + final List observations = new ArrayList<>(); + for (CSVObsHandler csvObsHandler : csvObsHandlers) { + observations.addAll(csvObsHandler.handle(encounterRow)); + } + return observations; + } + + public List getObservations(EncounterRow encounterRow, boolean shouldPerformForm2Validations) throws ParseException { + final List observations = new ArrayList<>(); + for (CSVObsHandler csvObsHandler : csvObsHandlers) { + final List allObs = csvObsHandler.handle(encounterRow, shouldPerformForm2Validations); + if(allObs != null) + observations.addAll(allObs); + } + return observations; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/handler/CSVObsHandler.java b/admin/src/main/java/org/bahmni/module/admin/observation/handler/CSVObsHandler.java new file mode 100644 index 0000000000..cf4dee5504 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/handler/CSVObsHandler.java @@ -0,0 +1,18 @@ +package org.bahmni.module.admin.observation.handler; + + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.text.ParseException; +import java.util.List; + +public interface CSVObsHandler { + + List getRelatedCSVObs(EncounterRow encounterRow); + + List handle(EncounterRow encounterRow) throws ParseException; + + List handle(EncounterRow encounterRow, boolean shouldPerformForm2Validations) throws ParseException; +} diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/handler/Form1CSVObsHandler.java b/admin/src/main/java/org/bahmni/module/admin/observation/handler/Form1CSVObsHandler.java new file mode 100644 index 0000000000..45008e29a0 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/handler/Form1CSVObsHandler.java @@ -0,0 +1,54 @@ +package org.bahmni.module.admin.observation.handler; + + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.observation.CSVObservationHelper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.apache.commons.lang.StringUtils.isNotBlank; + +@Component +public class Form1CSVObsHandler implements CSVObsHandler { + + private CSVObservationHelper csvObservationHelper; + + @Autowired + public Form1CSVObsHandler(CSVObservationHelper csvObservationHelper) { + this.csvObservationHelper = csvObservationHelper; + } + + @Override + public List getRelatedCSVObs(EncounterRow encounterRow) { + return encounterRow.obsRows.stream().filter(csvObservation -> csvObservationHelper.isForm1Type(csvObservation)) + .collect(Collectors.toList()); + } + + @Override + public List handle(EncounterRow encounterRow) throws ParseException { + List observations = new ArrayList<>(); + List csvObservations = getRelatedCSVObs(encounterRow); + for (KeyValue csvObservation : csvObservations) { + if (isNotBlank(csvObservation.getValue())) { + List conceptNames = csvObservationHelper.getCSVHeaderParts(csvObservation); + csvObservationHelper.verifyNumericConceptValue(csvObservation, conceptNames); + csvObservationHelper.createObservations(observations, encounterRow.getEncounterDate(), + csvObservation, conceptNames); + } + } + return observations; + } + + @Override + public List handle(EncounterRow encounterRow, boolean shouldPerformForm2Validations) throws ParseException { + return null; + } + +} diff --git a/admin/src/main/java/org/bahmni/module/admin/observation/handler/Form2CSVObsHandler.java b/admin/src/main/java/org/bahmni/module/admin/observation/handler/Form2CSVObsHandler.java new file mode 100644 index 0000000000..ca7ba9a529 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/observation/handler/Form2CSVObsHandler.java @@ -0,0 +1,288 @@ +package org.bahmni.module.admin.observation.handler; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.csv.models.SectionPositionValue; +import org.bahmni.module.admin.csv.service.FormFieldPathGeneratorService; +import org.bahmni.module.admin.csv.utils.CSVUtils; +import org.bahmni.module.admin.observation.CSVObservationHelper; +import org.bahmni.form2.service.FormFieldPathService; +import org.openmrs.api.APIException; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.*; +import java.util.stream.Collectors; + +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static org.apache.commons.lang.StringUtils.isNotBlank; +import static org.bahmni.module.admin.observation.CSVObservationHelper.getLastItem; + +@Component +public class Form2CSVObsHandler implements CSVObsHandler { + + private static final String DATE = "Date"; + private static final String ATTRIBUTE_QUERY_SEPARATOR = "?"; + private static final String ATTRIBUTE_SEPARATOR = "&"; + private static final String ATTRIBUTE_ISJSON = "isJson"; + private static final String SECTION_SPLITTER = "/"; + private static final String KEY_SECTION_VALUES = "values"; + private static final int NOT_MULTISELECT_OBS_INDEX = -1; + private static final int NOT_ADDMORE_OBS_INDEX = -1; + + private CSVObservationHelper csvObservationHelper; + private FormFieldPathService formFieldPathService; + private FormFieldPathGeneratorService formFieldPathGeneratorService; + + @Autowired + public Form2CSVObsHandler(CSVObservationHelper csvObservationHelper, FormFieldPathService formFieldPathService, FormFieldPathGeneratorService formFieldPathGeneratorService) { + this.csvObservationHelper = csvObservationHelper; + this.formFieldPathService = formFieldPathService; + this.formFieldPathGeneratorService = formFieldPathGeneratorService; + } + + @Override + public List getRelatedCSVObs(EncounterRow encounterRow) { + return encounterRow.obsRows.stream().filter(csvObservation -> csvObservationHelper.isForm2Type(csvObservation)) + .collect(Collectors.toList()); + } + + @Override + public List handle(EncounterRow encounterRow) throws ParseException { + List form2Observations = new ArrayList<>(); + List form2CSVObservations = getRelatedCSVObs(encounterRow); + for (KeyValue form2CSVObservation : form2CSVObservations) { + if (isNotBlank(form2CSVObservation.getValue())) { + final List form2CSVHeaderParts = getCSVHeaderPartsByIgnoringForm2KeyWord(form2CSVObservation); + verifyCSVHeaderHasConcepts(form2CSVObservation, form2CSVHeaderParts); + csvObservationHelper.verifyNumericConceptValue(form2CSVObservation, form2CSVHeaderParts); + csvObservationHelper.createObservations(form2Observations, encounterRow.getEncounterDate(), + form2CSVObservation, getConceptNames(form2CSVHeaderParts)); + formFieldPathGeneratorService.setFormNamespaceAndFieldPath(form2Observations, form2CSVHeaderParts); + } + } + return form2Observations; + } + + @Override + public List handle(EncounterRow encounterRow, boolean shouldPerformForm2Validations) throws ParseException { + if(!shouldPerformForm2Validations) + return handle(encounterRow); + List form2Observations = new ArrayList<>(); + List form2CSVObservations = getRelatedCSVObs(encounterRow); + for (KeyValue form2CSVObservation : form2CSVObservations) { + Map headerAttributes = parseCSVHeader(form2CSVObservation); + boolean isJsonAttribute = headerAttributes.getOrDefault(ATTRIBUTE_ISJSON, false); + final List form2CSVHeaderParts = getCSVHeaderPartsByIgnoringForm2KeyWord(form2CSVObservation); + final boolean validCSVHeader = formFieldPathService.isValidCSVHeader(form2CSVHeaderParts); + if(!validCSVHeader) + throw new APIException(format("No concepts found in %s", form2CSVObservation.getKey())); + if (isNotBlank(form2CSVObservation.getValue())) { + if(isJsonAttribute) { + processJsonConceptValue(form2CSVObservation, form2CSVHeaderParts, form2Observations, encounterRow); + } else { + verifyCSVHeaderHasConcepts(form2CSVObservation, form2CSVHeaderParts); + csvObservationHelper.verifyNumericConceptValue(form2CSVObservation, form2CSVHeaderParts); + verifyForMultiSelect(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts); + verifyForAddMore(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts); + verifyAndValidateObs(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts); + } + } else { + verifyForMandatoryObs(form2CSVHeaderParts); + } + } + return form2Observations; + } + + private void verifyCSVHeaderHasConcepts(KeyValue form2CSVObservation, List form2CSVHeaderParts) { + if (form2CSVHeaderParts.size() <= 1) { + throw new APIException(format("No concepts found in %s", form2CSVObservation.getKey())); + } + } + + private List getCSVHeaderPartsByIgnoringForm2KeyWord(KeyValue csvObservation) { + final List csvHeaderParts = csvObservationHelper.getCSVHeaderParts(csvObservation); + // removes form2 keyword + csvHeaderParts.remove(0); + return csvHeaderParts; + } + + private List getConceptNames(List form2CSVHeaderParts) { + return asList(getLastItem(form2CSVHeaderParts)); + } + + private void verifyForMultiSelect(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts) throws ParseException { + boolean isMultiSelectObs = formFieldPathService.isMultiSelectObs(form2CSVHeaderParts); + if(isMultiSelectObs) { + processMultiSelectObs(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts); + } + } + + private void verifyForAddMore(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts) throws ParseException { + boolean isAddmoreConceptObs = formFieldPathService.isAddmore(form2CSVHeaderParts); + boolean isMultiSelectObs = formFieldPathService.isMultiSelectObs(form2CSVHeaderParts); + if(!isMultiSelectObs && isAddmoreConceptObs) { + processAddmoreConcept(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts); + } + } + + private void verifyForMandatoryObs(List form2CSVHeaderParts) { + boolean mandatoryFieldMissing = formFieldPathService.isMandatory(form2CSVHeaderParts); + if(mandatoryFieldMissing) { + throw new APIException(format("Empty value provided for mandatory field %s", form2CSVHeaderParts.get(form2CSVHeaderParts.size()-1))); + } + } + + private void verifyAndValidateObs(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts) throws ParseException { + boolean isMultiSelectObs = formFieldPathService.isMultiSelectObs(form2CSVHeaderParts); + boolean isAddmoreConceptObs = formFieldPathService.isAddmore(form2CSVHeaderParts); + if(!isMultiSelectObs && !isAddmoreConceptObs) { + csvObservationHelper.createObservations(form2Observations, encounterRow.getEncounterDate(), + form2CSVObservation, getConceptNames(form2CSVHeaderParts)); + formFieldPathGeneratorService.setFormNamespaceAndFieldPath(form2Observations, form2CSVHeaderParts); + validateObsForFutureDate(form2Observations, form2CSVObservation, form2CSVHeaderParts); + } + } + + private void processMultiSelectObs(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts) throws ParseException { + List multiSelectValues = csvObservationHelper.getMultiSelectObs(form2CSVObservation); + List multiSelectCSVObservations = processMultipleValues(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts, multiSelectValues); + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForMultiSelectObs(form2Observations, form2CSVHeaderParts, multiSelectCSVObservations); + } + + private void processAddmoreConcept(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts) throws ParseException { + List multiSelectValues = csvObservationHelper.getAddmoreObs(form2CSVObservation); + List addmoreCSVObservations = processMultipleValues(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts, multiSelectValues); + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForAddmoreObs(form2Observations, form2CSVHeaderParts, addmoreCSVObservations); + } + + private List processMultipleValues(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts, List multipleValues) throws ParseException { + List form2CSVObservations = new ArrayList<>(); + for (String value : multipleValues) { + KeyValue newForm2CSVObservation = new KeyValue(); + newForm2CSVObservation.setKey(form2CSVObservation.getKey()); + newForm2CSVObservation.setValue(value.trim()); + form2CSVObservations.add(newForm2CSVObservation); + } + csvObservationHelper.createObservations(form2Observations, encounterRow.getEncounterDate(), + form2CSVObservations, getConceptNames(form2CSVHeaderParts)); + return form2CSVObservations; + } + + private void validateObsForFutureDate(List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts) throws ParseException { + EncounterTransaction.Observation observation = getLastItem(form2Observations); + if(DATE.equals(observation.getConcept().getDataType())) { + boolean isAllowFutureDates = formFieldPathService.isAllowFutureDates(form2CSVHeaderParts); + if(!isAllowFutureDates) { + Date todaysDate = CSVUtils.getTodayDate(); + if(todaysDate.before(CSVUtils.getDateFromString((String)observation.getValue()))) { + throw new APIException(format("Future date [%s] is not allowed for [%s]", form2CSVObservation.getValue(), form2CSVHeaderParts.get(form2CSVHeaderParts.size()-1))); + } + } + } + } + + private void processJsonConceptValue(KeyValue form2CSVObservation, List form2CSVHeaderParts, List form2Observations, EncounterRow encounterRow) throws ParseException { + SimpleObject jsonObject = parseJson(form2CSVObservation); + List sectionPositionValues = getSectionPositions(form2CSVObservation, jsonObject, form2CSVHeaderParts); + verifyCSVHeaderHasConcepts(form2CSVObservation, form2CSVHeaderParts); + verifyAndValidateObsForJsonValue(encounterRow, form2Observations, form2CSVObservation, form2CSVHeaderParts, sectionPositionValues); + } + + private void verifyAndValidateObsForJsonValue(EncounterRow encounterRow, List form2Observations, KeyValue form2CSVObservation, List form2CSVHeaderParts, List sectionPositionValues) throws ParseException { + List form2CSVObservations = new ArrayList<>(); + sectionPositionValues.stream().forEach(sectionPositionValue -> { + if(isNotBlank(sectionPositionValue.getValue())) { + KeyValue newForm2CSVObservation = new KeyValue(); + newForm2CSVObservation.setKey(form2CSVObservation.getKey()); + newForm2CSVObservation.setValue(sectionPositionValue.getValue().trim()); + form2CSVObservations.add(newForm2CSVObservation); + } + }); + csvObservationHelper.createObservations(form2Observations, encounterRow.getEncounterDate(), + form2CSVObservations, getConceptNames(form2CSVHeaderParts)); + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForJsonValue(form2Observations, form2CSVHeaderParts, form2CSVObservations, sectionPositionValues); + } + + private Map parseCSVHeader(KeyValue form2CSVObservation) { + Map attributeMap = new HashMap<>(); + String header = form2CSVObservation.getKey(); + final int attributeStartIndex = header.lastIndexOf(ATTRIBUTE_QUERY_SEPARATOR); + if(attributeStartIndex != -1) { + final String[] attributes = header.substring(attributeStartIndex + 1).split(ATTRIBUTE_SEPARATOR); + Arrays.stream(attributes).forEach(attribute -> { + if(attribute.contains("=")) { + String attributeName = attribute.split("=")[0]; + String attributeValue = attribute.split("=")[1]; + attributeMap.put(attributeName, Boolean.valueOf(attributeValue)); + } + }); + if(attributeMap.size() > 0) + form2CSVObservation.setKey(header.substring(0, header.lastIndexOf(ATTRIBUTE_QUERY_SEPARATOR))); + } + return attributeMap; + } + + private SimpleObject parseJson(KeyValue form2CSVObservation) { + SimpleObject jsonObject; + try { + String jsonValueStr = form2CSVObservation.getValue(); + jsonObject = SimpleObject.parseJson(jsonValueStr); + } catch (Exception e) { + throw new APIException(format("Error in parsing json value for %s", form2CSVObservation.getKey())); + } + return jsonObject; + } + + private List getSectionPositions(KeyValue form2CSVObservation, SimpleObject jsonObject, List form2CSVHeaderParts) { + List sectionPositionValues = new ArrayList<>(); + String initialSectionIndex = "0"; + Object objectValue = jsonObject.get(KEY_SECTION_VALUES); + if(objectValue == null) + throw new APIException(format("Error in parsing json value for %s", form2CSVObservation.getKey())); + + boolean isAddmoreConceptObs = formFieldPathService.isAddmore(form2CSVHeaderParts); + boolean isMultiSelectObs = formFieldPathService.isMultiSelectObs(form2CSVHeaderParts); + + updateSectionPositionValues(sectionPositionValues, objectValue, initialSectionIndex, isMultiSelectObs, isAddmoreConceptObs); + return sectionPositionValues; + } + + private void updateSectionPositionValues(List sectionPositionValues, Object objectValue, String sectionIndex, boolean isMultiselectObs, boolean isAddmoreObs) { + if(objectValue instanceof List) { + List values = (ArrayList) objectValue; + for(int i = 0; i < values.size(); i++) { + if(values.get(i) instanceof String) { + String value = (String) values.get(i); + if(isMultiselectObs) { + List multiSelectObs = csvObservationHelper.getMultiSelectObsForJsonValue(value); + addObstoList(sectionPositionValues, sectionIndex, isMultiselectObs, isAddmoreObs, i, value, multiSelectObs); + } else if(isAddmoreObs) { + List addmoreObs = csvObservationHelper.getAddmoreObsForJsonValue(value); + addObstoList(sectionPositionValues, sectionIndex, isMultiselectObs, isAddmoreObs, i, value, addmoreObs); + } else { + SectionPositionValue sectionPositionValue = new SectionPositionValue(value, sectionIndex, i, NOT_MULTISELECT_OBS_INDEX, NOT_ADDMORE_OBS_INDEX); + sectionPositionValues.add(sectionPositionValue); + } + } else { + updateSectionPositionValues(sectionPositionValues, values.get(i), sectionIndex + SECTION_SPLITTER + i, isMultiselectObs, isAddmoreObs); + } + } + } + } + + private void addObstoList(List sectionPositionValues, String sectionIndex, boolean isMultiselectObs, boolean isAddmoreObs, int obsIndex, String value, List multipleObs) { + for(int i = 0; i < multipleObs.size(); i++) { + SectionPositionValue sectionPositionValue = null; + if(isMultiselectObs) + sectionPositionValue = new SectionPositionValue(multipleObs.get(i), sectionIndex, obsIndex, i, NOT_ADDMORE_OBS_INDEX); + else if(isMultiselectObs) + sectionPositionValue = new SectionPositionValue(multipleObs.get(i), sectionIndex, obsIndex, NOT_MULTISELECT_OBS_INDEX, i); + sectionPositionValues.add(sectionPositionValue); + } + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/domain/BahmniVisit.java b/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/domain/BahmniVisit.java new file mode 100644 index 0000000000..7cac111bed --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/domain/BahmniVisit.java @@ -0,0 +1,28 @@ +package org.bahmni.module.admin.retrospectiveEncounter.domain; + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Visit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class BahmniVisit { + private Visit visit; + + public BahmniVisit(Visit visit) { + this.visit = visit; + } + + public List obsFor(String requestedEncounterType) { + List allObs = new ArrayList<>(); + for (Encounter anEncounter : visit.getEncounters()) { + if (anEncounter.getEncounterType().getName().equals(requestedEncounterType)) { + Set obs = anEncounter.getObs(); + allObs.addAll(obs); + } + } + return allObs; + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/domain/DuplicateObservationsMatcher.java b/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/domain/DuplicateObservationsMatcher.java new file mode 100644 index 0000000000..81da7c949f --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/domain/DuplicateObservationsMatcher.java @@ -0,0 +1,124 @@ +package org.bahmni.module.admin.retrospectiveEncounter.domain; + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.EmrApiConstants; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Set; + +public class DuplicateObservationsMatcher { + private Visit matchingVisit; + private BahmniVisit visit; + private List visitObservations; + private String requestedEncounterType; + + public DuplicateObservationsMatcher(Visit matchingVisit, String requestedEncounterType) { + this.visit = new BahmniVisit(matchingVisit); + this.matchingVisit = matchingVisit; + this.requestedEncounterType = requestedEncounterType; + } + + public List getUniqueObservations(List observations) { + List allObs = getObservationsForVisit(); + + List uniqueObservations = new ArrayList<>(); + for (EncounterTransaction.Observation anObservation : observations) { + String anObservationValue = (String) anObservation.getValue(); + String observationConceptName = anObservation.getConcept().getName(); + if (isUnique(allObs, anObservationValue, observationConceptName)) { + uniqueObservations.add(anObservation); + } + } + return uniqueObservations; + } + + public Collection getNewlyAddedBahmniObservations(Collection observations, Date encounterDateTime) { + List matchedEncounters = getAllEncountersByDate(encounterDateTime); + return filterObsIfItIsExists(observations, matchedEncounters); + } + + private Collection filterObsIfItIsExists(Collection observations, List matchedEncounters) { + List existingObs = new ArrayList<>(); + for (Encounter matchedEncounter : matchedEncounters) { + for (BahmniObservation observation : observations) { + if (isObsExisits(observation, matchedEncounter.getAllObs())) { + existingObs.add(observation); + } + } + } + observations.removeAll(existingObs); + return observations; + } + + private boolean isObsExisits(BahmniObservation observation, Set existingObs) { + for (Obs obs : existingObs) { + if (doesConceptNameMatch(obs, observation.getConcept().getName())) { + return true; + } + } + return false; + } + + private List getAllEncountersByDate(Date encounterDateTime) { + Set encounters = matchingVisit.getEncounters(); + List matchingEncounters = new ArrayList<>(); + for (Encounter encounter : encounters) { + if (encounterDateTime.equals(encounter.getEncounterDatetime())) + matchingEncounters.add(encounter); + } + return matchingEncounters; + } + + + public List getUniqueDiagnoses(List bahmniDiagnoses) { + List allObs = getObservationsForVisit(); + + List uniqueDiagnoses = new ArrayList<>(); + for (BahmniDiagnosisRequest diagnosisRequest : bahmniDiagnoses) { + if (diagnosisRequest.getCodedAnswer() != null && isUnique(allObs, diagnosisRequest.getCodedAnswer().getUuid(), EmrApiConstants.CONCEPT_CODE_CODED_DIAGNOSIS)) { + uniqueDiagnoses.add(diagnosisRequest); + } else if (diagnosisRequest.getCodedAnswer() == null) { + uniqueDiagnoses.add(diagnosisRequest); + } + } + return uniqueDiagnoses; + } + + private List getObservationsForVisit() { + if (visitObservations == null) + visitObservations = visit.obsFor(requestedEncounterType); + + return visitObservations; + } + + private boolean isUnique(List allObs, String anObservationValue, String observationConceptName) { + for (Obs anObs : allObs) { + if (doesConceptNameMatch(anObs, observationConceptName) && doesObsValueMatch(anObs, anObservationValue)) { + return false; + } + } + return true; + } + + private boolean doesConceptNameMatch(Obs obs, String conceptName) { + return conceptName.equalsIgnoreCase(obs.getConcept().getName().getName()); + } + + private boolean doesObsValueMatch(Obs obs, String anObservationValue) { + if (obs.getConcept().getDatatype().isCoded() && obs.getValueCoded() != null) { + return anObservationValue.equalsIgnoreCase(obs.getValueCoded().getUuid()); + } else if (obs.getConcept().isNumeric()) { + return Double.parseDouble(anObservationValue) == obs.getValueNumeric(); + } + return anObservationValue.equalsIgnoreCase(obs.getValueAsString(Context.getLocale())); + } +} diff --git a/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/service/DuplicateObservationService.java b/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/service/DuplicateObservationService.java new file mode 100644 index 0000000000..7700714855 --- /dev/null +++ b/admin/src/main/java/org/bahmni/module/admin/retrospectiveEncounter/service/DuplicateObservationService.java @@ -0,0 +1,38 @@ +package org.bahmni.module.admin.retrospectiveEncounter.service; + +import org.bahmni.module.admin.retrospectiveEncounter.domain.DuplicateObservationsMatcher; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitIdentificationHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +@Component +public class DuplicateObservationService { + protected final VisitIdentificationHelper visitIdentificationHelper; + + @Autowired + public DuplicateObservationService(VisitService visitService) { + visitIdentificationHelper = new VisitIdentificationHelper(visitService, null); + } + + public void filter(BahmniEncounterTransaction bahmniEncounterTransaction, Patient patient, Date visitStartDate, Date visitEndDate) { + Visit matchingVisit = visitIdentificationHelper.getVisitFor(patient, bahmniEncounterTransaction.getVisitType(), + bahmniEncounterTransaction.getEncounterDateTime(), visitStartDate, visitEndDate,bahmniEncounterTransaction.getLocationUuid()); + + DuplicateObservationsMatcher duplicateObservationsMatcher = new DuplicateObservationsMatcher(matchingVisit, bahmniEncounterTransaction.getEncounterType()); + Collection uniqueObservations = duplicateObservationsMatcher.getNewlyAddedBahmniObservations(bahmniEncounterTransaction.getObservations(), bahmniEncounterTransaction.getEncounterDateTime()); + List uniqueDiagnoses = duplicateObservationsMatcher.getUniqueDiagnoses(bahmniEncounterTransaction.getBahmniDiagnoses()); + + bahmniEncounterTransaction.setObservations(uniqueObservations); + bahmniEncounterTransaction.setBahmniDiagnoses(uniqueDiagnoses); + } +} \ No newline at end of file diff --git a/admin/src/main/resources/BahmniConfig.hbm.xml b/admin/src/main/resources/BahmniConfig.hbm.xml new file mode 100644 index 0000000000..7cb8052286 --- /dev/null +++ b/admin/src/main/resources/BahmniConfig.hbm.xml @@ -0,0 +1,32 @@ + + + + + + + + + config_id_seq + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/src/main/resources/moduleApplicationContext.xml b/admin/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..29ac3297da --- /dev/null +++ b/admin/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/admin/src/test/java/org/bahmni/module/admin/BaseIntegrationTest.java b/admin/src/test/java/org/bahmni/module/admin/BaseIntegrationTest.java new file mode 100644 index 0000000000..4e4e32e460 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/BaseIntegrationTest.java @@ -0,0 +1,8 @@ +package org.bahmni.module.admin; + +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BaseIntegrationTest extends BaseModuleWebContextSensitiveTest { +} diff --git a/admin/src/test/java/org/bahmni/module/admin/builder/BahmniObservationBuilder.java b/admin/src/test/java/org/bahmni/module/admin/builder/BahmniObservationBuilder.java new file mode 100644 index 0000000000..2b8db60c54 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/builder/BahmniObservationBuilder.java @@ -0,0 +1,40 @@ +package org.bahmni.module.admin.builder; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; + +public class BahmniObservationBuilder { + private BahmniObservation bahmniObservation; + + public BahmniObservationBuilder() { + this.bahmniObservation = new BahmniObservation(); + } + + public BahmniObservation build() { + return bahmniObservation; + } + + public BahmniObservationBuilder withConcept(String conceptName) { + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(); + concept.setName(conceptName); + bahmniObservation.setConcept(concept); + return this; + } + + public BahmniObservationBuilder withValue(String value) { + bahmniObservation.setValue(value); + return this; + } + + public BahmniObservationBuilder withEncounterDate(Date encounterDate) { + bahmniObservation.setEncounterDateTime(encounterDate); + return this; + } + + public BahmniObservationBuilder withSetMember(BahmniObservation member) { + bahmniObservation.addGroupMember(member); + return this; + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/concepts/mapper/ConceptMapperTest.java b/admin/src/test/java/org/bahmni/module/admin/concepts/mapper/ConceptMapperTest.java new file mode 100644 index 0000000000..85c2f3a2c6 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/concepts/mapper/ConceptMapperTest.java @@ -0,0 +1,122 @@ +package org.bahmni.module.admin.concepts.mapper; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class ConceptMapperTest { + + private ConceptMapper conceptMapper; + + @Before + public void setUp() throws Exception { + conceptMapper = new ConceptMapper(); + } + + @Test + public void mapConceptRowToConceptDTo() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "UniqueName"; + conceptRow.uuid = UUID.randomUUID().toString(); + conceptRow.shortName = "UName"; + conceptRow.conceptClass = "Finding"; + conceptRow.allowDecimal = "true"; + Concept mappedConcept = conceptMapper.map(conceptRow); + assertEquals(conceptRow.name, mappedConcept.getUniqueName()); + assertEquals(conceptRow.shortName, mappedConcept.getDisplayName()); + assertEquals(conceptRow.conceptClass, mappedConcept.getClassName()); + assertEquals(conceptRow.allowDecimal, mappedConcept.getAllowDecimal()); + assertEquals(conceptRow.getDataType(), mappedConcept.getDataType()); + assertEquals(conceptRow.getUuid(), mappedConcept.getUuid()); + } + + @Test + public void setDefaultDatatypeToNA() throws Exception { + Concept mappedConcept = conceptMapper.map(new ConceptRow()); + assertEquals("N/A", mappedConcept.getDataType()); + } + + @Test + public void getEmptyListForNoAnswers() throws Exception { + Concept mappedConcept = conceptMapper.map(new ConceptRow()); + assertEquals(0, mappedConcept.getAnswers().size()); + } + + @Test + public void getEmptyListForNoSynonyms() throws Exception { + Concept mappedConcept = conceptMapper.map(new ConceptRow()); + assertEquals(0, mappedConcept.getSynonyms().size()); + } + + @Test + public void mapConceptReferenceTerm() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + ConceptReferenceTermRow referenceTermRowOne = new ConceptReferenceTermRow("source", "codeOne", "SAME-AS"); + ConceptReferenceTermRow referenceTermRowTwo = new ConceptReferenceTermRow("source", "codeTwo", "SAME-AS"); + conceptRow.setReferenceTerms(Arrays.asList(referenceTermRowOne, referenceTermRowTwo)); + Concept mappedConcept = conceptMapper.map(conceptRow); + + assertEquals(2, mappedConcept.getConceptReferenceTermsList().size()); + assertEquals("codeOne", mappedConcept.getConceptReferenceTermsList().get(0).getReferenceTermCode()); + assertEquals("codeTwo", mappedConcept.getConceptReferenceTermsList().get(1).getReferenceTermCode()); + } + + @Test + public void shouldNotMapEmptySynonyms() throws Exception { + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("Synonym.1", "")); + synonyms.add(new KeyValue("Synonym.2", "Synonym")); + ConceptRow conceptRow = new ConceptRow(); + conceptRow.synonyms = synonyms; + Concept mappedConcept = conceptMapper.map(conceptRow); + assertEquals(1, mappedConcept.getSynonyms().size()); + assertEquals("Synonym", mappedConcept.getSynonyms().get(0)); + } + + @Test + public void shouldNotMapEmptyAnswers() throws Exception { + List answers = new ArrayList<>(); + answers.add(new KeyValue("1", "")); + answers.add(new KeyValue("2", "Answer")); + ConceptRow conceptRow = new ConceptRow(); + conceptRow.answers = answers; + Concept mappedConcept = conceptMapper.map(conceptRow); + assertEquals(1, mappedConcept.getAnswers().size()); + assertEquals("Answer", mappedConcept.getAnswers().get(0)); + } + + @Test + public void mapDescriptionNullIfEmpty() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.description = ""; + Concept mappedConcept = conceptMapper.map(conceptRow); + assertNull(mappedConcept.getDescription()); + } + + @Test + public void uuidNullIfNotSpecified() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.uuid = null; + Concept map = conceptMapper.map(conceptRow); + assertNull(map.getUuid()); + } + + @Test + public void uuidNullIfNotValid() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.uuid = "invalid UUID"; + Concept map = conceptMapper.map(conceptRow); + assertNull(map.getUuid()); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/concepts/mapper/ConceptSetMapperIntegrationTest.java b/admin/src/test/java/org/bahmni/module/admin/concepts/mapper/ConceptSetMapperIntegrationTest.java new file mode 100644 index 0000000000..ab4287bca0 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/concepts/mapper/ConceptSetMapperIntegrationTest.java @@ -0,0 +1,187 @@ +package org.bahmni.module.admin.concepts.mapper; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.admin.csv.models.ConceptRows; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class ConceptSetMapperIntegrationTest { + public static final String SAME_AS = "SAME-AS"; + private ConceptSetMapper conceptSetMapper; + private ArrayList children; + private org.bahmni.module.referencedata.labconcepts.mapper.ConceptSetMapper referenceDataConceptSetMapper; + + @Before + public void setUp() throws Exception { + conceptSetMapper = new ConceptSetMapper(); + referenceDataConceptSetMapper = new org.bahmni.module.referencedata.labconcepts.mapper.ConceptSetMapper(); + children = new ArrayList<>(); + children.add(new KeyValue("1", "child1")); + children.add(new KeyValue("2", "child2")); + } + + @Test + public void mapConceptSetRowToConceptSetDto() throws Exception { + ConceptSetRow conceptSetRow = new ConceptSetRow(); + conceptSetRow.name = "UniqueName"; + conceptSetRow.shortName = "shortName"; + conceptSetRow.conceptClass = "ConvSet"; + conceptSetRow.children = children; + conceptSetRow.uuid = UUID.randomUUID().toString(); + + ConceptSet conceptSet = conceptSetMapper.map(conceptSetRow); + assertEquals(2, conceptSet.getChildren().size()); + assertEquals(conceptSetRow.name, conceptSet.getUniqueName()); + assertEquals(conceptSetRow.shortName, conceptSet.getDisplayName()); + assertEquals(conceptSetRow.conceptClass, conceptSet.getClassName()); + assertEquals(conceptSetRow.getUuid(), conceptSet.getUuid()); + } + + @Test + public void nullIfNoShortName() throws Exception { + ConceptSetRow conceptSetRow = new ConceptSetRow(); + conceptSetRow.name = "Some"; + conceptSetRow.shortName = " "; + ConceptSet map = conceptSetMapper.map(conceptSetRow); + assertNull(map.getDisplayName()); + assertEquals(conceptSetRow.name, map.getUniqueName()); + } + + @Test + public void shouldNotMapEmptyChildren() throws Exception { + ConceptSetRow conceptSetRow = new ConceptSetRow(); + conceptSetRow.name = "UniqueName"; + conceptSetRow.shortName = "shortName"; + conceptSetRow.conceptClass = "ConvSet"; + conceptSetRow.children = children; + conceptSetRow.children.add(new KeyValue("3", "")); + + ConceptSet conceptSet = conceptSetMapper.map(conceptSetRow); + assertEquals(2, conceptSet.getChildren().size()); + assertEquals(conceptSetRow.name, conceptSet.getUniqueName()); + assertEquals(conceptSetRow.shortName, conceptSet.getDisplayName()); + assertEquals(conceptSetRow.conceptClass, conceptSet.getClassName()); + + } + + @Test + public void mapConceptReferenceTermToConceptSetDto() throws Exception { + ConceptSetRow conceptSetRow = new ConceptSetRow(); + conceptSetRow.name = "UniqueName"; + conceptSetRow.shortName = "shortName"; + conceptSetRow.conceptClass = "ConvSet"; + conceptSetRow.children = children; + ConceptReferenceTermRow conceptReferenceTermRow = new ConceptReferenceTermRow( "org.openmrs.module.emrapi","New Code", SAME_AS); + List conceptReferenceTermsList = new ArrayList<>(Arrays.asList(conceptReferenceTermRow)); + conceptSetRow.referenceTerms = conceptReferenceTermsList; + + ConceptSet conceptSet = conceptSetMapper.map(conceptSetRow); + assertEquals(2, conceptSet.getChildren().size()); + assertEquals(conceptSetRow.name, conceptSet.getUniqueName()); + assertEquals(conceptSetRow.shortName, conceptSet.getDisplayName()); + assertEquals(conceptSetRow.conceptClass, conceptSet.getClassName()); + assertEquals("New Code", conceptSet.getConceptReferenceTermsList().get(0).getReferenceTermCode()); + assertEquals(SAME_AS, conceptSet.getConceptReferenceTermsList().get(0).getReferenceTermRelationship()); + assertEquals("org.openmrs.module.emrapi", conceptSet.getConceptReferenceTermsList().get(0).getReferenceTermSource()); + } + + @Test + public void getConceptListInOrderFromConceptSet() throws Exception { + org.openmrs.Concept child1 = new ConceptBuilder().withName("Child1").withDescription("Description").withClass("Some").withDataType("N/A").withShortName("short").build(); + org.openmrs.Concept child2 = new ConceptBuilder().withName("Child2").withDescription("Description").withClass("Some").withDataType("N/A").withShortName("short").build(); + org.openmrs.Concept child3 = new ConceptBuilder().withName("Child3").withDescription("Description").withClass("Some").withDataType("N/A").withShortName("short").build(); + org.openmrs.Concept child4 = new ConceptBuilder().withName("Child4").withDescription("Description").withClass("Some").withDataType("N/A").withShortName("short").build(); + org.openmrs.Concept conceptSet = new ConceptBuilder().withName("Parent Concept").withClass("Misc").withDataType("N/A").withShortName("Shortn").withUUID("Parent").withSetMember(child1).withSetMember(child2).withSetMember(child3).withSetMember(child4).build(); + List conceptRows = conceptSetMapper.mapAll(referenceDataConceptSetMapper.mapAll(conceptSet)).getConceptRows(); + assertEquals(4, conceptRows.size()); + assertEquals("Child1", conceptRows.get(0).name); + assertEquals("Child2", conceptRows.get(1).name); + assertEquals("Child3", conceptRows.get(2).name); + assertEquals("Child4", conceptRows.get(3).name); + assertEquals("Description", conceptRows.get(0).description); + assertEquals("Some", conceptRows.get(0).conceptClass); + assertEquals("N/A", conceptRows.get(0).getDataType()); + assertEquals(0, conceptRows.get(0).getSynonyms().size()); + assertEquals(0, conceptRows.get(1).getSynonyms().size()); + assertEquals(0, conceptRows.get(2).getSynonyms().size()); + assertEquals(0, conceptRows.get(3).getSynonyms().size()); + } + + @Test + public void getListOfConceptWithConceptAnswers() throws Exception { + org.openmrs.Concept answer1 = new ConceptBuilder().withName("Answer1").withDataType("N/A").withClass("Misc").withShortName("ShortName3").withUUID("answer1").build(); + org.openmrs.Concept child1 = new ConceptBuilder().withName("Child1").withDataType("N/A").withClass("Misc").withShortName("ShortName1").withUUID("child1").withAnswer(answer1).build(); + org.openmrs.Concept child2 = new ConceptBuilder().withName("Child2").withDataType("N/A").withClass("Misc").withShortName("ShortName2").withUUID("child2").build(); + org.openmrs.Concept conceptSet = new ConceptBuilder().withName("Parent Concept").withClass("Misc").withDataType("N/A").withShortName("Shortn").withUUID("Parent").withSetMember(child1).withSetMember(child2).build(); + ConceptRows conceptRows = conceptSetMapper.mapAll(referenceDataConceptSetMapper.mapAll(conceptSet)); + List conceptList = conceptRows.getConceptRows(); + ConceptRow answer = conceptList.get(0); + ConceptRow child1Row = conceptList.get(1); + ConceptRow child2Row = conceptList.get(2); + assertEquals(3, conceptList.size()); + assertEquals("Answer1", answer.name); + assertEquals("Child1", child1Row.name); + assertEquals("Child2", child2Row.name); + } + + @Test + public void getListOfConceptWithConceptSets() throws Exception { + org.openmrs.Concept answer1 = new ConceptBuilder().withName("Answer1").withDataType("N/A").withClass("Misc").withShortName("ShortName3").withUUID("answer1").build(); + org.openmrs.Concept child1 = new ConceptBuilder().withName("Child1").withDataType("N/A").withClass("Misc").withShortName("ShortName1").withUUID("child1").withAnswer(answer1).build(); + org.openmrs.Concept child2 = new ConceptBuilder().withName("Child2").withDataType("N/A").withClass("Misc").withShortName("ShortName2").withUUID("child2").build(); + org.openmrs.Concept child3 = new ConceptBuilder().withName("Child3").withDataType("N/A").withClass("Misc").withShortName("ShortName3").withUUID("child3").build(); + org.openmrs.Concept set1 = new ConceptBuilder().withName("Sub Parent").withDataType("N/A").withClass("Misc").withShortName("SubP").withUUID("subp").withSetMember(child3).build(); + set1.setSet(true); + org.openmrs.Concept conceptSet = new ConceptBuilder().withName("Parent Concept").withClass("Misc").withDataType("N/A").withShortName("Shortn").withUUID("Parent").withSetMember(child1).withSetMember(child2).withSetMember(set1).build(); + conceptSet.setSet(true); + ConceptRows conceptRows = conceptSetMapper.mapAll(referenceDataConceptSetMapper.mapAll(conceptSet)); + List conceptList = conceptRows.getConceptRows(); + List conceptSetList = conceptRows.getConceptSetRows(); + ConceptRow answer = conceptList.get(0); + ConceptRow child1Row = conceptList.get(1); + ConceptRow child2Row = conceptList.get(2); + assertEquals(4, conceptList.size()); + assertEquals("Answer1", answer.name); + assertEquals("answer1", answer.uuid); + assertEquals("Child1", child1Row.name); + assertEquals("child1", child1Row.uuid); + assertEquals("child2", child2Row.uuid); + assertEquals("Child2", child2Row.name); + assertEquals(2, conceptSetList.size()); + ConceptSetRow conceptSetRow1 = conceptSetList.get(0); + ConceptSetRow conceptSetRow2 = conceptSetList.get(1); + assertEquals("Parent Concept", conceptSetRow2.name); + assertEquals("Parent", conceptSetRow2.uuid); + assertEquals("Sub Parent", conceptSetRow1.name); + assertEquals("subp", conceptSetRow1.uuid); + } + + @Test + public void uuidNullIfNotSpecified() throws Exception { + ConceptSetRow conceptRow = new ConceptSetRow(); + conceptRow.uuid = null; + ConceptSet map = conceptSetMapper.map(conceptRow); + assertNull(map.getUuid()); + } + + @Test + public void uuidNullIfNotValid() throws Exception { + ConceptSetRow conceptSetRow = new ConceptSetRow(); + conceptSetRow.uuid = "invalid UUID"; + ConceptSet map = conceptSetMapper.map(conceptSetRow); + assertNull(map.getUuid()); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/config/dao/impl/BahmniConfigDaoImplIT.java b/admin/src/test/java/org/bahmni/module/admin/config/dao/impl/BahmniConfigDaoImplIT.java new file mode 100644 index 0000000000..efde952828 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/config/dao/impl/BahmniConfigDaoImplIT.java @@ -0,0 +1,87 @@ +package org.bahmni.module.admin.config.dao.impl; + +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.config.dao.BahmniConfigDao; +import org.bahmni.module.admin.config.model.BahmniConfig; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang.StringUtils; + +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class BahmniConfigDaoImplIT extends BaseIntegrationTest { + + @Autowired + private BahmniConfigDao bahmniConfigDao; + + @Before + public void setUp() throws Exception { + executeDataSet("configDataSetup.xml"); + } + + @Test + public void getConfigFromByAppAndConfigName() throws Exception { + BahmniConfig clinical = bahmniConfigDao.get("clinical", "app.json"); + assertNotNull(clinical); + assertEquals("clinical", clinical.getAppName()); + assertEquals("app.json", clinical.getConfigName()); + assertEquals("0aa1efd4-6eeb-4cea-bd4b-94af86f24d97", clinical.getUuid()); + assertFalse(StringUtils.isEmpty(clinical.getConfig())); + } + + @Test + public void getConfigFromByUuid() throws Exception { + BahmniConfig clinical = bahmniConfigDao.get("0aa1efd4-6eeb-4cea-bd4b-94af86f24d97"); + assertNotNull(clinical); + assertEquals("clinical", clinical.getAppName()); + assertEquals("app.json", clinical.getConfigName()); + assertEquals("0aa1efd4-6eeb-4cea-bd4b-94af86f24d97", clinical.getUuid()); + assertFalse(StringUtils.isEmpty(clinical.getConfig())); + } + + @Test + public void returnNullIfConfigNotAvailable() throws Exception { + BahmniConfig clinical = bahmniConfigDao.get("notclinical", "app.json"); + assertNull(clinical); + } + + @Test + public void getAllConfigsFor() throws Exception { + List clinical = bahmniConfigDao.getAllFor("clinical"); + assertEquals(2, clinical.size()); + } + + @Test + public void insertNewConfig() throws Exception { + BahmniConfig bahmniConfig = new BahmniConfig(); + bahmniConfig.setConfig("New Config"); + bahmniConfig.setAppName("registration"); + bahmniConfig.setConfigName("app.json"); + bahmniConfig.setCreator(Context.getUserContext().getAuthenticatedUser()); + bahmniConfig.setDateCreated(new Date()); + BahmniConfig add = bahmniConfigDao.save(bahmniConfig); + assertEquals("registration", add.getAppName()); + assertEquals("app.json", add.getConfigName()); + assertEquals("New Config", add.getConfig()); + } + + @Test + public void updateConfig() throws Exception { + BahmniConfig clinical = bahmniConfigDao.get("clinical", "app.json"); + clinical.setConfig("Modified Config"); + BahmniConfig add = bahmniConfigDao.update(clinical); + BahmniConfig modifiedClinical = bahmniConfigDao.get("clinical", "app.json"); + assertEquals("clinical", modifiedClinical.getAppName()); + assertEquals("app.json", modifiedClinical.getConfigName()); + assertEquals("Modified Config", modifiedClinical.getConfig()); + assertEquals(add, modifiedClinical); + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/config/service/impl/BahmniConfigServiceImplTest.java b/admin/src/test/java/org/bahmni/module/admin/config/service/impl/BahmniConfigServiceImplTest.java new file mode 100644 index 0000000000..876f5f27a6 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/config/service/impl/BahmniConfigServiceImplTest.java @@ -0,0 +1,87 @@ +package org.bahmni.module.admin.config.service.impl; + +import org.bahmni.module.admin.config.dao.impl.BahmniConfigDaoImpl; +import org.bahmni.module.admin.config.model.BahmniConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BahmniConfigServiceImplTest { + @Mock + private BahmniConfigDaoImpl bahmniConfigDao; + + private BahmniConfig existingConfig; + private BahmniConfig newConfig; + private BahmniConfigServiceImpl bahmniConfigService; + private User creator; + + @Before + public void setUp() throws Exception { + initMocks(this); + creator = new User(); + PowerMockito.mockStatic(Context.class); + when(Context.getAuthenticatedUser()).thenReturn(creator); + + existingConfig = new BahmniConfig(); + existingConfig.setUuid("existing"); + newConfig = new BahmniConfig(); + when(bahmniConfigDao.get("existing")).thenReturn(existingConfig); + when(bahmniConfigDao.get("new")).thenReturn(null); + when(bahmniConfigDao.save(any(BahmniConfig.class))).then(new Answer() { + @Override + public BahmniConfig answer(InvocationOnMock invocationOnMock) throws Throwable { + Object[] arguments = invocationOnMock.getArguments(); + BahmniConfig argument = (BahmniConfig) arguments[0]; + argument.setUuid("new"); + return argument; + } + }); + when(bahmniConfigDao.update(any(BahmniConfig.class))).then(new Answer() { + @Override + public BahmniConfig answer(InvocationOnMock invocationOnMock) throws Throwable { + Object[] arguments = invocationOnMock.getArguments(); + return (BahmniConfig) arguments[0]; + } + }); + bahmniConfigService = new BahmniConfigServiceImpl(bahmniConfigDao); + } + + @Test + public void updateChangedAuditFieldsAndConfigForExistingConfigs() throws Exception { + existingConfig.setConfig("Modified Config"); + assertNull(existingConfig.getChangedBy()); + assertNull(existingConfig.getDateChanged()); + BahmniConfig savedConfig = bahmniConfigService.update(existingConfig); + assertNotNull(savedConfig.getDateChanged()); + assertEquals(creator, savedConfig.getChangedBy()); + assertEquals("Modified Config", savedConfig.getConfig()); + } + + @Test + public void createNewConfigWithCreator() throws Exception { + newConfig.setConfig("Yo Config"); + assertNull(newConfig.getDateCreated()); + assertNull(newConfig.getCreator()); + BahmniConfig savedConfig = bahmniConfigService.save(newConfig); + assertNotNull(savedConfig.getDateCreated()); + assertEquals(creator, savedConfig.getCreator()); + assertEquals("Yo Config", savedConfig.getConfig()); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/exporter/ConceptSetExporterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/exporter/ConceptSetExporterIT.java new file mode 100644 index 0000000000..959b067193 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/exporter/ConceptSetExporterIT.java @@ -0,0 +1,93 @@ +package org.bahmni.module.admin.csv.exporter; + +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.admin.csv.models.ConceptRows; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.api.APIException; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class ConceptSetExporterIT extends BaseIntegrationTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Autowired + private ConceptSetExporter conceptSetExporter; + + @Before + public void setUp() throws Exception { + executeDataSet("conceptExportSetup.xml"); + } + + @Test + public void throwExceptionIfConceptDoesNotExist() throws Exception { + exception.expect(APIException.class); + exception.expectMessage("Concept Does not exist not found"); + conceptSetExporter.exportConcepts("Does not exist"); + } + + @Test + @Ignore + public void getListOfConceptRows() throws Exception { + ConceptRows result = conceptSetExporter.exportConcepts("Big Concept"); + List conceptRows = result.getConceptRows(); + List conceptSetRows = result.getConceptSetRows(); + assertEquals(9, conceptRows.size()); + ConceptRow child1 = conceptRows.get(4); + ConceptRow child2 = conceptRows.get(6); + ConceptRow child3 = conceptRows.get(8); + ConceptRow child4 = conceptRows.get(7); + ConceptRow answer01 = conceptRows.get(1); + ConceptRow answer11 = conceptRows.get(2); + ConceptRow answer12 = conceptRows.get(3); + ConceptRow answer21 = conceptRows.get(5); + assertEquals("Answer1", answer11.name); + assertEquals("Answer0", answer01.name); + assertEquals("Answer2", answer12.name); + assertEquals("Answer3", answer21.name); + assertEquals("Child1", child1.name); + assertEquals("d670df13-7fef-44af-aade-8db46f245522", child1.uuid); + assertEquals("Child2", child2.name); + assertEquals("Child3", child3.name); + assertEquals("Child4", child4.name); + assertEquals("Document", child1.dataType); + assertEquals("Document", child2.dataType); + assertEquals("Document", child3.dataType); + assertEquals("New Class", child1.conceptClass); + assertEquals("New Class", child2.conceptClass); + assertEquals("New Class", child3.conceptClass); + assertEquals(2, child1.getSynonyms().size()); + assertEquals(2, child2.getSynonyms().size()); + assertEquals(2, child3.getSynonyms().size()); + assertEquals(3, child1.getAnswers().size()); + assertEquals(3, child2.getAnswers().size()); + assertEquals(3, child3.getAnswers().size()); + assertEquals("Concept1 Description", child1.getDescription()); + assertNull(child2.getDescription()); + assertNull(child3.getDescription()); + assertEquals("New Code", child3.getReferenceTerms().get(0).getReferenceTermCode()); + assertEquals("SAME-AS".toLowerCase(), child3.getReferenceTerms().get(0).getReferenceTermRelationship().toLowerCase()); + assertEquals("org.openmrs.module.emrapi", child3.getReferenceTerms().get(0).getReferenceTermSource()); + assertEquals(3, conceptSetRows.size()); + ConceptSetRow small = conceptSetRows.get(1); + ConceptSetRow big = conceptSetRows.get(2); + assertEquals("Small Concept", small.name); + assertEquals("68637e4e-c8a9-4831-93b4-2ef2d987105d", small.uuid); + assertEquals("Big Concept", big.name); + assertEquals("39854ddf-b950-4c20-91d9-475729ca0ec6", big.uuid); + assertEquals(3, conceptRows.get(0).getAnswers().size()); + assertEquals(2, conceptRows.get(0).getSynonyms().size()); + assertEquals(5, conceptSetRows.get(0).getChildren().size()); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/models/LabResultsRowTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/models/LabResultsRowTest.java new file mode 100644 index 0000000000..c5d83cb676 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/models/LabResultsRowTest.java @@ -0,0 +1,31 @@ +package org.bahmni.module.admin.csv.models; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.hasItems; + +public class LabResultsRowTest { + + @Test + public void testGetTestResultsReturnsNonEmptyTestResults() throws Exception { + LabResultRow labResultRow1 = new LabResultRow(null, null); + LabResultRow labResultRow2 = new LabResultRow("", ""); + LabResultRow labResultRow3 = new LabResultRow("", null); + LabResultRow labResultRow4 = new LabResultRow("HB1Ac", null); + LabResultRow labResultRow5 = new LabResultRow("HB1Ac", "10"); + LabResultRow labResultRow6 = new LabResultRow("", "10"); + List allLabResultRows = Arrays.asList(labResultRow1, labResultRow2, labResultRow3, labResultRow4, labResultRow5, labResultRow6); + LabResultsRow labResultsRow = new LabResultsRow(); + labResultsRow.setTestResults(allLabResultRows); + + List testResults = labResultsRow.getTestResults(); + + assertEquals(3, testResults.size()); + assertThat(testResults, hasItems(labResultRow4, labResultRow5, labResultRow6)); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/models/MultipleEncounterRowBuilder.java b/admin/src/test/java/org/bahmni/module/admin/csv/models/MultipleEncounterRowBuilder.java new file mode 100644 index 0000000000..31a507ddf2 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/models/MultipleEncounterRowBuilder.java @@ -0,0 +1,30 @@ +package org.bahmni.module.admin.csv.models; + +import org.bahmni.csv.KeyValue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MultipleEncounterRowBuilder { + public MultipleEncounterRow getEmptyMultipleEncounterRow(String patientId) { + List emptyDiagnoses = new ArrayList<>(); + emptyDiagnoses.add(new KeyValue("diagnosis", " ")); + emptyDiagnoses.add(new KeyValue("diagnosis", " ")); + + List emptyObservations = new ArrayList<>(); + emptyObservations.add(new KeyValue("diagnosis", " ")); + emptyObservations.add(new KeyValue("diagnosis", " ")); + + EncounterRow emptyEncounterRow = new EncounterRow(); + emptyEncounterRow.encounterDateTime = " "; + emptyEncounterRow.obsRows = emptyObservations; + emptyEncounterRow.diagnosesRows = emptyDiagnoses; + + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.patientIdentifier = patientId; + multipleEncounterRow.encounterRows = Arrays.asList(emptyEncounterRow); + return multipleEncounterRow; + } + +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/models/MultipleEncounterRowTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/models/MultipleEncounterRowTest.java new file mode 100644 index 0000000000..3343bc4681 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/models/MultipleEncounterRowTest.java @@ -0,0 +1,14 @@ +package org.bahmni.module.admin.csv.models; + +import org.junit.Test; +import org.springframework.util.Assert; + +public class MultipleEncounterRowTest { + @Test + public void isEmptyReturnsTrueForEmptyRow() { + Assert.isTrue(new MultipleEncounterRow().getNonEmptyEncounterRows().isEmpty(), "No data in encounter"); + + MultipleEncounterRow emptyEncounterRow = new MultipleEncounterRowBuilder().getEmptyMultipleEncounterRow("GAN12345"); + Assert.isTrue(emptyEncounterRow.getNonEmptyEncounterRows().isEmpty(), "No data in encounter"); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptPersisterIT.java new file mode 100644 index 0000000000..f99e6f956e --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptPersisterIT.java @@ -0,0 +1,399 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class ConceptPersisterIT extends BaseIntegrationTest { + + public static final String SAME_AS = "SAME-AS"; + + @Autowired + private ConceptPersister conceptPersister; + + @Autowired + private ConceptService conceptService; + + @Before + public void setUp() throws Exception { + Context.authenticate("admin", "test"); + executeDataSet("conceptSetup.xml"); + } + + @Test + public void shouldFailValidationForNoConceptName() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + Messages errorMessages = conceptPersister.validate(conceptRow); + assertFalse(errorMessages.isEmpty()); + } + + @Test + public void shouldFailValidationForNoConceptClass() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "Concept Name"; + Messages errorMessages = conceptPersister.validate(conceptRow); + assertFalse(errorMessages.isEmpty()); + } + + + @Test + public void shouldPassValidationIfConceptNameAndConceptClassArePresent() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "concept Name"; + conceptRow.conceptClass = "concept Class"; + Messages errorMessages = conceptPersister.validate(conceptRow); + assertTrue(errorMessages.isEmpty()); + } + + @Test + public void shouldPersistNewConceptWithNameClassAndDescriptionInputOnly() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "New concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "New concept description"; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals("New concept description", persistedConcept.getDescription().getDescription()); + assertEquals(0, persistedConcept.getSynonyms().size()); + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldPersistNewConceptWithNameAndClassAndDatatypeDescriptionShortnameSynonymsInputOnly() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "New Concept"; + conceptRow.description = "New Description"; + conceptRow.conceptClass = "New Class"; + conceptRow.dataType = "Numeric"; + conceptRow.shortName = "NConcept"; + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(ConceptDatatype.NUMERIC_UUID, persistedConcept.getDatatype().getUuid()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldPersistNewConceptWithAnswers() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "New Concept"; + conceptRow.description = "New Description"; + conceptRow.conceptClass = "New Class"; + conceptRow.dataType = "Coded"; + conceptRow.shortName = "NConcept"; + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + List answers = new ArrayList<>(); + answers.add(new KeyValue("1", "Answer1")); + answers.add(new KeyValue("2", "Answer2")); + conceptRow.answers = answers; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(ConceptDatatype.CODED_UUID, persistedConcept.getDatatype().getUuid()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + assertEquals(2, persistedConcept.getAnswers().size()); + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + for (ConceptAnswer conceptAnswer : persistedConcept.getAnswers()) { + assertTrue(conceptAnswer.getAnswerConcept().getName(Context.getLocale()).getName().equals("Answer1") + || conceptAnswer.getAnswerConcept().getName(Context.getLocale()).getName().equals("Answer2")); + } + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldSetConceptReferenceTerms() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "New Concept"; + conceptRow.description = "New Description"; + conceptRow.conceptClass = "New Class"; + conceptRow.dataType = "Coded"; + conceptRow.shortName = "NConcept"; + ConceptReferenceTermRow conceptReferenceTermRow = new ConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", SAME_AS); + List conceptReferenceTermsList = new ArrayList<>(Arrays.asList(conceptReferenceTermRow)); + conceptRow.referenceTerms = conceptReferenceTermsList; + + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + List answers = new ArrayList<>(); + answers.add(new KeyValue("1", "Answer1")); + answers.add(new KeyValue("2", "Answer2")); + conceptRow.answers = answers; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(ConceptDatatype.CODED_UUID, persistedConcept.getDatatype().getUuid()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + assertEquals(2, persistedConcept.getAnswers().size()); + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + for (ConceptAnswer conceptAnswer : persistedConcept.getAnswers()) { + assertTrue(conceptAnswer.getAnswerConcept().getName(Context.getLocale()).getName().equals("Answer1") + || conceptAnswer.getAnswerConcept().getName(Context.getLocale()).getName().equals("Answer2")); + } + ArrayList conceptMaps = new ArrayList<>(persistedConcept.getConceptMappings()); + ConceptMap conceptMap = conceptMaps.get(0); + assertEquals(persistedConcept, conceptMap.getConcept()); + assertEquals(conceptReferenceTermRow.getReferenceTermCode(), conceptMap.getConceptReferenceTerm().getCode()); + assertEquals(conceptReferenceTermRow.getReferenceTermRelationship().toLowerCase(), conceptMap.getConceptMapType().toString()); + assertEquals(conceptReferenceTermRow.getReferenceTermSource(), conceptMap.getConceptReferenceTerm().getConceptSource().getName()); + Context.flushSession(); + Context.closeSession(); + + } + + @Test + @Ignore + public void shouldUpdateDetailsOnExistingConcepts() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "Existing Concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "Some Description"; + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + conceptRow.shortName = "NConcept"; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + assertEquals(0, persistedConcept.getAnswers().size()); + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + Context.flushSession(); + Context.closeSession(); + } + + @Test + @Ignore + public void shouldCreateNewMappingForExistingConcept() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "Existing Concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "Some Description"; + ConceptReferenceTermRow conceptReferenceTermRow = new ConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", SAME_AS); + List conceptReferenceTermsList = new ArrayList<>(Arrays.asList(conceptReferenceTermRow)); + conceptRow.referenceTerms = conceptReferenceTermsList; + + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + conceptRow.shortName = "NConcept"; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + assertEquals(0, persistedConcept.getAnswers().size()); + ArrayList conceptMaps = new ArrayList<>(persistedConcept.getConceptMappings()); + ConceptMap conceptMap = conceptMaps.get(0); + assertEquals(persistedConcept, conceptMap.getConcept()); + assertEquals(conceptReferenceTermRow.getReferenceTermCode(), conceptMap.getConceptReferenceTerm().getCode()); + assertEquals(conceptReferenceTermRow.getReferenceTermRelationship().toLowerCase(), conceptMap.getConceptMapType().toString()); + assertEquals(conceptReferenceTermRow.getReferenceTermSource(), conceptMap.getConceptReferenceTerm().getConceptSource().getName()); + + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + Context.flushSession(); + Context.closeSession(); + } + + @Test + @Ignore + public void shouldCreateNewMappingsForExistingConcept() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "Existing Concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "Some Description"; + ConceptReferenceTermRow conceptReferenceTermRow = new ConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", SAME_AS); + List conceptReferenceTermsList = new ArrayList<>(Arrays.asList(conceptReferenceTermRow)); + conceptRow.referenceTerms = conceptReferenceTermsList; + + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + conceptRow.shortName = "NConcept"; + Messages messages = conceptPersister.persist(conceptRow); + assertEquals(0, messages.size()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + assertEquals(0, persistedConcept.getAnswers().size()); + ArrayList conceptMaps = new ArrayList<>(persistedConcept.getConceptMappings()); + ConceptMap conceptMap = conceptMaps.get(0); + assertEquals(persistedConcept, conceptMap.getConcept()); + assertEquals(conceptReferenceTermRow.getReferenceTermCode(), conceptMap.getConceptReferenceTerm().getCode()); + assertEquals(conceptReferenceTermRow.getReferenceTermRelationship().toLowerCase(), conceptMap.getConceptMapType().toString()); + assertEquals(conceptReferenceTermRow.getReferenceTermSource(), conceptMap.getConceptReferenceTerm().getConceptSource().getName()); + + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void createNewConceptOfTypeNumericWithUnitsAndHinormalLownormal() throws Exception { + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "New Concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "Some Description"; + ConceptReferenceTermRow conceptReferenceTermRow = new ConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", SAME_AS); + List conceptReferenceTermsList = new ArrayList<>(Arrays.asList(conceptReferenceTermRow)); + conceptRow.referenceTerms = conceptReferenceTermsList; + conceptRow.dataType = "Numeric"; + conceptRow.units = "unit"; + conceptRow.hiNormal = "99"; + conceptRow.lowNormal = "10"; + + List synonyms = new ArrayList<>(); + synonyms.add(new KeyValue("1", "Synonym1")); + synonyms.add(new KeyValue("2", "Synonym2")); + conceptRow.synonyms = synonyms; + conceptRow.shortName = "NConcept"; + Messages errorMessages = conceptPersister.persist(conceptRow); + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.description, persistedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals(conceptRow.shortName, persistedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(2, persistedConcept.getSynonyms().size()); + assertEquals(0, persistedConcept.getAnswers().size()); + ArrayList conceptMaps = new ArrayList<>(persistedConcept.getConceptMappings()); + ConceptMap conceptMap = conceptMaps.get(0); + assertEquals(persistedConcept, conceptMap.getConcept()); + assertEquals(conceptReferenceTermRow.getReferenceTermCode(), conceptMap.getConceptReferenceTerm().getCode()); + assertEquals(conceptReferenceTermRow.getReferenceTermRelationship().toLowerCase(), conceptMap.getConceptMapType().toString()); + assertEquals(conceptReferenceTermRow.getReferenceTermSource(), conceptMap.getConceptReferenceTerm().getConceptSource().getName()); + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(persistedConcept.getConceptId()); + assertTrue(conceptNumeric.getUnits().equals(conceptRow.units)); + assertTrue(conceptNumeric.getHiNormal().equals(99.0)); + assertTrue(conceptNumeric.getLowNormal().equals(10.0)); + + for (ConceptName conceptName : persistedConcept.getSynonyms(Context.getLocale())) { + assertTrue(conceptName.getName().equals("Synonym1") || conceptName.getName().equals("Synonym2")); + } + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldCreateNewConceptWithGivenUUID() throws Exception { + String uuid = UUID.randomUUID().toString(); + ConceptRow conceptRow = new ConceptRow(); + conceptRow.name = "New concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "New concept description"; + conceptRow.uuid = uuid; + + Messages errorMessages = conceptPersister.persist(conceptRow); + + assertTrue(errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(uuid, persistedConcept.getUuid()); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals("New concept description", persistedConcept.getDescription().getDescription()); + assertEquals(0, persistedConcept.getSynonyms().size()); + Context.flushSession(); + Context.closeSession(); + + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptReferenceTermPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptReferenceTermPersisterIT.java new file mode 100644 index 0000000000..a7aa95798a --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptReferenceTermPersisterIT.java @@ -0,0 +1,230 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.ConceptReferenceTermRow; +import org.bahmni.module.admin.csv.models.FormerConceptReferenceRow; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.Concept; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ValidationException; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; + +public class ConceptReferenceTermPersisterIT extends BaseIntegrationTest { + + @Autowired + private ConceptReferenceTermPersister conceptReferenceTermPersister; + @Autowired + private ConceptService conceptService; + + private FormerConceptReferenceRow formerConceptReferenceRow; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + Context.authenticate("admin", "test"); + conceptReferenceTermPersister.init(Context.getUserContext()); + executeDataSet("conceptSetup.xml"); + executeDataSet("conceptReferenceTerm.xml"); + formerConceptReferenceRow = new FormerConceptReferenceRow(); + } + + @Test + public void shouldValidateTheGivenFormerReferenceTermRow() { + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "SAME-AS"))); + + assertTrue(conceptReferenceTermPersister.validate(formerConceptReferenceRow).isEmpty()); + } + + @Test + public void shouldGiveErrorMessageForInvalidConceptName() { + formerConceptReferenceRow.setConceptName("Not exist"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "SAME-AS"))); + + Messages messages = conceptReferenceTermPersister.validate(formerConceptReferenceRow); + assertFalse(messages.isEmpty()); + assertEquals(1, messages.size()); + assertEquals("Not exist concept is not present", messages.get(0)); + } + + @Test + public void shouldGiveErrorMessageForInvalidConceptReferenceSourceName() { + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.emrapi", "New Code", "SAME-AS"))); + + Messages messages = conceptReferenceTermPersister.validate(formerConceptReferenceRow); + assertFalse(messages.isEmpty()); + assertEquals(1, messages.size()); + assertEquals("New Code reference term code is not present in org.emrapi source", messages.get(0)); + } + + @Test + public void shouldGiveErrorMessageForInvalidConceptReferenceTermCode() { + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "No Code", "SAME-AS"))); + + Messages messages = conceptReferenceTermPersister.validate(formerConceptReferenceRow); + assertFalse(messages.isEmpty()); + assertEquals(1, messages.size()); + assertEquals("No Code reference term code is not present in org.openmrs.module.emrapi source", messages.get(0)); + } + + @Test + public void shouldGiveErrorMessageForInvalidReferenceRelationship() { + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "New Rel"))); + + Messages messages = conceptReferenceTermPersister.validate(formerConceptReferenceRow); + assertFalse(messages.isEmpty()); + assertEquals(1, messages.size()); + assertEquals("New Rel concept map type is not present", messages.get(0)); + } + + @Test + public void shouldValidateMultipleConceptReferenceTermRow() { + formerConceptReferenceRow.setConceptName("Not existing Concept"); + List referenceTerms = Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "SAME-AS"), + getConceptReferenceTermRow("org.openmrs.module.emrapi", "No Code", "New Rel")); + formerConceptReferenceRow.setReferenceTerms(referenceTerms); + + List expectedErrorMessages = Arrays.asList("Not existing Concept concept is not present", + "No Code reference term code is not present in org.openmrs.module.emrapi source", + "New Rel concept map type is not present"); + Messages messages = conceptReferenceTermPersister.validate(formerConceptReferenceRow); + + assertFalse(messages.isEmpty()); + assertEquals(3, messages.size()); + assertTrue(messages.containsAll(expectedErrorMessages)); + } + + @Test + public void shouldPersistNewlyGivenConceptReferenceTermRow() { + Context.openSession(); + Context.authenticate("admin", "test"); + + Concept concept = conceptService.getConceptByName("Existing Concept"); + assertTrue(concept.getConceptMappings().isEmpty()); + + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "SAME-AS"))); + + conceptReferenceTermPersister.persist(formerConceptReferenceRow); + Context.flushSession(); + concept = conceptService.getConceptByName("Existing Concept"); + ArrayList conceptMappings = new ArrayList<>(concept.getConceptMappings()); + + assertFalse(conceptMappings.isEmpty()); + assertEquals(1, conceptMappings.size()); + assertEquals("SAME-AS", StringUtils.upperCase(conceptMappings.get(0).getConceptMapType().getName())); + ConceptReferenceTerm conceptReferenceTerm = conceptMappings.get(0).getConceptReferenceTerm(); + + assertEquals("New Code", conceptReferenceTerm.getCode()); + assertEquals("org.openmrs.module.emrapi", conceptReferenceTerm.getConceptSource().getName()); + + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldAddNewReferenceButShouldNotRemoveAlreadyExistingConceptReferenceTermsFromConcept() { + Context.openSession(); + Context.authenticate("admin", "test"); + + Concept concept = conceptService.getConceptByName("Existing Concept"); + assertTrue(concept.getConceptMappings().isEmpty()); + + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "SAME-AS"))); + + conceptReferenceTermPersister.persist(formerConceptReferenceRow); + Context.flushSession(); + concept = conceptService.getConceptByName("Existing Concept"); + ArrayList conceptMappings = new ArrayList<>(concept.getConceptMappings()); + + assertFalse(conceptMappings.isEmpty()); + assertEquals(1, conceptMappings.size()); + ConceptMap conceptMap = conceptMappings.get(0); + assertEquals("SAME-AS", StringUtils.upperCase(conceptMap.getConceptMapType().getName())); + ConceptReferenceTerm conceptReferenceTerm = conceptMap.getConceptReferenceTerm(); + + assertEquals("New Code", conceptReferenceTerm.getCode()); + assertEquals("org.openmrs.module.emrapi", conceptReferenceTerm.getConceptSource().getName()); + + Context.flushSession(); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("IT", "New Code 1", "TEST"))); + conceptReferenceTermPersister.persist(formerConceptReferenceRow); + Context.flushSession(); + concept = conceptService.getConceptByName("Existing Concept"); + conceptMappings = new ArrayList<>(concept.getConceptMappings()); + assertEquals(2, conceptMappings.size()); + ConceptMap conceptMap1 = getConceptMapForSourceAndCode(conceptMappings, "org.openmrs.module.emrapi", "New Code"); + assertNotNull("Should Have found Concept Map with the code [New Code]", conceptMap1); + ConceptMap conceptMap2 = getConceptMapForSourceAndCode(conceptMappings, "IT", "New Code 1"); + assertNotNull("Should Have found Concept Map with the code [New Code 1]", conceptMap1); + assertEquals("SAME-AS", StringUtils.upperCase(conceptMap1.getConceptMapType().getName())); + assertEquals("TEST", StringUtils.upperCase(conceptMap2.getConceptMapType().getName())); + assertEquals(conceptMap, conceptMap1); + + conceptReferenceTerm = conceptMap2.getConceptReferenceTerm(); + + assertEquals("New Code 1", conceptReferenceTerm.getCode()); + assertEquals("IT", conceptReferenceTerm.getConceptSource().getName()); + + Context.flushSession(); + Context.closeSession(); + } + + private ConceptMap getConceptMapForSourceAndCode(ArrayList conceptMappings, String source, String code) { + return conceptMappings.stream().filter(conceptMap -> conceptMap.getConceptReferenceTerm().getConceptSource().getName().equals(source) && conceptMap.getConceptReferenceTerm().getCode().equals(code)).findFirst().get(); + } + + @Test + public void shouldNotBeAbleToAddSameReferenceTermTwiceInSameConcept() { + Context.openSession(); + Context.authenticate("admin", "test"); + + formerConceptReferenceRow.setConceptName("Existing Concept"); + formerConceptReferenceRow.setReferenceTerms(Arrays.asList(getConceptReferenceTermRow("org.openmrs.module.emrapi", "New Code", "SAME-AS"))); + + conceptReferenceTermPersister.persist(formerConceptReferenceRow); + Context.flushSession(); + Concept concept = conceptService.getConceptByName("Existing Concept"); + ArrayList conceptMappings = new ArrayList<>(concept.getConceptMappings()); + + assertFalse(conceptMappings.isEmpty()); + assertEquals(1, conceptMappings.size()); + ConceptMap conceptMap = conceptMappings.get(0); + assertEquals("SAME-AS", StringUtils.upperCase(conceptMap.getConceptMapType().getName())); + ConceptReferenceTerm conceptReferenceTerm = conceptMap.getConceptReferenceTerm(); + + assertEquals("New Code", conceptReferenceTerm.getCode()); + assertEquals("org.openmrs.module.emrapi", conceptReferenceTerm.getConceptSource().getName()); + + expectedException.expect(ValidationException.class); + expectedException.expectMessage("ConceptReferenceTerm.term.alreadyMapped"); + conceptReferenceTermPersister.persist(formerConceptReferenceRow); + } + + private ConceptReferenceTermRow getConceptReferenceTermRow(String source, String code, String relationshipType) { + return new ConceptReferenceTermRow(source, code, relationshipType); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptSetPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptSetPersisterIT.java new file mode 100644 index 0000000000..4332f837dc --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ConceptSetPersisterIT.java @@ -0,0 +1,186 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class ConceptSetPersisterIT extends BaseIntegrationTest { + + @Autowired + private ConceptSetPersister conceptSetPersister; + + @Autowired + private ConceptService conceptService; + + @Before + public void setUp() throws Exception { + Context.authenticate("admin", "test"); + executeDataSet("conceptSetup.xml"); + } + + @Test + public void shouldFailValidationForNoConceptName() throws Exception { + ConceptSetRow conceptRow = new ConceptSetRow(); + Messages persistErrorMessages = conceptSetPersister.validate(conceptRow); + assertFalse(persistErrorMessages.isEmpty()); + } + + @Test + public void shouldFailValidationForNoConceptClass() throws Exception { + ConceptSetRow conceptRow = new ConceptSetRow(); + conceptRow.name = "Concept Name"; + Messages persistErrorMessages = conceptSetPersister.validate(conceptRow); + assertFalse(persistErrorMessages.isEmpty()); + } + + + @Test + public void shouldPassValidationIfConceptNameAndConceptClassArePresent() throws Exception { + ConceptSetRow conceptRow = new ConceptSetRow(); + conceptRow.name = "concept Name"; + conceptRow.conceptClass = "concept Class"; + Messages persistErrorMessages = conceptSetPersister.validate(conceptRow); + assertTrue(persistErrorMessages.isEmpty()); + } + + @Test + public void shouldPersistNewConceptSetWithNameClassDescriptionInputOnly() throws Exception { + ConceptSetRow conceptRow = new ConceptSetRow(); + conceptRow.name = "New concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "some description"; + Messages persistErrorMessages = conceptSetPersister.persist(conceptRow); + assertTrue(persistErrorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals("some description", persistedConcept.getDescription().getDescription()); + assertEquals(0, persistedConcept.getSynonyms().size()); + assertTrue(persistedConcept.isSet()); + Context.flushSession(); + Context.closeSession(); + } + + + @Test + public void addSetMembers() throws Exception { + ConceptSetRow conceptRow = new ConceptSetRow(); + conceptRow.name = "New concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "some description"; + + List children = new ArrayList<>(); + children.add(new KeyValue("1", "Child1")); + children.add(new KeyValue("2", "Child2")); + conceptRow.children = children; + Messages persistErrorMessages = conceptSetPersister.persist(conceptRow); + assertTrue(persistErrorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(conceptRow.conceptClass, persistedConcept.getConceptClass().getName()); + assertEquals("some description", persistedConcept.getDescription().getDescription()); + + assertEquals(2, persistedConcept.getSetMembers().size()); + assertEquals("some description", persistedConcept.getDescription().getDescription()); + assertEquals(0, persistedConcept.getSynonyms().size()); + assertTrue(persistedConcept.isSet()); + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void should_fail_validation_for_conceptset_with_cycle () throws Exception{ + ConceptSetRow conceptSetRow = new ConceptSetRow(); + conceptSetRow.name = "Cycle concept Name"; + conceptSetRow.conceptClass = "Cycle concept Class"; + + List children = new ArrayList<>(); + children.add(new KeyValue("1", "Child1")); + children.add(new KeyValue("2", "Cycle concept Name")); + conceptSetRow.children = children; + Messages persistErrorMessages = conceptSetPersister.validate(conceptSetRow); + assertFalse("Validation did not catch cycle", persistErrorMessages.isEmpty()); + } + + @Test + public void should_fail_to_persist_if_conceptSetRow_introduces_cycle() throws Exception { + ConceptSetRow row1 = new ConceptSetRow(); + row1.name = "ConceptA"; + row1.conceptClass = "New Class"; + row1.description = "some description"; + List children = new ArrayList<>(); + children.add(new KeyValue("1", "Child1")); + children.add(new KeyValue("2", "Child2")); + row1.children = children; + + Messages persistErrorMessages = conceptSetPersister.persist(row1); + assertTrue(persistErrorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(row1.name); + assertNotNull(persistedConcept); + + ConceptSetRow row2 = new ConceptSetRow(); + row2.name = "Child2"; + row2.conceptClass = "New Class"; + row2.description = "some description"; + List children1 = new ArrayList<>(); + children1.add(new KeyValue("1", "ConceptA")); + children1.add(new KeyValue("2", "Child3")); + row2.children = children1; + + Messages persistErrorMessages1 = conceptSetPersister.persist(row2); + assertFalse(persistErrorMessages1.isEmpty()); + + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldCreateNewConceptSetWithGivenUUID() throws Exception { + String uuid = UUID.randomUUID().toString(); + ConceptSetRow conceptRow = new ConceptSetRow(); + conceptRow.name = "New concept"; + conceptRow.conceptClass = "New Class"; + conceptRow.description = "some description"; + conceptRow.uuid = uuid; + + Messages persistErrorMessages = conceptSetPersister.persist(conceptRow); + + assertTrue(persistErrorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + Concept persistedConcept = conceptService.getConceptByName(conceptRow.name); + assertNotNull(persistedConcept); + assertEquals(conceptRow.name, persistedConcept.getName(Context.getLocale()).getName()); + assertEquals(uuid, persistedConcept.getUuid()); + Context.flushSession(); + Context.closeSession(); + } + + + + +} diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/EncounterPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/EncounterPersisterIT.java new file mode 100644 index 0000000000..424744779e --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/EncounterPersisterIT.java @@ -0,0 +1,784 @@ +package org.bahmni.module.admin.csv.persister; + +import org.apache.commons.lang.StringUtils; +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.csv.models.MultipleEncounterRow; +import org.bahmni.module.admin.csv.utils.CSVUtils; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +@Ignore +public class EncounterPersisterIT extends BaseIntegrationTest { + + @Autowired + private EncounterPersister encounterPersister; + + @Autowired + private EncounterService encounterService; + + @Autowired + private VisitService visitService; + + protected UserContext userContext; + private boolean shouldMatchExactPatientId = false; + + @Before + public void setUp() throws Exception { + executeDataSet("baseMetaData.xml"); + executeDataSet("diagnosisMetaData.xml"); + executeDataSet("dispositionMetaData.xml"); + executeDataSet("dataSetup.xml"); + String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + System.setProperty("OPENMRS_APPLICATION_DATA_DIRECTORY", path); + + + Context.authenticate("admin", "test"); + userContext = Context.getUserContext(); + boolean shouldMatchExactPatientId = false; + boolean shouldPerformForm2Validations = false; + encounterPersister.init(userContext, null, shouldMatchExactPatientId, null, shouldPerformForm2Validations); + } + + @Test + public void failValidationForEmptyEncounterType() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + Messages rowResult = encounterPersister.persist(multipleEncounterRow); + assertTrue("No Encounter details. Should have failed", !rowResult.isEmpty()); + } + + @Test + public void failValidationForEncounterTypeNotFound() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "INVALID ENCOUNTER TYPE"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.encounterDateTime = "11-11-1111"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages validationErrors = encounterPersister.persist(multipleEncounterRow); + assertTrue("Invalid Encounter Type not found. Error Message:", + validationErrors.toString().contains("Encounter type:'INVALID ENCOUNTER TYPE' not found")); + } + + @Test + public void failValidationForVisitTypeNotFound() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "INVALID VISIT TYPE"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages validationErrors = encounterPersister.persist(multipleEncounterRow); + assertTrue("Invalid Visit Type not found. Error Message:" + validationErrors.toString(), + validationErrors.toString().contains("Visit type:'INVALID VISIT TYPE' not found")); + } + + @Test + public void failValidationForEmptyVisitType() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages validationErrors = encounterPersister.persist(multipleEncounterRow); + assertTrue("Visit Type null not found. Error Message:" + validationErrors.toString(), + validationErrors.toString().contains("Visit type:'null' not found")); + } + + @Test + public void failValidationForEncounterDateInIncorrectFormat() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + multipleEncounterRow.visitType = "OPD"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.encounterDateTime = "1977/08/23"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages validationErrors = encounterPersister.persist(multipleEncounterRow); + assertTrue("Encounter date time is required and should be 'dd/mm/yyyy' format.. Error Message:" + validationErrors.toString(), + validationErrors.toString().contains("Unparseable date: \"1977/08/23\"")); + } + + @Test + public void noValidationForEncounters() { + Messages validationErrors = encounterPersister.validate(new MultipleEncounterRow()); + assertTrue("No Validation failure. Encounter Import does not run validation stage", validationErrors.isEmpty()); + } + + @Test + public void persistEncountersForPatient() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row.", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + assertEquals(1, encounters.size()); + + Encounter encounter = encounters.get(0); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + + Date encounterDatetime = encounter.getEncounterDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(encounterDatetime)); + } + + @Test + public void createVisitAsPerDatesInFile() throws Exception { + String registrationNumber = "GAN200000"; + String visitStartDate = "2011-11-11"; + String visitEndDate = "2011-12-13"; + String encounterDateTime = "2011-12-12"; + + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = registrationNumber; + multipleEncounterRow.visitStartDate = visitStartDate; + multipleEncounterRow.visitEndDate = visitEndDate; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = encounterDateTime; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row.", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + + Patient patient = new Patient(); + PatientIdentifier patientIdentifier = new PatientIdentifier(); + patientIdentifier.setIdentifier(registrationNumber); + patient.addIdentifier(patientIdentifier); + + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + Visit newlyCreatedVisit = encounters.get(0).getVisit(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN); + assertEquals(visitStartDate, simpleDateFormat.format(newlyCreatedVisit.getStartDatetime())); + assertEquals(visitEndDate, simpleDateFormat.format(newlyCreatedVisit.getStopDatetime())); + assertEquals(encounterDateTime, simpleDateFormat.format(newlyCreatedVisit.getEncounters().iterator().next().getEncounterDatetime())); + } + + + @Test + public void persistEncounterWithObservationHierarchyForPatient() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("Vitals.WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages persistenceResult = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row." + persistenceResult.asString(), StringUtils.isEmpty(persistenceResult.asString())); + + Context.openSession(); + Context.authenticate("admin", "test"); + + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + assertEquals(1, encounters.size()); + + Encounter encounter = encounters.get(0); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + + assertEquals(1, encounter.getAllObs().size()); + + Obs vitals = encounter.getAllObs().iterator().next(); + assertEquals("Vitals", vitals.getConcept().getName().getName()); + assertEquals(1, vitals.getGroupMembers().size()); + + Obs weight = vitals.getGroupMembers().iterator().next(); + assertEquals("WEIGHT", weight.getConcept().getName().getName()); + assertEquals(Double.valueOf(150), weight.getValueNumeric()); + + Date encounterDatetime = encounter.getEncounterDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(encounterDatetime)); + } + + @Test + public void persistEncountersWithSameDateWhichHasSameRootObservationsInIt() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow weightEncounter = new EncounterRow(); + weightEncounter.obsRows = new ArrayList<>(); + weightEncounter.obsRows.add(new KeyValue("Vitals.WEIGHT", "150")); + weightEncounter.encounterDateTime = "1111-11-11"; + + EncounterRow heightEncounter = new EncounterRow(); + heightEncounter.obsRows = new ArrayList<>(); + heightEncounter.obsRows.add(new KeyValue("Vitals.HEIGHT", "150")); + heightEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(weightEncounter); + multipleEncounterRow.encounterRows.add(heightEncounter); + + Messages persistenceResult = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row." + persistenceResult.asString(), StringUtils.isEmpty(persistenceResult.asString())); + + + Context.openSession(); + Context.authenticate("admin", "test"); + + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + assertEquals(1, encounters.size()); + + Encounter savedEncounter = encounters.get(0); + assertEquals("Anad", savedEncounter.getPatient().getGivenName()); + assertEquals("Kewat", savedEncounter.getPatient().getFamilyName()); + assertEquals("OPD", savedEncounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", savedEncounter.getEncounterType().getName()); + + assertEquals(2, savedEncounter.getAllObs().size()); + + Iterator allObs = savedEncounter.getAllObs().iterator(); + Obs vitals1 = allObs.next(); + assertEquals("Vitals", vitals1.getConcept().getName().getName()); + Set groupMembers = vitals1.getGroupMembers(); + assertEquals(1, groupMembers.size()); + + Obs vitals2 = allObs.next(); + assertEquals("Vitals", vitals2.getConcept().getName().getName()); + assertEquals(1, vitals2.getGroupMembers().size()); + + Date encounterDatetime = savedEncounter.getEncounterDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(encounterDatetime)); + } + + @Test + public void persistEncounterWithObservationHierarchyWithMultipleGroupMembers() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("Vitals.HEIGHT", "30")); + anEncounter.obsRows.add(new KeyValue("Vitals.WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages persistenceResult = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row." + persistenceResult.asString(), StringUtils.isEmpty(persistenceResult.asString())); + + Context.openSession(); + Context.authenticate("admin", "test"); + + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + assertEquals(1, encounters.size()); + + Encounter encounter = encounters.get(0); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + + assertEquals(1, encounter.getAllObs().size()); + Obs vitals = encounter.getAllObs().iterator().next(); + assertEquals("Vitals", vitals.getConcept().getName().getName()); + Set groupMembers = vitals.getGroupMembers(); + assertEquals(2, groupMembers.size()); + assertEquals(Double.valueOf(150), findObs(groupMembers, "WEIGHT").getValueNumeric()); + assertEquals(Double.valueOf(30), findObs(groupMembers, "HEIGHT").getValueNumeric()); + Date encounterDatetime = encounter.getEncounterDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(encounterDatetime)); + } + + @Test + public void persistEncounterWithAbnormalObservation() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("Vitals.Height Data.HEIGHT", "30")); + anEncounter.obsRows.add(new KeyValue("Vitals.Height Data.Height Abnormal", "true")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages persistenceResult = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row." + persistenceResult.asString(), StringUtils.isEmpty(persistenceResult.asString())); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + assertEquals(1, encounters.size()); + + Encounter encounter = encounters.get(0); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + + assertEquals(1, encounter.getAllObs().size()); + + Obs vitals = encounter.getAllObs().iterator().next(); + assertEquals("Vitals", vitals.getConcept().getName().getName()); + + assertEquals(1, vitals.getGroupMembers().size()); + Obs heightData = vitals.getGroupMembers().iterator().next(); + assertEquals("Height Data", heightData.getConcept().getName().getName()); + + assertEquals(2, heightData.getGroupMembers().size()); + Obs heightValue = findObs(heightData.getGroupMembers(), "HEIGHT"); + assertEquals(Double.valueOf(30), heightValue.getValueNumeric()); + + Obs heightAbnormal = findObs(heightData.getGroupMembers(), "Height Abnormal"); + assertEquals("YES", heightAbnormal.getValueCoded().getName().getName()); + + Date encounterDatetime = encounter.getEncounterDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(encounterDatetime)); + } + + + @Test + public void persistMultipleEncountersForPatient() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + EncounterRow anotherEncounter = new EncounterRow(); + anotherEncounter.obsRows = new ArrayList<>(); + anotherEncounter.obsRows.add(new KeyValue("HEIGHT", "75")); + anotherEncounter.encounterDateTime = "1111-11-12"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + multipleEncounterRow.encounterRows.add(anotherEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row.", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.flushSession(); + Context.closeSession(); + + assertEquals(2, encounters.size()); + } + + @Test + public void persistObservationsForPatient() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row.", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.closeSession(); + + Encounter encounter = encounters.get(0); + assertEquals(1, encounters.size()); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + assertEquals(1, encounter.getAllObs().size()); + assertEquals("WEIGHT", encounter.getAllObs().iterator().next().getConcept().getName().getName()); + Date obsDatetime = encounter.getAllObs().iterator().next().getObsDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(obsDatetime)); + assertEquals("150.0", encounter.getAllObs().iterator().next().getValueAsString(Context.getLocale())); + } + + @Test + public void persistDiagnosis() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + anEncounter.diagnosesRows = new ArrayList<>(); + anEncounter.diagnosesRows.add(new KeyValue("Diagnosis1", "Diabetes")); + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounters.", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.closeSession(); + + Encounter encounter = encounters.get(0); + assertEquals(1, encounters.size()); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + + List allObs = new ArrayList<>(); + allObs.addAll(encounter.getAllObs()); + assertEquals(2, allObs.size()); + + int weightIndex = 0; + int diagnosisIndex = 0; + if (allObs.get(0).getGroupMembers() == null || allObs.get(0).getGroupMembers().size() == 0) { + diagnosisIndex = 1; + } else { + weightIndex = 1; + } + Obs weightObs = allObs.get(weightIndex); + Obs diagnosisObs = allObs.get(diagnosisIndex); + assertEquals("WEIGHT", weightObs.getConcept().getName().getName()); + assertEquals("150.0", weightObs.getValueAsString(Context.getLocale())); + assertEquals("Diagnosis Concept Set", diagnosisObs.getConcept().getName().getName()); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(diagnosisObs.getObsDatetime())); + + List obsConceptNames = new ArrayList<>(); + for (Obs obs : diagnosisObs.getGroupMembers()) { + obsConceptNames.add(obs.getConcept().getName().getName()); + } + assertTrue(obsConceptNames.contains("Diabetes")); + assertTrue(obsConceptNames.contains("Diagnosis Certainty")); + assertTrue(obsConceptNames.contains("Diagnosis Order")); + assertTrue(obsConceptNames.contains("Bahmni Diagnosis Status")); + assertTrue(obsConceptNames.contains("Bahmni Diagnosis Revised")); + assertTrue(obsConceptNames.contains("Bahmni Initial Diagnosis")); + } + + @Test + public void rollBackTransactionOncePersistenceFailsForOneResource() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + multipleEncounterRow.encounterRows = new ArrayList<>(); + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + + multipleEncounterRow.encounterRows.add(anEncounter); + + multipleEncounterRow.encounterType = "O1PD"; + encounterPersister.persist(multipleEncounterRow); + Context.openSession(); + Context.authenticate("admin", "test"); + + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + List visits = visitService.getVisitsByPatient(new Patient(1)); + Context.closeSession(); + assertEquals(0, visits.size()); + assertEquals(0, encounters.size()); + } + + @Test + public void throwErrorWhenPatientNotFound() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200001"; + + encounterPersister.init(userContext, "NoMatch.groovy", shouldMatchExactPatientId, null, false); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertThat(errorMessages.size(), is(Matchers.greaterThan(0))); + assertTrue(errorMessages.toString().contains("No matching patients found with ID:'GAN200001'")); + } + + @Test + public void throwErrorWhenMultiplePatientsFound() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "200000"; + encounterPersister.init(userContext, "MultipleMatchPatient.groovy", shouldMatchExactPatientId, null, false); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + + assertTrue(errorMessages.toString().contains("GAN200000, SEM200000")); + } + + @Test + public void externalAlgorithmShouldReturnOnlyPatientsWithGanIdentifier() throws Exception { + String patientId = "200000"; + + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = patientId; + encounterPersister.init(userContext, "GANIdentifier.groovy", shouldMatchExactPatientId, null, false); + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + + assertTrue("Should have persisted the encounters.", errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + + multipleEncounterRow.patientIdentifier = "GAN" + patientId; + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.closeSession(); + assertEquals(1, encounters.size()); + } + + @Test + public void externalAlgorithmReturnsPatientsMatchingIdAndName() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + multipleEncounterRow.patientAttributes = getPatientAttributes(); + encounterPersister.init(userContext, "IdAndNameMatch.groovy", shouldMatchExactPatientId, null, false); + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounters.", errorMessages.isEmpty()); + Context.openSession(); + Context.authenticate("admin", "test"); + + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.closeSession(); + assertEquals(1, encounters.size()); + } + + @Test + @Ignore + public void persistCaseInsensitiveCodedConceptValues() { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("Diagnosis Certainty", "ConFirmeD")); + anEncounter.encounterDateTime = "1111-11-11"; + anEncounter.diagnosesRows = new ArrayList<>(); + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + encounterPersister.persist(multipleEncounterRow); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.closeSession(); + + Set allObs = encounters.get(0).getAllObs(); + assertEquals(407, allObs.iterator().next().getValueCoded().getId().intValue()); + } + + @Test + public void persistMultipleObservationForSameConcepts() throws Exception { + MultipleEncounterRow multipleEncounterRow = new MultipleEncounterRow(); + multipleEncounterRow.encounterType = "Consultation"; + multipleEncounterRow.visitType = "OPD"; + multipleEncounterRow.patientIdentifier = "GAN200000"; + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + anEncounter.obsRows.add(new KeyValue("WEIGHT", "150")); + anEncounter.obsRows.add(new KeyValue("HEIGHT", "70")); + anEncounter.obsRows.add(new KeyValue("HEIGHT", "200")); + anEncounter.obsRows.add(new KeyValue("Vitals.Height Data.HEIGHT", "10")); + anEncounter.obsRows.add(new KeyValue("Vitals.Height Data.WEIGHT", "20")); + anEncounter.encounterDateTime = "1111-11-11"; + + multipleEncounterRow.encounterRows = new ArrayList<>(); + multipleEncounterRow.encounterRows.add(anEncounter); + + Messages errorMessages = encounterPersister.persist(multipleEncounterRow); + assertTrue("Should have persisted the encounter row.", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + List encounters = encounterService.getEncountersByPatientIdentifier(multipleEncounterRow.patientIdentifier); + Context.closeSession(); + + Encounter encounter = encounters.get(0); + assertEquals(1, encounters.size()); + assertEquals("Anad", encounter.getPatient().getGivenName()); + assertEquals("Kewat", encounter.getPatient().getFamilyName()); + assertEquals("OPD", encounter.getVisit().getVisitType().getName()); + assertEquals("Consultation", encounter.getEncounterType().getName()); + Set allObs = encounter.getAllObs(); + assertEquals(4, allObs.size()); + assertTrue(isObsPresentInEncounter(allObs, "WEIGHT", "150.0")); + assertTrue(isObsPresentInEncounter(allObs, "HEIGHT", "70.0")); + assertTrue(isObsPresentInEncounter(allObs, "HEIGHT", "200.0")); + Obs vitals = findObsFromAllObs(allObs, "Vitals"); + Set heightDataObs = vitals.getGroupMembers().iterator().next().getGroupMembers(); + assertEquals(1, vitals.getGroupMembers().size()); + assertEquals(2, heightDataObs.size()); + assertTrue(isObsPresentInEncounter(heightDataObs, "HEIGHT", "10.0")); + assertTrue(isObsPresentInEncounter(heightDataObs, "WEIGHT", "20.0")); + Date obsDatetime = allObs.iterator().next().getObsDatetime(); + assertEquals("1111-11-11", new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN).format(obsDatetime)); + } + + private Obs findObsFromAllObs(Set allObs, String concept) { + for (Obs obs : allObs) { + if(obs.getConcept().getName().getName().equals(concept)) + return obs; + } + return null; + } + + private boolean isObsPresentInEncounter(Set allObs, String concept, String value) { + for (Obs obs : allObs) { + if(obs.getConcept().getName().getName().equals(concept) && obs.getValueAsString(Context.getLocale()).equals(value)) + return true; + } + return false; + } + + private List getPatientAttributes() { + List patientAttributes = new ArrayList<>(); + patientAttributes.add(new KeyValue("given_name", "Anad")); + return patientAttributes; + } + + private Obs findObs(Set groupMembers, String conceptName) { + for (Obs groupMember : groupMembers) { + if (conceptName.equals(groupMember.getConcept().getName().getName())){ + return groupMember; + } + } + return null; + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/LabResultPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/LabResultPersisterIT.java new file mode 100644 index 0000000000..5cf426b6ad --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/LabResultPersisterIT.java @@ -0,0 +1,165 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.LabResultRow; +import org.bahmni.module.admin.csv.models.LabResultsRow; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.CareSetting; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.service.LabOrderResultsService; +import org.openmrs.test.TestUtil; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class LabResultPersisterIT extends BaseIntegrationTest { + + @Autowired + private VisitService visitService; + + @Autowired + private PatientService patientService; + + @Autowired + private LabResultPersister labResultPersister; + + @Autowired + private LabOrderResultsService labOrderResultsService; + private UserContext userContext; + + @Before + public void setUp() throws Exception { + executeDataSet("baseMetaData.xml"); + executeDataSet("diagnosisMetaData.xml"); + executeDataSet("dispositionMetaData.xml"); + executeDataSet("labResultMetaData.xml"); + executeDataSet("labResult.xml"); + executeDataSet("visitAttributeDataSet.xml"); + Context.authenticate("admin", "test"); + userContext = Context.getUserContext(); + labResultPersister.init(userContext, null, true, "be69741b-29e9-49a1-adc9-2a726e6610e4"); + } + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void shouldThrowExceptionIfLabResultsHaveDecimalInANonAllowDecimalConcept() throws Exception { + String visitType = "LAB RESULT IMPORT VISIT"; + LabResultsRow labResultsRow = new LabResultsRow(); + labResultsRow.setPatientIdentifier("GAN200001").setTestDateString("2014-10-11").setVisitType(visitType); + labResultsRow.setTestResults(Arrays.asList(new LabResultRow().setTest("Eosinophil (Blood)").setResult("10.6"))); + + expectedException.expect(org.openmrs.api.APIException.class); + expectedException.expectMessage("Decimal is not allowed for Eosinophil (Blood) concept"); + + labResultPersister.persist(labResultsRow); + } + + @Test + public void shouldSetCodedValueOfATest() throws Exception { + String visitType = "LAB RESULT IMPORT VISIT"; + LabResultsRow labResultsRow = new LabResultsRow(); + labResultsRow.setPatientIdentifier("GAN200001").setTestDateString("2014-10-11").setVisitType(visitType); + labResultsRow.setTestResults(Collections.singletonList(new LabResultRow().setTest("Proteins").setResult("+"))); + + Messages errorMessages = labResultPersister.persist(labResultsRow); + + Patient patient = patientService.getPatientByUuid("75e04d42-3ca8-11e3-bf2b-ab87271c1b75"); + List visits = visitService.getVisitsByPatient(patient); + assertTrue(errorMessages.isEmpty()); + // Assert visit data + assertEquals(1, visits.size()); + Visit visit = visits.get(0); + assertEquals(visitType, visit.getVisitType().getName()); + assertEquals(1, visit.getEncounters().size()); + assertEquals(TestUtil.createDateTime("2014-10-11"), visit.getStartDatetime()); + assertEquals(TestUtil.createDateTime("2014-10-11 23:59:59"), visit.getStopDatetime()); + // Assert encounter data + Encounter encounter = visit.getEncounters().iterator().next(); + assertEquals(1, encounter.getEncounterProviders().size()); + assertEquals(LabResultPersister.LAB_RESULT_ENCOUNTER_TYPE, encounter.getEncounterType().getName()); + assertEquals(TestUtil.createDateTime("2014-10-11"), encounter.getEncounterDatetime()); + final EncounterProvider provider = encounter.getEncounterProviders().iterator().next(); + assertEquals(userContext.getAuthenticatedUser().getId(), provider.getProvider().getPerson().getId()); + // Assert tests orders data + assertEquals(1, encounter.getOrders().size()); + Order order = encounter.getOrders().iterator().next(); + assertEquals("Proteins", order.getConcept().getName().getName()); + assertEquals(userContext.getAuthenticatedUser().getId(), order.getOrderer().getId()); + assertEquals(TestUtil.createDateTime("2014-10-11"), order.getDateActivated()); + assertEquals(TestUtil.createDateTime("2014-10-11 23:59:59"), order.getAutoExpireDate()); + assertEquals(LabResultPersister.LAB_ORDER_TYPE, order.getOrderType().getName()); + assertEquals(CareSetting.CareSettingType.OUTPATIENT.name(), order.getCareSetting().getName()); + // Assert results data + List labOrderResults = labOrderResultsService.getAll(patient, visits, Integer.MAX_VALUE).getResults(); + assertEquals(1, labOrderResults.size()); + LabOrderResult labOrderResult = labOrderResults.get(0); + assertEquals("Proteins", labOrderResult.getTestName()); + assertEquals("+", labOrderResult.getResult()); + assertEquals(TestUtil.createDateTime("2014-10-11"), labOrderResult.getResultDateTime()); + ExpectedException.none(); + } + + @Test + public void testPersist() throws Exception { + String visitType = "LAB RESULT IMPORT VISIT"; + LabResultsRow labResultsRow = new LabResultsRow(); + labResultsRow.setPatientIdentifier("GAN200001").setTestDateString("2014-10-11").setVisitType(visitType); + labResultsRow.setTestResults(Arrays.asList(new LabResultRow().setTest("Urea Nitorgen").setResult("10"))); + + Messages errorMessages = labResultPersister.persist(labResultsRow); + + Patient patient = patientService.getPatientByUuid("75e04d42-3ca8-11e3-bf2b-ab87271c1b75"); + List visits = visitService.getVisitsByPatient(patient); + assertTrue(errorMessages.isEmpty()); + // Assert visit data + assertEquals(1, visits.size()); + Visit visit = visits.get(0); + assertEquals(visitType, visit.getVisitType().getName()); + assertEquals(1, visit.getEncounters().size()); + assertEquals(TestUtil.createDateTime("2014-10-11"), visit.getStartDatetime()); + assertEquals(TestUtil.createDateTime("2014-10-11 23:59:59"), visit.getStopDatetime()); + // Assert encounter data + Encounter encounter = visit.getEncounters().iterator().next(); + assertEquals(1, encounter.getEncounterProviders().size()); + assertEquals(LabResultPersister.LAB_RESULT_ENCOUNTER_TYPE, encounter.getEncounterType().getName()); + assertEquals(TestUtil.createDateTime("2014-10-11"), encounter.getEncounterDatetime()); + final EncounterProvider provider = encounter.getEncounterProviders().iterator().next(); + assertEquals(userContext.getAuthenticatedUser().getId(), provider.getProvider().getPerson().getId()); + // Assert tests orders data + assertEquals(1, encounter.getOrders().size()); + Order order = encounter.getOrders().iterator().next(); + assertEquals("Urea Nitorgen", order.getConcept().getName().getName()); + assertEquals(userContext.getAuthenticatedUser().getId(), order.getOrderer().getId()); + assertEquals(TestUtil.createDateTime("2014-10-11"), order.getDateActivated()); + assertEquals(TestUtil.createDateTime("2014-10-11 23:59:59"), order.getAutoExpireDate()); + assertEquals(LabResultPersister.LAB_ORDER_TYPE, order.getOrderType().getName()); + assertEquals(CareSetting.CareSettingType.OUTPATIENT.name(), order.getCareSetting().getName()); + // Assert results data + List labOrderResults = labOrderResultsService.getAll(patient, visits, Integer.MAX_VALUE).getResults(); + assertEquals(1, labOrderResults.size()); + LabOrderResult labOrderResult = labOrderResults.get(0); + assertEquals("Urea Nitorgen", labOrderResult.getTestName()); + assertEquals("10.0", labOrderResult.getResult()); + assertEquals(TestUtil.createDateTime("2014-10-11"), labOrderResult.getResultDateTime()); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/PatientPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/PatientPersisterIT.java new file mode 100644 index 0000000000..d464bef6ba --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/PatientPersisterIT.java @@ -0,0 +1,77 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.KeyValue; +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.PatientRow; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertTrue; + +@Ignore("Was never working. Injection needs to be fixed") +public class PatientPersisterIT extends BaseIntegrationTest { + + @Autowired + private PatientPersister patientPersister; + + @Before + public void setUp() throws Exception { + String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + System.setProperty("OPENMRS_APPLICATION_DATA_DIRECTORY", path); + + Context.authenticate("admin", "test"); + UserContext userContext = Context.getUserContext(); + patientPersister.init(userContext); + } + + @Test + @Ignore("Was never working. Injection needs to be fixed") + public void save_patient_row() { + PatientRow patientRow = patientRow("Ram", "Laxman", "Kumar", "1999-08-8", "Male", "reg-no", addressParts("galli", "shahar", "state", "desh", "100001"), attibutesList("ram", "farmer", "10th pass")); + Messages errorMessages = patientPersister.persist(patientRow); + + assertTrue("should have persisted the patient row", errorMessages.isEmpty()); + } + + private PatientRow patientRow(String firstName, String middleName, String lastName, String birthdate, String gender, String registrationNumber, List addressParts, List attributes) { + PatientRow patientRow = new PatientRow(); + patientRow.firstName = firstName; + patientRow.middleName = middleName; + patientRow.lastName = lastName; + patientRow.birthdate = birthdate; + patientRow.gender = gender; + patientRow.registrationNumber = registrationNumber; + patientRow.addressParts = addressParts; + patientRow.attributes = attributes; + return patientRow; + } + + private List addressParts(final String street, final String city, final String state, final String country, final String postalCode) { + List addressParts = new ArrayList() {{ + add(new KeyValue("Street", street)); + add(new KeyValue("City", city)); + add(new KeyValue("State", state)); + add(new KeyValue("Country", country)); + add(new KeyValue("Postal Code", postalCode)); + }}; + return addressParts; + } + + private List attibutesList(final String localName, final String occupation, final String education) { + List attributes = new ArrayList() {{ + add(new KeyValue("familyNameLocal", localName)); + add(new KeyValue("occupation", occupation)); + add(new KeyValue("education", education)); + }}; + return attributes; + } + +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/PatientProgramPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/PatientProgramPersisterIT.java new file mode 100644 index 0000000000..7f98844012 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/PatientProgramPersisterIT.java @@ -0,0 +1,77 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.PatientProgramRow; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.api.ProgramWorkflowService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class PatientProgramPersisterIT extends BaseIntegrationTest { + + @Autowired + private PatientProgramPersister patientProgramPersister; + @Autowired + private ProgramWorkflowService programWorkflowService; + @Autowired + private BahmniPatientService patientService; + + protected UserContext userContext; + + @Before + public void setUp() throws Exception { + String path; + executeDataSet("dataSetup.xml"); + path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + System.setProperty("OPENMRS_APPLICATION_DATA_DIRECTORY", path); + + Context.authenticate("admin", "test"); + userContext = Context.getUserContext(); + patientProgramPersister.init(userContext, null); + } + + @Test + public void enrollPatientInAProgram() throws Exception { + PatientProgramRow patientProgramRow = new PatientProgramRow(); + patientProgramRow.patientIdentifier = "GAN200000"; + patientProgramRow.programName = "Diabetes Program"; + patientProgramRow.enrollmentDateTime = "1111-11-11"; + + Messages persistenceResult = patientProgramPersister.persist(patientProgramRow); + assertTrue("Should have persisted the encounter row with the program. ", persistenceResult.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + Patient patient = patientService.get("GAN200000", true).get(0); + List patientPrograms = programWorkflowService.getPatientPrograms(patient, null, null, null, null, null, false); + + assertTrue("patient should have been enrolled in a program", !patientPrograms.isEmpty()); + assertEquals("Diabetes Program", patientPrograms.get(0).getProgram().getName()); + + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void shouldNotEnrollAnAlreadyEnrolledPatientInAProgram() throws Exception { + PatientProgramRow patientProgramRow = new PatientProgramRow(); + patientProgramRow.patientIdentifier = "SEM200000"; + patientProgramRow.enrollmentDateTime = "1111-11-11"; + patientProgramRow.programName = "DIABETES PROGRAM"; + + Messages errorMessages = patientProgramPersister.persist(patientProgramRow); + assertTrue(errorMessages.toString().contains("Patient already enrolled in Diabetes Program")); + } + +} diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/ReferenceTermPersisterIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ReferenceTermPersisterIT.java new file mode 100644 index 0000000000..91adf88a5a --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/ReferenceTermPersisterIT.java @@ -0,0 +1,90 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.ReferenceTermRow; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.ConceptSource; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ReferenceTermPersisterIT extends BaseIntegrationTest { + + @Autowired + private ReferenceTermPersister referenceTermPersister; + + @Autowired + private ConceptService conceptService; + + @Before + public void setUp() throws Exception { + String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + System.setProperty("OPENMRS_APPLICATION_DATA_DIRECTORY", path); + + Context.authenticate("admin", "test"); + UserContext userContext = Context.getUserContext(); + referenceTermPersister.init(userContext); + } + + @Test + public void saveNewReferenceTerm() { + ReferenceTermRow referenceTermRow = new ReferenceTermRow("TB1002", "SNOMED CT", "Tuberclosis", null, null); + Messages errorMessages = referenceTermPersister.persist(referenceTermRow); + assertTrue("should have persisted the reference term row", errorMessages.isEmpty()); + + Context.openSession(); + Context.authenticate("admin", "test"); + ConceptReferenceTerm conceptReferenceTerm = conceptService.getConceptReferenceTermByCode(referenceTermRow.getCode(), conceptService.getConceptSourceByName(referenceTermRow.getSource())); + assertEquals(referenceTermRow.getCode(), conceptReferenceTerm.getCode()); + + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void updateExisitingReferenceTerm() { + + ReferenceTermRow referenceTermRow = new ReferenceTermRow("TB100", "SNOMED CT", "Tuberclosis", null, null); + referenceTermPersister.persist(referenceTermRow); + + Context.openSession(); + Context.authenticate("admin", "test"); + ConceptSource conceptSource = conceptService.getConceptSourceByName(referenceTermRow.getSource()); + ConceptReferenceTerm existingConceptReferenceTerm = conceptService.getConceptReferenceTermByCode(referenceTermRow.getCode(), conceptSource); + assertEquals("TB100", existingConceptReferenceTerm.getCode()); + assertEquals("Tuberclosis", existingConceptReferenceTerm.getName()); + Context.flushSession(); + Context.closeSession(); + + + ReferenceTermRow updatedReferenceTermRow = new ReferenceTermRow("TB100", "SNOMED CT", "TuberclosisEdited", "Description", "1.1"); + referenceTermPersister.persist(updatedReferenceTermRow); + + Context.openSession(); + Context.authenticate("admin", "test"); + ConceptReferenceTerm updatedConceptReferenceTerm = conceptService.getConceptReferenceTermByCode(updatedReferenceTermRow.getCode(), conceptSource); + assertEquals("TB100", existingConceptReferenceTerm.getCode()); + assertEquals("TuberclosisEdited", updatedConceptReferenceTerm.getName()); + assertEquals("Description", updatedConceptReferenceTerm.getDescription()); + assertEquals("1.1", updatedConceptReferenceTerm.getVersion()); + Context.flushSession(); + Context.closeSession(); + } + + @Test + public void failsSaveWhenInvalidConceptsource() { + ReferenceTermRow referenceTermRow = new ReferenceTermRow("TB100", "ICG 11", "Tuberclosis", null, null); + Messages errorMessages = referenceTermPersister.persist(referenceTermRow); + + assertFalse("should have persisted the reference term row", errorMessages.isEmpty()); + assertTrue(errorMessages.toString().contains("Concept reference source ICG 11 does not exists.")); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/persister/RelationshipPersisterTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/persister/RelationshipPersisterTest.java new file mode 100644 index 0000000000..cba3ae3cd9 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/persister/RelationshipPersisterTest.java @@ -0,0 +1,100 @@ +package org.bahmni.module.admin.csv.persister; + +import org.bahmni.csv.Messages; +import org.bahmni.module.admin.csv.models.RelationshipRow; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class}) +public class RelationshipPersisterTest { + + @Mock + private AdministrationService administrationService; + + @Mock + private UserContext userContext; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Before + public void setUp() { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + } + + @Test + public void shouldPassValidationIfAllRequiredFieldsAreProvided() throws Exception { + Messages messages = getRelationshipPersister().validate(new RelationshipRow("GAN200012", "GAN200015", "Parent", "Child", "2014-02-01", "2015-01-01")); + assertEquals(0, messages.size()); + } + + @Test + public void shouldThrowExceptionIfPersonAIsNotSpecified() throws Exception { + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Patient unique identifier not specified."); + getRelationshipPersister().validateRow(new RelationshipRow(null, "GAN200015", "", "Child", "2014-02-01", "2015-01-01")); + } + + @Test + public void shouldThrowExceptionIfProviderNameAndRelationalIdentifierIsNotSpecified() throws Exception { + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Both Provider Name and Relation Identifier cannot be null."); + getRelationshipPersister().validateRow(new RelationshipRow("GAN200015", null, "", "Child", "2014-02-01", "2015-01-01")); + } + + @Test + public void shouldThrowExceptionIfRelationshipBIsToANotSpecified() throws Exception { + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Relationship type is not specified."); + getRelationshipPersister().validateRow(new RelationshipRow("GAN200015", "GAN200016", "ProviderName", null, "2014-02-01", "2015-01-01")); + } + + + @Test + public void shouldThrowExceptionIfEndDateIsBeforeStartDate() throws Exception { + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Start date should be before end date."); + getRelationshipPersister().validateRow(new RelationshipRow("GAN200012", "GAN200015", "ProviderName", "Child", "2015-02-01", "2014-01-01")); + } + + @Test + public void shouldThrowExceptionIfTheStartDateFormatIsWrong() throws Exception { + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Date format 02-01-2015 doesn't match `bahmni.admin.csv.upload.dateFormat` global property, expected format yyyy-M-d"); + getRelationshipPersister().validateRow(new RelationshipRow("GAN200012", "GAN200015", "ProviderName", "Child", "02-01-2015", "2014-01-01")); + } + + @Test + public void shouldThrowExceptionIfTheEndDateFormatIsWrong() throws Exception { + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Date format 01-01-2014 doesn't match `bahmni.admin.csv.upload.dateFormat` global property, expected format yyyy-M-d"); + getRelationshipPersister().validateRow(new RelationshipRow("GAN200012", "GAN200015", "ProviderName", "Child", "2015-02-01", "01-01-2014")); + } + + private RelationshipPersister getRelationshipPersister() { + return new RelationshipPersister(); + } + + +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVAddressServiceTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVAddressServiceTest.java new file mode 100644 index 0000000000..7360401b2c --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVAddressServiceTest.java @@ -0,0 +1,122 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.csv.KeyValue; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.PersonAddress; +import org.openmrs.module.addresshierarchy.AddressField; +import org.openmrs.module.addresshierarchy.AddressHierarchyLevel; +import org.openmrs.module.addresshierarchy.service.AddressHierarchyService; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CSVAddressServiceTest { + private AddressHierarchyService mockAddressHierarchyService; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + mockAddressHierarchyService = mock(AddressHierarchyService.class); + } + + @Test + public void mapThroughAddressHierarchyLevels() { + List addressParts = new ArrayList() {{ + add(new KeyValue("Cities", "zhumri tallayya")); + add(new KeyValue("States", "Timbaktu")); + add(new KeyValue("Countries", "Bharat")); + add(new KeyValue("ZipCode", "555555")); + }}; + + AddressHierarchyLevel cityLevel = new AddressHierarchyLevel(); + cityLevel.setName("Cities"); + cityLevel.setAddressField(AddressField.CITY_VILLAGE); + + AddressHierarchyLevel stateLevel = new AddressHierarchyLevel(); + stateLevel.setName("States"); + stateLevel.setAddressField(AddressField.STATE_PROVINCE); + + AddressHierarchyLevel countryLevel = new AddressHierarchyLevel(); + countryLevel.setName("Countries"); + countryLevel.setAddressField(AddressField.COUNTRY); + + AddressHierarchyLevel postalCodeLevel = new AddressHierarchyLevel(); + postalCodeLevel.setName("ZipCode"); + postalCodeLevel.setAddressField(AddressField.POSTAL_CODE); + + ArrayList addressHierarchyLevels = new ArrayList<>(); + addressHierarchyLevels.add(cityLevel); + addressHierarchyLevels.add(stateLevel); + addressHierarchyLevels.add(countryLevel); + addressHierarchyLevels.add(postalCodeLevel); + when(mockAddressHierarchyService.getAddressHierarchyLevels()).thenReturn(addressHierarchyLevels); + + CSVAddressService csvAddressService = new CSVAddressService(mockAddressHierarchyService); + PersonAddress personAddress = csvAddressService.getPersonAddress(addressParts); + + assertEquals("zhumri tallayya", personAddress.getCityVillage()); + assertEquals("Timbaktu", personAddress.getStateProvince()); + assertEquals("Bharat", personAddress.getCountry()); + assertEquals("555555", personAddress.getPostalCode()); + } + + @Test + public void throwErrorWhenAddressLevelNotFound() { + List addressParts = new ArrayList() {{ + add(new KeyValue("Cities", "zhumri tallayya")); + }}; + + AddressHierarchyLevel cityLevel = new AddressHierarchyLevel(); + cityLevel.setName("City"); + cityLevel.setAddressField(AddressField.CITY_VILLAGE); + + ArrayList addressHierarchyLevels = new ArrayList<>(); + addressHierarchyLevels.add(cityLevel); + + when(mockAddressHierarchyService.getAddressHierarchyLevels()).thenReturn(addressHierarchyLevels); + + exception.expect(RuntimeException.class); + exception.expectMessage(String.format("Address Hierarchy level {0} does not exist.", "Cities")); + + CSVAddressService csvAddressService = new CSVAddressService(mockAddressHierarchyService); + csvAddressService.getPersonAddress(addressParts); + } + + @Test + public void mapOtherAddressHierarchyLevels() { + List addressParts = new ArrayList() {{ + add(new KeyValue("tehsil", "zhumri tallayya")); + add(new KeyValue("gram panchayat", "Timbaktu")); + }}; + + AddressHierarchyLevel tehsilLevel = new AddressHierarchyLevel(); + tehsilLevel.setName("tehsil"); + tehsilLevel.setAddressField(AddressField.ADDRESS_1); + + AddressHierarchyLevel panchayatLevel = new AddressHierarchyLevel(); + panchayatLevel.setName("gram panchayat"); + panchayatLevel.setAddressField(AddressField.ADDRESS_2); + + + ArrayList addressHierarchyLevels = new ArrayList<>(); + addressHierarchyLevels.add(tehsilLevel); + addressHierarchyLevels.add(panchayatLevel); + when(mockAddressHierarchyService.getAddressHierarchyLevels()).thenReturn(addressHierarchyLevels); + + CSVAddressService csvAddressService = new CSVAddressService(mockAddressHierarchyService); + PersonAddress personAddress = csvAddressService.getPersonAddress(addressParts); + + assertEquals("zhumri tallayya", personAddress.getAddress1()); + assertEquals("Timbaktu", personAddress.getAddress2()); + } + +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVPatientServiceTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVPatientServiceTest.java new file mode 100644 index 0000000000..e1ca673307 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVPatientServiceTest.java @@ -0,0 +1,423 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.common.config.registration.service.RegistrationPageService; +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.PatientRow; +import org.bahmni.module.admin.csv.utils.CSVUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Patient; +import org.openmrs.PersonAddress; +import org.openmrs.PersonAttributeType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.addresshierarchy.AddressField; +import org.openmrs.module.addresshierarchy.AddressHierarchyLevel; +import org.openmrs.module.addresshierarchy.service.AddressHierarchyService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.eq; +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class}) +public class CSVPatientServiceTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + @Mock + private PatientService mockPatientService; + @Mock + private PersonService mockPersonService; + @Mock + private ConceptService conceptService; + @Mock + private AdministrationService mockAdminService; + @Mock + private AddressHierarchyService addressHierarchyService; + @Mock + private CSVAddressService csvAddressService; + @Mock + private RegistrationPageService registrationPageService; + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(mockAdminService); + when(mockAdminService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + } + + @Test + public void savePatientName() throws ParseException { + PatientRow patientRow = new PatientRow(); + patientRow.firstName = "Romesh"; + patientRow.middleName = "Sharad"; + patientRow.lastName = "Powar"; + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + + csvPatientService.save(patientRow); + + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient capturedPatient = patientArgumentCaptor.getValue(); + assertEquals("Romesh", capturedPatient.getGivenName()); + assertEquals("Sharad", capturedPatient.getMiddleName()); + assertEquals("Powar", capturedPatient.getFamilyName()); + } + + @Test + public void saveRegistrationNumberBirthdateGender() throws ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(CSVUtils.ENCOUNTER_DATE_PATTERN); + + PatientRow patientRow = new PatientRow(); + patientRow.age = "34"; + patientRow.gender = "Male"; + patientRow.registrationNumber = "reg-no"; + patientRow.birthdate = "1998-07-07"; + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + + csvPatientService.save(patientRow); + + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient capturedPatient = patientArgumentCaptor.getValue(); + assertEquals("Male", capturedPatient.getGender()); + assertEquals("reg-no", capturedPatient.getPatientIdentifier().getIdentifier()); + assertEquals(simpleDateFormat.parse("1998-07-07"), capturedPatient.getBirthdate()); + + } + + @Test + public void saveRegistrationNumberAgeGender() throws ParseException { + PatientRow patientRow = new PatientRow(); + patientRow.age = "34"; + patientRow.gender = "Male"; + patientRow.registrationNumber = "reg-no"; + + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + + csvPatientService.save(patientRow); + + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient capturedPatient = patientArgumentCaptor.getValue(); + assertEquals("Male", capturedPatient.getGender()); + assertEquals("reg-no", capturedPatient.getPatientIdentifier().getIdentifier()); + assertEquals(new Integer(34), capturedPatient.getAge()); + + } + + @Test + public void saveAddressparts() throws ParseException { + PatientRow patientRow = new PatientRow(); + + List addressParts = new ArrayList() {{ + add(new KeyValue("Cities", "zhumri tallayya")); + add(new KeyValue("States", "Timbaktu")); + add(new KeyValue("Countries", "Bharat")); + add(new KeyValue("ZipCode", "555555")); + }}; + patientRow.addressParts = addressParts; + + AddressHierarchyLevel cityLevel = new AddressHierarchyLevel(); + cityLevel.setName("Cities"); + cityLevel.setAddressField(AddressField.CITY_VILLAGE); + + AddressHierarchyLevel stateLevel = new AddressHierarchyLevel(); + stateLevel.setName("States"); + stateLevel.setAddressField(AddressField.STATE_PROVINCE); + + AddressHierarchyLevel countryLevel = new AddressHierarchyLevel(); + countryLevel.setName("Countries"); + countryLevel.setAddressField(AddressField.COUNTRY); + + AddressHierarchyLevel postalCodeLevel = new AddressHierarchyLevel(); + postalCodeLevel.setName("ZipCode"); + postalCodeLevel.setAddressField(AddressField.POSTAL_CODE); + + ArrayList addressHierarchyLevels = new ArrayList<>(); + addressHierarchyLevels.add(cityLevel); + addressHierarchyLevels.add(stateLevel); + addressHierarchyLevels.add(countryLevel); + addressHierarchyLevels.add(postalCodeLevel); + + when(addressHierarchyService.getAddressHierarchyLevels()).thenReturn(addressHierarchyLevels); + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, new CSVAddressService(addressHierarchyService), registrationPageService); + csvPatientService.save(patientRow); + + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient patient = patientArgumentCaptor.getValue(); + Set addresses = patient.getAddresses(); + PersonAddress capturedAddress = addresses.iterator().next(); + assertEquals("zhumri tallayya", capturedAddress.getCityVillage()); + assertEquals("Timbaktu", capturedAddress.getStateProvince()); + assertEquals("Bharat", capturedAddress.getCountry()); + assertEquals("555555", capturedAddress.getPostalCode()); + } + + @Test + public void savePersonAttributes() throws ParseException { + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Arrays.asList( + createPersonAttributeType("familyNameLocal", "java.lang.String"), + createPersonAttributeType("caste", "java.lang.String") + )); + PatientRow patientRow = new PatientRow(); + patientRow.attributes = new ArrayList() {{ + add(new KeyValue("familyNameLocal", "ram")); + add(new KeyValue("caste", "gond")); + }}; + + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + csvPatientService.save(patientRow); + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient patient = patientArgumentCaptor.getValue(); + assertEquals(patient.getAttribute("familyNameLocal").getValue(), "ram"); + assertEquals(patient.getAttribute("caste").getValue(), "gond"); + } + + @Test + public void shouldOnlyAddPersonAttributesOfFormatOpenMrsConceptAndJavaDataTypes() throws ParseException { + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Arrays.asList( + createPersonAttributeType("education", "org.openmrs.Concept"), + createPersonAttributeType("isUrban", "java.lang.Boolean"), + createPersonAttributeType("visitDate", "org.openmrs.util.AttributableDate"), + createPersonAttributeType("landHolding", "java.lang.Integer") + )); + + Concept concept = new Concept(); + ConceptName conceptNameFullySpecified = new ConceptName(); + conceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + conceptNameFullySpecified.setName("123"); + concept.setNames(Collections.singleton(conceptNameFullySpecified)); + concept.setId(123); + when(conceptService.getConceptsByName("123")).thenReturn(Collections.singletonList(concept)); + PatientRow patientRow = new PatientRow(); + patientRow.attributes = new ArrayList() {{ + add(new KeyValue("education", "123")); + add(new KeyValue("isUrban", "true")); + add(new KeyValue("visitDate", "2016-11-22")); + add(new KeyValue("landHolding", "222")); + }}; + + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + csvPatientService.save(patientRow); + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient patient = patientArgumentCaptor.getValue(); + assertThat(patient.getAttributes().size(), is(4)); + assertThat(patient.getAttribute("education").getValue(), is("123")); + assertThat(patient.getAttribute("isUrban").getValue(), is("true")); + assertThat(patient.getAttribute("landHolding").getValue(), is("222")); + } + + @Test + public void shouldOnlyUseTheConceptIfItsFullySpecifiedOrShortNameMatchesTheCodedAnswer() throws ParseException { + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Collections.singletonList( + createPersonAttributeType("confirmedByChw", "org.openmrs.Concept") + )); + + Concept concept = new Concept(); + ConceptName conceptNameFullySpecified = new ConceptName(); + conceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + conceptNameFullySpecified.setName("Yes"); + ConceptName conceptNameShort = new ConceptName(); + conceptNameShort.setConceptNameType(ConceptNameType.SHORT); + conceptNameShort.setName("yes"); + concept.setId(123); + concept.setNames(Arrays.asList(conceptNameFullySpecified, conceptNameShort)); + + Concept secondConcept = new Concept(); + ConceptName secondConceptNameFullySpecified = new ConceptName(); + secondConceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + secondConceptNameFullySpecified.setName("True"); + ConceptName secondConceptName = new ConceptName(); + secondConceptName.setName("Yes"); + secondConcept.setNames(Arrays.asList(secondConceptNameFullySpecified, secondConceptName)); + secondConcept.setId(321); + + when(conceptService.getConceptsByName("Yes")).thenReturn(Arrays.asList(concept, secondConcept)); + PatientRow patientRow = new PatientRow(); + patientRow.attributes = new ArrayList() {{ + add(new KeyValue("confirmedByChw", "Yes")); + }}; + + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + csvPatientService.save(patientRow); + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient patient = patientArgumentCaptor.getValue(); + assertThat(patient.getAttributes().size(), is(1)); + assertThat(patient.getAttribute("confirmedByChw").getValue(), is("123")); + } + + @Test(expected = RuntimeException.class) + public void shouldThrowExceptionIfTheCodedAttributeValueGivenIsInvalid() throws ParseException { + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Collections.singletonList( + createPersonAttributeType("confirmedByChw", "org.openmrs.Concept") + )); + + when(conceptService.getConceptsByName("Yes")).thenReturn(null); + PatientRow patientRow = new PatientRow(); + patientRow.attributes = new ArrayList() {{ + add(new KeyValue("confirmedByChw", "Yes")); + }}; + + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + csvPatientService.save(patientRow); + } + + @Test(expected = RuntimeException.class) + public void shouldThrowAnExceptionIfNoFullySpecifiedNameMatches() throws ParseException { + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Collections.singletonList( + createPersonAttributeType("confirmedByChw", "org.openmrs.Concept") + )); + + Concept concept = new Concept(); + ConceptName conceptNameFullySpecified = new ConceptName(); + conceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + conceptNameFullySpecified.setName("Nope"); + ConceptName conceptNameShort = new ConceptName(); + conceptNameShort.setConceptNameType(ConceptNameType.SHORT); + conceptNameShort.setName("nope"); + concept.setId(123); + concept.setNames(Arrays.asList(conceptNameFullySpecified, conceptNameShort)); + + Concept secondConcept = new Concept(); + ConceptName secondConceptNameFullySpecified = new ConceptName(); + secondConceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + secondConceptNameFullySpecified.setName("True"); + ConceptName secondConceptName = new ConceptName(); + secondConceptName.setName("Yes"); + secondConcept.setNames(Arrays.asList(secondConceptNameFullySpecified, secondConceptName)); + secondConcept.setId(321); + + when(conceptService.getConceptsByName("Yes")).thenReturn(Arrays.asList(concept, secondConcept)); + PatientRow patientRow = new PatientRow(); + patientRow.attributes = new ArrayList() {{ + add(new KeyValue("confirmedByChw", "Yes")); + }}; + + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + csvPatientService.save(patientRow); + } + + @Test + public void failsWhenNonExistingAttributeIsImported() throws ParseException { + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Arrays.asList(createPersonAttributeType("familyNameLocal", "java.lang.String"))); + + PatientRow patientRow = new PatientRow(); + patientRow.attributes = Arrays.asList(new KeyValue("nonExisting", "someValue")); + + exception.expect(RuntimeException.class); + exception.expectMessage("Person Attribute nonExisting not found"); + csvPatientService.save(patientRow); + } + + @Test + public void shouldThrowExceptionWhenMandatoryAttributeIsMissing() throws ParseException { + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Arrays.asList(createPersonAttributeType("familyNameLocal", "java.lang.String"))); + when(mockAdminService.getGlobalProperty(anyString())).thenReturn("true"); + when(registrationPageService.getMandatoryAttributes()).thenReturn(Arrays.asList("Admission Date")); + + PatientRow patientRow = new PatientRow(); + patientRow.attributes = Arrays.asList(new KeyValue("Admission Date", "")); + + exception.expect(RuntimeException.class); + exception.expectMessage("Missing value for mandatory attribute \"Admission Date\""); + csvPatientService.save(patientRow); + } + + @Test + public void shouldThrowExceptionWhenPatientConfigIsNotAvailable() throws ParseException { + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Arrays.asList(createPersonAttributeType("familyNameLocal", "java.lang.String"))); + when(mockAdminService.getGlobalProperty(anyString())).thenReturn("true"); + when(registrationPageService.getMandatoryAttributes()).thenReturn(null); + + PatientRow patientRow = new PatientRow(); + patientRow.attributes = Arrays.asList(new KeyValue("Admission Date", "")); + + exception.expect(RuntimeException.class); + exception.expectMessage("Error in reading patient registration config"); + csvPatientService.save(patientRow); + } + + @Test + public void shouldSkipAttributeCreationWhenEmptyAndNotMandatory() throws ParseException { + CSVPatientService csvPatientService = new CSVPatientService(mockPatientService, mockPersonService, conceptService, mockAdminService, csvAddressService, registrationPageService); + when(mockPersonService.getAllPersonAttributeTypes(false)).thenReturn(Arrays.asList(createPersonAttributeType("familyNameLocal", "java.lang.String"))); + when(mockAdminService.getGlobalProperty(anyString())).thenReturn("true"); + when(registrationPageService.getMandatoryAttributes()).thenReturn(Arrays.asList()); + + PatientRow patientRow = new PatientRow(); + patientRow.attributes = Arrays.asList(new KeyValue("Admission Date", "")); + + csvPatientService.save(patientRow); + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + verify(mockPatientService).savePatient(patientArgumentCaptor.capture()); + + Patient patient = patientArgumentCaptor.getValue(); + assertThat(patient.getAttributes().size(), is(0)); + assertNull(patient.getAttribute("Admission Date")); + } + + private PersonAttributeType createPersonAttributeType(String name, String format) { + PersonAttributeType personAttributeType = new PersonAttributeType(); + personAttributeType.setName(name); + personAttributeType.setFormat(format); + return personAttributeType; + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVRelationshipServiceIT.java b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVRelationshipServiceIT.java new file mode 100644 index 0000000000..5e8752bb41 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVRelationshipServiceIT.java @@ -0,0 +1,95 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.RelationshipRow; +import org.bahmni.module.admin.csv.utils.CSVUtils; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.Relationship; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PersonService; +import org.openmrs.api.ProviderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CSVRelationshipServiceIT extends BaseIntegrationTest { + @Autowired + private BahmniPatientService patientService; + + @Autowired + private PersonService personService; + + @Autowired + private ProviderService providerService; + + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + private CSVRelationshipService csvRelationshipService; + + @Before + public void setUp() throws Exception { + executeDataSet("relationshipDataSetup.xml"); + } + + @Test + public void shouldSavePatientRelationship() throws Exception { + csvRelationshipService = new CSVRelationshipService(patientService, personService, providerService, administrationService); + + Relationship relationship = csvRelationshipService.save(new RelationshipRow("ABC123", "XYZ", "", "Parent", "2015-04-28", "2016-04-28")); + + assertNotNull("Should have saved the relationship", relationship); + assertEquals(relationship.getPersonA().getPersonId().intValue(), 8); + assertEquals(relationship.getPersonB().getPersonId().intValue(), 999); + assertEquals(relationship.getRelationshipType().getId().intValue(), 2); + assertEquals(relationship.getStartDate(), CSVUtils.getDateFromString("2015-04-28")); + assertEquals(relationship.getEndDate(), CSVUtils.getDateFromString("2016-04-28")); + } + + @Test + public void shouldSavePatientRelationshipWithTodayDateIfStartDateIsNotSpecified() throws Exception { + csvRelationshipService = new CSVRelationshipService(patientService, personService, providerService, administrationService); + + Relationship relationship = csvRelationshipService.save(new RelationshipRow("ABC123", "XYZ", "", "Parent", null, "2099-04-01")); + + assertNotNull("Should have saved the relationship", relationship); + assertEquals(relationship.getPersonA().getPersonId().intValue(), 8); + assertEquals(relationship.getPersonB().getPersonId().intValue(), 999); + assertEquals(relationship.getRelationshipType().getId().intValue(), 2); + assertEquals(relationship.getStartDate(), CSVUtils.getTodayDate()); + } + + @Test + public void shouldUpdateExistingPatientRelationshipThatExists() throws Exception { + csvRelationshipService = new CSVRelationshipService(patientService, personService, providerService, administrationService); + + csvRelationshipService.save(new RelationshipRow("ABC123", "XYZ", "", "Parent", "2015-04-28", "2016-04-28")); + + Relationship relationship = csvRelationshipService.save(new RelationshipRow("ABC123", "XYZ", "", "Parent", "2015-04-29", "2016-04-29")); + assertEquals(relationship.getStartDate(), CSVUtils.getDateFromString("2015-04-29")); + } + + @Test + public void shouldSaveProviderRelationship() throws Exception { + csvRelationshipService = new CSVRelationshipService(patientService, personService, providerService, administrationService); + + Relationship relationship = csvRelationshipService.save(new RelationshipRow("ABC123", "", "Super User", "Nurse", "2015-04-28", "2016-04-28")); + + assertNotNull("Should have saved the relationship", relationship); + assertEquals(relationship.getPersonA().getPersonId().intValue(), 8); + assertEquals(relationship.getPersonB().getPersonId().intValue(), 1); + assertEquals(relationship.getRelationshipType().getId().intValue(), 10); + assertEquals(relationship.getStartDate(), CSVUtils.getDateFromString("2015-04-28")); + assertEquals(relationship.getEndDate(), CSVUtils.getDateFromString("2016-04-28")); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVRelationshipServiceTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVRelationshipServiceTest.java new file mode 100644 index 0000000000..15b6ff985c --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/service/CSVRelationshipServiceTest.java @@ -0,0 +1,193 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.module.admin.csv.models.RelationshipRow; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Relationship; +import org.openmrs.RelationshipType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PersonService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class}) +public class CSVRelationshipServiceTest { + @Mock + private BahmniPatientService patientService; + + @Mock + private PersonService personService; + + @Mock + private ProviderService providerService; + + @Mock + @Qualifier("adminService") + private AdministrationService administrationService; + + @Mock + private UserContext userContext; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + private CSVRelationshipService csvRelationshipService; + + @Before + public void setUp() throws Exception { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + csvRelationshipService = new CSVRelationshipService(patientService, personService, providerService, administrationService); + } + + @Test + public void shouldFailIfPersonADoesNotExist() throws Exception { + when(patientService.get("", true)).thenReturn(null); + + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("No matching patients found with ID:'null'"); + + csvRelationshipService.save(new RelationshipRow()); + } + + @Test + public void shouldFailIfAisToBRelationshipDoesNotExist() throws Exception { + when(patientService.get(null, true)).thenReturn(getPatients()); + when(patientService.getByAIsToB("")).thenReturn(null); + + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("No matching relationship type found with relationship type name:'null'"); + + csvRelationshipService.save(new RelationshipRow()); + } + + @Test + public void shouldFailIfBisToARelationshipDoesNotExist() throws Exception { + when(patientService.get("GAN200012", true)).thenReturn(getPatients()); + ArrayList relationshipTypes = getRelationshipTypes(); + when(patientService.getByAIsToB("Parent")).thenReturn(relationshipTypes); + + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("No matching relationship type found with relationship type name:'something'"); + + csvRelationshipService.save(new RelationshipRow("GAN200012", "","", "something", null, null)); + } + + @Test + public void shouldFailIfPersonBDoesNotExist() throws Exception { + when(patientService.get("GAN200012", true)).thenReturn(getPatients()); + ArrayList relationshipTypes = getRelationshipTypes(); + when(patientService.getByAIsToB("Parent")).thenReturn(relationshipTypes); + when(patientService.get("GAN200013", true)).thenReturn(null); + + when(administrationService.getGlobalProperty(anyString())).thenReturn("{patient: [\"Parent\"]}"); + + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("No matching patients found with ID:'GAN200013'"); + + csvRelationshipService.save(new RelationshipRow("GAN200012", "GAN200013", "", "Parent", null, null)); + } + + @Test + public void shouldFailIfPersonBAsProviderDoesNotExist() throws Exception { + when(patientService.get("GAN200012", true)).thenReturn(getPatients()); + ArrayList relationshipTypes = getRelationshipTypes(); + when(patientService.getByAIsToB("Parent")).thenReturn(relationshipTypes); + when(providerService.getProviders("Super User", null, null, null)).thenReturn(null); + + when(administrationService.getGlobalProperty(anyString())).thenReturn("{provider: [\"Parent\"]}"); + + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("No matching provider found with ID:'Super User'"); + + csvRelationshipService.save(new RelationshipRow("GAN200012", "", "Super User", "Parent", null, null)); + } + + @Test + public void shouldFailIfRelationshipMapDoesNotExist() throws Exception { + when(patientService.get("GAN200012", true)).thenReturn(getPatients()); + when(patientService.get("GAN200013", true)).thenReturn(null); + ArrayList relationshipTypes = getRelationshipTypes(); + when(patientService.getByAIsToB("Parent")).thenReturn(relationshipTypes); + when(providerService.getProviders("Super User", null, null, null)).thenReturn(null); + + when(administrationService.getGlobalProperty(anyString())).thenReturn(null); + + expectedEx.expect(RuntimeException.class); + expectedEx.expectMessage("Relationship not found ProviderName"); + + csvRelationshipService.save(new RelationshipRow("GAN200012", "GAN200013", "ProviderName", "Parent", null, null)); + } + + @Test + public void shouldSaveRelationship() throws Exception { + when(patientService.get("GAN200012", true)).thenReturn(getPatients()); + ArrayList relationshipTypes = getRelationshipTypes(); + when(patientService.getByAIsToB("Doctor")).thenReturn(relationshipTypes); + when(providerService.getProviders("Super User", null, null, null)).thenReturn(getProviders()); + when(administrationService.getGlobalProperty(anyString())).thenReturn("{provider: [\"Doctor\"]}"); + when(administrationService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + + Relationship expectedRelationship = new Relationship(); + expectedRelationship.setPersonA(getPatients().get(0)); + expectedRelationship.setPersonB(getProviders().get(0).getPerson()); + when(personService.saveRelationship(any(Relationship.class))).thenReturn(expectedRelationship); + + Relationship relationship = csvRelationshipService.save(new RelationshipRow("GAN200012", "", "Super User", "Doctor", null, null)); + assertNotNull("Relationship should not be null", relationship); + assertEquals(expectedRelationship.getPersonA(), relationship.getPersonA()); + assertEquals(expectedRelationship.getPersonB(), relationship.getPersonB()); + + } + + private List getPatients() { + List patients = new ArrayList<>(); + Patient patient = new Patient(); + patient.setId(1); + patients.add(patient); + return patients; + } + + private ArrayList getProviders() { + ArrayList providers = new ArrayList(); + Provider provider = new Provider(); + provider.setName("Super User"); + providers.add(provider); + return providers; + } + + private ArrayList getRelationshipTypes() { + ArrayList relationshipTypes = new ArrayList(); + RelationshipType relationshipType = new RelationshipType(); + relationshipType.setaIsToB("Parent"); + relationshipType.setbIsToA("Child"); + relationshipTypes.add(relationshipType); + return relationshipTypes; + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/csv/service/FormFieldPathGeneratorServiceTest.java b/admin/src/test/java/org/bahmni/module/admin/csv/service/FormFieldPathGeneratorServiceTest.java new file mode 100644 index 0000000000..e1321b2f66 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/csv/service/FormFieldPathGeneratorServiceTest.java @@ -0,0 +1,252 @@ +package org.bahmni.module.admin.csv.service; + +import org.bahmni.csv.KeyValue; +import org.bahmni.form2.service.FormFieldPathService; +import org.bahmni.module.admin.csv.models.SectionPositionValue; +import org.bahmni.module.admin.observation.CSVObservationHelper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Mockito.mock; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@PrepareForTest(CSVObservationHelper.class) +@RunWith(PowerMockRunner.class) +public class FormFieldPathGeneratorServiceTest { + + private FormFieldPathService formFieldPathService; + private FormFieldPathGeneratorService formFieldPathGeneratorService; + + @Before + public void setUp() { + formFieldPathService = mock(FormFieldPathService.class); + formFieldPathGeneratorService = new FormFieldPathGeneratorService(formFieldPathService); + } + + @Test + public void shouldNotSetFormFieldPathForEmptyObserevations() { + List form2Observations = asList(); + List form2CSVHeaderParts = null; + formFieldPathGeneratorService.setFormNamespaceAndFieldPath(form2Observations, form2CSVHeaderParts); + + assertEquals(0, form2Observations.size()); + } + + @Test + public void shouldSetFormFieldPathForObserevation() { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid("UUID"); + observation.setConcept(new EncounterTransaction.Concept()); + observation.setValue("Dummy Value"); + + List form2Observations = asList(observation); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Vitals", "Height")); + + PowerMockito.mockStatic(CSVObservationHelper.class); + when(CSVObservationHelper.getLastItem(anyListOf(EncounterTransaction.Observation.class))).thenReturn(observation); + when(formFieldPathService.getFormFieldPath(anyListOf(String.class))).thenReturn("Vitals.1/1-0"); + + formFieldPathGeneratorService.setFormNamespaceAndFieldPath(form2Observations, headerParts); + + assertEquals("Vitals.1/1-0", form2Observations.get(0).getFormFieldPath()); + assertEquals("Bahmni", form2Observations.get(0).getFormNamespace()); + } + + @Test + public void shouldSetFormFieldPathForMultiSelectObserevation() { + EncounterTransaction.Observation observation1 = new EncounterTransaction.Observation(); + observation1.setUuid("UUID1"); + observation1.setConcept(new EncounterTransaction.Concept()); + observation1.setValue("Cough"); + + EncounterTransaction.Observation observation2 = new EncounterTransaction.Observation(); + observation2.setUuid("UUID2"); + observation2.setConcept(new EncounterTransaction.Concept()); + observation2.setValue("Fever"); + + final KeyValue obs1 = new KeyValue("Covid.Symptoms", "Cough"); + final KeyValue obs2 = new KeyValue("Covid.Symptoms", "Fever"); + + List form2Observations = asList(observation1, observation2); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Covid", "Symptoms")); + + PowerMockito.mockStatic(CSVObservationHelper.class); + when(CSVObservationHelper.getLastItem(anyListOf(EncounterTransaction.Observation.class))).thenReturn(observation1); + when(formFieldPathService.getFormFieldPath(anyListOf(String.class))).thenReturn("Covid.1/1-0"); + + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForMultiSelectObs(form2Observations, headerParts, asList(obs1,obs2)); + + assertEquals("Covid.1/1-0", form2Observations.get(0).getFormFieldPath()); + assertEquals("Covid.1/1-0", form2Observations.get(1).getFormFieldPath()); + assertEquals("Bahmni", form2Observations.get(0).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(1).getFormNamespace()); + } + + @Test + public void shouldSetFormFieldPathForAddmoreObserevation() { + EncounterTransaction.Observation observation1 = new EncounterTransaction.Observation(); + observation1.setUuid("UUID1"); + observation1.setConcept(new EncounterTransaction.Concept()); + observation1.setValue("Cough"); + + EncounterTransaction.Observation observation2 = new EncounterTransaction.Observation(); + observation2.setUuid("UUID2"); + observation2.setConcept(new EncounterTransaction.Concept()); + observation2.setValue("Fever"); + + final KeyValue obs1 = new KeyValue("Covid.Symptoms", "Cough"); + final KeyValue obs2 = new KeyValue("Covid.Symptoms", "Fever"); + + List form2Observations = asList(observation1, observation2); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Covid", "Symptoms")); + + PowerMockito.mockStatic(CSVObservationHelper.class); + when(CSVObservationHelper.getLastItem(anyListOf(EncounterTransaction.Observation.class))).thenReturn(observation1); + when(formFieldPathService.getFormFieldPath(anyListOf(String.class))).thenReturn("Covid.1/1-0"); + + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForAddmoreObs(form2Observations, headerParts, asList(obs1,obs2)); + + assertEquals("Covid.1/1-0", form2Observations.get(0).getFormFieldPath()); + assertEquals("Covid.1/1-1", form2Observations.get(1).getFormFieldPath()); + assertEquals("Bahmni", form2Observations.get(0).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(1).getFormNamespace()); + } + + @Test + public void shouldSetFormFieldPathForObservationInsideAddmoreSection() { + EncounterTransaction.Observation observation1 = new EncounterTransaction.Observation(); + observation1.setUuid("UUID1"); + observation1.setConcept(new EncounterTransaction.Concept()); + observation1.setValue("Male"); + + EncounterTransaction.Observation observation2 = new EncounterTransaction.Observation(); + observation2.setUuid("UUID2"); + observation2.setConcept(new EncounterTransaction.Concept()); + observation2.setValue("Female"); + + KeyValue csvObs1 = new KeyValue("form2.Birth Details.Infant Details.Infant Gender", "Male"); + KeyValue csvObs2 = new KeyValue("form2.Birth Details.Infant Details.Infant Gender", "Female"); + + SectionPositionValue sectionPositionValue1 = new SectionPositionValue("Male", "0", 0, -1, -1); + SectionPositionValue sectionPositionValue2 = new SectionPositionValue("Female", "0", 1, -1, -1); + + List form2Observations = asList(observation1, observation2); + List headerParts = asList("form2", "Birth Details", "Infant Details", "Infant Gender"); + List csvObservations = asList(csvObs1, csvObs2); + List sectionPositionValuesList = asList(sectionPositionValue1, sectionPositionValue2); + + when(formFieldPathService.getFormFieldPath(anyListOf(String.class))).thenReturn("Birth Details.1/1-0/10-0"); + when(formFieldPathService.isAddmore(headerParts.subList(0,3))).thenReturn(true); + + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForJsonValue(form2Observations, headerParts, csvObservations, sectionPositionValuesList); + + assertEquals("Birth Details.1/1-0/10-0", form2Observations.get(0).getFormFieldPath()); + assertEquals("Birth Details.1/1-1/10-0", form2Observations.get(1).getFormFieldPath()); + assertEquals("Bahmni", form2Observations.get(0).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(1).getFormNamespace()); + } + + @Test + public void shouldSetFormFieldPathForObservationInsideNestedAddmoreSection() { + List form2Observations = new ArrayList<>(); + List obsInJson = asList("Xpert Qual/DNA PCR", "Antibody Test (RDT)", "Ultrasensitive AgP24", "Xpert Qual/DNA PCR", "Not specified"); + obsInJson.stream().forEach(obs -> { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid("UUID" + obs); + observation.setConcept(new EncounterTransaction.Concept()); + observation.setValue(obs); + form2Observations.add(observation); + }); + + KeyValue csvObs1 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Xpert Qual/DNA PCR"); + KeyValue csvObs2 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Antibody Test (RDT)"); + KeyValue csvObs3 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Ultrasensitive AgP24"); + KeyValue csvObs4 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Xpert Qual/DNA PCR"); + KeyValue csvObs5 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Not specified"); + + SectionPositionValue sectionPositionValue1 = new SectionPositionValue("Xpert Qual/DNA PCR", "0/0", 0, -1, -1); + SectionPositionValue sectionPositionValue2 = new SectionPositionValue("Antibody Test (RDT)", "0/0", 1, -1, -1); + SectionPositionValue sectionPositionValue3 = new SectionPositionValue("Ultrasensitive AgP24", "0/1", 0, -1, -1); + SectionPositionValue sectionPositionValue4 = new SectionPositionValue("Xpert Qual/DNA PCR", "0/1", 1, -1, -1); + SectionPositionValue sectionPositionValue5 = new SectionPositionValue("Not specified", "0/1", 2, -1, -1); + + List headerParts = asList("form2", "Birth Details", "Infant Details", "HIV Assessments", "Infant interim HIV test type"); + List csvObservations = asList(csvObs1, csvObs2, csvObs3, csvObs4, csvObs5); + List sectionPositionValuesList = asList(sectionPositionValue1, sectionPositionValue2, sectionPositionValue3, sectionPositionValue4, sectionPositionValue5); + + when(formFieldPathService.getFormFieldPath(anyListOf(String.class))).thenReturn("Birth Details.1/17-0/31-0/57-0"); + when(formFieldPathService.isAddmore(headerParts.subList(0,2))).thenReturn(true); + when(formFieldPathService.isAddmore(headerParts.subList(0,3))).thenReturn(true); + + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForJsonValue(form2Observations, headerParts, csvObservations, sectionPositionValuesList); + + assertEquals("Birth Details.1/17-0/31-0/57-0", form2Observations.get(0).getFormFieldPath()); + assertEquals("Birth Details.1/17-0/31-1/57-0", form2Observations.get(1).getFormFieldPath()); + assertEquals("Birth Details.1/17-1/31-0/57-0", form2Observations.get(2).getFormFieldPath()); + assertEquals("Birth Details.1/17-1/31-1/57-0", form2Observations.get(3).getFormFieldPath()); + assertEquals("Birth Details.1/17-1/31-2/57-0", form2Observations.get(4).getFormFieldPath()); + assertEquals("Bahmni", form2Observations.get(0).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(1).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(2).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(3).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(4).getFormNamespace()); + } + + @Test + public void shouldSetFormFieldPathForAddmoreObservationInsideNestedAddmoreSection() { + List form2Observations = new ArrayList<>(); + List obsInJson = asList("Xpert Qual/DNA PCR", "Antibody Test (RDT)", "Ultrasensitive AgP24", "Xpert Qual/DNA PCR", "Not specified"); + obsInJson.stream().forEach(obs -> { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid("UUID" + obs); + observation.setConcept(new EncounterTransaction.Concept()); + observation.setValue(obs); + form2Observations.add(observation); + }); + + KeyValue csvObs1 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Xpert Qual/DNA PCR"); + KeyValue csvObs2 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Antibody Test (RDT)"); + KeyValue csvObs3 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Ultrasensitive AgP24"); + KeyValue csvObs4 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Xpert Qual/DNA PCR"); + KeyValue csvObs5 = new KeyValue("form2.Birth Details.Infant Details.HIV Assessments.Infant interim HIV test type", "Not specified"); + + SectionPositionValue sectionPositionValue1 = new SectionPositionValue("Xpert Qual/DNA PCR", "0/0", 0, -1, 0); + SectionPositionValue sectionPositionValue2 = new SectionPositionValue("Antibody Test (RDT)", "0/0", 0, -1, 1); + SectionPositionValue sectionPositionValue3 = new SectionPositionValue("Ultrasensitive AgP24", "0/1", 0, -1, 0); + SectionPositionValue sectionPositionValue4 = new SectionPositionValue("Xpert Qual/DNA PCR", "0/1", 0, -1, 1); + SectionPositionValue sectionPositionValue5 = new SectionPositionValue("Not specified", "0/1", 0, -1, 2); + + List headerParts = asList("form2", "Birth Details", "Infant Details", "HIV Assessments", "Infant interim HIV test type"); + List csvObservations = asList(csvObs1, csvObs2, csvObs3, csvObs4, csvObs5); + List sectionPositionValuesList = asList(sectionPositionValue1, sectionPositionValue2, sectionPositionValue3, sectionPositionValue4, sectionPositionValue5); + + when(formFieldPathService.getFormFieldPath(anyListOf(String.class))).thenReturn("Birth Details.1/17-0/31-0/57-0"); + when(formFieldPathService.isAddmore(headerParts.subList(0,2))).thenReturn(true); + when(formFieldPathService.isAddmore(headerParts.subList(0,3))).thenReturn(true); + + formFieldPathGeneratorService.setFormNamespaceAndFieldPathForJsonValue(form2Observations, headerParts, csvObservations, sectionPositionValuesList); + + assertEquals("Birth Details.1/17-0/31-0/57-0", form2Observations.get(0).getFormFieldPath()); + assertEquals("Birth Details.1/17-0/31-0/57-1", form2Observations.get(1).getFormFieldPath()); + assertEquals("Birth Details.1/17-1/31-0/57-0", form2Observations.get(2).getFormFieldPath()); + assertEquals("Birth Details.1/17-1/31-0/57-1", form2Observations.get(3).getFormFieldPath()); + assertEquals("Birth Details.1/17-1/31-0/57-2", form2Observations.get(4).getFormFieldPath()); + assertEquals("Bahmni", form2Observations.get(0).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(1).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(2).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(3).getFormNamespace()); + assertEquals("Bahmni", form2Observations.get(4).getFormNamespace()); + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/encounter/BahmniEncounterTransactionImportServiceTest.java b/admin/src/test/java/org/bahmni/module/admin/encounter/BahmniEncounterTransactionImportServiceTest.java new file mode 100644 index 0000000000..6824e7bf2c --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/encounter/BahmniEncounterTransactionImportServiceTest.java @@ -0,0 +1,32 @@ +package org.bahmni.module.admin.encounter; + +import org.bahmni.module.admin.csv.models.MultipleEncounterRow; +import org.bahmni.module.admin.csv.models.MultipleEncounterRowBuilder; +import org.junit.Test; +import org.openmrs.EncounterType; +import org.openmrs.api.EncounterService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.springframework.util.Assert; + +import java.text.ParseException; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class BahmniEncounterTransactionImportServiceTest { + @Test + public void returnEmptyEncounterTransactionForEmptyEncounterRow() throws ParseException { + EncounterService mockEncounterService = mock(EncounterService.class); + when(mockEncounterService.getEncounterType("Consultation")).thenReturn(new EncounterType()); + + BahmniEncounterTransactionImportService bahmniEncounterTransactionImportService = new BahmniEncounterTransactionImportService(mockEncounterService, null, null, null); + MultipleEncounterRow emptyEncounterRow = new MultipleEncounterRowBuilder().getEmptyMultipleEncounterRow("GAN12345"); + emptyEncounterRow.encounterType = "Consultation"; + List bahmniEncounterTransaction = bahmniEncounterTransactionImportService.getBahmniEncounterTransaction(emptyEncounterRow, null, false); + Assert.isTrue(bahmniEncounterTransaction.isEmpty(), "Should ignore empty encounters"); + + bahmniEncounterTransaction = bahmniEncounterTransactionImportService.getBahmniEncounterTransaction(new MultipleEncounterRow(), null, false); + Assert.isTrue(bahmniEncounterTransaction.isEmpty(), "Should ignore empty encounters"); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/observation/CSVObservationHelperTest.java b/admin/src/test/java/org/bahmni/module/admin/observation/CSVObservationHelperTest.java new file mode 100644 index 0000000000..5bcc685572 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/observation/CSVObservationHelperTest.java @@ -0,0 +1,425 @@ +package org.bahmni.module.admin.observation; + +import org.bahmni.csv.KeyValue; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.APIException; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.bahmni.module.admin.observation.CSVObservationHelper.getLastItem; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class CSVObservationHelperTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + @Mock + private ConceptService conceptService; + private List conceptNames; + private List observations; + private ConceptDatatype conceptDatatype; + @Mock + private Concept heightConcept; + + @Mock + private ConceptName heightConceptName; + + @Mock + private AdministrationService administrationService; + + @Before + public void setUp() { + initMocks(this); + conceptNames = new ArrayList<>(); + observations = new ArrayList<>(); + + when(conceptService.getConceptByName("Height")).thenReturn(heightConcept); + + when(heightConcept.getName()).thenReturn(heightConceptName); + when(heightConceptName.getName()).thenReturn("Height"); + conceptDatatype = mock(ConceptDatatype.class); + when(heightConcept.getDatatype()).thenReturn(conceptDatatype); + when(administrationService.getGlobalProperty("bahmni.admin.csv.upload.obsPath.splitter")).thenReturn("."); + } + + + @Test + public void shouldCreateHeightObservationForTheGivenObsRow() throws ParseException { + KeyValue heightObsRow = new KeyValue("Height", "100"); + conceptNames.add("Height"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + + assertEquals(1, observations.size()); + EncounterTransaction.Observation heightObservation = observations.get(0); + assertEquals("Height", heightObservation.getConcept().getName()); + assertEquals("100", heightObservation.getValue()); + assertEquals(encounterDate, heightObservation.getObservationDateTime()); + + } + + @Test + public void shouldSetAbnormalInterpretationIfObsValueIsOutOfRange() throws ParseException { + KeyValue heightObsRow = new KeyValue("Height", "100"); + conceptNames.add("Height"); + + ConceptNumeric heightNumericConcept = mock(ConceptNumeric.class); + + when(heightNumericConcept.getDatatype()).thenReturn(conceptDatatype); + when(heightNumericConcept.getName()).thenReturn(heightConceptName); + when(conceptDatatype.isNumeric()).thenReturn(true); + when(conceptService.getConceptByName("Height")).thenReturn(heightNumericConcept); + when(heightNumericConcept.getHiNormal()).thenReturn(new Double(110)); + when(heightNumericConcept.getLowNormal()).thenReturn(new Double(105)); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + + assertEquals(1, observations.size()); + EncounterTransaction.Observation heightObservation = observations.get(0); + assertEquals("Height", heightObservation.getConcept().getName()); + assertEquals("100", heightObservation.getValue()); + assertEquals(encounterDate, heightObservation.getObservationDateTime()); + assertEquals("ABNORMAL", heightObservation.getInterpretation()); + } + + @Test + public void shouldCreateHeightObservationAsGroupMemberOfBMIDataObservation() throws ParseException { + KeyValue heightObsRow = new KeyValue("BMI Data.Height", "100"); + conceptNames.add("BMI Data"); + conceptNames.add("Height"); + + Concept bmiDataConcept = mock(Concept.class); + ConceptName bmiConceptName = mock(ConceptName.class); + + when(conceptService.getConceptByName("BMI Data")).thenReturn(bmiDataConcept); + when(bmiDataConcept.getName()).thenReturn(bmiConceptName); + when(bmiConceptName.getName()).thenReturn("BMI Data"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + + assertEquals(1, observations.size()); + + assertEquals("BMI Data", observations.get(0).getConcept().getName()); + assertEquals(1, observations.get(0).getGroupMembers().size()); + EncounterTransaction.Observation heightObservation = observations.get(0).getGroupMembers().get(0); + assertEquals("Height", heightObservation.getConcept().getName()); + assertEquals("100", heightObservation.getValue()); + assertEquals(encounterDate, heightObservation.getObservationDateTime()); + + } + + @Test + public void shouldCreateHeightObservationAndWeightObservationAsGroupMembersOfBMIDataObservation() throws ParseException { + KeyValue heightObsRow = new KeyValue("BMI Data.Height", "100"); + KeyValue weightObsRow = new KeyValue("BMI Data.Weight", "150"); + String bmiData = "BMI Data"; + conceptNames.add(bmiData); + conceptNames.add("Height"); + + List bmiAndWeightConcepts = new ArrayList<>(); + bmiAndWeightConcepts.add(bmiData); + bmiAndWeightConcepts.add("Weight"); + + Concept bmiDataConcept = mock(Concept.class); + ConceptName bmiConceptName = mock(ConceptName.class); + + when(conceptService.getConceptByName(bmiData)).thenReturn(bmiDataConcept); + when(bmiDataConcept.getName()).thenReturn(bmiConceptName); + when(bmiConceptName.getName()).thenReturn(bmiData); + + + Concept weightConcept = mock(Concept.class); + ConceptName weightConceptName = mock(ConceptName.class); + + when(conceptService.getConceptByName("Weight")).thenReturn(weightConcept); + + when(weightConcept.getName()).thenReturn(weightConceptName); + when(weightConceptName.getName()).thenReturn("Weight"); + ConceptDatatype conceptDatatype = mock(ConceptDatatype.class); + when(weightConcept.getDatatype()).thenReturn(conceptDatatype); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + csvObservationHelper.createObservations(observations, encounterDate, weightObsRow, bmiAndWeightConcepts); + + + assertEquals(1, observations.size()); + assertEquals(bmiData, observations.get(0).getConcept().getName()); + assertEquals(2, observations.get(0).getGroupMembers().size()); + EncounterTransaction.Observation heightObservation = observations.get(0).getGroupMembers().get(0); + assertEquals("Height", heightObservation.getConcept().getName()); + assertEquals("100", heightObservation.getValue()); + assertEquals(encounterDate, heightObservation.getObservationDateTime()); + EncounterTransaction.Observation weightObservation = observations.get(0).getGroupMembers().get(1); + assertEquals("Weight", weightObservation.getConcept().getName()); + assertEquals("150", weightObservation.getValue()); + assertEquals(encounterDate, weightObservation.getObservationDateTime()); + + } + + @Test + public void shouldCreateTwoHeightObsInBMIData() throws ParseException { + KeyValue heightObsRow = new KeyValue("BMI Data.Height", "100"); + KeyValue secondHeightObsRow = new KeyValue("BMI Data.Height", "200"); + String bmiData = "BMI Data"; + conceptNames.add(bmiData); + String height = "Height"; + conceptNames.add(height); + + List heightConcepts = new ArrayList<>(); + heightConcepts.add(bmiData); + heightConcepts.add(height); + + Concept bmiDataConcept = mock(Concept.class); + ConceptName bmiConceptName = mock(ConceptName.class); + + when(conceptService.getConceptByName(bmiData)).thenReturn(bmiDataConcept); + when(bmiDataConcept.getName()).thenReturn(bmiConceptName); + when(bmiConceptName.getName()).thenReturn(bmiData); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + csvObservationHelper.createObservations(observations, encounterDate, secondHeightObsRow, heightConcepts); + + assertEquals(1, observations.size()); + assertEquals(2, observations.get(0).getGroupMembers().size()); + EncounterTransaction.Observation heightObservation = observations.get(0).getGroupMembers().get(0); + assertEquals(height, heightObservation.getConcept().getName()); + EncounterTransaction.Observation secondHeightObservation = observations.get(0).getGroupMembers().get(1); + assertEquals(height, secondHeightObservation.getConcept().getName()); + assertEquals("100", heightObservation.getValue()); + assertEquals("200", secondHeightObservation.getValue()); + + } + + @Test + public void shouldCreateCodedHeightObservationForTheGivenObsRow() throws ParseException { + KeyValue heightObsRow = new KeyValue("Height", "tall"); + conceptNames.add("Height"); + Concept valueConcept = mock(Concept.class); + + when(conceptDatatype.isCoded()).thenReturn(true); + when(conceptService.getConceptsByName("tall")).thenReturn(asList(valueConcept)); + + ConceptName valueConceptName = mock(ConceptName.class); + when(valueConcept.getFullySpecifiedName(Matchers.any())).thenReturn(valueConceptName); + when(valueConcept.getName()).thenReturn(valueConceptName); + when(valueConceptName.getName()).thenReturn("tall"); + when(valueConcept.getUuid()).thenReturn("108abe5c-555e-40d2-ba16-5645a7ad237b"); + when(valueConcept.getName().getName()).thenReturn("tall"); + when(valueConcept.getName().getUuid()).thenReturn("108abe5c-555e-40d2-ba16-5645a7ad45237"); + + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + + assertEquals(1, observations.size()); + EncounterTransaction.Observation heightObservation = observations.get(0); + assertEquals("Height", heightObservation.getConcept().getName()); + assertEquals("108abe5c-555e-40d2-ba16-5645a7ad237b", (String) ((LinkedHashMap) heightObservation.getValue()).get("uuid")); + assertEquals("108abe5c-555e-40d2-ba16-5645a7ad45237", (String) ((HashMap) ((LinkedHashMap) heightObservation.getValue()).get("name")).get("uuid")); + assertEquals("tall", (String) ((HashMap) ((LinkedHashMap) heightObservation.getValue()).get("name")).get("name")); + assertEquals(encounterDate, heightObservation.getObservationDateTime()); + + } + + @Test + public void shouldThrowConceptNotFoundExceptionForInvalidCodedAnswer() throws ParseException { + KeyValue heightObsRow = new KeyValue("Height", "invalid-concept"); + conceptNames.add("Height"); + + when(conceptDatatype.isCoded()).thenReturn(true); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + + exception.expect(Exception.class); + exception.expectMessage("invalid-concept not found"); + + csvObservationHelper.createObservations(observations, encounterDate, heightObsRow, conceptNames); + + } + + @Test + public void shouldThrowExceptionIfDecimalValueisGivenForNumericConcept() { + ConceptNumeric bmiConcept = mock(ConceptNumeric.class); + when(bmiConcept.isNumeric()).thenReturn(true); + String bmi = "BMI"; + conceptNames.add(bmi); + + when(conceptService.getConceptByName(bmi)).thenReturn(bmiConcept); + ConceptName conceptName = new ConceptName(); + conceptName.setName(bmi); + when(bmiConcept.getName()).thenReturn(conceptName); + KeyValue csvHeightObs = new KeyValue(bmi, "1.34"); + + exception.expect(APIException.class); + exception.expectMessage("Decimal is not allowed for BMI concept"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + csvObservationHelper.verifyNumericConceptValue(csvHeightObs, conceptNames); + + } + + @Test + public void shouldReturnCSVHeaderPartsFromGivenObsRow() { + KeyValue csvObservation = new KeyValue(); + csvObservation.setKey("BMI Data.Height"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + List csvHeaderParts = csvObservationHelper.getCSVHeaderParts(csvObservation); + + assertEquals(csvHeaderParts.get(0), "BMI Data"); + assertEquals(csvHeaderParts.get(1), "Height"); + } + + @Test + public void shouldReturnEmptyListIfKeyIsEmpty() { + KeyValue csvObservation = new KeyValue(); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + List csvHeaderParts = csvObservationHelper.getCSVHeaderParts(csvObservation); + + assertTrue(csvHeaderParts.isEmpty()); + } + + @Test + public void shouldReturnTrueIfCSVObsIsOfForm1Type() { + KeyValue csvObservation = new KeyValue(); + csvObservation.setKey("BMI Data.Height"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + + assertTrue(csvObservationHelper.isForm1Type(csvObservation)); + } + + @Test + public void shouldReturnTrueIfCSVObsIsOfForm2TypeWithDefaultObsPathSplitter() { + KeyValue csvObservation = new KeyValue(); + csvObservation.setKey("Form2.BMI Data.Height"); + + when(administrationService.getGlobalProperty("bahmni.admin.csv.upload.obsPath.splitter")) + .thenReturn(""); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + + assertTrue(csvObservationHelper.isForm2Type(csvObservation)); + } + + @Test + public void shouldReturnTrueIfCSVObsIsOfForm2TypeWithConfiguredObsPathSplitter() { + KeyValue csvObservation = new KeyValue(); + csvObservation.setKey("Form2$BMI Data$Height"); + + when(administrationService.getGlobalProperty("bahmni.admin.csv.upload.obsPath.splitter")) + .thenReturn("$"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + + assertTrue(csvObservationHelper.isForm2Type(csvObservation)); + } + + @Test + public void shouldReturnLastItem() { + final List emptyList = Arrays.asList("Vitals", "Height"); + + assertEquals("Height", getLastItem(emptyList)); + } + + @Test + public void shouldThrowExceptionWhenEmptyItemsAreSent() { + exception.expectMessage("Empty items"); + + getLastItem(new ArrayList<>()); + + } + + @Test + public void shouldSplitCSVHeaderPartsBasedOnConfiguredValue() throws Exception { + String csvHeaderKey = "Vitals$BMI$Patient.Height"; + String value = "100"; + final KeyValue csvObservation = new KeyValue(csvHeaderKey, value); + + when(administrationService.getGlobalProperty("bahmni.admin.csv.upload.obsPath.splitter")) + .thenReturn("$"); + + final CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + + final List csvHeaderParts = csvObservationHelper.getCSVHeaderParts(csvObservation); + + assertEquals(3, csvHeaderParts.size()); + } + + @Test + public void shouldSplitCSVHeaderPartsWithDotIfNoValueIsConfigured() { + String csvHeaderKey = "Vitals.BMI.Patient.Height"; + String value = "100"; + final KeyValue csvObservation = new KeyValue(csvHeaderKey, value); + + when(administrationService.getGlobalProperty("bahmni.admin.csv.upload.obsPath.splitter")) + .thenReturn(""); + + final CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + + final List csvHeaderParts = csvObservationHelper.getCSVHeaderParts(csvObservation); + + assertEquals(4, csvHeaderParts.size()); + + } + + @Test + public void shouldCreateMultipleObservationsForTheGivenObsRowHavingMultiSelectConcept() throws ParseException { + KeyValue obs1 = new KeyValue("Height", "173"); + KeyValue obs2 = new KeyValue("Height", "174"); + conceptNames.add("Height"); + + CSVObservationHelper csvObservationHelper = new CSVObservationHelper(conceptService, administrationService); + Date encounterDate = new Date(); + csvObservationHelper.createObservations(observations, encounterDate, asList(obs1, obs2), conceptNames); + + + assertEquals(2, observations.size()); + EncounterTransaction.Observation heightObservation1 = observations.get(0); + assertEquals("Height", heightObservation1.getConcept().getName()); + assertEquals("173", heightObservation1.getValue()); + assertEquals(encounterDate, heightObservation1.getObservationDateTime()); + + EncounterTransaction.Observation heightObservation2 = observations.get(1); + assertEquals("Height", heightObservation2.getConcept().getName()); + assertEquals("174", heightObservation2.getValue()); + assertEquals(encounterDate, heightObservation2.getObservationDateTime()); + + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/observation/ConceptCacheTest.java b/admin/src/test/java/org/bahmni/module/admin/observation/ConceptCacheTest.java new file mode 100644 index 0000000000..808a81c99f --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/observation/ConceptCacheTest.java @@ -0,0 +1,47 @@ +package org.bahmni.module.admin.observation; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class ConceptCacheTest { + + + @Mock + private ConceptService conceptService; + + @Before + public void before() { + initMocks(this); + } + + @Test + public void shouldGetConceptByName() { + Concept expectedConcept = new Concept(); + String conceptName = "conceptName"; + when(conceptService.getConceptByName(conceptName)).thenReturn(expectedConcept); + + ConceptCache conceptCache = new ConceptCache(conceptService); + assertEquals(conceptCache.getConcept(conceptName), expectedConcept); + } + + @Test + public void shouldCacheConcepts() { + Concept expectedConcept = new Concept(); + String conceptName = "conceptName"; + when(conceptService.getConceptByName(conceptName)).thenReturn(expectedConcept); + + ConceptCache conceptCache = new ConceptCache(conceptService); + assertEquals(conceptCache.getConcept(conceptName), expectedConcept); + assertEquals(conceptCache.getConcept(conceptName), expectedConcept); + verify(conceptService, times(1)).getConceptByName(conceptName); + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/observation/DiagnosisMapperTest.java b/admin/src/test/java/org/bahmni/module/admin/observation/DiagnosisMapperTest.java new file mode 100644 index 0000000000..42e244fbfb --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/observation/DiagnosisMapperTest.java @@ -0,0 +1,79 @@ +package org.bahmni.module.admin.observation; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.util.Assert; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class}) +public class DiagnosisMapperTest { + + @Mock + private AdministrationService administrationService; + + @Mock + private UserContext userContext; + + @Before + public void setUp() { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + } + @Test + public void ignoreEmptyDiagnosis() throws ParseException { + List diagnosesKeyValues = Arrays.asList(new KeyValue("diagnosis", " ")); + + ConceptService mockConceptService = mock(ConceptService.class); + DiagnosisMapper diagnosisMapper = new DiagnosisMapper(mockConceptService); + + EncounterRow encounterRow = new EncounterRow(); + encounterRow.encounterDateTime = "2012-01-01"; + encounterRow.diagnosesRows = diagnosesKeyValues; + List bahmniDiagnosis = diagnosisMapper.getBahmniDiagnosis(encounterRow); + + Assert.isTrue(bahmniDiagnosis.isEmpty(), "Should ignore empty diagnoses"); + } + + @Test + public void diagnosisWithUnknownConcepts() throws ParseException { + List diagnosesKeyValues = Arrays.asList(new KeyValue("diagnosis", "ABCD")); + + ConceptService mockConceptService = mock(ConceptService.class); + when(mockConceptService.getConceptByName("diagnosis")).thenReturn(null); + DiagnosisMapper diagnosisMapper = new DiagnosisMapper(mockConceptService); + + EncounterRow encounterRow = new EncounterRow(); + encounterRow.encounterDateTime = "2012-01-01"; + encounterRow.diagnosesRows = diagnosesKeyValues; + List bahmniDiagnosis = diagnosisMapper.getBahmniDiagnosis(encounterRow); + + assertEquals(bahmniDiagnosis.size(), 1); + assertEquals(bahmniDiagnosis.get(0).getFreeTextAnswer(),"ABCD"); + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/observation/ObservationMapperIT.java b/admin/src/test/java/org/bahmni/module/admin/observation/ObservationMapperIT.java new file mode 100644 index 0000000000..d9d1979aa1 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/observation/ObservationMapperIT.java @@ -0,0 +1,82 @@ +package org.bahmni.module.admin.observation; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.BaseIntegrationTest; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +public class ObservationMapperIT extends BaseIntegrationTest { + + @Autowired + private ObservationMapper observationMapper; + + @Before + public void setUp() throws Exception { + executeDataSet("conceptSetup.xml"); + executeDataSet("form2DataSetup.xml"); + } + + @Test + public void shouldCreateForm1AndForm2Observations() throws ParseException { + List observation = Arrays.asList("Temperature", "100", "Vitals.1/2-0"); + List anotherObservation = Arrays.asList("Pulse", "150", null); + List> expectedObservations = Arrays.asList(observation, anotherObservation); + + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + + anEncounter.obsRows.add(new KeyValue("Pulse", "150")); + anEncounter.obsRows.add(new KeyValue("form2.Vitals.Section.Temperature", "100")); + anEncounter.encounterDateTime = "2019-09-19"; + + List> actualObservations = convertToList(observationMapper.getObservations(anEncounter)); + + assertEquals(2, actualObservations.size()); + assertTrue(actualObservations.containsAll(expectedObservations)); + } + + private List> convertToList(List observations) { + List> actualObservations = new ArrayList<>(); + observations + .forEach(obs -> + actualObservations.add(Arrays.asList(obs.getConcept().getName(), (String) obs.getValue(), obs.getFormFieldPath())) + ); + return actualObservations; + } + + @Test + public void shouldCreateForm2Observations() throws ParseException { + EncounterRow anEncounter = new EncounterRow(); + anEncounter.obsRows = new ArrayList<>(); + + anEncounter.obsRows.add(new KeyValue("form2.Form2EncountersTest.HIV Infection History.WHO Stage Conditions", "Asymptomatic|Herpes Zoster")); + anEncounter.encounterDateTime = "2019-09-19"; + + final List observations = observationMapper.getObservations(anEncounter, true); + + assertEquals(2, observations.size()); + + final EncounterTransaction.Observation multiSelectObs1 = observations.get(0); + assertEquals("WHO Stage Conditions", multiSelectObs1.getConcept().getName()); + assertEquals("Asymptomatic", multiSelectObs1.getValue()); + assertEquals("Form2EncountersTest.2/2-0", multiSelectObs1.getFormFieldPath()); + + final EncounterTransaction.Observation multiSelectObs2 = observations.get(1); + assertEquals("WHO Stage Conditions", multiSelectObs2.getConcept().getName()); + assertEquals("Herpes Zoster", multiSelectObs2.getValue()); + assertEquals("Form2EncountersTest.2/2-0", multiSelectObs2.getFormFieldPath()); + + } +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/observation/handler/Form1CSVObsHandlerTest.java b/admin/src/test/java/org/bahmni/module/admin/observation/handler/Form1CSVObsHandlerTest.java new file mode 100644 index 0000000000..9504b8e207 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/observation/handler/Form1CSVObsHandlerTest.java @@ -0,0 +1,109 @@ +package org.bahmni.module.admin.observation.handler; + + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.observation.CSVObservationHelper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.util.Date; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class}) +public class Form1CSVObsHandlerTest { + + private Form1CSVObsHandler form1CSVObsHandler; + + private CSVObservationHelper csvObservationHelper; + + @Mock + private AdministrationService administrationService; + + @Mock + private UserContext userContext; + + @Before + public void setUp() { + initMocks(this); + csvObservationHelper = mock(CSVObservationHelper.class); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + } + + @Test + public void shouldFilterForm1CSVObs() { + final KeyValue form1CSVObservation = new KeyValue("Vitals.Height", "100"); + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals.Height", "100"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form1CSVObservation, form2CSVObservation); + + when(csvObservationHelper.isForm1Type(form1CSVObservation)).thenReturn(true); + when(csvObservationHelper.isForm1Type(form2CSVObservation)).thenReturn(false); + + form1CSVObsHandler = new Form1CSVObsHandler(csvObservationHelper); + + final List form1CSVObs = form1CSVObsHandler.getRelatedCSVObs(encounterRow); + + assertEquals(1, form1CSVObs.size()); + assertEquals(form1CSVObservation, form1CSVObs.get(0)); + verify(csvObservationHelper).isForm1Type(form1CSVObservation); + verify(csvObservationHelper).isForm1Type(form2CSVObservation); + } + + @Test + public void shouldVerifyCreateObservationsIsCalledWhileHandlingObservations() throws ParseException { + final KeyValue form1CSVObservation = new KeyValue("Vitals.Height", "100"); + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals.Height", "100"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form1CSVObservation, form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm1Type(form1CSVObservation)).thenReturn(true); + when(csvObservationHelper.isForm1Type(form2CSVObservation)).thenReturn(false); + + final List conceptNames = asList("Vitals", "Height"); + when(csvObservationHelper.getCSVHeaderParts(form1CSVObservation)).thenReturn(conceptNames); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form1CSVObservation, conceptNames); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + + form1CSVObsHandler = new Form1CSVObsHandler(csvObservationHelper); + + form1CSVObsHandler.handle(encounterRow); + + verify(csvObservationHelper).isForm1Type(form1CSVObservation); + verify(csvObservationHelper).isForm1Type(form2CSVObservation); + verify(csvObservationHelper).getCSVHeaderParts(form1CSVObservation); + verify(csvObservationHelper).verifyNumericConceptValue(form1CSVObservation, conceptNames); + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + + } + +} \ No newline at end of file diff --git a/admin/src/test/java/org/bahmni/module/admin/observation/handler/Form2CSVObsHandlerTest.java b/admin/src/test/java/org/bahmni/module/admin/observation/handler/Form2CSVObsHandlerTest.java new file mode 100644 index 0000000000..092773f5a5 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/observation/handler/Form2CSVObsHandlerTest.java @@ -0,0 +1,390 @@ +package org.bahmni.module.admin.observation.handler; + +import org.bahmni.csv.KeyValue; +import org.bahmni.module.admin.csv.models.EncounterRow; +import org.bahmni.module.admin.csv.service.FormFieldPathGeneratorService; +import org.bahmni.module.admin.observation.CSVObservationHelper; +import org.bahmni.form2.service.FormFieldPathService; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.APIException; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Mockito.*; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest({CSVObservationHelper.class, Context.class}) +@RunWith(PowerMockRunner.class) +public class Form2CSVObsHandlerTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + private Form2CSVObsHandler form2CSVObsHandler; + private CSVObservationHelper csvObservationHelper; + private FormFieldPathService formFieldPathService; + private FormFieldPathGeneratorService formFieldPathGeneratorService; + + @Mock + private AdministrationService administrationService; + + @Mock + private UserContext userContext; + + @Before + public void setUp() { + initMocks(this); + csvObservationHelper = mock(CSVObservationHelper.class); + formFieldPathService = mock(FormFieldPathService.class); + formFieldPathGeneratorService = mock(FormFieldPathGeneratorService.class); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(eq("bahmni.admin.csv.upload.dateFormat"))).thenReturn("yyyy-M-d"); + } + + @Test + public void shouldFilterForm2CSVObs() { + final KeyValue form1CSVObservation = new KeyValue("Vitals.Height", "100"); + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals.Height", "100"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form1CSVObservation, form2CSVObservation); + + when(csvObservationHelper.isForm2Type(form1CSVObservation)).thenReturn(false); + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, null, null); + + final List form2CSVObs = form2CSVObsHandler.getRelatedCSVObs(encounterRow); + + assertEquals(1, form2CSVObs.size()); + assertEquals(form2CSVObservation, form2CSVObs.get(0)); + verify(csvObservationHelper).isForm2Type(form1CSVObservation); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + } + + @Test + public void shouldVerifyCreateObservationsIsCalled() throws ParseException { + final KeyValue form1CSVObservation = new KeyValue("Vitals.Height", "100"); + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals.Height", "100"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form1CSVObservation, form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form1CSVObservation)).thenReturn(false); + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Vitals", "Height")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + when(formFieldPathService.getFormFieldPath(asList("Vitals", "Height"))).thenReturn("Vitals.1/1-0"); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + form2CSVObsHandler.handle(encounterRow); + + verify(csvObservationHelper).isForm2Type(form1CSVObservation); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + verify(csvObservationHelper).getCSVHeaderParts(form2CSVObservation); + verify(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldVerifyCreateObservationIsNotCalledWhenAnEmptyValueIsGiven() throws ParseException { + final KeyValue form1CSVObservation = new KeyValue("Vitals.Height", "100"); + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals.Height", ""); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form1CSVObservation, form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form1CSVObservation)).thenReturn(false); + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + form2CSVObsHandler.handle(encounterRow); + + verify(csvObservationHelper).isForm2Type(form1CSVObservation); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + verify(csvObservationHelper, never()).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldThrowAPIExceptionIfNoConceptProvidedWithCSVHeader() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals", "100"); + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = singletonList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Vitals")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + expectedException.expect(APIException.class); + expectedException.expectMessage(format("No concepts found in %s", form2CSVObservation.getKey())); + + form2CSVObsHandler.handle(encounterRow); + } + + @Test + public void shouldCreateObsForMultiSelectConcept() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.HIV_History.PresentConditions", "Asymptomatic|Herpes Zoster"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + final List headerParts = new ArrayList<>(Arrays.asList("form2", "HIV_History", "PresentConditions")); + final List obsValues = new ArrayList<>(Arrays.asList("Asymptomatic", "Herpes Zoster")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + when(csvObservationHelper.getMultiSelectObs(form2CSVObservation)).thenReturn(obsValues); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + when(formFieldPathService.isMultiSelectObs(asList("HIV_History", "PresentConditions"))).thenReturn(true); + when(formFieldPathService.isValidCSVHeader(asList("HIV_History", "PresentConditions"))).thenReturn(true); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + form2CSVObsHandler.handle(encounterRow, true); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + verify(csvObservationHelper).getCSVHeaderParts(form2CSVObservation); + verify(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldCreateObsForAddmoreConcept() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.TB.Method of confirmation", "Smear|Hain test"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + final List headerParts = new ArrayList<>(Arrays.asList("form2", "TB", "Method of confirmation")); + final List obsValues = new ArrayList<>(Arrays.asList("Smear", "Hain test")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + when(csvObservationHelper.getMultiSelectObs(form2CSVObservation)).thenReturn(obsValues); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + when(formFieldPathService.isAddmore(asList("TB", "Method of confirmation"))).thenReturn(true); + when(formFieldPathService.isValidCSVHeader(asList("TB", "Method of confirmation"))).thenReturn(true); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + form2CSVObsHandler.handle(encounterRow, true); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + verify(csvObservationHelper).getCSVHeaderParts(form2CSVObservation); + verify(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldThrowAPIExceptionIfMandatoryObsIsEmpty() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.Vitals", ""); + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = singletonList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Vitals")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + when(formFieldPathService.isMandatory(asList("Vitals"))).thenReturn(true); + when(formFieldPathService.isValidCSVHeader(asList("Vitals"))).thenReturn(true); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + expectedException.expect(APIException.class); + expectedException.expectMessage("Empty value provided for mandatory field Vitals"); + + form2CSVObsHandler.handle(encounterRow, true); + } + + @Test + public void shouldThrowAPIExceptionIfFutureDateIsProvided() throws ParseException { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid("UUID"); + observation.setConcept(new EncounterTransaction.Concept()); + observation.setValue("2099-12-31"); + observation.getConcept().setDataType("Date"); + + final KeyValue form2CSVObservation = new KeyValue("form2.TB.Past Visit Date", "2099-12-31"); + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = singletonList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "TB", "Past Visit Date")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + when(formFieldPathService.isAllowFutureDates(asList("TB", "Past Visit Date"))).thenReturn(false); + when(formFieldPathService.isValidCSVHeader(asList("TB", "Past Visit Date"))).thenReturn(true); + + PowerMockito.mockStatic(CSVObservationHelper.class); + when(csvObservationHelper.getLastItem(anyListOf(EncounterTransaction.Observation.class))).thenReturn(observation); + when(csvObservationHelper.getLastItem(eq(asList("TB", "Past Visit Date")))).thenReturn("Past Visit Date"); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + expectedException.expect(APIException.class); + expectedException.expectMessage("Future date [2099-12-31] is not allowed for [Past Visit Date]"); + + form2CSVObsHandler.handle(encounterRow, true ); + + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldThrowAPIExceptionIfCSVHeaderIsInvalid() throws ParseException { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid("UUID"); + observation.setConcept(new EncounterTransaction.Concept()); + observation.setValue("2099-12-31"); + observation.getConcept().setDataType("Date"); + + final KeyValue form2CSVObservation = new KeyValue("form2.TB.Past Visit Date", "2099-12-31"); + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = singletonList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + final List headerParts = new ArrayList<>(Arrays.asList("form2", "TB", "Past Visit Date")); + when(csvObservationHelper.getCSVHeaderParts(form2CSVObservation)).thenReturn(headerParts); + when(formFieldPathService.isValidCSVHeader(asList("TB", "Past Visit Date"))).thenReturn(false); + + PowerMockito.mockStatic(CSVObservationHelper.class); + when(csvObservationHelper.getLastItem(anyListOf(EncounterTransaction.Observation.class))).thenReturn(observation); + when(csvObservationHelper.getLastItem(eq(asList("TB", "Past Visit Date")))).thenReturn("Past Visit Date"); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + expectedException.expect(APIException.class); + expectedException.expectMessage("No concepts found in form2.TB.Past Visit Date"); + + form2CSVObsHandler.handle(encounterRow, true ); + + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldCreateObsForAddmoreSection() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.Birth Details.Infant Details.Infant Gender?isJson=true", "{\"values\":[\"Male\", \"Female\"]}"); + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Birth Details", "Infant Details", "Infant Gender")); + when(csvObservationHelper.getCSVHeaderParts(any(KeyValue.class))).thenReturn(headerParts); + when(formFieldPathService.isValidCSVHeader(anyList())).thenReturn(true); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + form2CSVObsHandler.handle(encounterRow, true); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + verify(csvObservationHelper).getCSVHeaderParts(form2CSVObservation); + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldCreateMultiSelectObsForAddmoreSection() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.TB History.Past TB Treatment.Past TB Drug regimen?isJson=true", "{\"values\":[\"Ethambutol (E)|Isoniazid (H)\",\"Streptomycin (S)|Thioacetazone (T)\"]}"); + + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + final List headerParts = new ArrayList<>(Arrays.asList("form2", "TB History", "Past TB Treatment", "Past TB Drug regimen")); + when(csvObservationHelper.getCSVHeaderParts(any(KeyValue.class))).thenReturn(headerParts); + when(csvObservationHelper.getMultiSelectObsForJsonValue("Ethambutol (E)|Isoniazid (H)")).thenReturn(asList("Ethambutol (E)","Isoniazid (H)")); + when(csvObservationHelper.getMultiSelectObsForJsonValue("Streptomycin (S)|Thioacetazone (T)")).thenReturn(asList("Streptomycin (S)","Thioacetazone (T)")); + when(formFieldPathService.isValidCSVHeader(anyList())).thenReturn(true); + when(formFieldPathService.isMultiSelectObs(anyList())).thenReturn(true); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + form2CSVObsHandler.handle(encounterRow, true); + verify(csvObservationHelper).isForm2Type(form2CSVObservation); + verify(csvObservationHelper).getCSVHeaderParts(form2CSVObservation); + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + } + + @Test + public void shouldThrowAPIExceptionIfJsonValueisIsInvalid() throws ParseException { + final KeyValue form2CSVObservation = new KeyValue("form2.Birth Details.Infant Details.Infant Gender?isJson=true", "{INVALID JSON DATA}"); + final EncounterRow encounterRow = new EncounterRow(); + encounterRow.obsRows = asList(form2CSVObservation); + encounterRow.encounterDateTime = "2019-11-11"; + + when(csvObservationHelper.isForm2Type(form2CSVObservation)).thenReturn(true); + + final List headerParts = new ArrayList<>(Arrays.asList("form2", "Birth Details", "Infant Details", "Infant Gender")); + when(csvObservationHelper.getCSVHeaderParts(any(KeyValue.class))).thenReturn(headerParts); + when(formFieldPathService.isValidCSVHeader(anyList())).thenReturn(true); + doNothing().when(csvObservationHelper).verifyNumericConceptValue(form2CSVObservation, headerParts); + doNothing().when(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), anyListOf(KeyValue.class), anyListOf(String.class)); + + form2CSVObsHandler = new Form2CSVObsHandler(csvObservationHelper, formFieldPathService, formFieldPathGeneratorService); + + expectedException.expect(APIException.class); + expectedException.expectMessage("Error in parsing json value for form2.Birth Details.Infant Details.Infant Gender"); + + form2CSVObsHandler.handle(encounterRow, true ); + + verify(csvObservationHelper).createObservations(anyListOf(EncounterTransaction.Observation.class), + any(Date.class), any(KeyValue.class), anyListOf(String.class)); + } +} diff --git a/admin/src/test/java/org/bahmni/module/admin/retrospectiveEncounter/domain/DuplicateObservationsMatcherTest.java b/admin/src/test/java/org/bahmni/module/admin/retrospectiveEncounter/domain/DuplicateObservationsMatcherTest.java new file mode 100644 index 0000000000..12867894d6 --- /dev/null +++ b/admin/src/test/java/org/bahmni/module/admin/retrospectiveEncounter/domain/DuplicateObservationsMatcherTest.java @@ -0,0 +1,218 @@ +package org.bahmni.module.admin.retrospectiveEncounter.domain; + +import org.bahmni.module.admin.builder.BahmniObservationBuilder; +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.EncounterBuilder; +import org.bahmni.test.builder.ObsBuilder; +import org.bahmni.test.builder.VisitBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({DuplicateObservationsMatcher.class, LocaleUtility.class}) +public class DuplicateObservationsMatcherTest { + + public static final Date VISIT_START_DATETIME = new Date(); + public static final Date ENCOUNTER_DATE = new Date(); + private DuplicateObservationsMatcher duplicateObservationsMatcher; + + @Mock + private BahmniVisit bahmniVisit; + + @Mock + private Visit visit; + + @Before + public void setUp() throws Exception { + initMocks(this); + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + } + + @Test + public void shouldNotGetAnObservationIfItExistsInTheSameEncounter() throws Exception { + Concept heightConcept = new ConceptBuilder().withName("HEIGHT").build(); + Obs height = new ObsBuilder().withConcept(heightConcept).withValue(150.9).build(); + + Set allObs = new HashSet<>(); + allObs.add(height); + + Encounter encounter = new EncounterBuilder().withDatetime(ENCOUNTER_DATE).build(); + encounter.setObs(allObs); + + Visit existingVisit = new VisitBuilder().withEncounter(encounter).withStartDatetime(VISIT_START_DATETIME).build(); + + List bahmniObservations = new ArrayList<>(); + bahmniObservations.add(new BahmniObservationBuilder().withConcept("HEIGHT").withValue("150.9").withEncounterDate(ENCOUNTER_DATE).build()); + + List obsList = new ArrayList<>(); + obsList.addAll(allObs); + + when(bahmniVisit.obsFor("OPD")).thenReturn(obsList); + whenNew(BahmniVisit.class).withArguments(existingVisit).thenReturn(bahmniVisit); + duplicateObservationsMatcher = new DuplicateObservationsMatcher(existingVisit, "OPD"); + Collection newlyAddedBahmniObservations = duplicateObservationsMatcher.getNewlyAddedBahmniObservations(bahmniObservations, ENCOUNTER_DATE); + assertEquals(0, newlyAddedBahmniObservations.size()); + } + + @Test + public void shouldGetObservationIfItDoesNotExistInSameEncounter() throws Exception { + Concept weightConcept = new ConceptBuilder().withName("WEIGHT").withDataTypeNumeric().build(); + Obs weight = new ObsBuilder().withConcept(weightConcept).withValue(200.9).build(); + + Set allObs = new HashSet<>(); + allObs.add(weight); + + Encounter encounter = new EncounterBuilder().withDatetime(ENCOUNTER_DATE).build(); + encounter.setObs(allObs); + + Visit existingVisit = new VisitBuilder().withEncounter(encounter).withStartDatetime(VISIT_START_DATETIME).build(); + + List bahmniObservations = new ArrayList<>(); + bahmniObservations.add(new BahmniObservationBuilder().withConcept("HEIGHT").withValue("150.9").withEncounterDate(ENCOUNTER_DATE).build()); + + List obsList = new ArrayList<>(); + obsList.addAll(allObs); + + when(bahmniVisit.obsFor("OPD")).thenReturn(obsList); + whenNew(BahmniVisit.class).withArguments(existingVisit).thenReturn(bahmniVisit); + + duplicateObservationsMatcher = new DuplicateObservationsMatcher(existingVisit, "OPD"); + Collection newlyAddedBahmniObservations = duplicateObservationsMatcher.getNewlyAddedBahmniObservations(bahmniObservations, ENCOUNTER_DATE); + + assertEquals(1, newlyAddedBahmniObservations.size()); + } + + @Test + public void shouldGetObservationIfSameObservationExistsInDifferentEncounter() throws Exception { + Concept weightConcept = new ConceptBuilder().withName("WEIGHT").build(); + Obs weight = new ObsBuilder().withConcept(weightConcept).withValue(200.9).build(); + + Set allObs = new HashSet<>(); + allObs.add(weight); + + Encounter encounter = new EncounterBuilder().withDatetime(ENCOUNTER_DATE).build(); + encounter.setObs(allObs); + + Visit existingVisit = new VisitBuilder().withEncounter(encounter).withStartDatetime(VISIT_START_DATETIME).build(); + + List bahmniObservations = new ArrayList<>(); + Date newEncounterDate = new Date(); + bahmniObservations.add(new BahmniObservationBuilder().withConcept("WEIGHT").withValue("200.9").withEncounterDate(newEncounterDate).build()); + + List obsList = new ArrayList<>(); + obsList.addAll(allObs); + + when(bahmniVisit.obsFor("OPD")).thenReturn(obsList); + whenNew(BahmniVisit.class).withArguments(existingVisit).thenReturn(bahmniVisit); + + duplicateObservationsMatcher = new DuplicateObservationsMatcher(existingVisit, "OPD"); + Collection newlyAddedBahmniObservations = duplicateObservationsMatcher.getNewlyAddedBahmniObservations(bahmniObservations, newEncounterDate); + + assertEquals(1, newlyAddedBahmniObservations.size()); + } + + @Test + public void shouldGetObservationIfDifferentObservationExistsInDifferentEncounter() throws Exception { + Concept weightConcept = new ConceptBuilder().withName("WEIGHT").build(); + Obs weight = new ObsBuilder().withConcept(weightConcept).withValue(200.9).build(); + + Set allObs = new HashSet<>(); + allObs.add(weight); + + Encounter encounter = new EncounterBuilder().withDatetime(ENCOUNTER_DATE).build(); + encounter.setObs(allObs); + + Visit existingVisit = new VisitBuilder().withEncounter(encounter).withStartDatetime(VISIT_START_DATETIME).build(); + + List bahmniObservations = new ArrayList<>(); + Date newEncounterDate = new Date(); + bahmniObservations.add(new BahmniObservationBuilder().withConcept("HEIGHT").withValue("200.9").withEncounterDate(newEncounterDate).build()); + + List obsList = new ArrayList<>(); + obsList.addAll(allObs); + + when(bahmniVisit.obsFor("OPD")).thenReturn(obsList); + whenNew(BahmniVisit.class).withArguments(existingVisit).thenReturn(bahmniVisit); + + duplicateObservationsMatcher = new DuplicateObservationsMatcher(existingVisit, "OPD"); + Collection newlyAddedBahmniObservations = duplicateObservationsMatcher.getNewlyAddedBahmniObservations(bahmniObservations, newEncounterDate); + + assertEquals(1, newlyAddedBahmniObservations.size()); + } + + @Test + public void shouldNotGetObservationIfDifferentObservationWithSameRootExistsInSameEncounter() throws Exception { + Concept heightConcept = new ConceptBuilder().withName("HEIGHT").withDataTypeNumeric().build(); + Obs heightObs = new ObsBuilder().withValue(150.0).withConcept(heightConcept).build(); + + Concept vitalConcept = new ConceptBuilder().withName("Vitals").build(); + Obs vitalObs = new ObsBuilder().withConcept(vitalConcept).withGroupMembers(heightObs).build(); + + Set allObs = new HashSet<>(); + allObs.add(vitalObs); + + Encounter encounter = new EncounterBuilder().withDatetime(ENCOUNTER_DATE).build(); + encounter.setObs(allObs); + + Visit existingVisit = new VisitBuilder().withEncounter(encounter).withStartDatetime(VISIT_START_DATETIME).build(); + + List bahmniObservations = new ArrayList<>(); + BahmniObservation weightObs = new BahmniObservationBuilder().withConcept("WEIGHT").withValue("190").withEncounterDate(ENCOUNTER_DATE).build(); + bahmniObservations.add(new BahmniObservationBuilder().withConcept("Vitals").withSetMember(weightObs).withEncounterDate(ENCOUNTER_DATE).build()); + + List obsList = new ArrayList<>(); + obsList.addAll(allObs); + + when(bahmniVisit.obsFor("OPD")).thenReturn(obsList); + whenNew(BahmniVisit.class).withArguments(existingVisit).thenReturn(bahmniVisit); + + duplicateObservationsMatcher = new DuplicateObservationsMatcher(existingVisit, "OPD"); + Collection newlyAddedBahmniObservations = duplicateObservationsMatcher.getNewlyAddedBahmniObservations(bahmniObservations, ENCOUNTER_DATE); + + assertEquals(0, newlyAddedBahmniObservations.size()); + } + + @Test + public void shouldIgnoreDuplicateObservationMatchingForFreeTextDiagnosisRequest() throws Exception { + + whenNew(BahmniVisit.class).withArguments(visit).thenReturn(bahmniVisit); + when(bahmniVisit.obsFor("OPD")).thenReturn(new ArrayList()); + List requests = new ArrayList<>(); + BahmniDiagnosisRequest request = new BahmniDiagnosisRequest(); + request.setCodedAnswer(null); + request.setFreeTextAnswer("Some Non-coded concept"); + requests.add(request); + + duplicateObservationsMatcher = new DuplicateObservationsMatcher(visit, "OPD"); + requests = duplicateObservationsMatcher.getUniqueDiagnoses(requests); + + assertEquals(1,requests.size()); + + } +} diff --git a/admin/src/test/resources/Form2Encounters.json b/admin/src/test/resources/Form2Encounters.json new file mode 100644 index 0000000000..a346d8de98 --- /dev/null +++ b/admin/src/test/resources/Form2Encounters.json @@ -0,0 +1,82 @@ +{ + "name": "Form2EncountersTest", + "id": 2, + "uuid": "47a3e6b8-0d5c-44ba-82b9-1ecfe5ae0803", + "defaultLocale": "en", + "controls": [ + { + "type": "section", + "label": { + "translationKey": "SECTION_1", + "type": "label", + "value": "HIV Infection History", + "id": "1" + }, + "properties": { + "addMore": false, + "location": { + "column": 0, + "row": 0 + } + }, + "id": "1", + "controls": [ + { + "type": "obsControl", + "label": { + "translationKey": "WHO_STAGE_CONDITIONS_2", + "id": "2", + "units": "", + "type": "label", + "value": "WHO Stage Conditions" + }, + "properties": { + "mandatory": true, + "notes": false, + "addMore": false, + "hideLabel": false, + "controlEvent": false, + "location": { + "column": 0, + "row": 1 + }, + "autoComplete": false, + "multiSelect": true, + "dropDown": false + }, + "id": "2", + "concept": { + "name": "WHO Stage Conditions", + "uuid": "c6fb0220-45d0-47b4-8390-8c43f7baabb8", + "datatype": "Coded", + "conceptClass": "Misc", + "conceptHandler": null, + "answers": [ + { + "uuid": "a36e5810-d096-42e3-a96e-795da3a1d052", + "name": { + "display": "Asymptomatic", + "uuid": "4f1a0c32-f4ce-421d-bf32-d5d174b27274", + "name": "Asymptomatic", + "locale": "en" + }, + "translationKey": "ASYMPTOMATIC_2" + }, + { + "uuid": "0b6c0cfb-141e-4ae2-a9de-384723ba158c", + "name": { + "display": "Herpes Zoster", + "uuid": "62097855-a54e-4b50-8dea-69085f10815c", + "name": "Herpes Zoster" + }, + "translationKey": "HERPES_2" + } + ] + } + } + ] + } + ], + "events": {}, + "translationsUrl": "/openmrs/ws/rest/v1/bahmniie/form/translations" +} \ No newline at end of file diff --git a/admin/src/test/resources/TestingApplicationContext.xml b/admin/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..4542d4fbe6 --- /dev/null +++ b/admin/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,24 @@ + + + + + + + classpath:hibernate.cfg.xml + classpath:test-hibernate.cfg.xml + + + + + + + + org.openmrs + + + + + diff --git a/admin/src/test/resources/Vitals_1.json b/admin/src/test/resources/Vitals_1.json new file mode 100644 index 0000000000..2726ca5ed6 --- /dev/null +++ b/admin/src/test/resources/Vitals_1.json @@ -0,0 +1,126 @@ +{ + "name": "Vitals", + "id": 4, + "uuid": "ca539cb4-f469-4c45-8d7f-f1652d8dd99a", + "defaultLocale": "en", + "controls": [ + { + "type": "section", + "label": { + "translationKey": "SECTION_1", + "type": "label", + "value": "Section", + "id": "1" + }, + "properties": { + "addMore": false, + "location": { + "column": 0, + "row": 0 + } + }, + "id": "1", + "controls": [ + { + "type": "obsControl", + "label": { + "translationKey": "TEMPERATURE_2", + "id": "2", + "units": "", + "type": "label", + "value": "Temperature" + }, + "properties": { + "mandatory": false, + "notes": false, + "addMore": false, + "hideLabel": false, + "controlEvent": false, + "location": { + "column": 0, + "row": 0 + }, + "abnormal": false + }, + "id": "2", + "concept": { + "name": "Temperature", + "uuid": "5090AAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "datatype": "Numeric", + "conceptClass": "Misc", + "conceptHandler": null, + "answers": [], + "properties": { + "allowDecimal": false + } + }, + "units": null, + "hiNormal": null, + "lowNormal": null, + "hiAbsolute": null, + "lowAbsolute": null + } + ] + }, + { + "type": "section", + "label": { + "translationKey": "SECTION_1", + "type": "label", + "value": "Section1", + "id": "3" + }, + "properties": { + "addMore": false, + "location": { + "column": 0, + "row": 1 + } + }, + "id": "3", + "controls": [ + { + "type": "obsControl", + "label": { + "translationKey": "PULSE_4", + "id": "4", + "units": "", + "type": "label", + "value": "Pulse" + }, + "properties": { + "mandatory": false, + "notes": false, + "addMore": false, + "hideLabel": false, + "controlEvent": false, + "location": { + "column": 0, + "row": 0 + }, + "abnormal": false + }, + "id": "4", + "concept": { + "name": "Pulse", + "uuid": "5089AAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "datatype": "Text", + "conceptClass": "Misc", + "conceptHandler": null, + "answers": [], + "properties": { + "allowDecimal": false + } + }, + "units": null, + "hiNormal": null, + "lowNormal": null, + "hiAbsolute": null, + "lowAbsolute": null + } + ] + } + ], + "events": {}, + "translationsUrl": "/openmrs/ws/rest/v1/bahmniie/form/translations" +} \ No newline at end of file diff --git a/admin/src/test/resources/baseMetaData.xml b/admin/src/test/resources/baseMetaData.xml new file mode 100644 index 0000000000..0207f65151 --- /dev/null +++ b/admin/src/test/resources/baseMetaData.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/admin/src/test/resources/conceptExportSetup.xml b/admin/src/test/resources/conceptExportSetup.xml new file mode 100644 index 0000000000..a846beb44e --- /dev/null +++ b/admin/src/test/resources/conceptExportSetup.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/src/test/resources/conceptReferenceTerm.xml b/admin/src/test/resources/conceptReferenceTerm.xml new file mode 100644 index 0000000000..ecf469f0e5 --- /dev/null +++ b/admin/src/test/resources/conceptReferenceTerm.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/admin/src/test/resources/conceptSetup.xml b/admin/src/test/resources/conceptSetup.xml new file mode 100644 index 0000000000..293b5f8597 --- /dev/null +++ b/admin/src/test/resources/conceptSetup.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/src/test/resources/concept_import.csv b/admin/src/test/resources/concept_import.csv new file mode 100644 index 0000000000..db387f1ebd --- /dev/null +++ b/admin/src/test/resources/concept_import.csv @@ -0,0 +1 @@ +name,shortname,Synonym.1,description,class,datatype,reference-term-source,reference-term-code,reference-term-relationship \ No newline at end of file diff --git a/admin/src/test/resources/concept_set_import.csv b/admin/src/test/resources/concept_set_import.csv new file mode 100644 index 0000000000..0742f64207 --- /dev/null +++ b/admin/src/test/resources/concept_set_import.csv @@ -0,0 +1 @@ +name,shortname,description,class,Reference-term-source,Reference-term-code,Reference-term-relationship,Child.1,Child.2 diff --git a/admin/src/test/resources/dataSetup.xml b/admin/src/test/resources/dataSetup.xml new file mode 100644 index 0000000000..37f10b501e --- /dev/null +++ b/admin/src/test/resources/dataSetup.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/src/test/resources/diagnosisMetaData.xml b/admin/src/test/resources/diagnosisMetaData.xml new file mode 100644 index 0000000000..343e1129d0 --- /dev/null +++ b/admin/src/test/resources/diagnosisMetaData.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/src/test/resources/dispositionMetaData.xml b/admin/src/test/resources/dispositionMetaData.xml new file mode 100644 index 0000000000..6497f136bf --- /dev/null +++ b/admin/src/test/resources/dispositionMetaData.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/src/test/resources/form2DataSetup.xml b/admin/src/test/resources/form2DataSetup.xml new file mode 100644 index 0000000000..2ccb75e2db --- /dev/null +++ b/admin/src/test/resources/form2DataSetup.xml @@ -0,0 +1,20 @@ + + + + + +
+ + + + + + \ No newline at end of file diff --git a/admin/src/test/resources/labResult.xml b/admin/src/test/resources/labResult.xml new file mode 100644 index 0000000000..064f9c81f2 --- /dev/null +++ b/admin/src/test/resources/labResult.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/src/test/resources/labResultMetaData.xml b/admin/src/test/resources/labResultMetaData.xml new file mode 100644 index 0000000000..2c4f9155ad --- /dev/null +++ b/admin/src/test/resources/labResultMetaData.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/src/test/resources/patientMatchingAlgorithm/GANIdentifier.groovy b/admin/src/test/resources/patientMatchingAlgorithm/GANIdentifier.groovy new file mode 100644 index 0000000000..37cb4d4012 --- /dev/null +++ b/admin/src/test/resources/patientMatchingAlgorithm/GANIdentifier.groovy @@ -0,0 +1,17 @@ +package patientMatchingAlgorithm; + +import org.bahmni.module.admin.csv.patientmatchingalgorithm.PatientMatchingAlgorithm +import org.openmrs.Patient; + + +public class GANIdentifier extends PatientMatchingAlgorithm { + @Override + Patient run(List patientList, List patientAttributes) { + for (Patient patient : patientList) { + if (patient.getPatientIdentifier().getIdentifier().contains("GAN")) { + return patient; + } + } + return null; + } +} \ No newline at end of file diff --git a/admin/src/test/resources/patientMatchingAlgorithm/IdAndNameMatch.groovy b/admin/src/test/resources/patientMatchingAlgorithm/IdAndNameMatch.groovy new file mode 100644 index 0000000000..387ed27209 --- /dev/null +++ b/admin/src/test/resources/patientMatchingAlgorithm/IdAndNameMatch.groovy @@ -0,0 +1,28 @@ +package patientMatchingAlgorithm + +import org.bahmni.csv.KeyValue +import org.bahmni.module.admin.csv.patientmatchingalgorithm.PatientMatchingAlgorithm +import org.openmrs.Patient + +public class IdAndNameMatch extends PatientMatchingAlgorithm{ + @Override + Patient run(List patientList, List patientAttributes) { + String patientNameToMatch = getPatientGivenName(patientAttributes) + + for (Patient patient : patientList) { + if (patient.getPatientIdentifier().getIdentifier().contains("GAN") && patient.getGivenName().equals(patientNameToMatch)) { + return patient; + } + } + return null; + } + + private String getPatientGivenName(List patientAttributes) { + for (KeyValue patientAttribute : patientAttributes) { + if(patientAttribute.getKey().equals("given_name")){ + return patientAttribute.getValue(); + } + } + return null; + } +} \ No newline at end of file diff --git a/admin/src/test/resources/patientMatchingAlgorithm/MultipleMatchPatient.groovy b/admin/src/test/resources/patientMatchingAlgorithm/MultipleMatchPatient.groovy new file mode 100644 index 0000000000..c4b11fef74 --- /dev/null +++ b/admin/src/test/resources/patientMatchingAlgorithm/MultipleMatchPatient.groovy @@ -0,0 +1,10 @@ +import org.bahmni.module.admin.csv.patientmatchingalgorithm.PatientMatchingAlgorithm +import org.bahmni.module.admin.csv.patientmatchingalgorithm.exception.CannotMatchPatientException +import org.openmrs.Patient + +public class MultipleMatchPatient extends PatientMatchingAlgorithm { + @Override + Patient run(List patientList, List patientAttributes) { + throw new CannotMatchPatientException(patientList); + } +} \ No newline at end of file diff --git a/admin/src/test/resources/patientMatchingAlgorithm/NoMatch.groovy b/admin/src/test/resources/patientMatchingAlgorithm/NoMatch.groovy new file mode 100644 index 0000000000..c2609af936 --- /dev/null +++ b/admin/src/test/resources/patientMatchingAlgorithm/NoMatch.groovy @@ -0,0 +1,14 @@ +package patientMatchingAlgorithm; + +import org.bahmni.module.admin.csv.patientmatchingalgorithm.PatientMatchingAlgorithm +import org.openmrs.Patient; + + +public class NoMatch extends PatientMatchingAlgorithm{ + + + @Override + Patient run(List patientList, List patientAttributes) { + return null + } +} \ No newline at end of file diff --git a/admin/src/test/resources/programSample.csv b/admin/src/test/resources/programSample.csv new file mode 100644 index 0000000000..25659d9154 --- /dev/null +++ b/admin/src/test/resources/programSample.csv @@ -0,0 +1,2 @@ +Sr. No.,Registration Number,Patient.Name,Patient.Husbands / Fathers name in full,Patient.AGE,Patient.Gender,Patient.Caste,Patient.Category,Patient.Occupation,Patient.Village,Program,EnrollmentDate +1,GAN200000,Dummy,Gayaram,50,M,Mehar,SC,,Achanakmar,"DIABETES PROGRAM",15-10-2012 \ No newline at end of file diff --git a/admin/src/test/resources/reference-term-source.csv b/admin/src/test/resources/reference-term-source.csv new file mode 100644 index 0000000000..a17e01a972 --- /dev/null +++ b/admin/src/test/resources/reference-term-source.csv @@ -0,0 +1 @@ +Reference-term-code,Reference-term-name,Reference-term-source diff --git a/admin/src/test/resources/relationshipDataSetup.xml b/admin/src/test/resources/relationshipDataSetup.xml new file mode 100644 index 0000000000..77cb93e738 --- /dev/null +++ b/admin/src/test/resources/relationshipDataSetup.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/admin/src/test/resources/sample.csv b/admin/src/test/resources/sample.csv new file mode 100644 index 0000000000..d2bf5bf473 --- /dev/null +++ b/admin/src/test/resources/sample.csv @@ -0,0 +1 @@ +Sr. No.,Registration Number,encounterType,visitType,Patient.Name,Patient.Husbands / Fathers name in full,Patient.AGE,Patient.Gender,Patient.Caste,Patient.Category,Patient.Occupation,Patient.Village,Patient.Cluster,Patient.Block,Repeat.1.EncounterDate,Repeat.1.Diagnosis.diagnosis1,Repeat.1.Obs.Weight,Repeat.1.Obs.Height,Repeat.2.EncounterDate,Repeat.2.Obs.Weight,Repeat.2.Obs.Height 1,6424,Consultation,OPD,Ganesh ram Mehar,Gayaram,50,M,Mehar,SC,,Achanakmar,4,,26-10-2012,"Diabetes, Type 1",51.75,,19-6-2013,48.7, \ No newline at end of file diff --git a/admin/src/test/resources/test-hibernate.cfg.xml b/admin/src/test/resources/test-hibernate.cfg.xml new file mode 100644 index 0000000000..de80c9c44a --- /dev/null +++ b/admin/src/test/resources/test-hibernate.cfg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/admin/src/test/resources/trial.csv b/admin/src/test/resources/trial.csv new file mode 100644 index 0000000000..63af6a0aec --- /dev/null +++ b/admin/src/test/resources/trial.csv @@ -0,0 +1,11 @@ +serialNumber,Registration Date,Patient.registrationNumber,Patient.name,Patient.age,Patient.gender,Patient.village,Patient.tehsil,Patient.district,Obs.HEIGHT,Obs.WEIGHT,Obs.BMI,Diagnsois.diagnosis +1,01/01/2014,200000,Anad xxx Kewat,49,M,Bharni,Takhatpur,Bilaspur,157,43,,2 +2,01/01/2014,200001,ram milan xxxx,62,M,devrikala,pendra,Bilaspur,159,53.5,,2 +3,01/01/2014,200002,shanti xxxx,65,F,manikpur,samnapur,Dindouri,148,55,,2 +4,03/01/2014,200003,shatruhan singh xxxx,53,M,sakari,Takhatpur,Bilaspur,165,50.4,,2 +5,03/01/2014,200004,Sharda bai xxxx,62,F,soniyamar,dindouri,Dindouri,152,41.2,,2 +6,06/01/2014,200005,Itwariya bai xxxx,65,F,kaswahi,jaitpur,Shahdol,140,31.3,,2 +7,06/01/2014,200006,dinesh kumar xxxx,42,M,hardi,janjgir,janjgir,162,55.2,,2 +8,20/12/2013,200007,urmila bai xxxx,55,F,kanwahi,jaitpur,Shahdol,150,38.4,,2 +9,13/01/2014,200008,prema bai xxxx,48,F,sodhi,mungelli,Bilaspur,153,37.6,,2 +10,13/01/2014,200009,tulsiya bai xxxx,70,F,naraud,marwahi,Bilaspur,153,38.5,,2 \ No newline at end of file diff --git a/admin/src/test/resources/visitAttributeDataSet.xml b/admin/src/test/resources/visitAttributeDataSet.xml new file mode 100644 index 0000000000..9a3a3bf17d --- /dev/null +++ b/admin/src/test/resources/visitAttributeDataSet.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml deleted file mode 100644 index 1c92ba6757..0000000000 --- a/api/pom.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - 4.0.0 - - org.raxa.module - raxacore - 0.2-SNAPSHOT - - raxacore-api - jar - RaxaEMR Core API - API project for RaxaEMR Core Module - - - - org.openmrs.api - openmrs-api - jar - - - org.openmrs.web - openmrs-web - jar - - - org.openmrs.api - openmrs-api - test-jar - test - - - org.openmrs.web - openmrs-web - test-jar - test - - - org.openmrs.test - openmrs-test - pom - test - - - - - - - src/main/resources - true - - - - - - src/test/resources - true - - - - - com.googlecode.maven-java-formatter-plugin - maven-java-formatter-plugin - - - - format - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - com.googlecode.maven-java-formatter-plugin - - - maven-java-formatter-plugin - - - [0.3.1,) - - - format - - - - - - - - - - - - - - - diff --git a/api/src/main/java/org/raxa/module/raxacore/Activator.java b/api/src/main/java/org/raxa/module/raxacore/Activator.java deleted file mode 100644 index 8d93ec83c6..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/Activator.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.module.BaseModuleActivator; -import org.openmrs.module.ModuleActivator; - -/** - * {@link ModuleActivator} for the raxacore module - */ -public class Activator extends BaseModuleActivator { - - private Log log = LogFactory.getLog(this.getClass()); - - @Override - public void started() { - log.info("Started the RaxaEMR Core module"); - } - - @Override - public void stopped() { - log.info("Stopped the RaxaEMR Core module"); - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugGroup.java b/api/src/main/java/org/raxa/module/raxacore/DrugGroup.java deleted file mode 100644 index f9eeba458c..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugGroup.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.io.Serializable; -import java.util.Set; -import java.util.HashSet; -import org.openmrs.BaseOpenmrsMetadata; -import org.openmrs.Drug; - -/** - * PatientList stores the data needed to lists patients for registration, - * screener, etc. - */ -public class DrugGroup extends BaseOpenmrsMetadata implements Serializable { - - private Integer id; - - private Set drugs = new HashSet(0); - - public DrugGroup() { - } - - /** - * Sets id - * - * @param id: id to set - */ - @Override - public void setId(Integer id) { - this.id = id; - } - - /** - * Gets id - * - * @return the patientListId - */ - @Override - public Integer getId() { - return id; - } - - /** - * @return the drugs - */ - public Set getDrugs() { - return drugs; - } - - /** - * @param drugs the drugs to set - */ - public void setDrugs(Set drugs) { - this.drugs = drugs; - } - - /** - * Compares two PatientList objects for similarity - * - * @param obj PatientList object to compare to - * @return boolean true/false whether or not they are the same objects - * @see java.lang.Object#equals(java.lang.Object) @should equal PatientList - * with same patientListId @should not equal PatientList with different - * patientListId @should not equal on null @should have equal patientList - * objects with no patientListIds @should not have equal PatientList objects - * when one has null patientListId - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof DrugGroup) { - DrugGroup pList = (DrugGroup) obj; - if (this.getId() != null && pList.getId() != null) { - return (this.getId().equals(pList.getId())); - } - } - return this == obj; - } - - /** - * @see java.lang.Object#hashCode() @should have same hashcode when equal - * @should have different hash code when not equal @should get hash code - * with null attributes - */ - @Override - public int hashCode() { - if (this.getId() == null) { - return super.hashCode(); - } - return this.getId().hashCode(); - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugGroupService.java b/api/src/main/java/org/raxa/module/raxacore/DrugGroupService.java deleted file mode 100644 index 31516d6c16..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugGroupService.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.Drug; -import org.openmrs.annotation.Authorized; -import org.openmrs.api.OpenmrsService; -import org.openmrs.util.PrivilegeConstants; -import org.raxa.module.raxacore.db.DrugGroupDAO; -import org.springframework.transaction.annotation.Transactional; - -/* - * Interface for interacting with the DrugGroup - */ -@Transactional -public interface DrugGroupService extends OpenmrsService { - - /** - * Sets Drug Group DAO - * - * @param dao - */ - public void setDrugGroupDAO(DrugGroupDAO dao); - - /** - * Saves DrugGroup - * - * @param drugGroup - * @return DrugGroup - */ - @Authorized( { "Add Drug Groups" }) - public DrugGroup saveDrugGroup(DrugGroup drugGroup); - - /** - * Gets a DrugGroup by Id - * - * @param id - * @return DrugGroups - */ - @Authorized( { "View Drug Groups" }) - public DrugGroup getDrugGroup(Integer id); - - /** - * Gets a DrugGroup by Name - * - * @param name - * @return list of DrugGroups - */ - @Authorized( { "View Drug Groups" }) - public List getDrugGroupByName(String name); - - /** - * Gets DrugGroup by uuid - * - * @param uuid - * @return DrugGroup - */ - @Authorized( { "View Drug Groups" }) - public DrugGroup getDrugGroupByUuid(String uuid); - - /** - * Gets all DrugGroups - * - * @return list of DrugGroups - */ - @Authorized( { "View Drug Groups" }) - public List getAllDrugGroup(boolean includeRetired); - - /** - * Updates DrugGroup - * - * @param DrugGroup - * @return DrugGroup - */ - @Authorized( { "Edit Drug Groups" }) - DrugGroup updateDrugGroup(DrugGroup drugGroup); - - /** - * Deletes DrugGroup - * - * @param DrugGroup - */ - @Authorized( { "Delete Drug Groups" }) - public void deleteDrugGroup(DrugGroup drugGroup); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugInfo.java b/api/src/main/java/org/raxa/module/raxacore/DrugInfo.java deleted file mode 100644 index 996c3202e5..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugInfo.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.io.Serializable; -import org.openmrs.BaseOpenmrsMetadata; -import org.openmrs.Drug; - -/** - * DrugInfo stores the data needed to lists patients for registration, screener, - * etc. - */ -public class DrugInfo extends BaseOpenmrsMetadata implements Serializable { - - private Integer id; - - private Integer drugId; - - private Drug drug; - - private double price; - - private double cost; - - private String shortName; - - private String brandName; - - private String supplier; - - private String manufacturer; - - private Integer reorderLevel; - - private String note; - - public DrugInfo() { - } - - /** - * Sets id - * - * @param id: id to set - */ - @Override - public void setId(Integer id) { - this.id = id; - } - - /** - * Gets id - * - * @return the drugInfoId - */ - @Override - public Integer getId() { - return id; - } - - /** - * Compares two DrugInfo objects for similarity - * - * @param obj DrugInfo object to compare to - * @return boolean true/false whether or not they are the same objects - * @see java.lang.Object#equals(java.lang.Object) - * @should equal DrugInfo with same drugInfoId - * @should not equal DrugInfo with different drugInfoId - * @should not equal on null - * @should have equal drugInfo objects with no drugInfoIds - * @should not have equal DrugInfo objects when one has null drugInfoId - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof DrugInfo) { - DrugInfo pList = (DrugInfo) obj; - if (this.getId() != null && pList.getId() != null) { - return (this.getId().equals(pList.getId())); - } - } - return this == obj; - } - - /** - * @see java.lang.Object#hashCode() - * @should have same hashcode when equal - * @should have different hash code when not equal - * @should get hash code with null attributes - */ - @Override - public int hashCode() { - if (this.getId() == null) { - return super.hashCode(); - } - return this.getId().hashCode(); - } - - /** - * @return the drug - */ - public Drug getDrug() { - return drug; - } - - /** - * @param drug the drug to set - */ - public void setDrug(Drug drug) { - this.drug = drug; - } - - /** - * @return the price - */ - public double getPrice() { - return price; - } - - /** - * @param price the price to set - */ - public void setPrice(double price) { - this.price = price; - } - - /** - * @return the cost - */ - public double getCost() { - return cost; - } - - /** - * @param cost the cost to set - */ - public void setCost(double cost) { - this.cost = cost; - } - - /** - * @return the note - */ - public String getNote() { - return note; - } - - /** - * @param note the note to set - */ - public void setNote(String note) { - this.note = note; - } - - /** - * @return the drugId - */ - public Integer getDrugId() { - return drugId; - } - - /** - * @param drugId the drugId to set - */ - public void setDrugId(Integer drugId) { - this.drugId = drugId; - } - - /** - * @return the shortName - */ - public String getShortName() { - return shortName; - } - - /** - * @param shortName the shortName to set - */ - public void setShortName(String shortName) { - this.shortName = shortName; - } - - /** - * @return the brandName - */ - public String getBrandName() { - return brandName; - } - - /** - * @param brandName the brandName to set - */ - public void setBrandName(String brandName) { - this.brandName = brandName; - } - - /** - * @return the supplier - */ - public String getSupplier() { - return supplier; - } - - /** - * @param supplier the supplier to set - */ - public void setSupplier(String supplier) { - this.supplier = supplier; - } - - /** - * @return the manufacturer - */ - public String getManufacturer() { - return manufacturer; - } - - /** - * @param manufacturer the manufacturer to set - */ - public void setManufacturer(String manufacturer) { - this.manufacturer = manufacturer; - } - - /** - * @return the reorderLevel - */ - public Integer getReorderLevel() { - return reorderLevel; - } - - /** - * @param reorderLevel the reorderLevel to set - */ - public void setReorderLevel(Integer reorderLevel) { - this.reorderLevel = reorderLevel; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugInfoService.java b/api/src/main/java/org/raxa/module/raxacore/DrugInfoService.java deleted file mode 100644 index ef661f2598..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugInfoService.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.List; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.annotation.Authorized; -import org.openmrs.api.OpenmrsService; -import org.openmrs.util.PrivilegeConstants; -import org.raxa.module.raxacore.db.DrugInfoDAO; -import org.springframework.transaction.annotation.Transactional; - -/* - * Interface for interacting with the DrugInfo - */ -@Transactional -public interface DrugInfoService extends OpenmrsService { - - /** - * Sets Patient List DAO - * - * @param dao - */ - public void setDrugInfoDAO(DrugInfoDAO dao); - - /** - * Saves DrugInfo - * - * @param drugInfo - * @return DrugInfo - */ - @Authorized( { "Add Drug Info" }) - public DrugInfo saveDrugInfo(DrugInfo drugInfo); - - /** - * Gets a DrugInfo by Id - * - * @param id - * @return DrugInfos - */ - @Authorized( { "View Drug Info" }) - public DrugInfo getDrugInfo(Integer id); - - /** - * Gets DrugInfo by uuid - * - * @param uuid - * @return DrugInfo - */ - @Authorized( { "View Drug Info" }) - public DrugInfo getDrugInfoByUuid(String uuid); - - /** - * Gets DrugInfo by drug uuid - * - * @param uuid - * @return DrugInfo - */ - @Authorized( { "View Drug Info" }) - public DrugInfo getDrugInfoByDrugUuid(String uuid); - - /** - * Gets DrugInfo by drug name - * - * @param uuid - * @return DrugInfo - */ - @Authorized( { "View Drug Info" }) - public List getDrugInfosByDrugName(String name); - - /** - * Gets all DrugInfos - * - * @return - */ - @Authorized( { "View Drug Info" }) - public List getAllDrugInfo(boolean includeRetired); - - /** - * Updates DrugInfo - * - * @param drugInfo - * @return DrugInfo - */ - @Authorized( { "Edit Drug Info" }) - DrugInfo updateDrugInfo(DrugInfo drugInfo); - - /** - * Deletes DrugInfo - * - * @param drugInfo - */ - @Authorized( { "Delete Drug Info" }) - public void deleteDrugInfo(DrugInfo drugInfo); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugInventory.java b/api/src/main/java/org/raxa/module/raxacore/DrugInventory.java deleted file mode 100644 index e673e13c43..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugInventory.java +++ /dev/null @@ -1,217 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.io.Serializable; -import java.util.Date; - -import org.openmrs.BaseOpenmrsMetadata; -import org.openmrs.Drug; -import org.openmrs.Location; -import org.openmrs.Provider; - -public class DrugInventory extends BaseOpenmrsMetadata implements Serializable { - - private Integer id; - - private Integer drugId; - - private Integer quantity; - - private Integer originalQuantity; - - private Date expiryDate; - - private String batch; - - private String supplier; - - private String roomLocation; - - private Integer value; - - private String status; - - private Integer providerId; - - private Integer locationId; - - private Integer drugPurchaseOrderId; - - private Drug drug; - - private Provider provider; - - private Location location; - - private DrugPurchaseOrder drugPurchaseOrder; - - public DrugInventory() { - - } - - public Integer getId() { - return this.id; - } - - public void setId(Integer arg0) { - // TODO Auto-generated method stub - this.id = arg0; - } - - public Integer getDrugId() { - return drugId; - } - - public void setDrugId(Integer drugd) { - this.drugId = drugd; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } - - public Integer getOriginalQuantity() { - return originalQuantity; - } - - public void setOriginalQuantity(Integer originalQuantity) { - this.originalQuantity = originalQuantity; - } - - public Date getExpiryDate() { - return expiryDate; - } - - public void setExpiryDate(Date expiryDate) { - this.expiryDate = expiryDate; - } - - public String getBatch() { - return batch; - } - - public void setBatch(String batch) { - this.batch = batch; - } - - public Integer getValue() { - return value; - } - - public void setValue(Integer value) { - this.value = value; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Integer getProviderId() { - return providerId; - } - - public void setProviderId(Integer providerId) { - this.providerId = providerId; - } - - public Integer getLocationId() { - return locationId; - } - - public void setLocationId(Integer locationId) { - this.locationId = locationId; - - } - - public Integer getDrugPurchaseOrderId() { - return drugPurchaseOrderId; - } - - public void setDrugPurchaseOrderId(Integer drugPurchaseOrderId) { - this.drugPurchaseOrderId = drugPurchaseOrderId; - } - - public Drug getDrug() { - return drug; - } - - public void setDrug(Drug drug) { - this.drug = drug; - } - - public Provider getProvider() { - return provider; - } - - public void setProvider(Provider provider) { - this.provider = provider; - } - - public Location getLocation() { - return location; - } - - public void setLocation(Location location) { - this.location = location; - } - - public DrugPurchaseOrder getDrugPurchaseOrder() { - return drugPurchaseOrder; - } - - public void setDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - this.drugPurchaseOrder = drugPurchaseOrder; - } - - /** - * @return the roomLocation - */ - public String getRoomLocation() { - return roomLocation; - } - - /** - * @param roomLocation the roomLocation to set - */ - public void setRoomLocation(String roomLocation) { - this.roomLocation = roomLocation; - } - - /** - * @return the supplier - */ - public String getSupplier() { - return supplier; - } - - /** - * @param supplier the supplier to set - */ - public void setSupplier(String supplier) { - this.supplier = supplier; - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugInventoryService.java b/api/src/main/java/org/raxa/module/raxacore/DrugInventoryService.java deleted file mode 100644 index db9b23a3ff..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugInventoryService.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.List; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.annotation.Authorized; -import org.openmrs.api.OpenmrsService; -import org.openmrs.util.PrivilegeConstants; -import org.raxa.module.raxacore.db.DrugInventoryDAO; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public interface DrugInventoryService extends OpenmrsService { - - DrugInventory saveDrugInventory(DrugInventory drugInventory); - - DrugInventory getDrugInventoryByUuid(String uuid); - - List getAllDrugInventories(); - - List getAllDrugInventoriesByStatus(String status); - - DrugInventory updateDrugInventory(DrugInventory drugInventory); - - void deleteDrugInventory(DrugInventory drugInventory); - - List getDrugInventoryByProvider(Integer providerId); - - List getDrugInventoriesByLocation(Integer location); - - List getDrugInventoriesByDrugPurchaseOrder(Integer drugPurchaseOrderId); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugPurchaseOrder.java b/api/src/main/java/org/raxa/module/raxacore/DrugPurchaseOrder.java deleted file mode 100644 index 6c1df51b09..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugPurchaseOrder.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.io.Serializable; -import java.util.Date; - -import org.openmrs.BaseOpenmrsMetadata; -import org.openmrs.Location; -import org.openmrs.Provider; - -public class DrugPurchaseOrder extends BaseOpenmrsMetadata implements Serializable { - - public static final String ISSUENAME = "Pharmacy Issue"; - - public static final String RECEIPTNAME = "Pharmacy Receipt"; - - public static final String REQUISITIONNAME = "Pharmacy Requisition"; - - public static final String PRESCRIPTIONNAME = "Prescription"; - - private Integer id; - - private boolean received; - - private Integer providerId; - - private Integer dispenseLocationId; - - private Integer stockLocationId; - - private Date drugPurchaseOrderDate; - - private Provider provider; - - private Location dispenseLocation; - - private Location stockLocation; - - public DrugPurchaseOrder() { - - } - - public Integer getId() { - return id; - } - - public void setId(Integer arg0) { - this.id = arg0; - } - - public boolean isReceived() { - return received; - } - - public void setReceived(boolean received) { - this.received = received; - } - - public Integer getProviderId() { - return providerId; - } - - public void setProviderId(Integer providerId) { - this.providerId = providerId; - } - - public Date getDrugPurchaseOrderDate() { - return drugPurchaseOrderDate; - } - - public void setDrugPurchaseOrderDate(Date drugPurchaseOrderDate) { - this.drugPurchaseOrderDate = drugPurchaseOrderDate; - } - - public Provider getProvider() { - return provider; - } - - public void setProvider(Provider provider) { - this.provider = provider; - } - - /** - * @return the dispenseLocationId - */ - public Integer getDispenseLocationId() { - return dispenseLocationId; - } - - /** - * @param dispenseLocationId the dispenseLocationId to set - */ - public void setDispenseLocationId(Integer dispenseLocationId) { - this.dispenseLocationId = dispenseLocationId; - } - - /** - * @return the stockLocationId - */ - public Integer getStockLocationId() { - return stockLocationId; - } - - /** - * @param stockLocationId the stockLocationId to set - */ - public void setStockLocationId(Integer stockLocationId) { - this.stockLocationId = stockLocationId; - } - - /** - * @return the dispenseLocation - */ - public Location getDispenseLocation() { - return dispenseLocation; - } - - /** - * @param dispenseLocation the dispenseLocation to set - */ - public void setDispenseLocation(Location dispenseLocation) { - this.dispenseLocation = dispenseLocation; - } - - /** - * @return the stockLocation - */ - public Location getStockLocation() { - return stockLocation; - } - - /** - * @param stockLocation the stockLocation to set - */ - public void setStockLocation(Location stockLocation) { - this.stockLocation = stockLocation; - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/DrugPurchaseOrderService.java b/api/src/main/java/org/raxa/module/raxacore/DrugPurchaseOrderService.java deleted file mode 100644 index 2c220968c1..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/DrugPurchaseOrderService.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.List; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.annotation.Authorized; -import org.openmrs.api.OpenmrsService; -import org.openmrs.util.PrivilegeConstants; -import org.raxa.module.raxacore.db.DrugPurchaseOrderDAO; -import org.springframework.transaction.annotation.Transactional; - -public interface DrugPurchaseOrderService extends OpenmrsService { - - DrugPurchaseOrder saveDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder); - - DrugPurchaseOrder getDrugPurchaseOrderByUuid(String uuid); - - List getAllDrugPurchaseOrders(); - - List getAllDrugPurchaseOrdersNotReceived(); - - DrugPurchaseOrder updateDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder); - - void deleteDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder); - - List getDrugPurchaseOrderByProvider(Integer providerId); - - List getDrugPurchaseOrderByDispenseLocation(Integer dispenseLocation); - - List getDrugPurchaseOrderByStockLocation(Integer stockLocation); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/PatientList.java b/api/src/main/java/org/raxa/module/raxacore/PatientList.java deleted file mode 100644 index b1d4912c35..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/PatientList.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.io.Serializable; -import org.openmrs.BaseOpenmrsMetadata; - -/** - * PatientList stores the data needed to lists patients for registration, screener, etc. - */ -public class PatientList extends BaseOpenmrsMetadata implements Serializable { - - private Integer id; - - private String searchQuery; - - public PatientList() { - - } - - /** Sets id - * - * @param id: id to set - */ - @Override - public void setId(Integer id) { - this.id = id; - } - - /** Gets id - * - * @return the patientListId - */ - @Override - public Integer getId() { - return this.id; - } - - /** Compares two PatientList objects for similarity - * - * @param obj PatientList object to compare to - * @return boolean true/false whether or not they are the same objects - * @see java.lang.Object#equals(java.lang.Object) - * @should equal PatientList with same patientListId - * @should not equal PatientList with different patientListId - * @should not equal on null - * @should have equal patientList objects with no patientListIds - * @should not have equal PatientList objects when one has null patientListId - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof PatientList) { - PatientList pList = (PatientList) obj; - if (this.getId() != null && pList.getId() != null) - return (this.getId().equals(pList.getId())); - } - return this == obj; - } - - /** - * @see java.lang.Object#hashCode() - * @should have same hashcode when equal - * @should have different hash code when not equal - * @should get hash code with null attributes - */ - @Override - public int hashCode() { - if (this.getId() == null) - return super.hashCode(); - return this.getId().hashCode(); - } - - /** - * @return the searchQuery - */ - public String getSearchQuery() { - return searchQuery; - } - - /** - * @param searchQuery the searchQuery to set - */ - public void setSearchQuery(String searchQuery) { - this.searchQuery = searchQuery; - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/PatientListService.java b/api/src/main/java/org/raxa/module/raxacore/PatientListService.java deleted file mode 100644 index 51370e5088..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/PatientListService.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.List; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.annotation.Authorized; -import org.openmrs.api.OpenmrsService; -import org.openmrs.util.PrivilegeConstants; -import org.raxa.module.raxacore.db.PatientListDAO; -import org.springframework.transaction.annotation.Transactional; - -/* - * Interface for interacting with the PatientList - */ -@Transactional -public interface PatientListService extends OpenmrsService { - - /** - * Sets Patient List DAO - * - * @param dao - */ - public void setPatientListDAO(PatientListDAO dao); - - /** - * Saves PatientList - * - * @param patientList - * @return PatientList - */ - @Authorized( { "Add Patient Lists" }) - public PatientList savePatientList(PatientList patientList); - - /** - * Gets a PatientList by Id - * - * @param id - * @return PatientLists - */ - @Authorized( { "View Patient Lists" }) - public PatientList getPatientList(Integer id); - - /** - * Gets a PatientList by Name - * - * @param name - * @return list of PatientLists - */ - @Authorized( { "View Patient Lists" }) - public List getPatientListByName(String name); - - /** - * Gets PatientList by uuid - * - * @param uuid - * @return PatientList - */ - @Authorized( { "View Patient Lists" }) - public PatientList getPatientListByUuid(String uuid); - - /** - * Gets PatientLists by EncounterType - * - * @param encounterType - * @return list of PatientLists - */ - @Authorized(value = { "View Patient Lists", PrivilegeConstants.VIEW_ENCOUNTER_TYPES }, requireAll = true) - public List getPatientListByEncounterType(EncounterType encounterType); - - /** - * Gets all PatientLists - * - * @return list of PatientLists - */ - @Authorized( { "View Patient Lists" }) - public List getAllPatientList(boolean includeRetired); - - /** - * Gets all patients in PatientList - * - * @param patientList - * @return list of Patients - */ - @Authorized(value = { "View Patient Lists", PrivilegeConstants.VIEW_PATIENTS }, requireAll = true) - public List getPatientsInPatientList(PatientList patientList); - - /** - * Gets all the encounters in PatientList - * - * @param patientList - * @return list of Encounters - */ - @Authorized(value = { "View Patient Lists", PrivilegeConstants.VIEW_ENCOUNTERS }, requireAll = true) - public List getEncountersInPatientList(PatientList patientList); - - /** - * Updates PatientList - * - * @param patientList - * @return PatientList - */ - @Authorized( { "Edit Patient Lists" }) - PatientList updatePatientList(PatientList patientList); - - /** - * Deletes PatientList - * - * @param patientList - */ - @Authorized( { "Delete Patient Lists" }) - public void deletePatientList(PatientList patientList); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/RaxaAlert.java b/api/src/main/java/org/raxa/module/raxacore/RaxaAlert.java deleted file mode 100644 index 42019ec00b..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/RaxaAlert.java +++ /dev/null @@ -1,356 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.io.Serializable; -import java.util.*; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.openmrs.BaseOpenmrsData; -import org.openmrs.Location; -import org.openmrs.Obs; -import org.openmrs.Patient; -import org.openmrs.Provider; - -public class RaxaAlert extends BaseOpenmrsData implements Serializable { - - private Integer id; - - private String name; - - private String description; - - private Patient patient; - - private Integer patientId; - - private Boolean seen; - - private String alertType; - - private Date time; - - private String defaultTask; - - private Provider providerSent; - - private Integer providerSentId; - - private Provider providerRecipient; - - private Integer toLocationId; - - private Location toLocation; - - private Integer fromLocationId; - - private Location fromLocation; - - private Integer providerRecipientId; - - public RaxaAlert() { - } - - /** - * Sets id - * - * @param id: id to set - */ - @Override - public void setId(Integer id) { - this.id = id; - } - - /** - * Gets id - * - * @return the RaxaAlertId - */ - @Override - public Integer getId() { - return this.id; - } - - /** - * Compares two RaxaAlert objects for similarity - * - * @param obj RaxaAlert object to compare to - * @return boolean true/false whether or not they are the same objects - * @see java.lang.Object#equals(java.lang.Object) - * @should equal RaxaAlert with same raxaAlertID - * @should not equal RaxaAlert with different raxaAlertID - * @should not equal on null - * @should have equal raxaList objects with no raxaAlertIDs - * @should not have equal RaxaAlert objects when one has null raxaAlertID - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof RaxaAlert) { - RaxaAlert pList = (RaxaAlert) obj; - if (this.getId() != null && pList.getId() != null) { - return (this.getId().equals(pList.getId())); - } - } - return this == obj; - } - - /** - * @see java.lang.Object#hashCode() - * @should have same hashcode when equal - * @should have different hash code when not equal - * @should get hash code with null attributes - */ - @Override - public int hashCode() { - if (this.getId() == null) { - return super.hashCode(); - } - return this.getId().hashCode(); - } - - /** - * @return the patientId - */ - public Integer getPatientId() { - return patientId; - } - - /** - * @param patientId the patientId to set - */ - public void setPatientId(Integer patientId) { - this.patientId = patientId; - } - - /** - * @return the seen - */ - public Boolean getSeen() { - return seen; - } - - /** - * @param seen the seen to set - */ - public void setSeen(Boolean seen) { - this.seen = seen; - } - - /** - * @return the alertType - */ - public String getAlertType() { - return alertType; - } - - /** - * @param alertType the alertType to set - */ - public void setAlertType(String alertType) { - this.alertType = alertType; - } - - /** - * @return the description - */ - public String getDescription() { - return description; - } - - /** - * @param description the description to set - */ - public void setDescription(String description) { - this.description = description; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param alertType the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the time - */ - public Date getTime() { - return time; - } - - /** - * @param time the time to set - */ - public void setTime(Date time) { - this.time = time; - } - - /** - * @return the defaultTask - */ - public String getDefaultTask() { - return defaultTask; - } - - /** - * @param defaultTask the defaultTask to set - */ - public void setDefaultTask(String defaultTask) { - this.defaultTask = defaultTask; - } - - /** - * @return the providerSentId - */ - public Integer getProviderSentId() { - return providerSentId; - } - - /** - * @param providerSentId the providerSentId to set - */ - public void setProviderSentId(Integer providerSentId) { - this.providerSentId = providerSentId; - } - - /** - * @return the providerRecipientId - */ - public Integer getProviderRecipientId() { - return providerRecipientId; - } - - /** - * @param providerRecipientId the providerRecipientId to set - */ - public void setProviderRecipientId(Integer providerRecipientId) { - this.providerRecipientId = providerRecipientId; - } - - /** - * @return the patient - */ - public Patient getPatient() { - return patient; - } - - /** - * @param patient the patient to set - */ - public void setPatient(Patient patient) { - this.patient = patient; - } - - /** - * @return the providerSent - */ - public Provider getProviderSent() { - return providerSent; - } - - /** - * @param providerSent the providerSent to set - */ - public void setProviderSent(Provider providerSent) { - this.providerSent = providerSent; - } - - /** - * @return the providerRecipient - */ - public Provider getProviderRecipient() { - return providerRecipient; - } - - /** - * @param providerRecipient the providerRecipient to set - */ - public void setProviderRecipient(Provider providerRecipient) { - this.providerRecipient = providerRecipient; - } - - /** - * This function overrides a function in BaseOpenmrsData just to add JsonIgnore--- - * The serializer doesn't know what to do with both isVoided() and getVoided() - * So we add it here so it ignores getVoided() and uses isVoided() - * @return whether this Raxa Alert is voided - */ - @Override - @JsonIgnore - public Boolean getVoided() { - return isVoided(); - } - - /** - * @return the toLocationId - */ - public Integer getToLocationId() { - return toLocationId; - } - - /** - * @param toLocationId the toLocationId to set - */ - public void setToLocationId(Integer toLocationId) { - this.toLocationId = toLocationId; - } - - /** - * @return the toLocation - */ - public Location getToLocation() { - return toLocation; - } - - /** - * @param toLocation the toLocation to set - */ - public void setToLocation(Location toLocation) { - this.toLocation = toLocation; - } - - /** - * @return the fromLocationId - */ - public Integer getFromLocationId() { - return fromLocationId; - } - - /** - * @param fromLocationId the fromLocationId to set - */ - public void setFromLocationId(Integer fromLocationId) { - this.fromLocationId = fromLocationId; - } - - /** - * @return the fromLocation - */ - public Location getFromLocation() { - return fromLocation; - } - - /** - * @param fromLocation the fromLocation to set - */ - public void setFromLocation(Location fromLocation) { - this.fromLocation = fromLocation; - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/RaxaAlertProviderRecipient.java b/api/src/main/java/org/raxa/module/raxacore/RaxaAlertProviderRecipient.java deleted file mode 100644 index 84f4bbc5a6..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/RaxaAlertProviderRecipient.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.io.Serializable; -import org.openmrs.BaseOpenmrsData; - -public class RaxaAlertProviderRecipient extends BaseOpenmrsData implements Serializable { - - private Integer raxaAlertProviderRecipientId; - - private Integer providerRecipentId; - - public RaxaAlertProviderRecipient() { - } - - @Override - public Integer getId() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setId(Integer intgr) { - throw new UnsupportedOperationException("Not supported yet."); - } - - /** - * @return the raxaAlertProviderRecipientId - */ - public Integer getRaxaAlertProviderRecipientId() { - return raxaAlertProviderRecipientId; - } - - /** - * @param raxaAlertProviderRecipientId the raxaAlertProviderRecipientId to set - */ - public void setRaxaAlertProviderRecipientId(Integer raxaAlertProviderRecipientId) { - this.raxaAlertProviderRecipientId = raxaAlertProviderRecipientId; - } - - /** - * @return the providerRecipentId - */ - public Integer getProviderRecipentId() { - return providerRecipentId; - } - - /** - * @param providerRecipentId the providerRecipentId to set - */ - public void setProviderRecipentId(Integer providerRecipentId) { - this.providerRecipentId = providerRecipentId; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/RaxaAlertService.java b/api/src/main/java/org/raxa/module/raxacore/RaxaAlertService.java deleted file mode 100644 index cd80bc35af..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/RaxaAlertService.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.raxa.module.raxacore; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.List; -import org.openmrs.annotation.Authorized; -import org.openmrs.api.OpenmrsService; -import org.raxa.module.raxacore.db.RaxaAlertDAO; -import org.springframework.transaction.annotation.Transactional; - -/* - * Interface for interacting with the RaxaAlert - */ -@Transactional -public interface RaxaAlertService extends OpenmrsService { - - /** - * Sets Raxa Alert DAO - * - * @param dao - */ - public void setRaxaAlertDAO(RaxaAlertDAO dao); - - /** - * Saves RaxaAlert - * - * @param raxaAlert - * @return RaxaAlert - */ - @Authorized( { "Add Raxa Alerts" }) - public RaxaAlert saveRaxaAlert(RaxaAlert raxaAlert); - - /** - * Gets a RaxaAlert by Id - * - * @param id - * @return RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public RaxaAlert getRaxaAlert(Integer id); - - /** - * Gets a RaxaAlert by PatientId - * - * @param patientId - * @return RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertByPatientId(Integer patientId, boolean includeSeen); - - /** - * Gets a RaxaAlert by ProviderSentId - * - * @param providerSentId - * @return RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertByProviderSentId(Integer providerSentId, boolean includeSeen); - - /** - * Gets a RaxaAlert by ProviderRecipientId - * - * @param providerRecipientId - * @return RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertByProviderRecipientId(Integer providerRecipientId, boolean includeSeen); - - /** - * Gets a RaxaAlert by ProviderSentUuid - * - * @param providerSentUuid - * @return RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertByProviderSentUuid(String providerSentUuid, boolean includeSeen); - - /** - * Gets a RaxaAlert by ProviderRecipientUuid - * - * @param providerSentUuid - * @return RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertByProviderRecipientUuid(String providerRecipientUuid, boolean includeSeen); - - /** - * Gets a RaxaAlert by Name - * - * @param name - * @return list of RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertsByName(String name, boolean includeSeen); - - /** - * Gets RaxaAlert by uuid - * - * @param uuid - * @return RaxaAlert - */ - @Authorized( { "View Raxa Alerts" }) - public RaxaAlert getRaxaAlertByUuid(String uuid); - - /** - * Gets RaxaAlert by alertType - * - * @param uuid - * @return RaxaAlert - */ - @Authorized( { "View Raxa Alerts" }) - public List getRaxaAlertByAlertType(String alertType, boolean includeSeen); - - /** - * Gets all RaxaAlerts - * - * @return list of RaxaAlerts - */ - @Authorized( { "View Raxa Alerts" }) - public List getAllRaxaAlerts(boolean includeSeen); - - /** - * Mark RaxaAlert as seen - * - * @param seen - */ - @Authorized( { "Edit Raxa Alerts" }) - RaxaAlert markRaxaAlertAsSeen(RaxaAlert raxaAlert); - - /** - * Updates RaxaAlert - * - * @param raxaAlert - * @return RaxaAlert - */ - @Authorized( { "Edit Raxa Alerts" }) - RaxaAlert updateRaxaAlert(RaxaAlert raxaAlert); - - /** - * Deletes RaxaAlert - * - * @param raxaAlert - */ - @Authorized( { "Delete Raxa Alerts" }) - public void deleteRaxaAlert(RaxaAlert raxaAlert); - - @Authorized( { "Delete Raxa Alerts" }) - public void voidRaxaAlert(RaxaAlert raxaAlert, String reason); - - @Authorized( { "Delete Raxa Alerts" }) - public void purgeRaxaAlert(RaxaAlert raxaAlert); - - public List getRaxaAlertByToLocationUuid(String toLocation, boolean includeSeen); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/DrugGroupDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/DrugGroupDAO.java deleted file mode 100644 index b53aaf7bd2..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/DrugGroupDAO.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.raxa.module.raxacore.db; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugGroup; - -/** - * Interface for accessing raxacore_patient_list - */ -public interface DrugGroupDAO { - - /** - * Saves a DrugGroup - * - * @param DrugGroup to be saved - * @throws DAOException @should save a patient list - */ - public DrugGroup saveDrugGroup(DrugGroup drugGroup) throws DAOException; - - /** - * Purge a DrugGroup from database. - * - * @param DrugGroup object to be purged - */ - public void deleteDrugGroup(DrugGroup drugGroup) throws DAOException; - - /** - * Get patientList by internal identifier - * - * @param patientListId patientList id - * @return patientList with given internal identifier - * @throws DAOException @should get a patient list - */ - public DrugGroup getDrugGroup(Integer patientListId) throws DAOException; - - /** - * Find {@link PatientList} matching a uuid - * - * @param uuid - * @return {@link PatientList} @should get a patient list by uuid - */ - public DrugGroup getDrugGroupByUuid(String uuid); - - /** - * Find {@link PatientList} matching a name - * - * @param name - * @return List of PatientLists @should get a patient list by name - */ - public List getDrugGroupByName(String name); - - /** - * Get all {@link PatientList} - * - * @return List of PatientLists @should get all patient lists - */ - public List getAllDrugGroup(boolean includeRetired); - - /** - * Update PatientList - * - * @return {@link PatientList} @should update a PatientList - */ - DrugGroup updateDrugGroup(DrugGroup drugGroup) throws DAOException; -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/DrugInfoDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/DrugInfoDAO.java deleted file mode 100644 index 4df9e34181..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/DrugInfoDAO.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.raxa.module.raxacore.db; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugInfo; - -/** - * Interface for accessing raxacore_drug_info - */ -public interface DrugInfoDAO { - - /** - * Saves a DrugInfo - * - * @param DrugInfo to be saved - * @throws DAOException - * @should save a drug info - */ - public DrugInfo saveDrugInfo(DrugInfo drugInfo) throws DAOException; - - /** - * Purge a DrugInfo from database. - * - * @param DrugInfo object to be purged - */ - public void deleteDrugInfo(DrugInfo drugInfo) throws DAOException; - - /** - * Get drugInfo by internal identifier - * - * @param drugInfoId drugInfo id - * @return drugInfo with given internal identifier - * @throws DAOException - * @should get a drug info - */ - public DrugInfo getDrugInfo(Integer drugInfoId) throws DAOException; - - /** - * Find {@link DrugInfo} matching a uuid - * - * @param uuid - * @return {@link DrugInfo} - * @should get a drug info by uuid - */ - public DrugInfo getDrugInfoByUuid(String uuid); - - /** - * Find {@link DrugInfo} matching a name - * - * @param name - * @return List of DrugInfo - * @should get a drug info by name - */ - public List getDrugInfoByName(String name); - - /** - * Get all {@link DrugInfo} - * - * @return List of DrugInfo - * @should get all drug infos - */ - public List getAllDrugInfo(boolean includeRetired); - - /** - * Update DrugInfo - * @return {@link DrugInfo} - * @should update a DrugInfo - */ - DrugInfo updateDrugInfo(DrugInfo drugInfo) throws DAOException; - - public DrugInfo getDrugInfoByDrug(Integer id); - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/DrugInventoryDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/DrugInventoryDAO.java deleted file mode 100644 index 7f4cd3fdd3..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/DrugInventoryDAO.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.raxa.module.raxacore.db; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.util.List; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugInventory; - -public interface DrugInventoryDAO { - - public DrugInventory saveDrugInventory(DrugInventory drugInventory) throws DAOException; - - public void deleteDrugInventory(DrugInventory drugInventory) throws DAOException; - - public DrugInventory getDrugInventoryByUuid(String uuid); - - public List getAllDrugInventories() throws DAOException; - - public List getAllDrugInventoriesByStatus(String status); - - public DrugInventory updateDrugInventory(DrugInventory drugInventory); - - public List getDrugInventoryByProvider(Integer providerId); - - public List getDrugInventoriesByLocation(Integer location); - - public List getDrugInventoriesByDrugPurchaseOrder(Integer drugPurchaseOrderId); - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/DrugPurchaseOrderDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/DrugPurchaseOrderDAO.java deleted file mode 100644 index 74196d6f64..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/DrugPurchaseOrderDAO.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.raxa.module.raxacore.db; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.util.List; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugPurchaseOrder; - -public interface DrugPurchaseOrderDAO { - - public DrugPurchaseOrder saveDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder); - - public DrugPurchaseOrder getDrugPurchaseOrderByUuid(String uuid); - - public List getAllDrugPurchaseOrders(); - - public List getAllDrugPurchaseOrdersNotReceived(); - - public DrugPurchaseOrder updateDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder); - - public void deleteDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder); - - public List getDrugPurchaseOrderByProvider(Integer providerId); - - public List getDrugPurchaseOrderByDispenseLocation(Integer dispenseLocation); - - public List getDrugPurchaseOrderByStockLocation(Integer stockLocation); - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/PatientListDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/PatientListDAO.java deleted file mode 100644 index 148b9d7fdd..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/PatientListDAO.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.raxa.module.raxacore.db; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.PatientList; - -/** - * Interface for accessing raxacore_patient_list - */ -public interface PatientListDAO { - - /** - * Saves a PatientList - * - * @param PatientList to be saved - * @throws DAOException - * @should save a patient list - */ - public PatientList savePatientList(PatientList patientList) throws DAOException; - - /** - * Purge a PatientList from database. - * - * @param PatientList object to be purged - */ - public void deletePatientList(PatientList patientList) throws DAOException; - - /** - * Get patientList by internal identifier - * - * @param patientListId patientList id - * @return patientList with given internal identifier - * @throws DAOException - * @should get a patient list - */ - public PatientList getPatientList(Integer patientListId) throws DAOException; - - /** - * Find {@link PatientList} matching an EncounterType - * @param encounterType - * @should get a patient list by EncounterType - */ - public List getPatientListByEncounterType(EncounterType encounterType); - - /** - * Find {@link PatientList} matching a uuid - * - * @param uuid - * @return {@link PatientList} - * @should get a patient list by uuid - */ - public PatientList getPatientListByUuid(String uuid); - - /** - * Find {@link PatientList} matching a name - * - * @param name - * @return List of PatientLists - * @should get a patient list by name - */ - public List getPatientListByName(String name); - - /** - * Get all {@link PatientList} - * - * @return List of PatientLists - * @should get all patient lists - */ - public List getAllPatientList(boolean includeRetired); - - /** - * Update PatientList - * @return {@link PatientList} - * @should update a PatientList - */ - PatientList updatePatientList(PatientList patientList) throws DAOException; - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/RaxaAlertDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/RaxaAlertDAO.java deleted file mode 100644 index e5a140bfcc..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/RaxaAlertDAO.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.raxa.module.raxacore.db; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.RaxaAlert; - -/** - * Interface for accessing raxacore_raxa_alert_list - */ -public interface RaxaAlertDAO { - - /** - * Saves a RaxaAlert - * - * @param RaxaAlert to be saved - * @throws DAOException - * @should save a raxa alert - */ - public RaxaAlert saveRaxaAlert(RaxaAlert raxaAlert) throws DAOException; - - /** - * Purge a RaxaAlert from database - * @param RaxaAlert object to be purged - * @should delete a raxa alert - */ - public void deleteRaxaAlert(RaxaAlert raxaAlert) throws DAOException; - - /** - * Get raxaAlert by internal identifier - * - * @param raxaAlertID raxaAlert id - * @return raxaAlert with given internal identifier - * @throws DAOException - * @should get a raxa alert - */ - public RaxaAlert getRaxaAlert(Integer raxaAlertID) throws DAOException; - - /** - * Find {@link RaxaAlert} matching a patientId - * - * @param patient - * @return {@link RaxaAlert} - * @should get a raxa alert list by patientId - */ - public List getRaxaAlertByPatientId(Integer patientId, boolean includeSeen); - - /** - * Find {@link RaxaAlert} matching a uuid - * - * @param uuid - * @return {@link RaxaAlert} - * @should get a raxa alert by uuid - */ - public RaxaAlert getRaxaAlertByUuid(String uuid); - - /** - * Find {@link RaxaAlert} matching a name - * - * @param name - * @return {@link RaxaAlert} - * @should get a raxa alert by name - */ - public List getRaxaAlertByName(String name, boolean includeSeen); - - /** - * Find {@link RaxaAlert} matching a alertType - * - * @param alertType - * @return {@link RaxaAlert} - * @should get a raxa alert list by alertType - */ - public List getRaxaAlertByAlertType(String alertType, boolean includeSeen); - - /** - * Find {@link RaxaAlert} matching providerSentId - * - * @param providerSent - * @return List of RaxaAlerts - * @should get a raxa alert list by providerSentId - */ - public List getRaxaAlertByProviderSentId(Integer providerSentId, boolean includeSeen); - - /** - * Find {@link RaxaAlert} matching providerRecipientId - * - * @param providerRecipient - * @return List of RaxaAlerts - * @should get a raxa alert list by providerRecipientId - */ - public List getRaxaAlertByProviderRecipientId(Integer providerRecipientId, boolean includeSeen); - - /** - * Update RaxaAlert - * @return {@link RaxaAlert} - * @should update a RaxaAlert - */ - RaxaAlert updateRaxaAlert(RaxaAlert raxaAlert) throws DAOException; - - /** - *Get all RaxaAlert - *@param includeSeen - *@return List of RaxaAlerts - */ - public List getAllRaxaAlerts(boolean includeSeen) throws DAOException; - - /** - *Mark RaxaLert as seen - *@param Seen - @should mark a RaxaAlert as seen - */ - RaxaAlert markRaxaAlertAsSeen(RaxaAlert raxaAlert); - - /** - * Void a RaxaAlert in the database - * @param RaxaAlert object to be purged - * @param String reason for voiding RaxaAlert - * @should void a raxa alert - */ - public RaxaAlert voidRaxaAlert(RaxaAlert raxaAlert, String reason); - - public List getRaxaAlertByToLocationId(Integer id, boolean includeSeen); -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugGroupDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugGroupDAO.java deleted file mode 100644 index 92785b95d8..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugGroupDAO.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Restrictions; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.db.DrugGroupDAO; - -public class HibernateDrugGroupDAO implements DrugGroupDAO { - - protected final Log log = LogFactory.getLog(getClass()); - - /** - * Hibernate session factory - */ - private SessionFactory sessionFactory; - - /** - * Set session factory - * - * @param sessionFactory - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * @see - * org.raxa.module.db.DrugGroupDAO#saveDrugGroup(org.raxa.module.raxacore.DrugGroup) - */ - @Override - public DrugGroup saveDrugGroup(DrugGroup drugGroup) throws DAOException { - sessionFactory.getCurrentSession().saveOrUpdate(drugGroup); - return drugGroup; - } - - /** - * @see - * org.raxa.module.db.DrugGroupDAO#deleteDrugGroup(org.raxa.module.raxacore.DrugGroup) - */ - @Override - public void deleteDrugGroup(DrugGroup drugGroup) throws DAOException { - sessionFactory.getCurrentSession().delete(drugGroup); - } - - /** - * @see org.raxa.module.db.DrugGroupDAO#getDrugGroup(Integer) - */ - @Override - public DrugGroup getDrugGroup(Integer drugGroupId) throws DAOException { - return (DrugGroup) sessionFactory.getCurrentSession().get(DrugGroup.class, drugGroupId); - } - - /** - * @see org.raxa.module.db.DrugGroupDAO#getDrugGroupByUuid(String) - */ - @Override - public DrugGroup getDrugGroupByUuid(String uuid) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugGroup.class); - criteria.add(Restrictions.eq("uuid", uuid)); - return (DrugGroup) criteria.uniqueResult(); - } - - /** - * @see org.raxa.module.db.DrugGroupDAO#getDrugGroupByName(String) - */ - @Override - public List getDrugGroupByName(String name) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugGroup.class); - criteria.add(Restrictions.like("name", name)); - criteria.add(Restrictions.like("retired", false)); - List patients = new ArrayList(); - patients.addAll(criteria.list()); - return patients; - - } - - /** - * @see org.raxa.module.db.DrugGroupDAO#getAllDrugGroup() - */ - @Override - public List getAllDrugGroup(boolean includeRetired) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugGroup.class); - if (includeRetired == false) { - criteria.add(Restrictions.eq("retired", false)); - } - return criteria.list(); - } - - /** - * @see org.raxa.module.db.DrugGroupDAO#updateDrugGroup(Integer) - */ - @Override - public DrugGroup updateDrugGroup(DrugGroup drugGroup) throws DAOException { - sessionFactory.getCurrentSession().update(drugGroup); - return drugGroup; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInfoDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInfoDAO.java deleted file mode 100644 index 19639381ee..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInfoDAO.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Restrictions; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.db.DrugInfoDAO; - -/** - * Accesses raxacore_drug_info from DrugInfo - */ -public class HibernateDrugInfoDAO implements DrugInfoDAO { - - protected final Log log = LogFactory.getLog(getClass()); - - /** - * Hibernate session factory - */ - private SessionFactory sessionFactory; - - /** - * Set session factory - * - * @param sessionFactory - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#saveDrugInfo(org.raxa.module.raxacore.DrugInfo) - */ - @Override - public DrugInfo saveDrugInfo(DrugInfo drugInfo) throws DAOException { - sessionFactory.getCurrentSession().saveOrUpdate(drugInfo); - return drugInfo; - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#deleteDrugInfo(org.raxa.module.raxacore.DrugInfo) - */ - @Override - public void deleteDrugInfo(DrugInfo drugInfo) throws DAOException { - sessionFactory.getCurrentSession().delete(drugInfo); - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#getDrugInfo(Integer) - */ - @Override - public DrugInfo getDrugInfo(Integer drugInfoId) throws DAOException { - return (DrugInfo) sessionFactory.getCurrentSession().get(DrugInfo.class, drugInfoId); - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#getDrugInfoByUuid(String) - */ - @Override - public DrugInfo getDrugInfoByUuid(String uuid) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInfo.class); - criteria.add(Restrictions.eq("uuid", uuid)); - return (DrugInfo) criteria.uniqueResult(); - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#getDrugInfoByName(String) - */ - @Override - public List getDrugInfoByName(String name) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInfo.class); - criteria.add(Restrictions.like("name", name)); - criteria.add(Restrictions.like("retired", false)); - List patients = new ArrayList(); - patients.addAll(criteria.list()); - return patients; - - } - - @Override - public DrugInfo getDrugInfoByDrug(Integer id) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInfo.class); - criteria.add(Restrictions.eq("drugId", id)); - return (DrugInfo) criteria.uniqueResult(); - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#getAllDrugInfo() - */ - @Override - public List getAllDrugInfo(boolean includeRetired) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInfo.class); - if (includeRetired == false) { - criteria.add(Restrictions.eq("retired", false)); - } - return criteria.list(); - } - - /** - * @see org.raxa.module.db.DrugInfoDAO#updateDrugInfo(Integer) - */ - @Override - public DrugInfo updateDrugInfo(DrugInfo drugInfo) throws DAOException { - sessionFactory.getCurrentSession().update(drugInfo); - return drugInfo; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInventoryDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInventoryDAO.java deleted file mode 100644 index 1314355442..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInventoryDAO.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Restrictions; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.db.DrugInventoryDAO; -import org.raxa.module.raxacore.db.PatientListDAO; - -public class HibernateDrugInventoryDAO implements DrugInventoryDAO { - - protected final Log log = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - public DrugInventory saveDrugInventory(DrugInventory drugInventory) throws DAOException { - sessionFactory.getCurrentSession().saveOrUpdate(drugInventory); - return drugInventory; - } - - public void deleteDrugInventory(DrugInventory drugInventory) throws DAOException { - - sessionFactory.getCurrentSession().delete(drugInventory); - } - - public DrugInventory getDrugInventoryByUuid(String uuid) { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInventory.class); - criteria.add(Restrictions.eq("uuid", uuid)); - System.out.println("///////" + criteria.uniqueResult()); - return (DrugInventory) criteria.uniqueResult(); - } - - public List getAllDrugInventories() throws DAOException { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInventory.class); - return criteria.list(); - - } - - public List getAllDrugInventoriesByStatus(String status) { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInventory.class); - criteria.add(Restrictions.eq("status", status)); - List drugInventories = new ArrayList(); - drugInventories.addAll(criteria.list()); - return drugInventories; - - } - - public DrugInventory updateDrugInventory(DrugInventory drugInventory) { - - sessionFactory.getCurrentSession().update(drugInventory); - return drugInventory; - } - - public List getDrugInventoryByProvider(Integer providerId) { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInventory.class); - criteria.add(Restrictions.eq("providerId", providerId)); - List drugInventories = new ArrayList(); - drugInventories.addAll(criteria.list()); - return drugInventories; - } - - @Override - public List getDrugInventoriesByLocation(Integer location) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInventory.class); - criteria.add(Restrictions.eq("locationId", location)); - List drugInventories = new ArrayList(); - drugInventories.addAll(criteria.list()); - return drugInventories; - } - - @Override - public List getDrugInventoriesByDrugPurchaseOrder(Integer drugPurchaseOrderId) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugInventory.class); - criteria.add(Restrictions.eq("drugPurchaseOrderId", drugPurchaseOrderId)); - List drugInventories = new ArrayList(); - drugInventories.addAll(criteria.list()); - return drugInventories; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugPurchaseOrderDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugPurchaseOrderDAO.java deleted file mode 100644 index 7ce9daafa7..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugPurchaseOrderDAO.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Restrictions; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; - -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.db.DrugPurchaseOrderDAO; - -public class HibernateDrugPurchaseOrderDAO implements DrugPurchaseOrderDAO { - - protected final Log log = LogFactory.getLog(getClass()); - - private SessionFactory sessionFactory; - - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - public DrugPurchaseOrder saveDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - - sessionFactory.getCurrentSession().saveOrUpdate(drugPurchaseOrder); - return drugPurchaseOrder; - } - - public DrugPurchaseOrder getDrugPurchaseOrderByUuid(String uuid) { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugPurchaseOrder.class); - criteria.add(Restrictions.eq("uuid", uuid)); - System.out.println(criteria.uniqueResult()); - return (DrugPurchaseOrder) criteria.uniqueResult(); - } - - public List getAllDrugPurchaseOrders() { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugPurchaseOrder.class); - return criteria.list(); - } - - public List getAllDrugPurchaseOrdersNotReceived() { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugPurchaseOrder.class); - criteria.add(Restrictions.eq("received", false)); - List drugPurchaseOrders = new ArrayList(); - drugPurchaseOrders.addAll(criteria.list()); - return drugPurchaseOrders; - } - - public DrugPurchaseOrder updateDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - - sessionFactory.getCurrentSession().update(drugPurchaseOrder); - return drugPurchaseOrder; - } - - public void deleteDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - - sessionFactory.getCurrentSession().delete(drugPurchaseOrder); - } - - public List getDrugPurchaseOrderByProvider(Integer providerId) { - - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugPurchaseOrder.class); - criteria.add(Restrictions.eq("providerId", providerId)); - List drugPurchaseOrders = new ArrayList(); - drugPurchaseOrders.addAll(criteria.list()); - return drugPurchaseOrders; - } - - @Override - public List getDrugPurchaseOrderByDispenseLocation(Integer dispenseLocation) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugPurchaseOrder.class); - criteria.add(Restrictions.eq("dispenseLocationId", dispenseLocation)); - List drugPurchaseOrders = new ArrayList(); - drugPurchaseOrders.addAll(criteria.list()); - return drugPurchaseOrders; - } - - @Override - public List getDrugPurchaseOrderByStockLocation(Integer stockLocation) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(DrugPurchaseOrder.class); - criteria.add(Restrictions.eq("stockLocationId", stockLocation)); - List drugPurchaseOrders = new ArrayList(); - drugPurchaseOrders.addAll(criteria.list()); - return drugPurchaseOrders; - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernatePatientListDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernatePatientListDAO.java deleted file mode 100644 index 36f7ad054e..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernatePatientListDAO.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Restrictions; -import org.openmrs.EncounterType; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.db.PatientListDAO; - -/** - * Accesses raxacore_patient_list from PatientList - */ -public class HibernatePatientListDAO implements PatientListDAO { - - protected final Log log = LogFactory.getLog(getClass()); - - /** - * Hibernate session factory - */ - private SessionFactory sessionFactory; - - /** - * Set session factory - * - * @param sessionFactory - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - - } - - /** - * @see org.raxa.module.db.PatientListDAO#savePatientList(org.raxa.module.raxacore.PatientList) - */ - @Override - public PatientList savePatientList(PatientList patientList) throws DAOException { - sessionFactory.getCurrentSession().saveOrUpdate(patientList); - return patientList; - } - - /** - * @see org.raxa.module.db.PatientListDAO#deletePatientList(org.raxa.module.raxacore.PatientList) - */ - @Override - public void deletePatientList(PatientList patientList) throws DAOException { - sessionFactory.getCurrentSession().delete(patientList); - } - - /** - * @see org.raxa.module.db.PatientListDAO#getPatientList(Integer) - */ - @Override - public PatientList getPatientList(Integer patientListId) throws DAOException { - return (PatientList) sessionFactory.getCurrentSession().get(PatientList.class, patientListId); - } - - /** - * @see org.raxa.module.db.PatientListDAO#getPatientListByEncounterType(EncounterType) - */ - @Override - public List getPatientListByEncounterType(EncounterType encounterType) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientList.class); - //getting all the PatientLists that contain the encounterType's uuid. the % is for wildcards - //TODO: add in validator to check if the encountertype uuid exists - criteria.add(Restrictions.like("searchQuery", "%" + encounterType.getUuid() + "%")); - List patients = new ArrayList(); - patients.addAll(criteria.list()); - return patients; - } - - /** - * @see org.raxa.module.db.PatientListDAO#getPatientListByUuid(String) - */ - @Override - public PatientList getPatientListByUuid(String uuid) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientList.class); - criteria.add(Restrictions.eq("uuid", uuid)); - return (PatientList) criteria.uniqueResult(); - } - - /** - * @see org.raxa.module.db.PatientListDAO#getPatientListByName(String) - */ - @Override - public List getPatientListByName(String name) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientList.class); - criteria.add(Restrictions.like("name", name)); - criteria.add(Restrictions.like("retired", false)); - List patients = new ArrayList(); - patients.addAll(criteria.list()); - return patients; - - } - - /** - * @see org.raxa.module.db.PatientListDAO#getAllPatientList() - */ - @Override - public List getAllPatientList(boolean includeRetired) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientList.class); - if (includeRetired == false) { - criteria.add(Restrictions.eq("retired", false)); - } - return criteria.list(); - } - - /** - * @see org.raxa.module.db.PatientListDAO#updatePatientList(Integer) - */ - @Override - public PatientList updatePatientList(PatientList patientList) throws DAOException { - sessionFactory.getCurrentSession().update(patientList); - return patientList; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateRaxaAlertDAO.java b/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateRaxaAlertDAO.java deleted file mode 100644 index 12bce6089c..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/db/hibernate/HibernateRaxaAlertDAO.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.Criteria; -import org.hibernate.SessionFactory; -import org.hibernate.criterion.Restrictions; -import org.openmrs.Obs; -import org.openmrs.api.ObsService; -import org.openmrs.api.context.Context; -import org.openmrs.api.db.DAOException; -import org.raxa.module.raxacore.RaxaAlert; -import org.raxa.module.raxacore.db.RaxaAlertDAO; - -/** - * Accesses raxacore_raxaalert from RaxaAlert - */ -public class HibernateRaxaAlertDAO implements RaxaAlertDAO { - - protected final Log log = LogFactory.getLog(getClass()); - - /** - * Hibernate session factory - */ - private SessionFactory sessionFactory; - - /** - * Set session factory - * - * @param sessionFactory - */ - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#saveRaxaAlert(org.raxa.module.raxacore.RaxaAlert) - */ - @Override - public RaxaAlert saveRaxaAlert(RaxaAlert raxaAlert) throws DAOException { - sessionFactory.getCurrentSession().saveOrUpdate(raxaAlert); - return raxaAlert; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#deleteRaxaAlert(org.raxa.module.raxacore.RaxaAlert) - */ - @Override - public void deleteRaxaAlert(RaxaAlert raxaAlert) throws DAOException { - sessionFactory.getCurrentSession().delete(raxaAlert); - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlert(Integer) - */ - @Override - public RaxaAlert getRaxaAlert(Integer raxaAlertId) throws DAOException { - return (RaxaAlert) sessionFactory.getCurrentSession().get(RaxaAlert.class, raxaAlertId); - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlertByUuid(String) - */ - @Override - public RaxaAlert getRaxaAlertByUuid(String uuid) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.eq("uuid", uuid)); - return (RaxaAlert) criteria.uniqueResult(); - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlertByName(String) - */ - @Override - public List getRaxaAlertByName(String name, boolean includeSeen) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.eq("name", name)); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - List alerts = new ArrayList(); - alerts.addAll(criteria.list()); - return alerts; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlertByAlertType(String) - */ - @Override - public List getRaxaAlertByAlertType(String alertType, boolean includeSeen) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.like("alertType", alertType)); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - List alerts = new ArrayList(); - alerts.addAll(criteria.list()); - return alerts; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlertByPatientId(Integer) - */ - @Override - public List getRaxaAlertByPatientId(Integer patientId, boolean includeSeen) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.eq("patientId", patientId)); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - List alerts = new ArrayList(); - alerts.addAll(criteria.list()); - return alerts; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlertByProviderSentId(Integer) - */ - @Override - public List getRaxaAlertByProviderSentId(Integer providerSentId, boolean includeSeen) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.eq("providerSentId", providerSentId)); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - List alerts = new ArrayList(); - alerts.addAll(criteria.list()); - return alerts; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getRaxaAlertByProviderRecipientId(Integer) - */ - @Override - public List getRaxaAlertByProviderRecipientId(Integer providerRecipientId, boolean includeSeen) - throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.eq("providerRecipientId", providerRecipientId)); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - List alerts = new ArrayList(); - alerts.addAll(criteria.list()); - return alerts; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#getAllRaxaAlert() - */ - @Override - public List getAllRaxaAlerts(boolean includeSeen) throws DAOException { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - return criteria.list(); - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#updateRaxaAlert(Integer) - */ - @Override - public RaxaAlert updateRaxaAlert(RaxaAlert raxaAlert) throws DAOException { - sessionFactory.getCurrentSession().update(raxaAlert); - return raxaAlert; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#markRaxaAlertAsSeen(boolean) - */ - @Override - public RaxaAlert markRaxaAlertAsSeen(RaxaAlert raxaAlert) { - raxaAlert.setSeen(true); - return raxaAlert; - } - - /** - * @see org.raxa.module.db.RaxaAlertDAO#voidRaxaAlert(RaxaAlert) - */ - @Override - public RaxaAlert voidRaxaAlert(RaxaAlert raxaAlert, String reason) { - if (reason == null) { - throw new IllegalArgumentException("The argument 'reason' is required and so cannot be null"); - } - - raxaAlert.setVoided(true); - raxaAlert.setVoidedBy(Context.getAuthenticatedUser()); - raxaAlert.setDateVoided(new Date()); - raxaAlert.setVoidReason(reason); - saveRaxaAlert(raxaAlert); - return raxaAlert; - } - - @Override - public List getRaxaAlertByToLocationId(Integer id, boolean includeSeen) { - Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RaxaAlert.class); - criteria.add(Restrictions.eq("toLocationId", id)); - if (includeSeen == false) - criteria.add(Restrictions.eq("seen", false)); - List alerts = new ArrayList(); - alerts.addAll(criteria.list()); - return alerts; - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/impl/DrugGroupServiceImpl.java b/api/src/main/java/org/raxa/module/raxacore/impl/DrugGroupServiceImpl.java deleted file mode 100644 index ada738607b..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/impl/DrugGroupServiceImpl.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.User; -import org.openmrs.Provider; -import org.openmrs.Person; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.DrugGroupService; -import org.raxa.module.raxacore.db.DrugGroupDAO; - -public class DrugGroupServiceImpl implements DrugGroupService { - - private DrugGroupDAO dao; - - private Log log = LogFactory.getLog(this.getClass()); - - /** - * @see org.raxa.module.raxacore.PatientListService#setPatientListDAO - */ - @Override - public void setDrugGroupDAO(DrugGroupDAO dao) { - this.dao = dao; - } - - /** - * @see org.raxa.module.raxacore.PatientListService#savePatientList - */ - @Override - public DrugGroup saveDrugGroup(DrugGroup drugGroup) { - return dao.saveDrugGroup(drugGroup); - } - - /** - * @see org.raxa.module.raxacore.PatientListService#getPatientList(Integer) - */ - @Override - public DrugGroup getDrugGroup(Integer id) { - return dao.getDrugGroup(id); - } - - /** - * @see - * org.raxa.module.raxacore.PatientListService#getPatientListByName(String) - */ - @Override - public List getDrugGroupByName(String name) { - return dao.getDrugGroupByName(name); - } - - /** - * @see - * org.raxa.module.raxacore.PatientListService#getPatientListByUuid(String) - */ - @Override - public DrugGroup getDrugGroupByUuid(String uuid) { - return dao.getDrugGroupByUuid(uuid); - } - - /** - * @see org.raxa.module.raxacore.PatientListService#getAllPatientList - */ - @Override - public List getAllDrugGroup(boolean includeRetired) { - return dao.getAllDrugGroup(includeRetired); - } - - /** - * Parses a string into a date - * - * @param str String to be parsed (must be iso format) - * @return Date - */ - private Date getDateFromString(String str) { - - String[] supportedFormats = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(str); - return date; - } - catch (Exception ex) { - //log.error(ex.getMessage() + " Error parsing string " + str + " into Date"); - } - } - log.error("Date string is malformed"); - return null; - } - - /** - * @see org.raxa.module.raxacore.PatientListService#updatePatientList - */ - @Override - public DrugGroup updateDrugGroup(DrugGroup drugGroup) { - return dao.updateDrugGroup(drugGroup); - } - - /** - * @see org.raxa.module.raxacore.PatientListService#deletePatientList - */ - @Override - public void deleteDrugGroup(DrugGroup drugGroup) { - dao.deleteDrugGroup(drugGroup); - } - - @Override - public void onStartup() { - log.info("Starting patient list service"); - } - - @Override - public void onShutdown() { - log.info("Stopping patient list service"); - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/impl/DrugInfoServiceImpl.java b/api/src/main/java/org/raxa/module/raxacore/impl/DrugInfoServiceImpl.java deleted file mode 100644 index 5fe51fc950..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/impl/DrugInfoServiceImpl.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Concept; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.User; -import org.openmrs.Provider; -import org.openmrs.Person; -import org.openmrs.Patient; -import org.openmrs.Drug; -import org.openmrs.api.context.Context; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; -import org.raxa.module.raxacore.db.DrugInfoDAO; - -public class DrugInfoServiceImpl implements DrugInfoService { - - private DrugInfoDAO dao; - - private Log log = LogFactory.getLog(this.getClass()); - - /** - * @see org.raxa.module.raxacore.DrugInfoService#setDrugInfoDAO - */ - @Override - public void setDrugInfoDAO(DrugInfoDAO dao) { - this.dao = dao; - } - - /** - * @see org.raxa.module.raxacore.DrugInfoService#saveDrugInfo - */ - @Override - public DrugInfo saveDrugInfo(DrugInfo drugInfo) { - return dao.saveDrugInfo(drugInfo); - } - - /** - * @see org.raxa.module.raxacore.DrugInfoService#getDrugInfo(Integer) - */ - @Override - public DrugInfo getDrugInfo(Integer id) { - return dao.getDrugInfo(id); - } - - /** - * @see - * org.raxa.module.raxacore.DrugInfoService#getDrugInfoByUuid(String) - */ - @Override - public DrugInfo getDrugInfoByUuid(String uuid) { - return dao.getDrugInfoByUuid(uuid); - } - - @Override - public DrugInfo getDrugInfoByDrugUuid(String uuid) { - Drug d = Context.getConceptService().getDrugByUuid(uuid); - return dao.getDrugInfoByDrug(d.getId()); - } - - @Override - public List getDrugInfosByDrugName(String name) { - List drugs = Context.getConceptService().getDrugs(name); - List drugInfos = new ArrayList(); - for (int i = 0; i < drugs.size(); i++) { - drugInfos.add(dao.getDrugInfoByDrug(drugs.get(i).getDrugId())); - } - return drugInfos; - } - - /** - * @see org.raxa.module.raxacore.DrugInfoService#getAllDrugInfo - */ - @Override - public List getAllDrugInfo(boolean includeVoided) { - return dao.getAllDrugInfo(includeVoided); - } - - /** - * Parses a string into a date - * - * @param str String to be parsed (must be iso format) - * @return Date - */ - private Date getDateFromString(String str) { - - String[] supportedFormats = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(str); - return date; - } - catch (Exception ex) { - //log.error(ex.getMessage() + " Error parsing string " + str + " into Date"); - } - } - log.error("Date string is malformed"); - return null; - } - - /** - * @see org.raxa.module.raxacore.DrugInfoService#updateDrugInfo - */ - @Override - public DrugInfo updateDrugInfo(DrugInfo drugInfo) { - return dao.updateDrugInfo(drugInfo); - } - - /** - * @see org.raxa.module.raxacore.DrugInfoService#deleteDrugInfo - */ - @Override - public void deleteDrugInfo(DrugInfo drugInfo) { - dao.deleteDrugInfo(drugInfo); - } - - @Override - public void onStartup() { - log.info("Starting drug info service"); - } - - @Override - public void onShutdown() { - log.info("Stopping drug info service"); - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/impl/DrugInventoryServiceImpl.java b/api/src/main/java/org/raxa/module/raxacore/impl/DrugInventoryServiceImpl.java deleted file mode 100644 index ce684db8e1..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/impl/DrugInventoryServiceImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugInventoryService; -import org.raxa.module.raxacore.db.DrugInventoryDAO; -import org.raxa.module.raxacore.db.DrugPurchaseOrderDAO; - -public class DrugInventoryServiceImpl implements DrugInventoryService { - - private DrugInventoryDAO dao; - - private Log log = LogFactory.getLog(this.getClass()); - - public void setDrugInventoryDAO(DrugInventoryDAO dao) { - this.dao = dao; - - } - - @Override - public void onShutdown() { - - log.info("Stopping drug inventory service"); - } - - @Override - public void onStartup() { - - log.info("Starting drug inventory service"); - } - - @Override - public DrugInventory saveDrugInventory(DrugInventory drugInventory) { - if (drugInventory.getOriginalQuantity() == null) - drugInventory.setOriginalQuantity(drugInventory.getQuantity()); - return dao.saveDrugInventory(drugInventory); - } - - @Override - public DrugInventory getDrugInventoryByUuid(String uuid) { - - return dao.getDrugInventoryByUuid(uuid); - } - - @Override - public List getAllDrugInventories() { - - return dao.getAllDrugInventories(); - } - - @Override - public List getAllDrugInventoriesByStatus(String status) { - - return dao.getAllDrugInventoriesByStatus(status); - } - - @Override - public DrugInventory updateDrugInventory(DrugInventory drugInventory) { - - return dao.updateDrugInventory(drugInventory); - } - - @Override - public void deleteDrugInventory(DrugInventory drugInventory) { - - dao.deleteDrugInventory(drugInventory); - } - - @Override - public List getDrugInventoryByProvider(Integer providerId) { - - return dao.getDrugInventoryByProvider(providerId); - } - - @Override - public List getDrugInventoriesByLocation(Integer location) { - return dao.getDrugInventoriesByLocation(location); - } - - @Override - public List getDrugInventoriesByDrugPurchaseOrder(Integer drugPurchaseOrderId) { - return dao.getDrugInventoriesByDrugPurchaseOrder(drugPurchaseOrderId); - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/impl/DrugPurchaseOrderServiceImpl.java b/api/src/main/java/org/raxa/module/raxacore/impl/DrugPurchaseOrderServiceImpl.java deleted file mode 100644 index 58fa63a7bc..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/impl/DrugPurchaseOrderServiceImpl.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.DrugPurchaseOrderService; -import org.raxa.module.raxacore.db.DrugPurchaseOrderDAO; -import org.raxa.module.raxacore.db.PatientListDAO; - -public class DrugPurchaseOrderServiceImpl implements DrugPurchaseOrderService { - - private DrugPurchaseOrderDAO dao; - - private Log log = LogFactory.getLog(this.getClass()); - - public void setDrugPurchaseOrderDAO(DrugPurchaseOrderDAO dao) { - this.dao = dao; - - } - - public void onShutdown() { - - log.info("Starting drug purchase order service"); - } - - public void onStartup() { - - log.info("Starting drug purchase order service"); - } - - public DrugPurchaseOrder saveDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - - return dao.saveDrugPurchaseOrder(drugPurchaseOrder); - } - - public DrugPurchaseOrder getDrugPurchaseOrderByUuid(String uuid) { - - return dao.getDrugPurchaseOrderByUuid(uuid); - } - - public List getAllDrugPurchaseOrders() { - - return dao.getAllDrugPurchaseOrders(); - } - - public List getAllDrugPurchaseOrdersNotReceived() { - - return dao.getAllDrugPurchaseOrdersNotReceived(); - } - - public DrugPurchaseOrder updateDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - - return dao.updateDrugPurchaseOrder(drugPurchaseOrder); - } - - public void deleteDrugPurchaseOrder(DrugPurchaseOrder drugPurchaseOrder) { - - dao.deleteDrugPurchaseOrder(drugPurchaseOrder); - } - - public List getDrugPurchaseOrderByProvider(Integer providerId) { - - return dao.getDrugPurchaseOrderByProvider(providerId); - } - - @Override - public List getDrugPurchaseOrderByDispenseLocation(Integer dispenseLocation) { - return dao.getDrugPurchaseOrderByDispenseLocation(dispenseLocation); - } - - @Override - public List getDrugPurchaseOrderByStockLocation(Integer stockLocation) { - return dao.getDrugPurchaseOrderByStockLocation(stockLocation); - } - -} diff --git a/api/src/main/java/org/raxa/module/raxacore/impl/PatientListServiceImpl.java b/api/src/main/java/org/raxa/module/raxacore/impl/PatientListServiceImpl.java deleted file mode 100644 index d6d6d02678..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/impl/PatientListServiceImpl.java +++ /dev/null @@ -1,319 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Location; -import org.openmrs.Order; -import org.openmrs.User; -import org.openmrs.Provider; -import org.openmrs.Person; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; -import org.raxa.module.raxacore.db.PatientListDAO; - -/* - * Implements PatientListService.java Note the PatientList query must be in the - * form of: - * "?encounterType=&startDate=2012-05-07&endDate=2012-05-08&inlist=¬inlist=" - */ -public class PatientListServiceImpl implements PatientListService { - - private PatientListDAO dao; - - private Log log = LogFactory.getLog(this.getClass()); - - /** - * @see org.raxa.module.raxacore.PatientListService#setPatientListDAO - */ - @Override - public void setPatientListDAO(PatientListDAO dao) { - this.dao = dao; - } - - /** - * @see org.raxa.module.raxacore.PatientListService#savePatientList - */ - @Override - public PatientList savePatientList(PatientList patientList) { - return dao.savePatientList(patientList); - } - - /** - * @see org.raxa.module.raxacore.PatientListService#getPatientList(Integer) - */ - @Override - public PatientList getPatientList(Integer id) { - return dao.getPatientList(id); - } - - /** - * @see - * org.raxa.module.raxacore.PatientListService#getPatientListByName(String) - */ - @Override - public List getPatientListByName(String name) { - return dao.getPatientListByName(name); - } - - /** - * @see - * org.raxa.module.raxacore.PatientListService#getPatientListByUuid(String) - */ - @Override - public PatientList getPatientListByUuid(String uuid) { - return dao.getPatientListByUuid(uuid); - } - - /** - * @see - * org.raxa.module.raxacore.PatientListService#getPatientListByEncounterType - */ - @Override - public List getPatientListByEncounterType(EncounterType encounterType) { - return dao.getPatientListByEncounterType(encounterType); - } - - /** - * @see org.raxa.module.raxacore.PatientListService#getAllPatientList - */ - @Override - public List getAllPatientList(boolean includeRetired) { - return dao.getAllPatientList(includeRetired); - } - - /** - * Parses a string into a date - * - * @param str String to be parsed (must be iso format) - * @return Date - */ - private Date getDateFromString(String str) { - - String[] supportedFormats = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(str); - return date; - } - catch (Exception ex) { - //log.error(ex.getMessage() + " Error parsing string " + str + " into Date"); - } - } - log.error("Date string is malformed"); - return null; - } - - /** - * @see - * org.raxa.module.raxacore.PatientListService#getEncountersInPatientList - */ - @Override - public List getEncountersInPatientList(PatientList patientList) { - if (patientList.getSearchQuery() == null) { - return new ArrayList(); - } - String query = patientList.getSearchQuery(); - if (query.indexOf("?") == 0) { - query = query.substring(1); - } - //"?encounterType=&startDate=2012-05-07&endDate=2012-05-08&inlist=¬inlist=" - EncounterType encType = null; - Date startDate = null; - Date endDate = null; - Provider provid = null; - Patient patient = null; - String uuid = null; - //the return value can only choose encounters from this list (if not null) - List inListEncounters = null; - //the return value can not contain any patients from this list - List notInListPatients = new ArrayList(); - List notInListEncounters = new ArrayList(); - Location location = null; - String containsOrderType = ""; - String[] queryFields = query.split("&"); - //if we have an encountertype in our search query, set it - for (int i = 0; i < queryFields.length; i++) { - if (queryFields[i].indexOf("encounterType=") != -1) { - encType = Context.getEncounterService().getEncounterTypeByUuid(queryFields[i].substring(14)); - } else if (queryFields[i].indexOf("location=") != -1) { - location = Context.getLocationService().getLocationByUuid(queryFields[i].substring(9)); - } else if (queryFields[i].indexOf("startDate=") != -1) { - startDate = getDateFromString(queryFields[i].substring(10)); - } else if (queryFields[i].indexOf("endDate=") != -1) { - endDate = getDateFromString(queryFields[i].substring(8)); - } else if (queryFields[i].indexOf("inList=") != -1) { - inListEncounters = new ArrayList(); - //could be multiple lists here, add all that are in - String[] inListUuids = queryFields[i].substring(7).split(","); - for (int j = 0; j < inListUuids.length; j++) { - inListEncounters.addAll(getEncountersInPatientList(getPatientListByUuid(inListUuids[j]))); - } - } else if (queryFields[i].indexOf("notInList=") != -1) { - String[] notInListUuids = queryFields[i].substring(10).split(","); - for (int k = 0; k < notInListUuids.length; k++) { - notInListPatients.addAll(getPatientsInPatientList(getPatientListByUuid(notInListUuids[k]))); - notInListEncounters.addAll(getEncountersInPatientList(getPatientListByUuid(notInListUuids[k]))); - } - } else if (queryFields[i].indexOf("provider=") != -1) { - uuid = queryFields[i].substring(9); - provid = Context.getProviderService().getProviderByUuid(uuid); - } else if (queryFields[i].indexOf("patient=") != -1) { - uuid = queryFields[i].substring(8); - patient = Context.getPatientService().getPatientByUuid(uuid); - } else if (queryFields[i].indexOf("containsOrderType=") != -1) { - containsOrderType = queryFields[i].substring(18); - } - } - List encTypes = new ArrayList(); - List provids = new ArrayList(); - List encs = new ArrayList(); - encTypes.add(encType); - provids.add(provid); - //if we give inList, start with that list and remove encounters - if (inListEncounters != null) { - encs = inListEncounters; - Iterator iter = encs.iterator(); - while (iter.hasNext()) { - Encounter currEnc = iter.next(); - if ((startDate != null && currEnc.getEncounterDatetime().before(startDate)) - || (endDate != null && currEnc.getEncounterDatetime().after(endDate)) - || (encType != null && !currEnc.getEncounterType().equals(encType)) - || (patient != null && !currEnc.getPatient().equals(patient))) { - iter.remove(); - } else if (provid != null) { - Iterator> providerIter = currEnc.getProvidersByRoles().values().iterator(); - boolean hasProvider = false; - while (providerIter.hasNext() && !hasProvider) { - Set providerEncounters = providerIter.next(); - if (providerEncounters.contains(provid)) { - hasProvider = true; - } - } - if (!hasProvider) { - iter.remove(); - } - } - } - } - //otherwise, make an entirely new list - else { - if (uuid != null) { - encs = Context.getEncounterService().getEncounters(patient, location, startDate, endDate, null, encTypes, - provids, null, null, Boolean.FALSE); - } else { - encs = Context.getEncounterService().getEncounters(patient, location, startDate, endDate, null, encTypes, - null, null, null, Boolean.FALSE); - } - } - //refactor this to hash map so double loop is not required - if (notInListPatients != null) { - Iterator iter = encs.iterator(); - Iterator iter2; - //if patient is in notInListPatients, remove the encounter - while (iter.hasNext()) { - Encounter currEnc = iter.next(); - //if patient already has encounter, check the dates to see if he should be removed - if (notInListPatients.contains(currEnc.getPatient())) { - iter2 = notInListEncounters.iterator(); - boolean removed = false; - while (iter2.hasNext() && !removed) { - Encounter currEnc2 = iter2.next(); - if (currEnc2.getPatient().equals(currEnc.getPatient()) - && currEnc2.getEncounterDatetime().after(currEnc.getEncounterDatetime())) { - iter.remove(); - removed = true; - } - } - } - } - } - if (containsOrderType.equals("drugOrder")) { - boolean shouldRemove; - Iterator iter = encs.iterator(); - while (iter.hasNext()) { - shouldRemove = true; - Encounter currEnc = iter.next(); - Iterator orderIter = currEnc.getOrders().iterator(); - while (orderIter.hasNext()) { - Order o = orderIter.next(); - if (o.isDrugOrder()) { - shouldRemove = false; - break; - } - } - if (shouldRemove) { - iter.remove(); - } - } - } - return encs; - } - - /** - * @see org.raxa.module.raxacore.PatientListService#getPatientsInList - */ - @Override - public List getPatientsInPatientList(PatientList patientList) { - List encounters = getEncountersInPatientList(patientList); - List patients = new ArrayList(); - for (int j = 0; j < encounters.size(); j++) { - //just in case we have an encounter for the same type with the same patient, check if already exists - if (!patients.contains(encounters.get(j).getPatient())) { - patients.add(encounters.get(j).getPatient()); - } - } - return patients; - } - - /** - * @see org.raxa.module.raxacore.PatientListService#updatePatientList - */ - @Override - public PatientList updatePatientList(PatientList patientList) { - return dao.updatePatientList(patientList); - } - - /** - * @see org.raxa.module.raxacore.PatientListService#deletePatientList - */ - @Override - public void deletePatientList(PatientList patientList) { - dao.deletePatientList(patientList); - } - - @Override - public void onStartup() { - log.info("Starting patient list service"); - } - - @Override - public void onShutdown() { - log.info("Stopping patient list service"); - } -} diff --git a/api/src/main/java/org/raxa/module/raxacore/impl/RaxaAlertServiceImpl.java b/api/src/main/java/org/raxa/module/raxacore/impl/RaxaAlertServiceImpl.java deleted file mode 100644 index f3c72f5f23..0000000000 --- a/api/src/main/java/org/raxa/module/raxacore/impl/RaxaAlertServiceImpl.java +++ /dev/null @@ -1,188 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.openmrs.Provider; -import org.openmrs.api.context.Context; -import org.raxa.module.raxacore.RaxaAlert; -import org.raxa.module.raxacore.RaxaAlertService; -import org.raxa.module.raxacore.db.RaxaAlertDAO; - -/* - * Implements RaxaAlertService.java - */ -public class RaxaAlertServiceImpl implements RaxaAlertService { - - private RaxaAlertDAO dao; - - private Log log = LogFactory.getLog(this.getClass()); - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#setRaxaAlertDAO - */ - @Override - public void setRaxaAlertDAO(RaxaAlertDAO dao) { - this.dao = dao; - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#saveRaxaAlert - */ - @Override - public RaxaAlert saveRaxaAlert(RaxaAlert raxaAlert) { - return dao.saveRaxaAlert(raxaAlert); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlert(Integer) - */ - @Override - public RaxaAlert getRaxaAlert(Integer id) { - return dao.getRaxaAlert(id); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlertByName(String) - */ - @Override - public List getRaxaAlertsByName(String name, boolean includeSeen) { - return dao.getRaxaAlertByName(name, includeSeen); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlertByAlertType(String) - */ - @Override - public List getRaxaAlertByAlertType(String alertType, boolean includeSeen) { - return (List) dao.getRaxaAlertByAlertType(alertType, includeSeen); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlertByUuid(String) - */ - @Override - public RaxaAlert getRaxaAlertByUuid(String uuid) { - return dao.getRaxaAlertByUuid(uuid); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlertByPatientId(Integer) - */ - @Override - public List getRaxaAlertByPatientId(Integer patientId, boolean includeSeen) { - return dao.getRaxaAlertByPatientId(patientId, includeSeen); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlertByProviderRecipientId(Integer) - */ - @Override - public List getRaxaAlertByProviderRecipientId(Integer providerRecipientId, boolean includeSeen) { - return dao.getRaxaAlertByProviderRecipientId(providerRecipientId, includeSeen); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getRaxaAlertByProviderSentId(Integer) - */ - @Override - public List getRaxaAlertByProviderSentId(Integer providerSentId, boolean includeSeen) { - return dao.getRaxaAlertByProviderSentId(providerSentId, includeSeen); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#getAllRaxaAlert - */ - @Override - public List getAllRaxaAlerts(boolean includeSeen) { - return dao.getAllRaxaAlerts(includeSeen); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#markRaxaAlertAsSeen - */ - @Override - public RaxaAlert markRaxaAlertAsSeen(RaxaAlert raxaAlert) { - return dao.markRaxaAlertAsSeen(raxaAlert); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#updateRaxaAlert - */ - @Override - public RaxaAlert updateRaxaAlert(RaxaAlert raxaAlert) { - return dao.updateRaxaAlert(raxaAlert); - } - - /** - * @see org.raxa.module.raxacore.RaxaAlertService#deleteRaxaAlert - */ - @Override - public void deleteRaxaAlert(RaxaAlert raxaAlert) { - dao.deleteRaxaAlert(raxaAlert); - } - - /** - * This executes on startup - */ - @Override - public void onStartup() { - log.info("Starting raxa alert service"); - } - - /** - * This executes on shutdown - */ - @Override - public void onShutdown() { - log.info("Stopping raxa alert service"); - } - - @Override - public void voidRaxaAlert(RaxaAlert raxaAlert, String reason) { - dao.voidRaxaAlert(raxaAlert, reason); - } - - @Override - public void purgeRaxaAlert(RaxaAlert raxaAlert) { - dao.deleteRaxaAlert(raxaAlert); - } - - @Override - public List getRaxaAlertByProviderSentUuid(String providerSentUuid, boolean includeSeen) { - Provider p = Context.getProviderService().getProviderByUuid(providerSentUuid); - if (p == null) { - return new ArrayList(); - } - return dao.getRaxaAlertByProviderSentId(p.getId(), includeSeen); - } - - @Override - public List getRaxaAlertByProviderRecipientUuid(String providerRecipientUuid, boolean includeSeen) { - return dao.getRaxaAlertByProviderRecipientId(Context.getProviderService().getProviderByUuid(providerRecipientUuid) - .getId(), includeSeen); - } - - @Override - public List getRaxaAlertByToLocationUuid(String toLocation, boolean includeSeen) { - return dao.getRaxaAlertByToLocationId(Context.getLocationService().getLocationByUuid(toLocation).getId(), - includeSeen); - } - -} diff --git a/api/src/main/resources/RaxacoreDrugGroup.hbm.xml b/api/src/main/resources/RaxacoreDrugGroup.hbm.xml deleted file mode 100644 index 24ddfb459c..0000000000 --- a/api/src/main/resources/RaxacoreDrugGroup.hbm.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/main/resources/RaxacoreDrugInfo.hbm.xml b/api/src/main/resources/RaxacoreDrugInfo.hbm.xml deleted file mode 100644 index 385f17437e..0000000000 --- a/api/src/main/resources/RaxacoreDrugInfo.hbm.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/main/resources/RaxacoreDrugInventory.hbm.xml b/api/src/main/resources/RaxacoreDrugInventory.hbm.xml deleted file mode 100644 index 43eac611f5..0000000000 --- a/api/src/main/resources/RaxacoreDrugInventory.hbm.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/main/resources/RaxacoreDrugPurchaseOrder.hbm.xml b/api/src/main/resources/RaxacoreDrugPurchaseOrder.hbm.xml deleted file mode 100644 index 7c29718722..0000000000 --- a/api/src/main/resources/RaxacoreDrugPurchaseOrder.hbm.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/main/resources/RaxacorePatientList.hbm.xml b/api/src/main/resources/RaxacorePatientList.hbm.xml deleted file mode 100644 index 18c7fd30cd..0000000000 --- a/api/src/main/resources/RaxacorePatientList.hbm.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/main/resources/RaxacoreRaxaAlert.hbm.xml b/api/src/main/resources/RaxacoreRaxaAlert.hbm.xml deleted file mode 100644 index 0f769ecbdd..0000000000 --- a/api/src/main/resources/RaxacoreRaxaAlert.hbm.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/src/main/resources/liquibase.xml b/api/src/main/resources/liquibase.xml deleted file mode 100644 index 0a73569234..0000000000 --- a/api/src/main/resources/liquibase.xml +++ /dev/null @@ -1,1426 +0,0 @@ - - - - - - - - - - - - - - Schema for raxacore_patient_list table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for auditing PatientList--making sure - anyone who creates/voids a PatientList table is a user - - - - - - - - - - - - - - Schema for raxacore_raxaalert table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for auditing Raxaalert--making sure - anyone who creates/voids a Raxaalert table is a user - - - - - - - - - - - - - - - Schema for raxacore_raxaalert_providerrecipient table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Schema for raxacore_drug_group table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Schema for drug_purchase_order table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for drug_purchase_order. - - - - - - - - - - - - - - - - - - - - - - - - - Schema for drug_inventory_resource table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for drug_inventory_resource. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Schema for raxacore_billing table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding drug_purchase_order_id column to drug_inventory_resource - - - - - - - - - - - - - Adding dispense_location stock_location, removing Location_id - - - - - - - - - - - - - - - - - Adding dispense_location stock_location, removing Location_id - - - - - - - - - - - - Adding to, from locations, removing constraints in raxa alert - - - - - - - - - - - - - - - - - - Schema for raxacore_drug_info table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for auditing drug_info - - - - - - - - - - - - Schema for raxacore_drug_drug_group table - - - - - - - - - - - - - - - - - Adding constraints for auditing raxacore_drug_drug_group - - - - - - - - - - - Removing voided columns in raxacore_drug_info - - - - - - - - - - - - - Adding supplier field to drug inventory - - - - - - - - - - - - Adding short name and brand name fields to drug info - - - - - - - - - - - - - - - - - - Schema for raxacore_image table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for auditing images, tying image to patient - - - - - - - - - - - - - - Adding supplier/manufacturer fields to raxacore drug info - - - - - - - - - - - - - - - - - - Adding constraints for raxacore_billing - - - - - - - - - - - - - - - - - - - - - - - Schema for raxacore_billing_item table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for raxacore_billing_item - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Schema for raxacore_billing_item_adjustment - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adding constraints for raxacore_billing_item_adjustment - - - - - - - - - - - - - - - Alter Schema for raxacore_billing_item - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/main/resources/moduleApplicationContext.xml b/api/src/main/resources/moduleApplicationContext.xml deleted file mode 100644 index 0d8091b5ed..0000000000 --- a/api/src/main/resources/moduleApplicationContext.xml +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - classpath:hibernate.cfg.xml - classpath:test-hibernate.cfg.xml - - - - - - - - - - - - - - - org.raxa.module.raxacore.PatientListService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.RaxaAlertService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugGroupService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugInfoService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugInventoryService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugPurchaseOrderService - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugGroupDAOTest.java b/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugGroupDAOTest.java deleted file mode 100644 index 2cfdecedee..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugGroupDAOTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.*; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Concept; -import org.openmrs.Drug; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.db.DrugGroupDAO; - -public class HibernateDrugGroupDAOTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private DrugGroupDAO dao = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - dao = (HibernateDrugGroupDAO) applicationContext - .getBean("org.raxa.module.raxacore.db.hibernate.HibernateDrugGroupDAO"); - } - - @Test - public void testSaveDrugGroup() { - DrugGroup drugGroup = new DrugGroup(); - drugGroup.setName("TestDrugGroup3"); - drugGroup.setDescription("Third Test Drug Group"); - drugGroup.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugGroup.setDateCreated(new java.util.Date()); - drugGroup.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - drugGroup.setRetired(Boolean.FALSE); - dao.saveDrugGroup(drugGroup); - List result = dao.getDrugGroupByName("TestDrugGroup3"); - String name = result.get(0).getName(); - assertEquals(name, "TestDrugGroup3"); - } - - @Test - public void testDeleteDrugGroup() { - DrugGroup drugGroup = new DrugGroup(); - drugGroup.setId(2); - drugGroup.setName("TestDrugGroup2"); - drugGroup.setDescription("Second Test Drug Group"); - drugGroup.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugGroup.setDateCreated(new java.util.Date()); - drugGroup.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - drugGroup.setRetired(Boolean.FALSE); - Set drugs = new HashSet(); - Drug drug1 = new Drug(); - Drug drug2 = new Drug(); - drug1.setId(1); - drug1.setConcept(new Concept(792)); - drug1.setDateCreated(new Date()); - drug1.setCreator(Context.getUserContext().getAuthenticatedUser()); - drug2.setId(2); - drug2.setConcept(new Concept(792)); - drug2.setDateCreated(new Date()); - drug2.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugs.add(drug1); - drugs.add(drug2); - drugGroup.setDrugs(drugs); - dao.deleteDrugGroup(drugGroup); - DrugGroup result = dao.getDrugGroup(2); - assertEquals(null, result); - } - - @Test - public void testGetDrugGroup() { - Integer drugGroupId = 1; - DrugGroup result = dao.getDrugGroup(drugGroupId); - String name = result.getName(); - assertEquals("TestDrugGroup1", name); - - Set resDrugs = result.getDrugs(); - Iterator itr = resDrugs.iterator(); - Drug drug3 = itr.next(); - Integer drugId = 11; - assertEquals(drug3.getId(), drugId); - } - - @Test - public void testGetDrugGroupByUuid() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = dao.getDrugGroupByUuid(uuid).getName(); - assertEquals("TestDrugGroup2", result); - } - - @Test - public void testGetDrugGroupByName() { - String name = "TestDrugGroup1"; - String result = dao.getDrugGroupByName(name).get(0).getName(); - assertEquals(name, result); - } - - @Test - public void testUpdateDrugGroup() { - String nameSet = "NewDrugGroupName"; - String nameRetrieved; - DrugGroup drugGroup = dao.getDrugGroup(1); - drugGroup.setName(nameSet); - Set drugs = new HashSet(); - Drug drug1 = new Drug(); - Drug drug2 = new Drug(); - drug1.setId(1); - drug1.setConcept(new Concept(792)); - drug2.setId(2); - drug2.setConcept(new Concept(792)); - drugs.add(drug1); - drugs.add(drug2); - drugGroup.setDrugs(drugs); - dao.updateDrugGroup(drugGroup); - nameRetrieved = dao.getDrugGroup(1).getName(); - Set resDrugs = dao.getDrugGroup(1).getDrugs(); - assertEquals(nameSet, nameRetrieved); - assertEquals(resDrugs.contains(drug1), true); - assertEquals(resDrugs.contains(drug2), true); - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInfoDAOTest.java b/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInfoDAOTest.java deleted file mode 100644 index fda09332b9..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInfoDAOTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Drug; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.db.DrugInfoDAO; - -public class HibernateDrugInfoDAOTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private DrugInfoDAO dao = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - dao = (HibernateDrugInfoDAO) applicationContext - .getBean("org.raxa.module.raxacore.db.hibernate.HibernateDrugInfoDAO"); - } - - /** - * Test of saveDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testSaveDrugInfo() { - DrugInfo drugInfo = new DrugInfo(); - Drug drug = new Drug(); - drug.setId(3); - drugInfo.setDrug(drug); - drugInfo.setDrugId(drug.getId()); - drugInfo.setName("TestDrugInfo3"); - drugInfo.setDescription("Third Test DrugInfo"); - drugInfo.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugInfo.setDateCreated(new java.util.Date()); - drugInfo.setUuid("68547121-1b70-465c-99ef-c9dfd95e7d30"); - drugInfo.setRetired(Boolean.FALSE); - dao.saveDrugInfo(drugInfo); - DrugInfo result = dao.getDrugInfoByUuid("68547121-1b70-465c-99ef-c9dfd95e7d30"); - String name = result.getName(); - assertEquals(name, "TestDrugInfo3"); - } - - /** - * Test of deleteDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testDeleteDrugInfo() { - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setId(2); - Drug drug = new Drug(); - drug.setId(5); - drug.setDrugId(5); - drugInfo.setDrugId(5); - drugInfo.setDrug(drug); - drugInfo.setName("TestDrugInfo2"); - drugInfo.setDescription("Second Test DrugInfo"); - drugInfo.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugInfo.setDateCreated(new java.util.Date()); - drugInfo.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - drugInfo.setRetired(Boolean.FALSE); - dao.deleteDrugInfo(drugInfo); - DrugInfo result = dao.getDrugInfo(2); - assertEquals(null, result); - } - - /** - * Test of getDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testGetDrugInfo() { - Integer drugInfoId = 1; - DrugInfo result = dao.getDrugInfo(drugInfoId); - String name = result.getName(); - assertEquals("TestDrugInfo1", name); - } - - /** - * Test of getDrugInfoByUuid method, of class HibernateDrugInfoDAO. - */ - @Test - public void testGetDrugInfoByUuid() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = dao.getDrugInfoByUuid(uuid).getName(); - assertEquals("TestDrugInfo2", result); - } - - /** - * Test of getDrugInfoByName method, of class HibernateDrugInfoDAO. - */ - @Test - public void testGetDrugInfoByName() { - String name = "TestDrugInfo1"; - String result = dao.getDrugInfoByName(name).get(0).getName(); - assertEquals(name, result); - } - - /** - * Test of updateDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testUpdateDrugInfo() { - DrugInfo drugInfo = dao.getDrugInfo(1); - drugInfo.setName("NewNameDrugInfo"); - dao.updateDrugInfo(drugInfo); - String name = dao.getDrugInfo(1).getName(); - assertEquals(name, "NewNameDrugInfo"); - } - - /** - * Test of getAllDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testGetAllDrugInfo_shouldReturnUnretiredDrugInfo() { - List allDrugInfo = dao.getAllDrugInfo(false); - assertEquals(allDrugInfo.size(), 2); - } - - /** - * Test of getAllDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testGetAllDrugInfo_shouldReturnAllDrugInfoIncludingRetired() { - List allDrugInfo = dao.getAllDrugInfo(true); - assertEquals(allDrugInfo.size(), 3); - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInventoryDAOTest.java b/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInventoryDAOTest.java deleted file mode 100644 index dbc78c55e6..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugInventoryDAOTest.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.Date; -import java.util.List; -import static org.junit.Assert.*; - -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Drug; -import org.openmrs.EncounterType; -import org.openmrs.Location; -import org.openmrs.Provider; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.db.DrugInventoryDAO; -import org.raxa.module.raxacore.db.PatientListDAO; - -public class HibernateDrugInventoryDAOTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private DrugInventoryDAO dao = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - dao = (DrugInventoryDAO) applicationContext - .getBean("org.raxa.module.raxacore.db.hibernate.HibernateDrugInventoryDAO"); - } - - @Test - public void testSaveDrugInventory() { - DrugInventory dInventory = new DrugInventory(); - //NOTE: never set Id, will be generated automatically (when saving) - - dInventory.setName("TestList6"); - dInventory.setDescription("Third Test List"); - dInventory.setCreator(Context.getUserContext().getAuthenticatedUser()); - dInventory.setDateCreated(new java.util.Date()); - dInventory.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d34"); - dInventory.setDateCreated(new java.util.Date()); - dInventory.setRetired(Boolean.FALSE); - dInventory.setBatch("batch 1"); - dInventory.setQuantity(10); - dInventory.setStatus("true"); - //dInventory.setDrugId(2); - dInventory.setExpiryDate(new Date(2012 - 1 - 1)); - dInventory.setValue(20); - dInventory.setProviderId(2); - dInventory.setLocationId(1); - dInventory.setDrugPurchaseOrderId(14); - dInventory.setOriginalQuantity(20); - - dao.saveDrugInventory(dInventory); - DrugInventory result = dao.getDrugInventoryByUuid("68547121-1b70-465c-99ee-c9dfd95e7d34"); - //DrugInventory result=dao.get - String uuid = result.getUuid(); - assertEquals(uuid, "68547121-1b70-465c-99ee-c9dfd95e7d34"); - } - - @Test - public void testDeleteDrugInventory() { - DrugInventory dInventory = new DrugInventory(); - dInventory.setName("TestList6"); - dInventory.setDescription("Third Test List"); - dInventory.setCreator(Context.getUserContext().getAuthenticatedUser()); - dInventory.setDateCreated(new java.util.Date()); - dInventory.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d34"); - dInventory.setDateCreated(new java.util.Date()); - dInventory.setRetired(Boolean.FALSE); - dInventory.setBatch("batch 1"); - dInventory.setQuantity(10); - dInventory.setStatus("true"); - //dInventory.setDrugId(2); - dInventory.setExpiryDate(new Date(2012 - 1 - 1)); - dInventory.setValue(20); - dInventory.setProviderId(2); - dInventory.setLocationId(1); - dInventory.setDrugPurchaseOrderId(14); - dInventory.setOriginalQuantity(20); - - dao.deleteDrugInventory(dInventory); - - DrugInventory result = dao.getDrugInventoryByUuid("68547121-1b70-465c-99ee-c9dfd95e7d34"); - assertEquals(result, null); - - } - - @Test - public void testGetDrugInventoryByUuid() { - DrugInventory result = dao.getDrugInventoryByUuid("68547121-1b70-465c-99ee-c9dfd95e7d36"); - String name = result.getName(); - assertEquals(name, "Test drug inventory"); - - } - - @Test - public void testGetAllDrugInventories() { - - List allDrugInventories = dao.getAllDrugInventories(); - assertEquals(allDrugInventories.size(), 1); - - } - - @Test - public void testGetAllDrugInventoriesByStatus() { - List allDrugInventories = dao.getAllDrugInventoriesByStatus("on the way"); - assertEquals(allDrugInventories.size(), 1); - } - - @Test - public void testUpdateDrugInventory() { - DrugInventory dInventory = dao.getDrugInventoryByUuid("68547121-1b70-465c-99ee-c9dfd95e7d36"); - dInventory.setName("new test list"); - dao.updateDrugInventory(dInventory); - String name = dao.getDrugInventoryByUuid("68547121-1b70-465c-99ee-c9dfd95e7d36").getName(); - assertEquals(name, "new test list"); - - } - - @Test - public void testGetDrugInventoryByProvider() { - List result = dao.getDrugInventoryByProvider(1); - assertEquals(result.size(), 1); - - } - - @Test - public void testGetDrugInventoryByLocation() { - List result = dao.getDrugInventoriesByLocation(1); - assertEquals(result.size(), 1); - - } - - @Test - public void testGetDrugInventoryByDrugPurchaseOrder() { - List result = dao.getDrugInventoriesByDrugPurchaseOrder(1); - assertEquals(result.size(), 1); - - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugPurchaseOrderDAOTest.java b/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugPurchaseOrderDAOTest.java deleted file mode 100644 index bc408f52ae..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateDrugPurchaseOrderDAOTest.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -import java.util.Date; -import java.util.List; -import static org.junit.Assert.*; - -import org.junit.Before; -import org.junit.Test; -import org.openmrs.EncounterType; -import org.openmrs.Location; -import org.openmrs.Provider; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.db.DrugPurchaseOrderDAO; - -public class HibernateDrugPurchaseOrderDAOTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private DrugPurchaseOrderDAO dao = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - dao = (HibernateDrugPurchaseOrderDAO) applicationContext - .getBean("org.raxa.module.raxacore.db.hibernate.HibernateDrugPurchaseOrderDAO"); - } - - @Test - public void testsaveDrugPurchaseOrder() { - DrugPurchaseOrder dpOrder = new DrugPurchaseOrder(); - - Provider provider = new Provider(1); - provider.setDateCreated(new Date()); - Location location = new Location(1); - location.setDateCreated(new Date()); - - //NOTE: never set Id, will be generated automatically (when saving) - - dpOrder.setName("TestList4"); - dpOrder.setDescription("Third Test List"); - dpOrder.setCreator(Context.getUserContext().getAuthenticatedUser()); - dpOrder.setDateCreated(new java.util.Date()); - dpOrder.setDrugPurchaseOrderDate(new Date()); - - dpOrder.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - dpOrder.setRetired(Boolean.FALSE); - dpOrder.setProviderId(new Integer(3)); - dpOrder.setDispenseLocationId(1); - dpOrder.setStockLocationId(2); - dpOrder.setProvider(provider); - dpOrder.setDispenseLocation(Context.getLocationService().getLocation(1)); - dpOrder.setStockLocation(Context.getLocationService().getLocation(2)); - - dao.saveDrugPurchaseOrder(dpOrder); - DrugPurchaseOrder result = dao.getDrugPurchaseOrderByUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - - String uuid = result.getUuid(); - assertEquals(uuid, "68547121-1b70-465c-99ee-c9dfd95e7d30"); - //assertEquals() - - } - - @Test - public void testGetDrugPurchaseOrderByUuid() { - - DrugPurchaseOrder result = dao.getDrugPurchaseOrderByUuid("68547121-1b70-465c-99ee-c9dfd95e7d31"); - String name = result.getName(); - assertEquals(name, "Test drug PO"); - } - - @Test - public void testGetAllDrugPurchaseOrders() { - List allDrugPurchaseOrders = dao.getAllDrugPurchaseOrders(); - assertEquals(allDrugPurchaseOrders.size(), 2); - } - - @Test - public void testGetAllDrugPurchaseOrdersNotReceived() { - List allDrugPurchaseOrders = dao.getAllDrugPurchaseOrders(); - int size = allDrugPurchaseOrders.size(); - - for (DrugPurchaseOrder dpOrder : allDrugPurchaseOrders) { - if (dpOrder.isReceived()) { - size--; - } - } - assertEquals(size, 1); - } - - @Test - public void testDeleteDrugPurchaseOrder() { - DrugPurchaseOrder dpOrder = new DrugPurchaseOrder(); - - Provider provider = new Provider(1); - provider.setDateCreated(new Date()); - Location location = new Location(1); - location.setDateCreated(new Date()); - - //NOTE: never set Id, will be generated automatically (when saving) - - dpOrder.setName("TestList4"); - dpOrder.setDescription("Third Test List"); - dpOrder.setCreator(Context.getUserContext().getAuthenticatedUser()); - dpOrder.setDateCreated(new java.util.Date()); - dpOrder.setDrugPurchaseOrderDate(new Date()); - - dpOrder.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - dpOrder.setRetired(Boolean.FALSE); - dpOrder.setProviderId(new Integer(3)); - dpOrder.setDispenseLocationId(new Integer(1)); - dpOrder.setStockLocationId(new Integer(2)); - dpOrder.setProvider(provider); - dpOrder.setDispenseLocation(Context.getLocationService().getLocation(1)); - dpOrder.setStockLocation(Context.getLocationService().getLocation(2)); - - dao.deleteDrugPurchaseOrder(dpOrder); - DrugPurchaseOrder result = dao.getDrugPurchaseOrderByUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - assertEquals(result, null); - } - - @Test - public void testGetDrugPurchaseOrderByProvider() { - List result = dao.getDrugPurchaseOrderByProvider(1); - assertEquals(result.size(), 2); - } - - @Test - public void testGetDrugPurchaseOrderByDispenseLocation() { - List result = dao.getDrugPurchaseOrderByDispenseLocation(1); - assertEquals(1, result.size()); - } - - @Test - public void testGetDrugPurchaseOrderByStockLocation() { - List result = dao.getDrugPurchaseOrderByStockLocation(1); - assertEquals(1, result.size()); - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernatePatientListDAOTest.java b/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernatePatientListDAOTest.java deleted file mode 100644 index ebc4bebe53..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernatePatientListDAOTest.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.EncounterType; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.db.PatientListDAO; - -public class HibernatePatientListDAOTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private PatientListDAO dao = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - dao = (HibernatePatientListDAO) applicationContext - .getBean("org.raxa.module.raxacore.db.hibernate.HibernatePatientListDAO"); - } - - /** - * Test of savePatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testSavePatientList() { - PatientList pList = new PatientList(); - //NOTE: never set Id, will be generated automatically (when saving) - pList.setName("TestList3"); - pList.setDescription("Third Test List"); - pList.setCreator(Context.getUserContext().getAuthenticatedUser()); - pList.setDateCreated(new java.util.Date()); - pList.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - pList.setRetired(Boolean.FALSE); - pList.setSearchQuery("test Query"); - dao.savePatientList(pList); - List result = dao.getPatientListByName("TestList3"); - String name = result.get(0).getName(); - assertEquals(name, "TestList3"); - } - - /** - * Test of deletePatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testDeletePatientList() { - PatientList pList = new PatientList(); - pList.setId(2); - pList.setName("TestList2"); - pList.setDescription("Second Test List"); - pList.setCreator(Context.getUserContext().getAuthenticatedUser()); - pList.setDateCreated(new java.util.Date()); - pList.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - pList.setRetired(Boolean.FALSE); - pList.setSearchQuery(""); - dao.deletePatientList(pList); - PatientList result = dao.getPatientList(2); - assertEquals(null, result); - } - - /** - * Test of getPatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testGetPatientList() { - Integer patientListId = 1; - PatientList result = dao.getPatientList(patientListId); - String name = result.getName(); - assertEquals("TestList1", name); - } - - /** - * Test of getPatientListByEncounterType method, of class HibernatePatientListDAO. - */ - @Test - public void testGetPatientListByEncounterType() { - EncounterType encounterType = new EncounterType(); - encounterType.setName("Registration"); - encounterType.setUuid("61ae96f4-6afe-4351-b6f8-cd4fc383cce1"); - encounterType.setDescription("Patient has been registered"); - encounterType.setRetired(Boolean.FALSE); - String name = dao.getPatientListByEncounterType(encounterType).get(0).getName(); - assertEquals("TestList1", name); - } - - /** - * Test of getPatientListByUuid method, of class HibernatePatientListDAO. - */ - @Test - public void testGetPatientListByUuid() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = dao.getPatientListByUuid(uuid).getName(); - assertEquals("TestList2", result); - } - - /** - * Test of getPatientListByName method, of class HibernatePatientListDAO. - */ - @Test - public void testGetPatientListByName() { - String name = "TestList1"; - String result = dao.getPatientListByName(name).get(0).getName(); - assertEquals(name, result); - } - - /** - * Test of updatePatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testUpdatePatientList() { - PatientList patientList = dao.getPatientList(1); - patientList.setName("NewNameList"); - dao.updatePatientList(patientList); - String name = dao.getPatientList(1).getName(); - assertEquals(name, "NewNameList"); - } - - /** - * Test of getAllPatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testGetAllPatientList_shouldReturnUnretiredPatientList() { - List allPatientList = dao.getAllPatientList(false); - assertEquals(allPatientList.size(), 2); - } - - /** - * Test of getAllPatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testGetAllPatientList_shouldReturnAllPatientListIncludingRetired() { - List allPatientList = dao.getAllPatientList(true); - assertEquals(allPatientList.size(), 3); - } - -} diff --git a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateRaxaAlertDAOTest.java b/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateRaxaAlertDAOTest.java deleted file mode 100644 index e3f8d432dd..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/db/hibernate/HibernateRaxaAlertDAOTest.java +++ /dev/null @@ -1,202 +0,0 @@ -package org.raxa.module.raxacore.db.hibernate; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -import java.util.List; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.RaxaAlert; -import org.raxa.module.raxacore.db.RaxaAlertDAO; - -/** - * @author Tarang Mahajan - */ - -public class HibernateRaxaAlertDAOTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private RaxaAlertDAO dao = null; - - /** - * Getting test data and bean - */ - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - dao = (HibernateRaxaAlertDAO) applicationContext - .getBean("org.raxa.module.raxacore.db.hibernate.HibernateRaxaAlertDAO"); - } - - /** - * Test of saveRaxaAlert method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testSaveRaxaAlert() { - RaxaAlert rAlert = new RaxaAlert(); - //NOTE: never set Id, will be generated automatically (when saving) - rAlert.setName("TestList3"); - rAlert.setDescription("Third Test List"); - rAlert.setCreator(Context.getUserContext().getAuthenticatedUser()); - rAlert.setDateCreated(new java.util.Date()); - rAlert.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - rAlert.setVoided(Boolean.FALSE); - rAlert.setProviderSentId(1); - rAlert.setProviderRecipientId(2); - dao.saveRaxaAlert(rAlert); - RaxaAlert result = dao.getRaxaAlertByName("TestList3", true).get(0); - String name = result.getName(); - assertEquals(name, "TestList3"); - } - - /** - * Test of deleteRaxaAlert method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testDeleteRaxaAlert() { - RaxaAlert rAlert = new RaxaAlert(); - rAlert.setName("TestList2"); - rAlert.setId(2); - rAlert.setDescription("Second Test List"); - rAlert.setCreator(Context.getUserContext().getAuthenticatedUser()); - rAlert.setDateCreated(new java.util.Date()); - rAlert.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - rAlert.setVoided(Boolean.FALSE); - rAlert.setProviderSentId(1); - rAlert.setProviderRecipientId(2); - dao.deleteRaxaAlert(rAlert); - RaxaAlert result = dao.getRaxaAlert(2); - assertEquals(null, result); - } - - /** - * Test of getRaxaAlert method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlert() { - Integer raxaAlertId = 1; - RaxaAlert result = dao.getRaxaAlert(raxaAlertId); - String name = result.getName(); - assertEquals("TestList1", name); - } - - /** - * Test of getRaxaAlertByUuid method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlertByUuid() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = dao.getRaxaAlertByUuid(uuid).getName(); - assertEquals("TestList1", result); - } - - /** - * Test of getRaxaAlertByName method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlertByName() { - String name = "TestList1"; - String result = dao.getRaxaAlertByName(name, true).get(0).getName(); - assertEquals(name, result); - } - - /** - * Test of getRaxaAlertByAlertType method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlertByAlertType() { - String alertType = "test1"; - String result = dao.getRaxaAlertByAlertType(alertType, true).get(0).getAlertType(); - assertEquals(alertType, result); - } - - /** - * Test of getRaxaAlertByPatientId method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlertByPatientId() { - Integer patientId = 1; - String result = dao.getRaxaAlertByPatientId(patientId, true).get(0).getName(); - assertEquals("TestList1", result); - } - - /** - * Test of getRaxaAlertByProviderSentId method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlertByProviderSentId() { - Integer providerSentId = 1; - String result = dao.getRaxaAlertByProviderSentId(providerSentId, true).get(0).getName(); - assertEquals("TestList1", result); - } - - /** - * Test of getRaxaAlertByProviderRecipientId method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetRaxaAlertByProviderRecipientId() { - Integer providerRecipientId = 1; - String result = dao.getRaxaAlertByProviderRecipientId(providerRecipientId, true).get(0).getName(); - assertEquals("TestList1", result); - } - - /** - * Test of getAllRaxaAlerts method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetAllRaxaAlert_shouldReturnAllRaxaAlertsIncludingVoided() { - List allRaxaAlert = dao.getAllRaxaAlerts(true); - assertEquals(allRaxaAlert.size(), 1); - } - - /** - * Test of getAllRaxaAlerts method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testGetAllRaxaAlert_shouldReturnAllUnvoidedRaxaAlerts() { - List allRaxaAlert = dao.getAllRaxaAlerts(false); - assertEquals(allRaxaAlert.size(), 0); - } - - /** - * Test of updateRaxaAlert method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testUpdateRaxaAlert() { - RaxaAlert raxaAlert = dao.getRaxaAlert(1); - raxaAlert.setName("NewNameList"); - dao.updateRaxaAlert(raxaAlert); - String name = dao.getRaxaAlert(1).getName(); - assertEquals(name, "NewNameList"); - } - - /** - * Test of markRaxaAlertAsSeen method, of class HibernateRaxaAlertDAO. - */ - @Test - public void testMarkRaxaAlertAsSeen() { - RaxaAlert raxaAlert = dao.getRaxaAlert(1); - dao.markRaxaAlertAsSeen(raxaAlert); - Boolean seen = dao.getRaxaAlert(1).getSeen(); - assertEquals(seen, true); - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/impl/DrugGroupServiceImplTest.java b/api/src/test/java/org/raxa/module/raxacore/impl/DrugGroupServiceImplTest.java deleted file mode 100644 index 5f4dfaaaae..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/impl/DrugGroupServiceImplTest.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Concept; -import org.openmrs.Drug; -import org.openmrs.User; -import org.openmrs.api.APIAuthenticationException; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.DrugGroupService; - -/* - * Testing the methods in DrugGroupServiceImpl - */ -public class DrugGroupServiceImplTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private DrugGroupService s = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - s = Context.getService(DrugGroupService.class); - //removing system developer role to test our privileges - } - - @Test - public void testSaveDrugGroupShouldUsePrivileges() throws Exception { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - DrugGroup drugGroup = new DrugGroup(); - drugGroup.setName("TestDrugGroup3"); - drugGroup.setDescription("Third Test Drug Group"); - drugGroup.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugGroup.setDateCreated(new java.util.Date()); - drugGroup.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - drugGroup.setRetired(Boolean.FALSE); - try { - s.saveDrugGroup(drugGroup); - // if we don't throw exception fail - no privileges required! - fail("No privileges required for saveDrugGroup"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Add Drug Groups"); - Context.getUserContext().addProxyPrivilege("View Drug Groups"); - Context.getUserContext().addProxyPrivilege("View Users"); - s.saveDrugGroup(drugGroup); - } - } - - @Test - public void testSaveDrugGroupShouldSaveDrugGroup() throws Exception { - DrugGroup drugGroup = new DrugGroup(); - Set drugs = new HashSet(); - Drug drug1 = new Drug(); - Drug drug2 = new Drug(); - drug1.setId(1); - drug1.setConcept(new Concept(792)); - drug2.setId(2); - drug2.setConcept(new Concept(792)); - drugs.add(drug1); - drugs.add(drug2); - //NOTE: never set Id, will be generated automatically (when saving) - drugGroup.setName("TestDrugGroup3"); - drugGroup.setDescription("Third Test Drug Group"); - drugGroup.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugGroup.setDateCreated(new java.util.Date()); - drugGroup.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - drugGroup.setRetired(Boolean.FALSE); - drugGroup.setDrugs(drugs); - s.saveDrugGroup(drugGroup); - List result = s.getDrugGroupByName("TestDrugGroup3"); - String name = result.get(0).getName(); - Set resDrugs = result.get(0).getDrugs(); - assertEquals(name, "TestDrugGroup3"); - assertEquals(resDrugs.contains(drug1), true); - assertEquals(resDrugs.contains(drug2), true); - } - - @Test - public void testGetDrugGroupShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Drug Groups"); - Integer drugGroupId = 1; - DrugGroup result = null; - try { - result = s.getDrugGroup(drugGroupId); - // if we don't throw exception fail - no privileges required! - fail("No privileges required for getDrugGroup"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Drug Groups"); - result = s.getDrugGroup(drugGroupId); - } - } - - @Test - public void testGetDrugGroupShouldReturnDrugGroup() { - Integer DrugGroupId = 1; - DrugGroup result = s.getDrugGroup(DrugGroupId); - String name = result.getName(); - assertEquals("TestDrugGroup1", name); - } - - @Test - public void testGetDrugGroupByNameShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Drug Groups"); - String name = "TestDrugGroup1"; - String result = null; - try { - result = s.getDrugGroupByName(name).get(0).getName(); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getDrugGroupByName"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Drug Groups"); - result = s.getDrugGroupByName(name).get(0).getName(); - } - } - - @Test - public void testGetDrugGroupByNameShouldReturnDrugGroup() { - String name = "TestDrugGroup1"; - String result = s.getDrugGroupByName(name).get(0).getName(); - assertEquals(name, result); - } - - @Test - public void testGetDrugGroupByUuidShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Drug Groups"); - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = null; - try { - result = s.getDrugGroupByUuid(uuid).getName(); - // if we don't throw exception fail - no privileges required! - fail("No privileges required for getDrugGroupByUuid"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Drug Groups"); - result = s.getDrugGroupByUuid(uuid).getName(); - } - } - - @Test - public void testGetDrugGroupByUuidShouldReturnDrugGroup() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = s.getDrugGroupByUuid(uuid).getName(); - assertEquals("TestDrugGroup2", result); - } - - @Test - public void testUpdateDrugGroupShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().addProxyPrivilege("View Drug Groups"); - DrugGroup drugGroup = s.getDrugGroup(1); - drugGroup.setName("NewNameDrugGroup"); - try { - s.updateDrugGroup(drugGroup); - // if we don't throw exception fail - no privileges required! - fail("No privileges required for updateDrugGroup"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Edit Drug Groups"); - s.updateDrugGroup(drugGroup); - } - } - - @Test - public void testUpdateDrugGroupShouldChangeDrugGroup() { - DrugGroup drugGroup = s.getDrugGroup(1); - drugGroup.setName("NewNameDrugGroup"); - s.updateDrugGroup(drugGroup); - String name = s.getDrugGroup(1).getName(); - assertEquals(name, "NewNameDrugGroup"); - } - - @Test - public void testDeleteDrugGroupShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - DrugGroup drugGroup = new DrugGroup(); - drugGroup.setId(2); - drugGroup.setName("TestDrugGroup2"); - drugGroup.setDescription("Second Test Drug Group"); - drugGroup.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugGroup.setDateCreated(new java.util.Date()); - drugGroup.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - drugGroup.setRetired(Boolean.FALSE); - try { - s.deleteDrugGroup(drugGroup); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for deleteDrugGroup"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Delete Drug Groups"); - Context.getUserContext().addProxyPrivilege("View Drug Groups"); - s.deleteDrugGroup(drugGroup); - } - } - - @Test - public void testDeleteDrugGroupShouldDeleteDrugGroup() { - DrugGroup drugGroup = new DrugGroup(); - Set drugs = new HashSet(); - Drug drug1 = new Drug(); - Drug drug2 = new Drug(); - drug1.setId(1); - drug1.setConcept(new Concept(792)); - drug1.setDateCreated(new Date()); - drug1.setCreator(Context.getUserContext().getAuthenticatedUser()); - drug2.setId(2); - drug2.setConcept(new Concept(792)); - drug2.setDateCreated(new Date()); - drug2.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugs.add(drug1); - drugs.add(drug2); - drugGroup.setId(2); - drugGroup.setName("TestDrugGroup2"); - drugGroup.setDescription("Second Test Drug Group"); - drugGroup.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugGroup.setDateCreated(new java.util.Date()); - drugGroup.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - drugGroup.setRetired(Boolean.FALSE); - drugGroup.setDrugs(drugs); - s.deleteDrugGroup(drugGroup); - DrugGroup result = s.getDrugGroup(2); - assertEquals(null, result); - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/impl/DrugInfoServiceImplTest.java b/api/src/test/java/org/raxa/module/raxacore/impl/DrugInfoServiceImplTest.java deleted file mode 100644 index 0624822000..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/impl/DrugInfoServiceImplTest.java +++ /dev/null @@ -1,270 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.User; -import org.openmrs.Drug; -import org.openmrs.api.APIAuthenticationException; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; - -/* - * Testing the methods in DrugInfoServiceImpl - */ -public class DrugInfoServiceImplTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private DrugInfoService s = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - s = Context.getService(DrugInfoService.class); - //removing system developer role to test our privileges - - } - - /** - * Test of saveDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testSaveDrugInfoShouldUsePrivileges() throws Exception { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Drug drug = new Drug(); - drug.setId(3); - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setDrug(drug); - drugInfo.setName("TestDrugInfo3"); - drugInfo.setDescription("Third Test DrugInfo"); - drugInfo.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugInfo.setDateCreated(new java.util.Date()); - drugInfo.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - drugInfo.setRetired(Boolean.FALSE); - try { - s.saveDrugInfo(drugInfo); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for saveDrugInfo"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Add Drug Info"); - Context.getUserContext().addProxyPrivilege("View Drug Info"); - Context.getUserContext().addProxyPrivilege("View Users"); - s.saveDrugInfo(drugInfo); - } - } - - /** - * Test of saveDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testSaveDrugInfoShouldSaveDrugInfo() throws Exception { - Drug drug = new Drug(); - drug.setId(3); - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setDrug(drug); - drugInfo.setName("TestDrugInfo3"); - drugInfo.setDescription("Third Test DrugInfo"); - drugInfo.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugInfo.setDateCreated(new java.util.Date()); - drugInfo.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - drugInfo.setRetired(Boolean.FALSE); - s.saveDrugInfo(drugInfo); - DrugInfo result = s.getDrugInfoByUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - String name = result.getName(); - assertEquals(name, "TestDrugInfo3"); - } - - /** - * Test of getDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testGetDrugInfoShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Drug Info"); - Integer drugInfoId = 1; - DrugInfo result = null; - try { - result = s.getDrugInfo(drugInfoId); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getDrugInfo"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Drug Info"); - result = s.getDrugInfo(drugInfoId); - } - } - - /** - * Test of getDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testGetDrugInfoShouldReturnDrugInfo() { - Integer drugInfoId = 1; - DrugInfo result = s.getDrugInfo(drugInfoId); - String name = result.getName(); - assertEquals("TestDrugInfo1", name); - } - - /** - * Test of getDrugInfosByName method, of class DrugInfoServiceImpl. - */ - @Test - public void testGetDrugInfosByNameShouldReturnDrugInfos() { - String drugName = "nyquil"; - List results = s.getDrugInfosByDrugName(drugName); - String name = results.get(0).getName(); - assertEquals("TestDrugInfo1", name); - } - - /** - * Test of getDrugInfoByUuid method, of class DrugInfoServiceImpl. - */ - @Test - public void testGetDrugInfoByUuidShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Drug Info"); - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = null; - try { - result = s.getDrugInfoByUuid(uuid).getName(); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getDrugInfoByUuid"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Drug Info"); - result = s.getDrugInfoByUuid(uuid).getName(); - } - } - - /** - * Test of getDrugInfoByUuid method, of class DrugInfoServiceImpl. - */ - @Test - public void testGetDrugInfoByUuidShouldReturnDrugInfo() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = s.getDrugInfoByUuid(uuid).getName(); - assertEquals("TestDrugInfo2", result); - } - - /** - * Test of updateDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testUpdateDrugInfoShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().addProxyPrivilege("View Drug Info"); - DrugInfo drugInfo = s.getDrugInfo(1); - drugInfo.setName("NewNameDrugInfo"); - try { - s.updateDrugInfo(drugInfo); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for updateDrugInfo"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Edit Drug Info"); - s.updateDrugInfo(drugInfo); - } - } - - /** - * Test of updateDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testUpdateDrugInfoShouldChangeDrugInfo() { - DrugInfo drugInfo = s.getDrugInfo(1); - drugInfo.setName("NewNameDrugInfo"); - s.updateDrugInfo(drugInfo); - String name = s.getDrugInfo(1).getName(); - assertEquals(name, "NewNameDrugInfo"); - } - - /** - * Test of deleteDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testDeleteDrugInfoShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Drug drug = new Drug(); - drug.setId(3); - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setDrug(drug); - drugInfo.setId(2); - drugInfo.setName("TestDrugInfo2"); - drugInfo.setDescription("Second Test DrugInfo"); - drugInfo.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugInfo.setDateCreated(new java.util.Date()); - drugInfo.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - drugInfo.setRetired(Boolean.FALSE); - try { - s.deleteDrugInfo(drugInfo); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for deleteDrugInfo"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Delete Drug Info"); - Context.getUserContext().addProxyPrivilege("View Drug Info"); - s.deleteDrugInfo(drugInfo); - } - } - - /** - * Test of deleteDrugInfo method, of class DrugInfoServiceImpl. - */ - @Test - public void testDeleteDrugInfoShouldDeleteDrugInfo() { - Drug drug = new Drug(); - drug.setId(3); - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setDrug(drug); - drugInfo.setId(2); - drugInfo.setName("TestDrugInfo2"); - drugInfo.setDescription("Second Test DrugInfo"); - drugInfo.setCreator(Context.getUserContext().getAuthenticatedUser()); - drugInfo.setDateCreated(new java.util.Date()); - drugInfo.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - drugInfo.setRetired(Boolean.FALSE); - s.deleteDrugInfo(drugInfo); - DrugInfo result = s.getDrugInfo(2); - assertEquals(null, result); - } - - /** - * Test of getAllDrugInfo method, of class DrugInfoService. - */ - @Test - public void testGetAllDrugInfo_shouldReturnUnretiredDrugInfo() { - List allDrugInfo = s.getAllDrugInfo(false); - assertEquals(allDrugInfo.size(), 2); - } - - /** - * Test of getAllDrugInfo method, of class HibernateDrugInfoDAO. - */ - @Test - public void testGetAllDrugInfo_shouldReturnAllDrugInfoIncludingRetired() { - List allDrugInfo = s.getAllDrugInfo(true); - assertEquals(allDrugInfo.size(), 3); - } -} diff --git a/api/src/test/java/org/raxa/module/raxacore/impl/PatientListServiceImplTest.java b/api/src/test/java/org/raxa/module/raxacore/impl/PatientListServiceImplTest.java deleted file mode 100644 index 7440d1e400..0000000000 --- a/api/src/test/java/org/raxa/module/raxacore/impl/PatientListServiceImplTest.java +++ /dev/null @@ -1,519 +0,0 @@ -package org.raxa.module.raxacore.impl; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Encounter; -import org.openmrs.EncounterType; -import org.openmrs.Patient; -import org.openmrs.User; -import org.openmrs.api.APIAuthenticationException; -import org.openmrs.api.context.Context; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; - -/* - * Testing the methods in PatientListServiceImpl - */ -public class PatientListServiceImplTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private PatientListService s = null; - - @Before - public void setUp() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - s = Context.getService(PatientListService.class); - //removing system developer role to test our privileges - - } - - /** - * Test of savePatientList method, of class PatientListServiceImpl. - */ - @Test - public void testSavePatientListShouldUsePrivileges() throws Exception { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - PatientList pList = new PatientList(); - //NOTE: never set Id, will be generated automatically (when saving) - pList.setName("TestList3"); - pList.setDescription("Third Test List"); - pList.setCreator(Context.getUserContext().getAuthenticatedUser()); - pList.setDateCreated(new java.util.Date()); - pList.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - pList.setRetired(Boolean.FALSE); - pList.setSearchQuery("test Query"); - try { - s.savePatientList(pList); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for savePatientList"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Add Patient Lists"); - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - Context.getUserContext().addProxyPrivilege("View Users"); - s.savePatientList(pList); - } - } - - /** - * Test of savePatientList method, of class PatientListServiceImpl. - */ - @Test - public void testSavePatientListShouldSavePatientList() throws Exception { - PatientList pList = new PatientList(); - //NOTE: never set Id, will be generated automatically (when saving) - pList.setName("TestList3"); - pList.setDescription("Third Test List"); - pList.setCreator(Context.getUserContext().getAuthenticatedUser()); - pList.setDateCreated(new java.util.Date()); - pList.setUuid("68547121-1b70-465c-99ee-c9dfd95e7d30"); - pList.setRetired(Boolean.FALSE); - pList.setSearchQuery("test Query"); - s.savePatientList(pList); - List result = s.getPatientListByName("TestList3"); - String name = result.get(0).getName(); - assertEquals(name, "TestList3"); - } - - /** - * Test of getPatientList method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientListShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Patient Lists"); - Integer patientListId = 1; - PatientList result = null; - try { - result = s.getPatientList(patientListId); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getPatientList"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - result = s.getPatientList(patientListId); - } - } - - /** - * Test of getPatientList method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientListShouldReturnPatientList() { - Integer patientListId = 1; - PatientList result = s.getPatientList(patientListId); - String name = result.getName(); - assertEquals("TestList1", name); - } - - /** - * Test of getPatientListByName method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientListByNameShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Patient Lists"); - String name = "TestList1"; - String result = null; - try { - result = s.getPatientListByName(name).get(0).getName(); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getPatientListByName"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - result = s.getPatientListByName(name).get(0).getName(); - } - } - - /** - * Test of getPatientListByName method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientListByNameShouldReturnPatientList() { - String name = "TestList1"; - String result = s.getPatientListByName(name).get(0).getName(); - assertEquals(name, result); - } - - /** - * Test of getPatientListByUuid method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientListByUuidShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().removeProxyPrivilege("View Patient Lists"); - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = null; - try { - result = s.getPatientListByUuid(uuid).getName(); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getPatientListByUuid"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - result = s.getPatientListByUuid(uuid).getName(); - } - } - - /** - * Test of getPatientListByUuid method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientListByUuidShouldReturnPatientList() { - String uuid = "68547121-1b70-465e-99ee-c9dfd95e7d30"; - String result = s.getPatientListByUuid(uuid).getName(); - assertEquals("TestList2", result); - } - - /** - * Test of getPatientListByEncounterType method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetPatientListByEncounterTypeShouldReturnPatientList() { - EncounterType encounterType = Context.getEncounterService().getEncounterTypeByUuid( - "61ae96f4-6afe-4351-b6f8-cd4fc383cce1"); - String result = s.getPatientListByEncounterType(encounterType).get(0).getName(); - assertEquals("TestList1", result); - } - - /** - * Test of getPatientListByEncounterType method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetPatientListByEncounterTypeShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().addProxyPrivilege("View Encounter Types"); - Context.getUserContext().removeProxyPrivilege("View Patient Lists"); - EncounterType encounterType = Context.getEncounterService().getEncounterTypeByUuid( - "61ae96f4-6afe-4351-b6f8-cd4fc383cce1"); - String result = null; - try { - result = s.getPatientListByEncounterType(encounterType).get(0).getName(); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getPatientListByEncounterType"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - result = s.getPatientListByEncounterType(encounterType).get(0).getName(); - } - } - - /** - * Test of getEncountersInPatientList method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetEncountersInPatientListShouldReturnEncounters() { - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00"); - List encs = s.getEncountersInPatientList(p); - //testing encounterType - assertEquals(encs.size() > 0, Boolean.TRUE); - //setting start + end dates same time, should return nothing - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2012-01-02T00:00:0&endDate=2012-01-01T00:00:00"); - encs = s.getEncountersInPatientList(p); - assertEquals(encs.size(), 0); - } - - /** - * Test of getEncountersInPatientList method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetEncountersInPatientListShouldNotReturnEncountersWithInvalidDates() { - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - //setting start + end dates same time, should return nothing - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2012-01-02T00:00:0&endDate=2012-01-01T00:00:00"); - List encs = s.getEncountersInPatientList(p); - assertEquals(encs.size(), 0); - } - - /** - * Test notInList according to Encounters of getEncountersInPatientList method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetEncountersInPatientListShouldNotReturnEncountersAccordingToNotInList() { - PatientList mainList = new PatientList(); - PatientList notInList1 = new PatientList(); - PatientList notInList2 = new PatientList(); - mainList.setName("GetPatientsTestList"); - notInList1.setName("TestPatientsNotInList"); - notInList2.setName("TestPatientsNotInList2"); - notInList1.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyy" - + "&startDate=2000-01-01T00:00:00&endDate=2004-08-16T00:00:00"); - notInList2.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyy" - + "&startDate=2004-08-16T00:00:00&endDate=2009-01-02T00:00:00"); - s.savePatientList(notInList1); - s.savePatientList(notInList2); - mainList.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyr" - + "&startDate=2000-01-01T00:00:00&endDate=2009-01-02T00:00:00¬InList=" + notInList1.getUuid() + "," - + notInList2.getUuid()); - List encs = s.getEncountersInPatientList(mainList); - //now checking that notInList works - assertEquals(encs.size(), 1); - //assertEquals(s.getPatientsInPatientList(mainList).get(0).getUuid()) - System.out.println(s.getPatientsInPatientList(mainList).get(0).getUuid()); - } - - /** - * Test notInList according to Patient of getEncountersInPatientList method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetEncountersInPatientListShouldNotReturnPatientsAccordingToNotInList() { - PatientList mainList = new PatientList(); - PatientList notInList1 = new PatientList(); - mainList.setName("GetPatientsTestList"); - notInList1.setName("TestPatientsNotInList"); - notInList1.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyy" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00"); - s.savePatientList(notInList1); - mainList.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyr" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00¬InList=" + notInList1.getUuid()); - List encs = s.getEncountersInPatientList(mainList); - //now checking that notInList works - assertEquals(encs.size(), 2); - } - - /** - * Test inList parts of getEncountersInPatientList method, of class - * PatientListServiceImpl. - */ - @Test - public void testGetEncountersInPatientListShouldOnlyReturnEncountersAccordingToInList() { - PatientList p = new PatientList(); - PatientList p2 = new PatientList(); - p.setCreator(Context.getUserContext().getAuthenticatedUser()); - p.setName("GetPatientsTestList"); - p2.setName("TestPatientsNotInList"); - //setting start + end dates for inList test - p2.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2008-08-14T00:00:0&endDate=2008-08-016T00:00:00"); - s.savePatientList(p2); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00"); - Context.getUserContext().addProxyPrivilege("Add Patient Lists"); - List encs = s.getEncountersInPatientList(p); - List encs2 = null; - int originalLength = encs.size(); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00&inList=" + p2.getUuid()); - encs = s.getEncountersInPatientList(p); - encs2 = s.getEncountersInPatientList(p2); - assertEquals(encs.size(), originalLength - encs2.size()); - } - - /** - * Test of GetEncountersInPatientList method, of class PatientListServiceImpl given provider uuid. - */ - @Test - public void testGetEncountersInPatientListShouldReturnEncountersOfRequiredProvider() { - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyr" - + "&provider=3effc802-12dd-4539-87f6-4065ca8e992c"); - List encs = s.getEncountersInPatientList(p); - //testing encounterType - - assertEquals(encs.size(), 1); - } - - /** - * Test of GetEncountersInPatientList method, of class PatientListServiceImpl given provider uuid. - */ - @Test - public void testGetEncountersInPatientListShouldFilterDrugOrders() { - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383ctyr" + "&containsOrderType=drugOrder"); - List encs = s.getEncountersInPatientList(p); - //testing encounterType - - assertEquals(encs.size(), 1); - } - - /** - * Test of getPatientsInPatientList method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientsInPatientListShouldReturnPatients() { - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00"); - List pList = s.getPatientsInPatientList(p); - //testing encounterType - assertEquals(pList.size() > 0, Boolean.TRUE); - } - - /** - * Test of getPatientsInPatientList method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientsInPatientListShouldNotReturnPatientsWithInvalidDates() { - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2012-01-02T00:00:0&endDate=2012-01-01T00:00:00"); - List pList = s.getPatientsInPatientList(p); - assertEquals(pList.size(), 0); - } - - /** - * Test of getPatientsInPatientList method, of class PatientListServiceImpl. - */ - @Test - public void testGetPatientsInPatientListShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - PatientList p = new PatientList(); - p.setCreator(new User()); - p.setName("GetPatientsTestList"); - p.setSearchQuery("?encounterType=61ae96f4-6afe-4351-b6f8-cd4fc383cce1" - + "&startDate=2000-01-01T00:00:00&endDate=2012-01-02T00:00:00"); - List pList = null; - try { - pList = s.getPatientsInPatientList(p); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for getPatientsInList"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("View Patients"); - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - Context.getUserContext().addProxyPrivilege("View Encounters"); - Context.getUserContext().addProxyPrivilege("View Encounter Types"); - pList = s.getPatientsInPatientList(p); - } - } - - /** - * Test of updatePatientList method, of class PatientListServiceImpl. - */ - @Test - public void testUpdatePatientListShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - PatientList patientList = s.getPatientList(1); - patientList.setName("NewNameList"); - try { - s.updatePatientList(patientList); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for updatePatientList"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Edit Patient Lists"); - s.updatePatientList(patientList); - } - } - - /** - * Test of updatePatientList method, of class PatientListServiceImpl. - */ - @Test - public void testUpdatePatientListShouldChangePatientList() { - PatientList patientList = s.getPatientList(1); - patientList.setName("NewNameList"); - s.updatePatientList(patientList); - String name = s.getPatientList(1).getName(); - assertEquals(name, "NewNameList"); - } - - /** - * Test of deletePatientList method, of class PatientListServiceImpl. - */ - @Test - public void testDeletePatientListShouldUsePrivileges() { - Context.getUserContext().getAuthenticatedUser().removeRole(Context.getUserService().getRole("System Developer")); - PatientList pList = new PatientList(); - pList.setId(2); - pList.setName("TestList2"); - pList.setDescription("Second Test List"); - pList.setCreator(Context.getUserContext().getAuthenticatedUser()); - pList.setDateCreated(new java.util.Date()); - pList.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - pList.setRetired(Boolean.FALSE); - pList.setSearchQuery(""); - try { - s.deletePatientList(pList); - //if we don't throw exception fail - no privileges required! - fail("No privileges required for deletePatientList"); - } - catch (APIAuthenticationException e) { - Context.getUserContext().addProxyPrivilege("Delete Patient Lists"); - Context.getUserContext().addProxyPrivilege("View Patient Lists"); - s.deletePatientList(pList); - } - } - - /** - * Test of deletePatientList method, of class PatientListServiceImpl. - */ - @Test - public void testDeletePatientListShouldDeletePatientList() { - PatientList pList = new PatientList(); - pList.setId(2); - pList.setName("TestList2"); - pList.setDescription("Second Test List"); - pList.setCreator(Context.getUserContext().getAuthenticatedUser()); - pList.setDateCreated(new java.util.Date()); - pList.setUuid("68547121-1b70-465e-99ee-c9dfd95e7d30"); - pList.setRetired(Boolean.FALSE); - pList.setSearchQuery(""); - s.deletePatientList(pList); - PatientList result = s.getPatientList(2); - assertEquals(null, result); - } - - /** - * Test of getAllPatientList method, of class PatientListService. - */ - @Test - public void testGetAllPatientList_shouldReturnUnretiredPatientList() { - List allPatientList = s.getAllPatientList(false); - assertEquals(allPatientList.size(), 2); - } - - /** - * Test of getAllPatientList method, of class HibernatePatientListDAO. - */ - @Test - public void testGetAllPatientList_shouldReturnAllPatientListIncludingRetired() { - List allPatientList = s.getAllPatientList(true); - assertEquals(allPatientList.size(), 3); - } -} diff --git a/api/src/test/resources/TestingApplicationContext.xml b/api/src/test/resources/TestingApplicationContext.xml deleted file mode 100644 index 9b4972fe9b..0000000000 --- a/api/src/test/resources/TestingApplicationContext.xml +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - classpath:hibernate.cfg.xml - classpath:test-hibernate.cfg.xml - - - - - - - - - - - - - - - org.raxa.module.raxacore.PatientListService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.RaxaAlertService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugGroupService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugInventoryService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugPurchaseOrderService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugInfoService - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/test/resources/org/raxa/module/raxacore/include/moduleTestData.xml b/api/src/test/resources/org/raxa/module/raxacore/include/moduleTestData.xml deleted file mode 100644 index fbcda967d7..0000000000 --- a/api/src/test/resources/org/raxa/module/raxacore/include/moduleTestData.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/src/test/resources/test-hibernate.cfg.xml b/api/src/test/resources/test-hibernate.cfg.xml deleted file mode 100644 index 8520921f0a..0000000000 --- a/api/src/test/resources/test-hibernate.cfg.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/bahmni-emr-api/pom.xml b/bahmni-emr-api/pom.xml new file mode 100644 index 0000000000..77df76dc48 --- /dev/null +++ b/bahmni-emr-api/pom.xml @@ -0,0 +1,242 @@ + + + + bahmni + org.bahmni.module + 1.2.0-SNAPSHOT + + 4.0.0 + + bahmni-emr-api + Bahmni EMR Api + jar + + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + provided + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + test-jar + test + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + test-jar + test + + + org.openmrs.api + openmrs-api + + + net.sf.ehcache + ehcache + + + jar + + + org.bahmni.module + bahmni-mapping + + + org.bahmni.module + bahmni-commons-api + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + test + + + org.openmrs.web + openmrs-web + test + + + org.openmrs.api + openmrs-api + test-jar + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + org.openmrs.test + openmrs-test + pom + test + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + provided + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + provided + + + junit + junit + test + + + joda-time + joda-time + 2.0 + + + org.apache.commons + commons-lang3 + 3.1 + provided + + + org.openmrs.module + appframework-api + + + org.openmrs.module + serialization.xstream-api-2.0 + + + org.openmrs.module + reporting-api + + + org.openmrs.module + calculation-api + + + javax.servlet + javax.servlet-api + + + org.openmrs.module + providermanagement-api + + + org.codehaus.groovy + groovy + provided + 1.7.6 + + + org.bahmni.module + obs-relationship + ${project.version} + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test-jar + test + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + javax.el + javax.el-api + 2.2.4 + + + org.glassfish.web + javax.el + 2.2.4 + + + + + + + src/main/resources + true + + + + + + src/test/resources + true + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.34 + + + BRANCH + COVEREDRATIO + 0.24 + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/BahmniEmrAPIException.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/BahmniEmrAPIException.java new file mode 100644 index 0000000000..3789cbe244 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/BahmniEmrAPIException.java @@ -0,0 +1,12 @@ +package org.openmrs.module.bahmniemrapi; + + +public class BahmniEmrAPIException extends RuntimeException { + public BahmniEmrAPIException(String message, Throwable cause) { + super(message, cause); + } + + public BahmniEmrAPIException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/accessionnote/contract/AccessionNote.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/accessionnote/contract/AccessionNote.java new file mode 100644 index 0000000000..c80e11cb03 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/accessionnote/contract/AccessionNote.java @@ -0,0 +1,56 @@ +package org.openmrs.module.bahmniemrapi.accessionnote.contract; + +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.util.Date; + +public class AccessionNote { + private String text; + private String providerName; + private String accessionUuid; + private Date dateTime; + + public AccessionNote() { + } + + public AccessionNote(String text, String providerName, String accessionUuid, Date dateTime) { + this.text = text; + this.providerName = providerName; + this.accessionUuid = accessionUuid; + this.dateTime = dateTime; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public String getAccessionUuid() { + return accessionUuid; + } + + public void setAccessionUuid(String accessionUuid) { + this.accessionUuid = accessionUuid; + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getDateTime() { + return dateTime; + } + + public void setDateTime(Date dateTime){ + this.dateTime = dateTime; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/accessionnote/mapper/AccessionNotesMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/accessionnote/mapper/AccessionNotesMapper.java new file mode 100644 index 0000000000..47e7253595 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/accessionnote/mapper/AccessionNotesMapper.java @@ -0,0 +1,74 @@ +package org.openmrs.module.bahmniemrapi.accessionnote.mapper; + +import org.openmrs.EncounterType; +import org.openmrs.api.EncounterService; +import org.openmrs.module.bahmniemrapi.accessionnote.contract.AccessionNote; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Component +public class AccessionNotesMapper { + + private static final String VALIDATION_NOTES_ENCOUNTER_TYPE = "VALIDATION NOTES"; + private static final String ACCESSION_UUID_CONCEPT_NAME = "Accession Uuid"; + private static final String ACCESSION_NOTES_CONCEPT_NAME = "Lab Manager Notes"; + + @Autowired + private EncounterService encounterService; + + private EncounterType validationNotesEncounterType; + + public List map(EncounterTransaction encounterTransaction) { + if(hasValidationNotes(encounterTransaction)){ + String providerName = encounterTransaction.getProviders().iterator().next().getName(); + return getAccessionNotes(encounterTransaction,providerName); + } + return Collections.emptyList(); + } + + private List getAccessionNotes(EncounterTransaction encounterTransaction, String providerName) { + List observations = encounterTransaction.getObservations(); + List accessionNotes = new ArrayList<>(); + String accessionUuid = getAccessionUuid(observations); + List filteredObservations = new ArrayList<>(); + for (EncounterTransaction.Observation observation : observations) { + if(observation.getConcept().getName().equals(ACCESSION_NOTES_CONCEPT_NAME)){ + AccessionNote note = new AccessionNote(); + note.setAccessionUuid(accessionUuid); + note.setText((String) observation.getValue()); + note.setDateTime(observation.getObservationDateTime()); + note.setProviderName(providerName); + accessionNotes.add(note); + } + else if(!observation.getConcept().getName().equals(ACCESSION_UUID_CONCEPT_NAME)){ + filteredObservations.add(observation); + } + } + encounterTransaction.setObservations(filteredObservations); + return accessionNotes; + } + + private String getAccessionUuid(List observations) { + for (EncounterTransaction.Observation observation : observations) { + if(observation.getConcept().getName().equals(ACCESSION_UUID_CONCEPT_NAME)){ + return (String) observation.getValue(); + } + } + return null; + } + + private boolean hasValidationNotes(EncounterTransaction encounterTransaction) { + if(validationNotesEncounterType == null){ + validationNotesEncounterType = encounterService.getEncounterType(VALIDATION_NOTES_ENCOUNTER_TYPE); + if(validationNotesEncounterType == null) return false; + } + return encounterTransaction.getEncounterTypeUuid() != null && encounterTransaction.getEncounterTypeUuid().equals(validationNotesEncounterType.getUuid()) && !encounterTransaction.getObservations().isEmpty(); + } + + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosis.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosis.java new file mode 100644 index 0000000000..31af6f29f7 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosis.java @@ -0,0 +1,73 @@ +package org.openmrs.module.bahmniemrapi.diagnosis.contract; + +import org.apache.commons.lang3.StringUtils; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BahmniDiagnosis extends EncounterTransaction.Diagnosis { + private EncounterTransaction.Concept diagnosisStatusConcept; + private BahmniDiagnosis firstDiagnosis; + private BahmniDiagnosis latestDiagnosis; + private boolean revised; + + public EncounterTransaction.Concept getDiagnosisStatusConcept() { + return diagnosisStatusConcept; + } + + public void setDiagnosisStatusConcept(EncounterTransaction.Concept diagnosisStatusConcept) { + this.diagnosisStatusConcept = diagnosisStatusConcept; + } + + public BahmniDiagnosis getFirstDiagnosis() { + return firstDiagnosis; + } + + public void setFirstDiagnosis(BahmniDiagnosis firstDiagnosis) { + this.firstDiagnosis = firstDiagnosis; + } + + public boolean isRevised() { + return revised; + } + + public void setRevised(boolean revised) { + this.revised = revised; + } + + public boolean isSame(EncounterTransaction.Diagnosis diagnosis) { + if (getFreeTextAnswer() != null || diagnosis.getFreeTextAnswer() != null) { + return isSameFreeTextAnswer(diagnosis); + } + return isSameCodedAnswer(diagnosis); + } + + public boolean isDiagnosisWithSameExistingObs(EncounterTransaction.Diagnosis diagnosis) { + if (StringUtils.isEmpty(getExistingObs())) { + return false; + } + return getExistingObs().equals(diagnosis.getExistingObs()) ; + } + + public boolean isSameFreeTextAnswer(EncounterTransaction.Diagnosis diagnosis) { + if (getFreeTextAnswer() == null || diagnosis.getFreeTextAnswer() == null) + return false; + + return getFreeTextAnswer().equals(diagnosis.getFreeTextAnswer()); + } + + public boolean isSameCodedAnswer(EncounterTransaction.Diagnosis diagnosis) { + if (getCodedAnswer() == null || diagnosis.getCodedAnswer() == null) + return false; + + return getCodedAnswer().getUuid().equals(diagnosis.getCodedAnswer().getUuid()); + } + + public BahmniDiagnosis getLatestDiagnosis() { + return latestDiagnosis; + } + + public void setLatestDiagnosis(BahmniDiagnosis latestDiagnosis) { + this.latestDiagnosis = latestDiagnosis; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosisRequest.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosisRequest.java new file mode 100644 index 0000000000..7d5b786035 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosisRequest.java @@ -0,0 +1,34 @@ +package org.openmrs.module.bahmniemrapi.diagnosis.contract; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BahmniDiagnosisRequest extends BahmniDiagnosis { + private String previousObs; + private String encounterUuid; + private String creatorName; + + public String getPreviousObs() { + return previousObs; + } + + public void setPreviousObs(String previousObs) { + this.previousObs = previousObs; + } + + public void setEncounterUuid(String encounterUuid) { + this.encounterUuid = encounterUuid; + } + + public String getEncounterUuid() { + return encounterUuid; + } + + public String getCreatorName() { + return this.creatorName; + } + + public void setCreatorName(String creatorName) { + this.creatorName = creatorName; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java new file mode 100644 index 0000000000..81be0b3332 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadata.java @@ -0,0 +1,260 @@ +package org.openmrs.module.bahmniemrapi.diagnosis.helper; + +import org.openmrs.Concept; +import org.openmrs.Obs; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.emrapi.EmrApiProperties; +import org.openmrs.module.emrapi.diagnosis.Diagnosis; +import org.openmrs.module.emrapi.encounter.EncounterTransactionMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import static java.util.stream.Collectors.toList; + +@Component +public class BahmniDiagnosisMetadata { + + private static final String BAHMNI_DIAGNOSIS_STATUS = "Bahmni Diagnosis Status"; + private static final String BAHMNI_DIAGNOSIS_REVISED = "Bahmni Diagnosis Revised"; + private static final String BAHMNI_INITIAL_DIAGNOSIS = "Bahmni Initial Diagnosis"; + + private ObsService obsService; + + private ConceptService conceptService; + + private EmrApiProperties emrApiProperties; + + private EncounterTransactionMapper encounterTransactionMapper; + + private Concept getConceptsByNameAndLocale(String name, Locale locale) { + List conceptList = conceptService.getConceptsByName(name, locale, false); + return conceptList.isEmpty() ? null : conceptList.get(0); + } + + public Concept getBahmniInitialDiagnosisConcept() { + return getConceptsByNameAndLocale(BAHMNI_INITIAL_DIAGNOSIS, Locale.ENGLISH); + } + + public Concept getBahmniDiagnosisRevisedConcept() { + return getConceptsByNameAndLocale(BAHMNI_DIAGNOSIS_REVISED, Locale.ENGLISH); + } + + public Concept getBahmniDiagnosisStatusConcept() { + return getConceptsByNameAndLocale(BAHMNI_DIAGNOSIS_STATUS, Locale.ENGLISH); + } + + @Autowired + public BahmniDiagnosisMetadata(ObsService obsService, ConceptService conceptService, + EmrApiProperties emrApiProperties, + EncounterTransactionMapper encounterTransactionMapper) { + this.obsService = obsService; + this.conceptService = conceptService; + this.emrApiProperties = emrApiProperties; + this.encounterTransactionMapper = encounterTransactionMapper; + } + + public String findInitialDiagnosisUuid(Obs visitDiagnosisObs) { + for (Obs obs : visitDiagnosisObs.getGroupMembers()) { + if (obs.getConcept().getName().getName().equals(BAHMNI_INITIAL_DIAGNOSIS)) { + return obs.getValueText(); + } + } + return null; + } + + public List map(List diagnoses, boolean includeAll) { + List bahmniDiagnoses = new ArrayList<>(); + for (EncounterTransaction.Diagnosis diagnosis : diagnoses) { + bahmniDiagnoses.add(mapBahmniDiagnosis(diagnosis, null, true, includeAll, diagnosisSchemaContainsStatus(), true)); + } + return bahmniDiagnoses; + } + + public BahmniDiagnosisRequest mapBahmniDiagnosis(EncounterTransaction.Diagnosis diagnosis, + EncounterTransaction.Diagnosis latestDiagnosis, + boolean mapFirstDiagnosis, boolean includeAll, + boolean diagnosisSchemaContainsStatus, + boolean includeRevisedDiagnosis) { + BahmniDiagnosisRequest bahmniDiagnosis = mapBasicDiagnosis(diagnosis); + + Obs diagnosisObsGroup = obsService.getObsByUuid(diagnosis.getExistingObs()); + HashMap requiredObs = getRequiredObs(diagnosisObsGroup); + Obs revisedObs = requiredObs.get(BAHMNI_DIAGNOSIS_REVISED); + if (revisedObs.getValueAsBoolean() && !includeRevisedDiagnosis) + return null; + if (diagnosisSchemaContainsStatus) { + Obs statusObs = requiredObs.get(BAHMNI_DIAGNOSIS_STATUS); + if (statusObs != null) { + Concept statusConcept = statusObs.getValueCoded(); + if (statusConcept != null) { + bahmniDiagnosis.setDiagnosisStatusConcept(new EncounterTransaction.Concept(statusConcept.getUuid(), statusConcept.getName().getName())); + } + } + } + + if (mapFirstDiagnosis) { + Obs initialObs = requiredObs.get(BAHMNI_INITIAL_DIAGNOSIS); + Obs initialDiagnosisObsGroup = obsService.getObsByUuid(initialObs.getValueText()); + + if(initialDiagnosisObsGroup.getVoided()){ + initialDiagnosisObsGroup = diagnosisObsGroup; + initialObs.setValueText(diagnosisObsGroup.getUuid()); + obsService.saveObs(initialObs,"Initial obs got voided"); + } + EncounterTransaction encounterTransactionWithInitialDiagnosis = encounterTransactionMapper.map(initialDiagnosisObsGroup.getEncounter(), includeAll); + EncounterTransaction.Diagnosis initialDiagnosis = findInitialDiagnosis(encounterTransactionWithInitialDiagnosis, initialDiagnosisObsGroup); + bahmniDiagnosis.setFirstDiagnosis(mapBahmniDiagnosis(initialDiagnosis, null, false, includeAll, diagnosisSchemaContainsStatus, true)); + } + + if (latestDiagnosis != null) { + bahmniDiagnosis.setLatestDiagnosis(mapBahmniDiagnosis(latestDiagnosis, null, false, includeAll, diagnosisSchemaContainsStatus, true)); + } + + bahmniDiagnosis.setRevised(revisedObs.getValueAsBoolean()); + bahmniDiagnosis.setComments(diagnosisObsGroup.getComment()); + + bahmniDiagnosis.setEncounterUuid(diagnosisObsGroup.getEncounter().getUuid()); + bahmniDiagnosis.setCreatorName(diagnosisObsGroup.getCreator().getPersonName().toString()); + return bahmniDiagnosis; + } + + public boolean diagnosisSchemaContainsStatus() { + Concept diagnosisSetConcept = getDiagnosisSetConcept(); + return diagnosisSetConcept.getSetMembers().contains(getBahmniDiagnosisStatusConcept()); + } + + public Obs findInitialDiagnosis(Obs diagnosisObsGroup) { + return findObs(diagnosisObsGroup, BAHMNI_INITIAL_DIAGNOSIS); + } + + public Diagnosis buildDiagnosisFromObsGroup(Obs diagnosisObsGroup, Collection nonDiagnosisConcepts, Collection nonDiagnosisConceptSets) { + if (diagnosisObsGroup == null) + return null; + + Diagnosis diagnosis = emrApiProperties.getDiagnosisMetadata().toDiagnosis(diagnosisObsGroup); + + Set filter = new HashSet<>(); + filter.addAll(nonDiagnosisConcepts); + for (Concept conceptSet : nonDiagnosisConceptSets) { + filter.addAll(conceptSet.getSetMembers()); + } + + if (!filter.contains(diagnosis.getDiagnosis().getCodedAnswer())) { + return diagnosis; + } + return null; + } + + public Concept getDiagnosisSetConcept() { + return emrApiProperties.getDiagnosisMetadata().getDiagnosisSetConcept(); + } + + public boolean isDiagnosis(Obs obs) { + return obs.getConcept().equals(getDiagnosisSetConcept()); + } + + public Concept getCodedDiagnosisConcept() { + return emrApiProperties.getDiagnosisMetadata().getCodedDiagnosisConcept(); + } + + public Concept getNonCodedDiagnosisConcept() { + return emrApiProperties.getDiagnosisMetadata().getNonCodedDiagnosisConcept(); + } + + public Obs findMatchingDiagnosis(Collection observations, BahmniDiagnosis bahmniDiagnosis) { + List matchingObs = observations.stream() + .filter(obs -> isDiagnosis(obs)) + .filter(obs -> isDiagnosisNotRevised(obs)) + .filter(obs -> isDiagnosisMatching(obs, bahmniDiagnosis)).collect(toList()); + if (matchingObs.size() > 1) throw new RuntimeException("The same diagnosis cannot be saved more than once"); + return matchingObs.isEmpty()? null: matchingObs.get(0); + } + + private boolean isDiagnosisNotRevised(Obs obs) { + return !obs.getGroupMembers(false).stream() + .anyMatch(groupMember -> { + return groupMember.getConcept().equals(getBahmniDiagnosisRevisedConcept()) + && groupMember.getValueAsBoolean();}); + } + + private boolean isDiagnosisMatching(Obs obs, EncounterTransaction.Diagnosis diagnosis) { + return obs.getGroupMembers().stream() + .anyMatch(groupMember -> { + if (diagnosis.getCodedAnswer() != null && + groupMember.getConcept().equals(getCodedDiagnosisConcept())) { + return codedAnswersMatch(diagnosis, groupMember); + } + if (diagnosis.getFreeTextAnswer() != null && + groupMember.getConcept().equals(getNonCodedDiagnosisConcept())) { + return textAnswersMatch(diagnosis, groupMember); + } + return false; + } + ); + } + + private boolean textAnswersMatch(EncounterTransaction.Diagnosis diagnosis, Obs obs1) { + return obs1.getValueText().equals(diagnosis.getFreeTextAnswer()); + } + + private boolean codedAnswersMatch(EncounterTransaction.Diagnosis diagnosis, Obs obs1) { + return obs1.getValueCoded().getUuid().equals(diagnosis.getCodedAnswer().getUuid()) + || obs1.getValueCoded().getName().equals(diagnosis.getCodedAnswer().getName()); + } + + private HashMap getRequiredObs(Obs diagnosisObsGroup) { + HashMap requiredObs = new HashMap<>(); + for (Obs o : diagnosisObsGroup.getGroupMembers()) { + Concept concept = o.getConcept(); + if (concept.hasName(BAHMNI_DIAGNOSIS_STATUS, null)) { + requiredObs.put(BAHMNI_DIAGNOSIS_STATUS, o); + } else if (concept.hasName(BAHMNI_DIAGNOSIS_REVISED, null)) { + requiredObs.put(BAHMNI_DIAGNOSIS_REVISED, o); + } else if (concept.hasName(BAHMNI_INITIAL_DIAGNOSIS, null)) { + requiredObs.put(BAHMNI_INITIAL_DIAGNOSIS, o); + } + } + return requiredObs; + } + + private BahmniDiagnosisRequest mapBasicDiagnosis(EncounterTransaction.Diagnosis diagnosis) { + BahmniDiagnosisRequest bahmniDiagnosis = new BahmniDiagnosisRequest(); + bahmniDiagnosis.setCertainty(diagnosis.getCertainty()); + bahmniDiagnosis.setCodedAnswer(diagnosis.getCodedAnswer()); + bahmniDiagnosis.setFreeTextAnswer(diagnosis.getFreeTextAnswer()); + bahmniDiagnosis.setOrder(diagnosis.getOrder()); + bahmniDiagnosis.setExistingObs(diagnosis.getExistingObs()); + bahmniDiagnosis.setDiagnosisDateTime(diagnosis.getDiagnosisDateTime()); + bahmniDiagnosis.setProviders(diagnosis.getProviders()); + return bahmniDiagnosis; + } + + private EncounterTransaction.Diagnosis findInitialDiagnosis(EncounterTransaction encounterTransactionWithInitialDiagnosis, Obs initialDiagnosisObs) { + for (EncounterTransaction.Diagnosis diagnosis : encounterTransactionWithInitialDiagnosis.getDiagnoses()) { + if (diagnosis.getExistingObs().equals(initialDiagnosisObs.getUuid())) + return diagnosis; + } + throw new AssertionError(String.format("Initial Diagnosis not found for: %s", initialDiagnosisObs.getUuid())); + } + + private Obs findObs(Obs diagnosisObs, String conceptName) { + for (Obs o : diagnosisObs.getGroupMembers()) { + if (o.getConcept().hasName(conceptName, null)) { + return o; + } + } + return null; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/contract/BahmniDisposition.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/contract/BahmniDisposition.java new file mode 100644 index 0000000000..a0a8cbd61e --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/contract/BahmniDisposition.java @@ -0,0 +1,100 @@ +package org.openmrs.module.bahmniemrapi.disposition.contract; + +import org.openmrs.ConceptName; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.*; + +public class BahmniDisposition { + private String code; + private String conceptName; + private String existingObs; + private boolean voided; + private String voidReason; + private String creatorName; + private List additionalObs; + private Date dispositionDateTime; + private Set providers = new HashSet<>(); + + public String getPreferredName() { + return preferredName; + } + + public void setPreferredName(String preferredName) { + this.preferredName = preferredName; + } + + private String preferredName; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getConceptName() { + return conceptName; + } + + public void setConceptName(String conceptName) { + this.conceptName = conceptName; + } + + public String getExistingObs() { + return existingObs; + } + + public void setExistingObs(String existingObs) { + this.existingObs = existingObs; + } + + public boolean isVoided() { + return voided; + } + + public void setVoided(boolean voided) { + this.voided = voided; + } + + public String getVoidReason() { + return voidReason; + } + + public void setVoidReason(String voidReason) { + this.voidReason = voidReason; + } + + public List getAdditionalObs() { + return additionalObs; + } + + public void setAdditionalObs(List additionalObs) { + this.additionalObs = additionalObs; + } + + public Date getDispositionDateTime() { + return dispositionDateTime; + } + + public void setDispositionDateTime(Date dispositionDateTime) { + this.dispositionDateTime = dispositionDateTime; + } + + public Set getProviders() { + return providers; + } + + public void setProviders(Set providers) { + this.providers = providers; + } + + public String getCreatorName() { + return creatorName; + } + + public void setCreatorName(String creatorName) { + this.creatorName = creatorName; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/mapper/BahmniDispositionMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/mapper/BahmniDispositionMapper.java new file mode 100644 index 0000000000..e5c3835935 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/mapper/BahmniDispositionMapper.java @@ -0,0 +1,41 @@ +package org.openmrs.module.bahmniemrapi.disposition.mapper; + +import org.openmrs.Concept; +import org.openmrs.User; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Set; +import java.util.Locale; + +@Component +public class BahmniDispositionMapper { + + private ConceptService conceptService; + + @Autowired + public BahmniDispositionMapper(ConceptService conceptService) { + this.conceptService = conceptService; + } + public BahmniDisposition map(EncounterTransaction.Disposition disposition, Set providers, User user , Locale locale){ + BahmniDisposition bahmniDisposition = new BahmniDisposition(); + bahmniDisposition.setAdditionalObs(disposition.getAdditionalObs()); + bahmniDisposition.setCode(disposition.getCode()); + bahmniDisposition.setConceptName(disposition.getConceptName()); + bahmniDisposition.setDispositionDateTime(disposition.getDispositionDateTime()); + bahmniDisposition.setVoided(disposition.isVoided()); + bahmniDisposition.setExistingObs(disposition.getExistingObs()); + bahmniDisposition.setVoidReason(disposition.getVoidReason()); + bahmniDisposition.setProviders(providers); + bahmniDisposition.setCreatorName(user.getPersonName().toString()); + Concept concept = conceptService.getConcept(disposition.getConceptName()); + if(concept.getPreferredName(locale) != null) { + bahmniDisposition.setPreferredName(concept.getPreferredName(locale).getName()); + } + return bahmniDisposition; + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionService.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionService.java new file mode 100644 index 0000000000..4bc08b2b49 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionService.java @@ -0,0 +1,17 @@ +package org.openmrs.module.bahmniemrapi.disposition.service; + +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; + +import java.util.List; +import java.util.Locale; + +public interface BahmniDispositionService { + + List getDispositionByVisitUuid(String visitUuid); + List getDispositionByVisits(List visits); + + List getDispositionByVisitUuid(String visitUuid , Locale locale); + List getDispositionByVisits(List visits , Locale locale); + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionServiceImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionServiceImpl.java new file mode 100644 index 0000000000..2a0bdc0b7f --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionServiceImpl.java @@ -0,0 +1,113 @@ +package org.openmrs.module.bahmniemrapi.disposition.service; + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; +import org.openmrs.module.bahmniemrapi.disposition.mapper.BahmniDispositionMapper; +import org.openmrs.module.emrapi.encounter.DispositionMapper; +import org.openmrs.module.emrapi.encounter.EncounterProviderMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.matcher.ObservationTypeMatcher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +@Service +public class BahmniDispositionServiceImpl implements BahmniDispositionService { + + private VisitService visitService; + + private DispositionMapper dispositionMapper; + + private ObservationTypeMatcher observationTypeMatcher; + + private EncounterProviderMapper encounterProviderMapper; + + private BahmniDispositionMapper bahmniDispositionMapper; + + @Autowired + public BahmniDispositionServiceImpl(VisitService visitService, DispositionMapper dispositionMapper, + ObservationTypeMatcher observationTypeMatcher, EncounterProviderMapper encounterProviderMapper, + BahmniDispositionMapper bahmniDispositionMapper){ + this.visitService = visitService; + this.dispositionMapper = dispositionMapper; + this.observationTypeMatcher = observationTypeMatcher; + this.encounterProviderMapper = encounterProviderMapper; + this.bahmniDispositionMapper = bahmniDispositionMapper; + } + + @Override + public List getDispositionByVisitUuid(String visitUuid , Locale locale) { + Assert.notNull(visitUuid); + + Visit visit = visitService.getVisitByUuid(visitUuid); + + if(visit == null){ + return new ArrayList<>(); + } + + return getDispositionByVisit(visit, locale); + } + @Override + public List getDispositionByVisitUuid(String visitUuid) { + Assert.notNull(visitUuid); + + Visit visit = visitService.getVisitByUuid(visitUuid); + + if(visit == null){ + return new ArrayList<>(); + } + + return getDispositionByVisit(visit , new Locale("en")); + } + + public List getDispositionByVisits(List visits , Locale locale){ + List dispositions = new ArrayList<>(); + + for(Visit visit: visits){ + dispositions.addAll(getDispositionByVisit(visit , locale)); + } + + return dispositions; + } + public List getDispositionByVisits(List visits){ + List dispositions = new ArrayList<>(); + + for(Visit visit: visits){ + dispositions.addAll(getDispositionByVisit(visit , new Locale("en"))); + } + + return dispositions; + } + private List getDispositionByVisit(Visit visit , Locale locale) { + List dispositions = new ArrayList<>(); + for (Encounter encounter : visit.getEncounters()) { + Set observations = encounter.getObsAtTopLevel(false); + Set eTProvider = encounterProviderMapper.convert(encounter.getEncounterProviders()); + + for (Obs observation : observations) { + if(ObservationTypeMatcher.ObservationType.DISPOSITION.equals(observationTypeMatcher.getObservationType(observation))){ + addBahmniDisposition(dispositions, eTProvider, observation , locale); + } + } + } + return dispositions; + } + + private void addBahmniDisposition(List dispositions, + Set eTProvider, + Obs observation , + Locale locale) { + EncounterTransaction.Disposition eTDisposition = dispositionMapper.getDisposition(observation); + if(eTDisposition!=null){ + dispositions.add(bahmniDispositionMapper.map(eTDisposition, eTProvider, observation.getCreator(),locale)); + } + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/Document.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/Document.java new file mode 100644 index 0000000000..e73e0e4ec3 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/Document.java @@ -0,0 +1,105 @@ +package org.openmrs.module.bahmniemrapi.document.contract; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Date; + +public class Document { + private String image; + private String format; + private String testUuid; + private String obsUuid; + private Date obsDateTime; + private boolean voided; + private String comment; + + public Document() { + } + + public Document(String image, String format, String testUuid, String obsUuid, Date obsDateTime, boolean voided) { + this.image = image; + this.format = format; + this.testUuid = testUuid; + this.obsUuid = obsUuid; + this.obsDateTime = obsDateTime; + this.voided = voided; + } + + public Document(String image, String format, String testUuid, String obsUuid, Date obsDateTime, boolean voided, String comment) { + this.image = image; + this.format = format; + this.testUuid = testUuid; + this.obsUuid = obsUuid; + this.obsDateTime = obsDateTime; + this.voided = voided; + this.comment = comment; + } + + public boolean isNew() { + return StringUtils.isBlank(getObsUuid()); + } + + public boolean shouldVoidDocument() { + return !StringUtils.isBlank(getObsUuid()) && isVoided(); + } + + public boolean hasConceptChanged(String referenceUuid) { + return !referenceUuid.equals(getTestUuid()); + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getTestUuid() { + return testUuid; + } + + public void setTestUuid(String testUuid) { + this.testUuid = testUuid; + } + + public String getObsUuid() { + return obsUuid; + } + + public void setObsUuid(String obsUuid) { + this.obsUuid = obsUuid; + } + + public Date getObsDateTime() { + return obsDateTime; + } + + public void setObsDateTime(Date obsDateTime) { + this.obsDateTime = obsDateTime; + } + + public boolean isVoided() { + return voided; + } + + public void setVoided(boolean voided) { + this.voided = voided; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/VisitDocumentRequest.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/VisitDocumentRequest.java new file mode 100644 index 0000000000..03585640d6 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/VisitDocumentRequest.java @@ -0,0 +1,127 @@ +package org.openmrs.module.bahmniemrapi.document.contract; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class VisitDocumentRequest { + private String patientUuid; + private String visitUuid; + private String visitTypeUuid; + private Date visitStartDate; + private Date visitEndDate; + private String encounterTypeUuid; + private Date encounterDateTime; + private List documents = new ArrayList<>(); + private String providerUuid; + private String locationUuid; + private String visitLocationUuid; + + public VisitDocumentRequest() { + } + + public VisitDocumentRequest(String patientUUID, String visitUuid, String visitTypeUUID, Date visitStartDate, + Date visitEndDate, String encounterTypeUUID, Date encounterDateTime, + List documents, String providerUuid, String locationUuid, String visitLocationUuid) { + this.patientUuid = patientUUID; + this.visitUuid = visitUuid; + this.visitTypeUuid = visitTypeUUID; + this.visitStartDate = visitStartDate; + this.visitEndDate = visitEndDate; + this.encounterTypeUuid = encounterTypeUUID; + this.encounterDateTime = encounterDateTime; + this.providerUuid = providerUuid; + this.documents = documents; + this.locationUuid = locationUuid; + this.visitLocationUuid = visitLocationUuid; + } + + public String getPatientUuid() { + return patientUuid; + } + + public void setPatientUuid(String patientUuid) { + this.patientUuid = patientUuid; + } + + public String getVisitUuid() { + return visitUuid; + } + + public void setVisitUuid(String visitUuid) { + this.visitUuid = visitUuid; + } + + public String getVisitTypeUuid() { + return visitTypeUuid; + } + + public void setVisitTypeUuid(String visitTypeUuid) { + this.visitTypeUuid = visitTypeUuid; + } + + public Date getVisitStartDate() { + return visitStartDate; + } + + public void setVisitStartDate(Date visitStartDate) { + this.visitStartDate = visitStartDate; + } + + public Date getVisitEndDate() { + return visitEndDate; + } + + public void setVisitEndDate(Date visitEndDate) { + this.visitEndDate = visitEndDate; + } + + public String getEncounterTypeUuid() { + return encounterTypeUuid; + } + + public void setEncounterTypeUuid(String encounterTypeUuid) { + this.encounterTypeUuid = encounterTypeUuid; + } + + public Date getEncounterDateTime() { + return encounterDateTime; + } + + public void setEncounterDateTime(Date encounterDateTime) { + this.encounterDateTime = encounterDateTime; + } + + public List getDocuments() { + return documents; + } + + public void setDocuments(List documents) { + this.documents = documents; + } + + public String getProviderUuid() { + return providerUuid; + } + + public void setProviderUuid(String providerUuid) { + this.providerUuid = providerUuid; + } + + public String getLocationUuid() { + return locationUuid; + } + + public void setLocationUuid(String locationUuid) { + this.locationUuid = locationUuid; + } + + public String getVisitLocationUuid() { + return visitLocationUuid; + } + + public void setVisitLocationUuid(String visitLocationUuid) { + this.visitLocationUuid = visitLocationUuid; + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/VisitDocumentResponse.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/VisitDocumentResponse.java new file mode 100644 index 0000000000..47e486e134 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/contract/VisitDocumentResponse.java @@ -0,0 +1,26 @@ +package org.openmrs.module.bahmniemrapi.document.contract; + +public class VisitDocumentResponse { + private String visitUuid; + private String encounterUuid; + + public VisitDocumentResponse(String visitUuid, String encounterUuid) { + this.visitUuid = visitUuid; + this.encounterUuid = encounterUuid; + } + + public VisitDocumentResponse() { + } + + public String getVisitUuid() { + return visitUuid; + } + + public void setVisitUuid(String visitUuid) { + this.visitUuid = visitUuid; + } + + public String getEncounterUuid() { + return encounterUuid; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/VisitDocumentService.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/VisitDocumentService.java new file mode 100644 index 0000000000..fcee50ad7b --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/VisitDocumentService.java @@ -0,0 +1,8 @@ +package org.openmrs.module.bahmniemrapi.document.service; + +import org.openmrs.Encounter; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentRequest; + +public interface VisitDocumentService { + Encounter upload(VisitDocumentRequest visitDocumentRequest); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java new file mode 100644 index 0000000000..87d1c00ebf --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImpl.java @@ -0,0 +1,221 @@ +package org.openmrs.module.bahmniemrapi.document.service.impl; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.EncounterType; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.document.contract.Document; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentRequest; +import org.openmrs.module.bahmniemrapi.document.service.VisitDocumentService; +import org.openmrs.module.bahmniemrapi.encountertransaction.matcher.EncounterProviderMatcher; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import java.util.Locale; +@Service +public class VisitDocumentServiceImpl implements VisitDocumentService { + + public static final String DOCUMENT_OBS_GROUP_CONCEPT_NAME = "Document"; + + private VisitService visitService; + private ConceptService conceptService; + private EncounterService encounterService; + private ObsRelationService obsRelationService; + + @Autowired + public VisitDocumentServiceImpl(VisitService visitService, ConceptService conceptService, + EncounterService encounterService, ObsRelationService obsRelationService) { + this.visitService = visitService; + this.conceptService = conceptService; + this.encounterService = encounterService; + this.obsRelationService = obsRelationService; + } + + @Override + public Encounter upload(VisitDocumentRequest visitDocumentRequest) { + Patient patient = Context.getPatientService().getPatientByUuid(visitDocumentRequest.getPatientUuid()); + + Visit visit = findOrCreateVisit(visitDocumentRequest, patient); + Date encounterDate = (visit.getStopDatetime() != null) ? visit.getStartDatetime() : new Date(); + Encounter encounter = findOrCreateEncounter(visit, visitDocumentRequest.getEncounterTypeUuid(), encounterDate, + patient, visitDocumentRequest.getProviderUuid(), visitDocumentRequest.getLocationUuid()); + visit.addEncounter(encounter); + + updateEncounter(encounter, encounterDate, visitDocumentRequest.getDocuments()); + + Context.getEncounterService().saveEncounter(encounter); + Context.getVisitService().saveVisit(visit); + linkDocumentAndImpressionObs(visitDocumentRequest); + + return encounter; + } + + private void linkDocumentAndImpressionObs(VisitDocumentRequest visitDocumentRequest) { + for (Document document : visitDocumentRequest.getDocuments()) { + if (document.getObsUuid() != null) { + Obs parentObs = Context.getObsService().getObsByUuid(document.getObsUuid()); + Set groupMembers = parentObs.getGroupMembers(); + if (groupMembers.size() > 0) { + Obs documentObs = groupMembers.iterator().next(); + if (documentObs.getPreviousVersion() != null) { + List obsRelations = obsRelationService.getRelationsBy(null, documentObs.getPreviousVersion()); + for (ObsRelationship obsRelationship : obsRelations) { + obsRelationship.setTargetObs(documentObs); + obsRelationService.saveOrUpdate(obsRelationship); + } + } + } + } + } + } + + private Concept getConceptsByNameAndLocale(String name, Locale locale) { + List conceptList = conceptService.getConceptsByName(name, locale, false); + return conceptList.isEmpty() ? null : conceptList.get(0); + } + + private void updateEncounter(Encounter encounter, Date encounterDateTime, List documents) { + Concept imageConcept = getConceptsByNameAndLocale(DOCUMENT_OBS_GROUP_CONCEPT_NAME, Locale.ENGLISH); + + for (Document document : documents) { + Concept testConcept = conceptService.getConceptByUuid(document.getTestUuid()); + Obs parentObservation = findOrCreateParentObs(encounter, encounterDateTime, testConcept, document.getObsUuid()); + String url = document.getImage(); + + if (document.isNew()) { + Obs member = newObs(parentObservation.getObsDatetime(), imageConcept, url, null, encounter); + setComment(member, document); + parentObservation.addGroupMember(member); + } + if (document.shouldVoidDocument()) { + voidDocumentObservationTree(parentObservation); + } else if (document.hasConceptChanged(parentObservation.getConcept().getUuid())) { + voidDocumentObservationTree(parentObservation); + parentObservation = newObs(parentObservation.getObsDatetime(), testConcept, null, parentObservation.getLocation(), encounter); + Obs member = newObs(parentObservation.getObsDatetime(), imageConcept, url, null, encounter); + parentObservation.addGroupMember(member); + } else if (hasCommentsChanged(document, parentObservation)) { + setComment(parentObservation.getGroupMembers().iterator().next(), document); + } + encounter.addObs(parentObservation); + } + + } + + private boolean hasCommentsChanged(Document document, Obs parentObs) { + if (parentObs.getUuid().equals(document.getObsUuid())) { + for (Obs member : parentObs.getGroupMembers()) { + if (member.getComment() == null || !member.getComment().equals(document.getComment())) { + return true; + } + } + } + return false; + } + + private void setComment(Obs observation, Document document) { + observation.setComment(document.getComment()); + } + + private Obs findOrCreateParentObs(Encounter encounter, Date observationDateTime, Concept testConcept, String obsUuid) { + Obs observation = findObservation(encounter.getAllObs(), obsUuid); + return observation != null ? observation : newObs(observationDateTime, testConcept, null, null, encounter); + } + + private void voidDocumentObservationTree(Obs obs) { + obs.setVoided(true); + Set groupMembers = obs.getGroupMembers(); + if (groupMembers != null) { + for (Obs groupMember : groupMembers) { + groupMember.setVoided(true); + } + } + } + + private Obs findObservation(Set allObs, String obsUuid) { + for (Obs obs : allObs) { + if (obs.getUuid().equals(obsUuid)) { + return obs; + } + } + return null; + } + + private Obs newObs(Date obsDate, Concept concept, String value, Location location, Encounter encounter) { + Obs observation = new Obs(); + observation.setConcept(concept); + observation.setObsDatetime(obsDate); + observation.setPerson(encounter.getPatient()); + observation.setEncounter(encounter); + if (value != null) { + observation.setValueText(value); + } + observation.setLocation(location); + return observation; + } + + private Encounter findOrCreateEncounter(Visit visit, String encounterTypeUUID, Date encounterDateTime, Patient patient, String providerUuid, String locationUuid) { + EncounterType encounterType = encounterService.getEncounterTypeByUuid(encounterTypeUUID); + Location location = Context.getLocationService().getLocationByUuid(locationUuid); + Provider provider = Context.getProviderService().getProviderByUuid(providerUuid); + + EncounterParameters encounterParameters = EncounterParameters.instance(); + encounterParameters.setEncounterType(encounterType) + .setProviders(new HashSet<>(Collections.singletonList(provider))) + .setLocation(location); + + Encounter existingEncounter = new EncounterProviderMatcher().findEncounter(visit, encounterParameters); + if (existingEncounter != null) { + return existingEncounter; + } + + Encounter encounter = new Encounter(); + encounter.setPatient(patient); + encounter.setEncounterType(encounterType); + encounter.setEncounterDatetime(encounterDateTime); + encounter.setLocation(location); + EncounterRole encounterRoleByUuid = Context.getEncounterService().getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID); + encounter.addProvider(encounterRoleByUuid, provider); + return encounter; + } + + private Visit createVisit(String visitTypeUUID, Date visitStartDate, Date visitEndDate, Patient patient, String visitLocationUuid) { + VisitType visitType = Context.getVisitService().getVisitTypeByUuid(visitTypeUUID); + Location visitLocation = Context.getLocationService().getLocationByUuid(visitLocationUuid); + Visit visit = new Visit(); + visit.setPatient(patient); + visit.setVisitType(visitType); + visit.setStartDatetime(visitStartDate); + visit.setStopDatetime(visitEndDate); + visit.setEncounters(new HashSet()); + visit.setLocation(visitLocation); + return visit; + } + + private Visit findOrCreateVisit(VisitDocumentRequest request, Patient patient) { + if (request.getVisitUuid() != null) { + return visitService.getVisitByUuid(request.getVisitUuid()); + } + return createVisit(request.getVisitTypeUuid(), request.getVisitStartDate(), request.getVisitEndDate(), + patient, request.getVisitLocationUuid()); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/BaseTableExtension.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/BaseTableExtension.java new file mode 100644 index 0000000000..99188fb7c2 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/BaseTableExtension.java @@ -0,0 +1,19 @@ +package org.openmrs.module.bahmniemrapi.drugogram.contract; + +public class BaseTableExtension implements TableExtension { + + @Override + public void update(T table) { + //Do nothing + } + + @Override + public void update(T table, String patientUuid) { + //Do nothing + } + + @Override + public void update(T table, String patientUuid, String patientProgramUuid) { + //Do nothing + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/RegimenRow.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/RegimenRow.java new file mode 100644 index 0000000000..40564c5f69 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/RegimenRow.java @@ -0,0 +1,72 @@ +package org.openmrs.module.bahmniemrapi.drugogram.contract; + +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +public class RegimenRow{ + + private String month; + private Date date; + private Map drugs = new HashMap<>(); + + public static class RegimenComparator implements Comparator{ + @Override + public int compare(RegimenRow o1, RegimenRow o2) { + if (o1.date.after(o2.date)) return 1; + if (o1.date.before(o2.date)) return -1; + return o1.drugs.equals(o2.drugs) ? 0 : 1; + } + } + + public RegimenRow() { + } + + public RegimenRow(Date date) { + this.date = date; + } + + + public String getDrugValue(String conceptName) { + if(drugs.containsKey(conceptName)) + return drugs.get(conceptName); + else + return ""; + } + + public RegimenRow(Date date, Map drugs) { + this.date = date; + this.drugs = drugs; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Map getDrugs() { + return drugs; + } + + public void setDrugs(Map drugs) { + this.drugs = drugs; + } + + public void addDrugs(String name, String dose) { + drugs.put(name, dose); + } + + public String getMonth() { + return month; + } + + public void setMonth(String month) { + this.month = month; + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TableExtension.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TableExtension.java new file mode 100644 index 0000000000..1e24789857 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TableExtension.java @@ -0,0 +1,8 @@ +package org.openmrs.module.bahmniemrapi.drugogram.contract; + +public interface TableExtension { + + void update(T table); + void update(T table, String patientUuid); + void update(T table, String patientUuid, String patientProgramUuid); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TreatmentRegimen.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TreatmentRegimen.java new file mode 100644 index 0000000000..f064b390a1 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TreatmentRegimen.java @@ -0,0 +1,39 @@ +package org.openmrs.module.bahmniemrapi.drugogram.contract; + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +public class TreatmentRegimen { + private Set headers = new LinkedHashSet<>(); + private SortedSet rows = new TreeSet<>(new RegimenRow.RegimenComparator()); + + public Set getHeaders() { + return headers; + } + + public void setHeaders(Set headers) { + this.headers = headers; + } + + public SortedSet getRows() { + return rows; + } + + public void setRows(SortedSet rows) { + this.rows.addAll(rows); + } + + public void addRow(Date startDate) { + for (RegimenRow row : rows) { + if(row.getDate().equals(startDate)){ + return; + } + } + rows.add(new RegimenRow(startDate)); + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/DrugOrderUtil.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/DrugOrderUtil.java new file mode 100644 index 0000000000..c3d70d276e --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/DrugOrderUtil.java @@ -0,0 +1,34 @@ +package org.openmrs.module.bahmniemrapi.drugorder; + +import org.openmrs.Concept; +import org.openmrs.Duration; +import org.openmrs.OrderFrequency; + +import java.util.Date; + +import static org.apache.commons.lang3.time.DateUtils.addSeconds; + +public class DrugOrderUtil { + public static Date calculateAutoExpireDate(Integer orderDuration, Concept durationUnits, Integer numRefills, Date effectiveStartDate, OrderFrequency frequency) { + if (orderDuration == null || durationUnits == null) { + return null; + } + if (numRefills != null && numRefills > 0) { + return null; + } + String durationCode = Duration.getCode(durationUnits); + if (durationCode == null) { + return null; + } + Duration duration = new Duration(orderDuration, durationCode); + return aSecondBefore(duration.addToDate(effectiveStartDate, frequency)); + } + + public static Date aSecondBefore(Date date) { + return addSeconds(date, -1); + } + public static Date aSecondAfter(Date date) { + return addSeconds(date, 1); + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/contract/BahmniDrugOrder.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/contract/BahmniDrugOrder.java new file mode 100644 index 0000000000..528adb0239 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/contract/BahmniDrugOrder.java @@ -0,0 +1,205 @@ +package org.openmrs.module.bahmniemrapi.drugorder.contract; + +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.visit.contract.VisitData; +import org.openmrs.module.emrapi.CareSettingType; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; +import java.util.List; + + +public class BahmniDrugOrder implements Comparable{ + + private VisitData visit; + private EncounterTransaction.DrugOrder drugOrder; + private EncounterTransaction.Provider provider; + private List orderAttributes; + private boolean retired; + private String encounterUuid; + + private String creatorName; + + public String getAction() { + return drugOrder.getAction(); + } + + public Date getAutoExpireDate() { + return drugOrder.getAutoExpireDate(); + } + + public CareSettingType getCareSetting() { + return drugOrder.getCareSetting(); + } + + public String getCommentToFulfiller() { + return drugOrder.getCommentToFulfiller(); + } + + public Date getDateActivated() { + return drugOrder.getDateActivated(); + } + + public Date getDateStopped() { + return drugOrder.getDateStopped(); + } + + public EncounterTransaction.DosingInstructions getDosingInstructions() { + return drugOrder.getDosingInstructions(); + } + + public String getDosingInstructionType() { + return drugOrder.getDosingInstructionType(); + } + + public String getDrugNonCoded() { + return drugOrder.getDrugNonCoded(); + } + + public EncounterTransaction.Drug getDrug() { + return drugOrder.getDrug(); + } + + public Integer getDuration() { + return drugOrder.getDuration(); + } + + public String getDurationUnits() { + return drugOrder.getDurationUnits(); + } + + public Date getEffectiveStartDate() { + return drugOrder.getEffectiveStartDate(); + } + + public Date getEffectiveStopDate() { + return drugOrder.getEffectiveStopDate(); + } + + public String getPreviousOrderUuid() { + return drugOrder.getPreviousOrderUuid(); + } + + public String getInstructions() { + return drugOrder.getInstructions(); + } + + public EncounterTransaction.Concept getOrderReasonConcept() { + return drugOrder.getOrderReasonConcept(); + } + + public String getOrderReasonText() { + return drugOrder.getOrderReasonText(); + } + + public String getOrderType() { + return drugOrder.getOrderType(); + } + + public EncounterTransaction.OrderGroup getOrderGroup(){ + return drugOrder.getOrderGroup(); + } + + public Double getSortWeight(){ + return drugOrder.getSortWeight(); + } + + public Date getScheduledDate() { + return drugOrder.getScheduledDate(); + } + + public String getUuid() { + return drugOrder.getUuid(); + } + + public void setVisit(Visit visit) { + this.visit = new VisitData(visit); + } + + public VisitData getVisit() { + return visit; + } + + public void setDrugOrder(EncounterTransaction.DrugOrder drugOrder) { + this.drugOrder = drugOrder; + } + + public EncounterTransaction.DrugOrder getDrugOrder() { + return this.drugOrder; + } + + public void setProvider(EncounterTransaction.Provider provider) { + this.provider = provider; + } + + public EncounterTransaction.Provider getProvider() { + return provider; + } + + public String getOrderNumber() { + return drugOrder.getOrderNumber(); + } + + public List getOrderAttributes() { + return orderAttributes; + } + + public void setOrderAttributes(List orderAttributes) { + this.orderAttributes = orderAttributes; + } + + public String getCreatorName() + { + return creatorName; + } + + public void setCreatorName(String creatorName) { + this.creatorName = creatorName; + } + + public void setOrderReasonConcept(EncounterTransaction.Concept concept ) { + this.drugOrder.setOrderReasonConcept(concept); + + } + public void setOrderReasonText(String orderReasonText) { + this.drugOrder.setOrderReasonText(orderReasonText); + } + + @Override + public boolean equals(Object otherOrder){ + if(otherOrder == null) return false; + if(!(otherOrder instanceof BahmniDrugOrder)) return false; + + BahmniDrugOrder other = (BahmniDrugOrder) otherOrder; + return this.getUuid().equals(other.getUuid()); + } + + @Override + public int compareTo(BahmniDrugOrder otherOrder) { + return otherOrder.getEffectiveStartDate().compareTo(this.getEffectiveStartDate()); + } + + public void setConcept(EncounterTransaction.Concept concept) { + this.drugOrder.setConcept(concept); + } + + public EncounterTransaction.Concept getConcept() { + return this.drugOrder.getConcept(); + } + + public boolean getRetired() { + return this.retired; + } + + public void setRetired(boolean retired) { + this.retired = retired; + } + + public String getEncounterUuid() { + return this.encounterUuid; + } + + public void setEncounterUuid(String encounterUuid) { + this.encounterUuid = encounterUuid; + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/contract/BahmniOrderAttribute.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/contract/BahmniOrderAttribute.java new file mode 100644 index 0000000000..51853a2df1 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/contract/BahmniOrderAttribute.java @@ -0,0 +1,61 @@ +package org.openmrs.module.bahmniemrapi.drugorder.contract; + +public class BahmniOrderAttribute { + public static final String ORDER_ATTRIBUTES_CONCEPT_SET_NAME = "Order Attributes"; + private String name; + private String value; + private String obsUuid; + private String conceptUuid; + private String encounterUuid; + + public BahmniOrderAttribute() { + } + + public BahmniOrderAttribute(String name, String value, String obsUuid, String conceptUuid, String encounterUuid) { + this.name = name; + this.value = value; + this.obsUuid = obsUuid; + this.conceptUuid = conceptUuid; + this.encounterUuid = encounterUuid; + } + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + public String getObsUuid() { + return obsUuid; + } + + public void setObsUuid(String obsUuid) { + this.obsUuid = obsUuid; + } + + public String getConceptUuid() { + return conceptUuid; + } + + public void setConceptUuid(String conceptUuid) { + this.conceptUuid = conceptUuid; + } + + public String getEncounterUuid() { + return encounterUuid; + } + + public void setEncounterUuid(String encounterUuid) { + this.encounterUuid = encounterUuid; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/dosinginstructions/FlexibleDosingInstructions.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/dosinginstructions/FlexibleDosingInstructions.java new file mode 100644 index 0000000000..188b33eaef --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/dosinginstructions/FlexibleDosingInstructions.java @@ -0,0 +1,46 @@ +package org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions; + +import org.openmrs.DosingInstructions; +import org.openmrs.DrugOrder; +import org.openmrs.api.APIException; +import org.openmrs.module.bahmniemrapi.drugorder.DrugOrderUtil; +import org.springframework.validation.Errors; + +import java.util.Date; +import java.util.Locale; + +public class FlexibleDosingInstructions implements DosingInstructions { + + public DrugOrderUtil drugOrderUtil; + + @Override + public String getDosingInstructionsAsString(Locale locale) { + return null; + } + + @Override + public void setDosingInstructions(DrugOrder order) { + order.setDosingType(this.getClass()); + } + + + @Override + public DosingInstructions getDosingInstructions(DrugOrder order) { + if (!order.getDosingType().equals(this.getClass())) { + throw new APIException("Dosing type of drug order is mismatched. Expected:" + this.getClass() + " but received:" + + order.getDosingType()); + } + return new FlexibleDosingInstructions(); + } + + @Override + public void validate(DrugOrder order, Errors errors) { + + } + + @Override + public Date getAutoExpireDate(DrugOrder drugOrder) { + return DrugOrderUtil.calculateAutoExpireDate(drugOrder.getDuration(), drugOrder.getDurationUnits(), drugOrder.getNumRefills(), drugOrder.getEffectiveStartDate(), drugOrder.getFrequency()); + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java new file mode 100644 index 0000000000..e7ba05e633 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniDrugOrderMapper.java @@ -0,0 +1,85 @@ +package org.openmrs.module.bahmniemrapi.drugorder.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.openmrs.DrugOrder; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.mapper.OrderMapper1_12; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Locale; +public class BahmniDrugOrderMapper { + + private BahmniProviderMapper providerMapper; + private OrderAttributesMapper orderAttributesMapper; + private ConceptMapper conceptMapper; + + public BahmniDrugOrderMapper() { + this.providerMapper = new BahmniProviderMapper(); + this.orderAttributesMapper = new OrderAttributesMapper(); + this.conceptMapper = new ConceptMapper(); + } + + public List mapToResponse(List activeDrugOrders, + Collection orderAttributeObs, + Map discontinuedOrderMap, + String locale) throws IOException { + + List bahmniDrugOrders = new ArrayList<>(); + + for (DrugOrder openMRSDrugOrder : activeDrugOrders) { + BahmniDrugOrder bahmniDrugOrder = mapDrugOrderToBahmniDrugOrder(openMRSDrugOrder, locale, discontinuedOrderMap); + bahmniDrugOrders.add(bahmniDrugOrder); + } + if(CollectionUtils.isNotEmpty(orderAttributeObs)){ + bahmniDrugOrders = orderAttributesMapper.map(bahmniDrugOrders,orderAttributeObs); + } + return bahmniDrugOrders; + } + + private BahmniDrugOrder mapDrugOrderToBahmniDrugOrder(DrugOrder openMRSDrugOrder, String locale, Map discontinuedOrderMap) { + OrderMapper1_12 drugOrderMapper = new OrderMapper1_12(); + BahmniDrugOrder bahmniDrugOrder = new BahmniDrugOrder(); + bahmniDrugOrder.setDrugOrder(drugOrderMapper.mapDrugOrder(openMRSDrugOrder)); + if(locale != null) { + Locale tempLocale = new Locale(locale); + String localeSpecificName = ""; + if (openMRSDrugOrder != null) { + localeSpecificName = openMRSDrugOrder.getDrug().getFullName(tempLocale); + bahmniDrugOrder.getDrugOrder().getDrug().setName(localeSpecificName); + } + } + + if((locale != null) && (openMRSDrugOrder.getFrequency().getConcept() != null) && (openMRSDrugOrder.getFrequency().getConcept().getPreferredName(new Locale((locale))) != null)) { + bahmniDrugOrder.getDrugOrder().getDosingInstructions().setFrequency(openMRSDrugOrder.getFrequency().getConcept().getPreferredName(new Locale((locale))).getName()); + } + bahmniDrugOrder.setVisit(openMRSDrugOrder.getEncounter().getVisit()); + bahmniDrugOrder.setProvider(providerMapper.map(openMRSDrugOrder.getOrderer())); + if(openMRSDrugOrder.getDrug() != null){ + bahmniDrugOrder.setRetired(openMRSDrugOrder.getDrug().getRetired()); + } + bahmniDrugOrder.setEncounterUuid(openMRSDrugOrder.getEncounter().getUuid()); + + bahmniDrugOrder.setCreatorName(openMRSDrugOrder.getCreator().getPersonName().toString()); + if(discontinuedOrderMap.containsKey(openMRSDrugOrder.getOrderNumber())){ + bahmniDrugOrder.setOrderReasonText(discontinuedOrderMap.get(openMRSDrugOrder.getOrderNumber()).getOrderReasonNonCoded()); + bahmniDrugOrder.setOrderReasonConcept(conceptMapper.map(discontinuedOrderMap.get(openMRSDrugOrder.getOrderNumber()).getOrderReason())); + } + return bahmniDrugOrder; + } + + public void setMappers(BahmniProviderMapper bahmniProviderMapper, OrderAttributesMapper orderAttributesMapper, ConceptMapper conceptMapper){ + providerMapper = bahmniProviderMapper; + this.orderAttributesMapper = orderAttributesMapper; + this.conceptMapper = conceptMapper; + } + + public BahmniDrugOrder mapToResponse(DrugOrder drugOrder, Map discontinuedDrugOrderMap) { + return mapDrugOrderToBahmniDrugOrder(drugOrder, null, discontinuedDrugOrderMap); + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniProviderMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniProviderMapper.java new file mode 100644 index 0000000000..1b21f00a8a --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniProviderMapper.java @@ -0,0 +1,13 @@ +package org.openmrs.module.bahmniemrapi.drugorder.mapper; + +import org.openmrs.Provider; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +public class BahmniProviderMapper { + public EncounterTransaction.Provider map(Provider provider) { + EncounterTransaction.Provider result = new EncounterTransaction.Provider(); + result.setUuid(provider.getUuid()); + result.setName(provider.getName()); + return result; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/OrderAttributesMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/OrderAttributesMapper.java new file mode 100644 index 0000000000..8159af01d6 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/OrderAttributesMapper.java @@ -0,0 +1,58 @@ +package org.openmrs.module.bahmniemrapi.drugorder.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniOrderAttribute; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Component +public class OrderAttributesMapper { + + public List map(List drugOrders, Collection observations){ + Map bahmniDrugOrderMap = createOrderUuidToDrugOrderMap(drugOrders); + if(CollectionUtils.isNotEmpty(observations) && MapUtils.isNotEmpty(bahmniDrugOrderMap)){ + for(BahmniObservation bahmniObservation : observations){ + if(bahmniDrugOrderMap.containsKey(bahmniObservation.getOrderUuid())){ + BahmniDrugOrder bahmniDrugOrder = bahmniDrugOrderMap.get(bahmniObservation.getOrderUuid()); + BahmniOrderAttribute bahmniOrderAttribute = + new BahmniOrderAttribute( + bahmniObservation.getConcept().getName(), + bahmniObservation.getValue().toString(), + bahmniObservation.getUuid(), + bahmniObservation.getConceptUuid(), + bahmniObservation.getEncounterUuid()); + addOrderAttributes(bahmniDrugOrder, bahmniOrderAttribute); + } + } + } + return new ArrayList<>(bahmniDrugOrderMap.values()); + } + + private void addOrderAttributes(BahmniDrugOrder bahmniDrugOrder, BahmniOrderAttribute bahmniOrderAttribute) { + if(CollectionUtils.isNotEmpty(bahmniDrugOrder.getOrderAttributes())){ + bahmniDrugOrder.getOrderAttributes().add(bahmniOrderAttribute); + }else{ + List bahmniOrderAttributes = new ArrayList<>(); + bahmniOrderAttributes.add(bahmniOrderAttribute); + bahmniDrugOrder.setOrderAttributes(bahmniOrderAttributes); + } + } + + private Map createOrderUuidToDrugOrderMap(List drugOrders){ + Map bahmniDrugOrderMap = new LinkedHashMap<>(); + if(CollectionUtils.isNotEmpty(drugOrders)){ + for(BahmniDrugOrder bahmniDrugOrder : drugOrders){ + bahmniDrugOrderMap.put(bahmniDrugOrder.getUuid(), bahmniDrugOrder); + } + } + return bahmniDrugOrderMap; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/advice/BahmniEncounterTransactionUpdateAdvice.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/advice/BahmniEncounterTransactionUpdateAdvice.java new file mode 100644 index 0000000000..397b484095 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/advice/BahmniEncounterTransactionUpdateAdvice.java @@ -0,0 +1,53 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.advice; + +import groovy.lang.GroovyClassLoader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.obscalculator.ObsValueCalculator; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.aop.MethodBeforeAdvice; + +import java.io.File; +import java.io.FileNotFoundException; +import java.lang.reflect.Method; +import java.nio.file.Paths; + +public class BahmniEncounterTransactionUpdateAdvice implements MethodBeforeAdvice { + + private static final String BAHMNI_EXECUTE_GROOVY_SCRIPT = "bahmni.executeGroovyObsValueCalculator" ; + private static Logger logger = LogManager.getLogger(BahmniEncounterTransactionUpdateAdvice.class); + private static String BAHMNI_OBS_VALUE_CALCULATOR_FILENAME = "BahmniObsValueCalculator.groovy"; + + @Override + public void before(Method method, Object[] args, Object target) throws Throwable { + if (!shouldExecuteGroovyScript()) return; + logger.info( "{}: Start", this.getClass().getName()); + GroovyClassLoader gcl = new GroovyClassLoader(); + String fileName = Paths.get( + OpenmrsUtil.getApplicationDataDirectory(), + "obscalculator", + BAHMNI_OBS_VALUE_CALCULATOR_FILENAME + ).toString(); + Class clazz; + try { + clazz = gcl.parseClass(new File(fileName)); + } catch (FileNotFoundException fileNotFound) { + logger.error("Could not find {} : {}. Possible system misconfiguration. {} ", ObsValueCalculator.class.getName(), fileName, fileNotFound); + return; + } + logger.info( "{} : Using rules in {}", this.getClass().getName(), clazz.getName()); + ObsValueCalculator obsValueCalculator = (ObsValueCalculator) clazz.newInstance(); + obsValueCalculator.run((BahmniEncounterTransaction) args[0]); + logger.info( " {}: Done", this.getClass().getName()); + } + + private boolean shouldExecuteGroovyScript() { + String propertyValue = Context.getAdministrationService().getGlobalProperty(BAHMNI_EXECUTE_GROOVY_SCRIPT); + return (propertyValue != null) ? Boolean.valueOf(propertyValue.trim()) : Boolean.FALSE; + } + + + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/advisor/BahmniEncounterServiceAdvisor.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/advisor/BahmniEncounterServiceAdvisor.java new file mode 100644 index 0000000000..7aeeec6796 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/advisor/BahmniEncounterServiceAdvisor.java @@ -0,0 +1,22 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.advisor; + +import org.aopalliance.aop.Advice; +import org.openmrs.module.bahmniemrapi.encountertransaction.advice.BahmniEncounterTransactionUpdateAdvice; +import org.springframework.aop.Advisor; +import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor; + +import java.lang.reflect.Method; + +public class BahmniEncounterServiceAdvisor extends StaticMethodMatcherPointcutAdvisor implements Advisor { + private static final String SAVE_METHOD = "save"; + + @Override + public boolean matches(Method method, Class aClass) { + return SAVE_METHOD.equals(method.getName()); + } + + @Override + public Advice getAdvice() { + return new BahmniEncounterTransactionUpdateAdvice(); + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/EncounterDataPostSaveCommand.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/EncounterDataPostSaveCommand.java new file mode 100644 index 0000000000..8a608b3db3 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/EncounterDataPostSaveCommand.java @@ -0,0 +1,10 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command; + +import org.openmrs.Encounter; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +public interface EncounterDataPostSaveCommand { + + EncounterTransaction save(BahmniEncounterTransaction bahmniEncounterTransaction, Encounter currentEncounter, EncounterTransaction updatedEncounterTransaction); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/EncounterDataPreSaveCommand.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/EncounterDataPreSaveCommand.java new file mode 100644 index 0000000000..18143c8467 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/EncounterDataPreSaveCommand.java @@ -0,0 +1,9 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.springframework.beans.factory.config.BeanPostProcessor; + +public interface EncounterDataPreSaveCommand extends BeanPostProcessor{ + + BahmniEncounterTransaction update(BahmniEncounterTransaction bahmniEncounterTransaction); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniObservationSaveCommandImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniObservationSaveCommandImpl.java new file mode 100644 index 0000000000..b42fa9a59d --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniObservationSaveCommandImpl.java @@ -0,0 +1,69 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.ObsService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPostSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class BahmniObservationSaveCommandImpl implements EncounterDataPostSaveCommand { + private ObsRelationService obsRelationService; + private ObsService obsService; + + @Autowired + public BahmniObservationSaveCommandImpl(ObsRelationService obsRelationService, ObsService obsService) { + this.obsRelationService = obsRelationService; + this.obsService = obsService; + } + + @Override + public EncounterTransaction save(BahmniEncounterTransaction bahmniEncounterTransaction, Encounter currentEncounter, EncounterTransaction updatedEncounterTransaction) { + for (BahmniObservation bahmniObservation : bahmniEncounterTransaction.getObservations()) { + if(bahmniObservation.hasTargetObsRelation()){ + Obs srcObservation =findMatchingObservation(bahmniObservation, currentEncounter); + Obs targetObservation =findMatchingObservation(bahmniObservation.getTargetObsRelation().getTargetObs(), currentEncounter); + + if(targetObservation == null){ + String uuid = bahmniObservation.getTargetObsRelation().getTargetObs().getUuid(); + targetObservation = obsService.getObsByUuid(uuid); + } + ObsRelationshipType obsRelationshipType = obsRelationService.getRelationshipTypeByName(bahmniObservation.getTargetObsRelation().getRelationshipType()); + ObsRelationship obsRelation = createNewIfDoesNotExist(bahmniObservation.getTargetObsRelation().getUuid()); + obsRelation.setSourceObs(srcObservation); + obsRelation.setTargetObs(targetObservation); + obsRelation.setObsRelationshipType(obsRelationshipType); + + obsRelationService.saveOrUpdate(obsRelation); + } + } + return updatedEncounterTransaction; + } + + private ObsRelationship createNewIfDoesNotExist(String obsRelationUuid){ + ObsRelationship obsRelation = new ObsRelationship(); + if(obsRelationUuid!= null){ + obsRelation = obsRelationService.getRelationByUuid(obsRelationUuid); + if(obsRelation == null){ + obsRelation = new ObsRelationship(); + } + } + return obsRelation; + } + + private Obs findMatchingObservation(BahmniObservation bahmniObservation, Encounter currentEncounter) { + for (Obs obs : currentEncounter.getAllObs()) { + if(bahmniObservation.isSameAs(obs)){ + return obs; + } + } + return null; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniVisitAttributeService.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniVisitAttributeService.java new file mode 100644 index 0000000000..ec462f1ef2 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniVisitAttributeService.java @@ -0,0 +1,101 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.openmrs.Encounter; +import org.openmrs.Visit; +import org.openmrs.VisitAttribute; +import org.openmrs.VisitAttributeType; +import org.openmrs.api.VisitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class BahmniVisitAttributeService { + public static final String VISIT_STATUS_ATTRIBUTE_TYPE = "Visit Status"; + public static final String ADMISSION_STATUS_ATTRIBUTE_TYPE = "Admission Status"; + public static final String OPD_VISIT_TYPE = "OPD"; + public static final String ADMISSION_ENCOUNTER_TYPE = "ADMISSION"; + private static final String DISCHARGE_ENCOUNTER_TYPE = "DISCHARGE"; + public static final String IPD_VISIT_TYPE = "IPD"; + private static final String CONSULTATION_ENCOUNTER_TYPE = "CONSULTATION"; + private VisitService visitService; + + @Autowired + public BahmniVisitAttributeService(VisitService visitService) { + this.visitService = visitService; + } + + + public void save(Encounter currentEncounter) { + Visit updatedVisit = createOrUpdateVisitAttribute(currentEncounter); + currentEncounter.setVisit(updatedVisit); + } + + private Visit createOrUpdateVisitAttribute(Encounter currentEncounter) { + Visit visit = currentEncounter.getVisit(); + if (findVisitAttribute(visit, ADMISSION_STATUS_ATTRIBUTE_TYPE) != null + && findVisitAttribute(visit, VISIT_STATUS_ATTRIBUTE_TYPE) != null + && currentEncounter.getEncounterType().getName().equalsIgnoreCase(CONSULTATION_ENCOUNTER_TYPE)) + { + return visit; + } + setVisitStatus(currentEncounter, visit); + setAdmissionStatus(currentEncounter, visit); + return visitService.saveVisit(visit); + } + + private void setAdmissionStatus(Encounter currentEncounter, Visit visit) { + VisitAttribute admissionStatus = findVisitAttribute(visit, ADMISSION_STATUS_ATTRIBUTE_TYPE); + if (admissionStatus == null) { + admissionStatus = createVisitAttribute(visit, null, ADMISSION_STATUS_ATTRIBUTE_TYPE); + } + if (currentEncounter.getEncounterType().getName().equalsIgnoreCase(ADMISSION_ENCOUNTER_TYPE)) { + admissionStatus.setValueReferenceInternal("Admitted"); + visit.setAttribute(admissionStatus); + } + if (currentEncounter.getEncounterType().getName().equalsIgnoreCase(DISCHARGE_ENCOUNTER_TYPE)) { + if(currentEncounter.isVoided()){ + admissionStatus.setValueReferenceInternal("Admitted"); + }else{ + admissionStatus.setValueReferenceInternal("Discharged"); + } + visit.setAttribute(admissionStatus); + } + } + + private void setVisitStatus(Encounter currentEncounter, Visit visit) { + VisitAttribute visitStatus = findVisitAttribute(visit, VISIT_STATUS_ATTRIBUTE_TYPE); + if (visitStatus == null) { + visitStatus = createVisitAttribute(visit, OPD_VISIT_TYPE, VISIT_STATUS_ATTRIBUTE_TYPE); + } + if (currentEncounter.getEncounterType().getName().equalsIgnoreCase(ADMISSION_ENCOUNTER_TYPE)) { + visitStatus.setValueReferenceInternal(IPD_VISIT_TYPE); + } + visit.setAttribute(visitStatus); + } + + private VisitAttribute createVisitAttribute(Visit visit, String value, String visitAttributeTypeName) { + VisitAttribute visitStatus = new VisitAttribute(); + visitStatus.setVisit(visit); + visitStatus.setAttributeType(getVisitAttributeType(visitAttributeTypeName)); + visitStatus.setValueReferenceInternal(value); + return visitStatus; + } + + private VisitAttributeType getVisitAttributeType(String visitAttributeTypeName) { + for (VisitAttributeType visitAttributeType : visitService.getAllVisitAttributeTypes()) { + if (visitAttributeType.getName().equalsIgnoreCase(visitAttributeTypeName)) { + return visitAttributeType; + } + } + return null; + } + + private VisitAttribute findVisitAttribute(Visit visit, String visitAttributeTypeName) { + for (VisitAttribute visitAttribute : visit.getAttributes()) { + if (visitAttribute.getAttributeType().getName().equalsIgnoreCase(visitAttributeTypeName)) { + return visitAttribute; + } + } + return null; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/DrugOrderSaveCommandImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/DrugOrderSaveCommandImpl.java new file mode 100644 index 0000000000..923e894edd --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/DrugOrderSaveCommandImpl.java @@ -0,0 +1,136 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.apache.commons.lang3.time.DateUtils; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.drugorder.DrugOrderUtil; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPreSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.service.OrderMetadataService; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Component +public class DrugOrderSaveCommandImpl implements EncounterDataPreSaveCommand { + + private OrderMetadataService orderMetadataService; + private ConceptService conceptService; + + private Comparator drugOrderStartDateComparator = new Comparator() { + @Override + public int compare(EncounterTransaction.DrugOrder o1, EncounterTransaction.DrugOrder o2) { + Date date1 = o1.getScheduledDate(); + Date date2 = o2.getScheduledDate(); + if(date1 == null){ + date1 = new Date(); + } + if(date2 == null){ + date2 = new Date(); + } + return date1.compareTo(date2); + } + }; + + + @Autowired + public DrugOrderSaveCommandImpl(OrderMetadataService orderMetadataService, ConceptService conceptService) { + this.orderMetadataService = orderMetadataService; + this.conceptService = conceptService; + } + + @Override + public BahmniEncounterTransaction update(BahmniEncounterTransaction bahmniEncounterTransaction) { + List drugOrders = bahmniEncounterTransaction.getDrugOrders(); + Map> sameDrugNameOrderLists = new LinkedHashMap<>(); + for (EncounterTransaction.DrugOrder drugOrder : drugOrders) { + String name = getDrugName(drugOrder); + if(sameDrugNameOrderLists.get(name) == null){ + sameDrugNameOrderLists.put(name, new ArrayList()); + } + sameDrugNameOrderLists.get(name).add(drugOrder); + } + + for (List orders : sameDrugNameOrderLists.values()) { + Collections.sort(orders, drugOrderStartDateComparator); + checkAndFixChainOverlapsWithCurrentDateOrder(orders, bahmniEncounterTransaction.getEncounterDateTime()); + } + + return bahmniEncounterTransaction; + } + + private String getDrugName(EncounterTransaction.DrugOrder drugOrder) { + String drugName = drugOrder.getDrugNonCoded(); + if (drugName == null && drugOrder.getDrug() != null ) { + drugName = drugOrder.getDrug().getName(); + } + return drugName; + } + + private void checkAndFixChainOverlapsWithCurrentDateOrder(Collection orders, Date encounterDateTime) { +// Refactor using Lambda expressions after updating to Java 8 + EncounterTransaction.DrugOrder currentDateOrder = getCurrentOrderFromOrderList(orders); + + if(currentDateOrder != null){ + Date expectedStartDateForCurrentOrder = getExpectedStartDateForOrder(currentDateOrder); + Date expectedStopDateForCurrentOrder = getExpectedStopDateForOrder(currentDateOrder, expectedStartDateForCurrentOrder); + + for (EncounterTransaction.DrugOrder order : orders) { + if((!order.equals(currentDateOrder)) && !"DISCONTINUE".equals(order.getAction()) && DateUtils.isSameDay(getExpectedStartDateForOrder(order), expectedStopDateForCurrentOrder)){ + currentDateOrder.setScheduledDate(expectedStartDateForCurrentOrder); + currentDateOrder.setAutoExpireDate(expectedStopDateForCurrentOrder); + + order.setScheduledDate(DrugOrderUtil.aSecondAfter(expectedStopDateForCurrentOrder)); + + currentDateOrder = order; + expectedStartDateForCurrentOrder = getExpectedStartDateForOrder(order); + expectedStopDateForCurrentOrder = getExpectedStopDateForOrder(currentDateOrder, expectedStartDateForCurrentOrder); + }else if(!"DISCONTINUE".equals(order.getAction()) && order.getScheduledDate() == null && !BahmniEncounterTransaction.isRetrospectiveEntry(encounterDateTime)){ + //In retro.. date will be put as encouter date/time + order.setDateActivated(expectedStartDateForCurrentOrder); + } + } + } + } + + private Date getExpectedStopDateForOrder(EncounterTransaction.DrugOrder order, Date expectedStartDateForCurrentOrder) { + Concept durationUnitConcept = conceptService.getConceptByName(order.getDurationUnits()); + return DrugOrderUtil.calculateAutoExpireDate(order.getDuration(), durationUnitConcept, null, expectedStartDateForCurrentOrder, orderMetadataService.getOrderFrequencyByName(order.getDosingInstructions().getFrequency(), false)); + } + + private Date getExpectedStartDateForOrder(EncounterTransaction.DrugOrder order) { + if( order.getScheduledDate() == null){ + return new Date(); + } + return order.getScheduledDate(); + } + + private EncounterTransaction.DrugOrder getCurrentOrderFromOrderList(Collection orders) { + for (EncounterTransaction.DrugOrder order : orders) { + if (!"DISCONTINUE".equals(order.getAction())) { // To detect orders with dateActivated = current date + return order; + } + } + return null; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/OrderSaveCommandImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/OrderSaveCommandImpl.java new file mode 100644 index 0000000000..cea8609dd0 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/OrderSaveCommandImpl.java @@ -0,0 +1,47 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.joda.time.DateTime; +import org.openmrs.api.AdministrationService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPreSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +public class OrderSaveCommandImpl implements EncounterDataPreSaveCommand { + + private AdministrationService adminService; + public static final int DEFAULT_SESSION_DURATION_IN_MINUTES = 60; + + @Autowired + public OrderSaveCommandImpl(@Qualifier("adminService") AdministrationService administrationService) { + this.adminService = administrationService; + } + + @Override + public BahmniEncounterTransaction update(BahmniEncounterTransaction bahmniEncounterTransaction) { + String configuredSessionDuration = adminService.getGlobalProperty("bahmni.encountersession.duration"); + int encounterSessionDuration = configuredSessionDuration != null ? Integer.parseInt(configuredSessionDuration) : DEFAULT_SESSION_DURATION_IN_MINUTES; + + for (EncounterTransaction.Order order : bahmniEncounterTransaction.getOrders()) { + if(order.getAutoExpireDate() == null){ + order.setAutoExpireDate(DateTime.now().plusMinutes(encounterSessionDuration).toDate()); + } + } + return bahmniEncounterTransaction; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/ParentConceptSaveCommandImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/ParentConceptSaveCommandImpl.java new file mode 100644 index 0000000000..be6be89103 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/ParentConceptSaveCommandImpl.java @@ -0,0 +1,44 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPreSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.springframework.beans.BeansException; +import org.springframework.stereotype.Component; + +import java.util.Collection; + +@Component +public class ParentConceptSaveCommandImpl implements EncounterDataPreSaveCommand{ + @Override + public BahmniEncounterTransaction update(BahmniEncounterTransaction bahmniEncounterTransaction) { + Collection bahmniObservations = bahmniEncounterTransaction.getObservations(); + + for(BahmniObservation bahmniObservation : bahmniObservations){ + String parentConceptUuid = bahmniObservation.getConceptUuid(); + bahmniObservation.setParentConceptUuid(parentConceptUuid); + updateChildren(bahmniObservation); + } + + return bahmniEncounterTransaction; + } + + private void updateChildren(BahmniObservation parentObs) { + Collection childrenObs = parentObs.getGroupMembers(); + + for(BahmniObservation observation: childrenObs){ + observation.setParentConceptUuid(parentObs.getParentConceptUuid()); + updateChildren(observation); + } + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterSearchParameters.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterSearchParameters.java new file mode 100644 index 0000000000..05ec65ba64 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterSearchParameters.java @@ -0,0 +1,27 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.contract; + +import org.openmrs.module.emrapi.encounter.EncounterSearchParameters; + +import java.util.Date; +import java.util.List; + +public class BahmniEncounterSearchParameters extends EncounterSearchParameters { + private String patientProgramUuid; + + public BahmniEncounterSearchParameters() { + super(); + } + + public BahmniEncounterSearchParameters(List visitUuids, String patientUuid, List visitTypeUuids, Date encounterDateTimeFrom, Date encounterDateTimeTo, List providerUuids, List encounterTypeUuids, String locationUuid, Boolean includeAll, String patientProgramUuid) { + super(visitUuids, patientUuid, visitTypeUuids, encounterDateTimeFrom, encounterDateTimeTo, providerUuids, encounterTypeUuids, locationUuid, includeAll); + this.patientProgramUuid = patientProgramUuid; + } + + public String getPatientProgramUuid() { + return patientProgramUuid; + } + + public void setPatientProgramUuid(String patientProgramUuid) { + this.patientProgramUuid = patientProgramUuid; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterTransaction.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterTransaction.java new file mode 100644 index 0000000000..bf7df9c9f2 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterTransaction.java @@ -0,0 +1,387 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.contract; + +import org.apache.commons.lang.StringUtils; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.joda.time.DateTime; +import org.openmrs.module.bahmniemrapi.accessionnote.contract.AccessionNote; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BahmniEncounterTransaction { + + private EncounterTransaction encounterTransaction = new EncounterTransaction(); + + private List bahmniDiagnoses = new ArrayList<>(); + private Collection observations = new TreeSet<>(); + private List accessionNotes; + private String encounterType; + private String visitType; + private String patientId; + private String reason; + + + public BahmniEncounterTransaction() { + this(new EncounterTransaction()); + } + + public BahmniEncounterTransaction(EncounterTransaction encounterTransaction) { + this.encounterTransaction = encounterTransaction; + } + + public List getBahmniDiagnoses() { + return bahmniDiagnoses; + } + + public void setBahmniDiagnoses(List bahmniDiagnoses) { + this.bahmniDiagnoses = bahmniDiagnoses; + List newDiagnoses = new ArrayList<>(); + for (BahmniDiagnosisRequest bahmniDiagnose : bahmniDiagnoses) { + newDiagnoses.add(bahmniDiagnose); + } + encounterTransaction.setDiagnoses(newDiagnoses); + } + + public String getVisitUuid() { + return encounterTransaction.getVisitUuid(); + } + + public void setVisitUuid(String visitUuid) { + encounterTransaction.setVisitUuid(visitUuid); + } + + + public String getEncounterUuid() { + return encounterTransaction.getEncounterUuid(); + } + + + public void setEncounterUuid(String encounterUuid) { + encounterTransaction.setEncounterUuid(encounterUuid); + } + + public String getPatientProgramUuid() { + return (String) encounterTransaction.getContext().get("patientProgramUuid"); + } + + public void setPatientProgramUuid(String patientProgramUuid) { + this.encounterTransaction.getContext().put("patientProgramUuid", patientProgramUuid); + } + + public void addObservation(BahmniObservation observation) { + observation.setEncounterDateTime(getEncounterDateTime()); + observations.add(observation); + } + + + public void addOrder(EncounterTransaction.Order order) { + encounterTransaction.addOrder(order); + } + + + public void addDrugOrder(EncounterTransaction.DrugOrder drugOrder) { + encounterTransaction.addDrugOrder(drugOrder); + } + + + public void addBahmniDiagnosis(BahmniDiagnosisRequest diagnosis) { + bahmniDiagnoses.add(diagnosis); + encounterTransaction.addDiagnosis(diagnosis); + } + + + public Set getProviders() { + return encounterTransaction.getProviders(); + } + + + public void setProviders(Set providers) { + encounterTransaction.setProviders(providers); + } + + + public EncounterTransaction.Disposition getDisposition() { + return encounterTransaction.getDisposition(); + } + + + public void setDisposition(EncounterTransaction.Disposition disposition) { + encounterTransaction.setDisposition(disposition); + } + + + public String getPatientUuid() { + return encounterTransaction.getPatientUuid(); + } + + + public String getEncounterTypeUuid() { + return encounterTransaction.getEncounterTypeUuid(); + } + + + public String getVisitTypeUuid() { + return encounterTransaction.getVisitTypeUuid(); + } + + + public EncounterTransaction setPatientUuid(String patientUuid) { + return encounterTransaction.setPatientUuid(patientUuid); + } + + + public EncounterTransaction setVisitTypeUuid(String visitTypeUuid) { + return encounterTransaction.setVisitTypeUuid(visitTypeUuid); + } + + + public EncounterTransaction setEncounterTypeUuid(String encounterTypeUuid) { + return encounterTransaction.setEncounterTypeUuid(encounterTypeUuid); + } + + public Collection getObservations() { + return new TreeSet<>(observations); + } + + public void setObservations(Collection observations) { + for (BahmniObservation observation : observations) { + observation.setEncounterDateTime(getEncounterDateTime()); + } + this.observations = observations; + } + + + public List getOrders() { + return encounterTransaction.getOrders(); + } + + + public void setOrders(List orders) { + encounterTransaction.setOrders(orders); + } + + + public List getDrugOrders() { + return encounterTransaction.getDrugOrders(); + } + + + public void setDrugOrders(List drugOrders) { + encounterTransaction.setDrugOrders(drugOrders); + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getEncounterDateTime() { + return encounterTransaction.getEncounterDateTime(); + } + + + public EncounterTransaction setEncounterDateTime(Date encounterDateTime) { + return encounterTransaction.setEncounterDateTime(encounterDateTime); + } + + + public String getLocationUuid() { + return encounterTransaction.getLocationUuid(); + } + + + public EncounterTransaction setLocationUuid(String locationUuid) { + return encounterTransaction.setLocationUuid(locationUuid); + } + + public String getLocationName() { + return encounterTransaction.getLocationName(); + } + + public EncounterTransaction setLocationName(String locationName) { + return encounterTransaction.setLocationName(locationName); + } + + public List getAccessionNotes() { + return accessionNotes; + } + + public void setAccessionNotes(List accessionNotes) { + this.accessionNotes = accessionNotes; + } + + public void setEncounterType(String encounterType) { + this.encounterType = encounterType; + } + + public void setVisitType(String visitType) { + this.visitType = visitType; + } + + public String getEncounterType() { + return encounterType; + } + + public String getVisitType() { + return visitType; + } + + public EncounterTransaction toEncounterTransaction() { + encounterTransaction.setObservations(BahmniObservation.toETObsFromBahmniObs(this.observations)); + return encounterTransaction; + } + + public Map getExtensions() { + return encounterTransaction.getExtensions(); + } + + public EncounterTransaction setExtensions(Map extensions) { + encounterTransaction.setExtensions(extensions); + return encounterTransaction; + } + + public Map getContext() { + return encounterTransaction.getContext(); + } + + public EncounterTransaction setContext(Map extensions) { + encounterTransaction.setContext(extensions); + return encounterTransaction; + } + + public String getPatientId() { + return patientId; + } + + public void setPatientId(String patientId) { + this.patientId = patientId; + } + + public BahmniEncounterTransaction updateForRetrospectiveEntry(Date encounterDate) { + this.setEncounterDateTime(encounterDate); + + updateObservationDates(encounterDate); + updateDiagnosisDates(encounterDate); + updateDrugOrderDates(encounterDate); + updateDisposition(encounterDate); + return this; + } + + public BahmniEncounterTransaction updateDisposition(Date encounterDate) { + if (getDisposition() != null && getDisposition().getDispositionDateTime() == null) { + getDisposition().setDispositionDateTime(encounterDate); + } + return this; + } + + public BahmniEncounterTransaction updateDrugOrderDates(Date encounterDate) { + for (EncounterTransaction.DrugOrder drugOrder : getDrugOrders()) { + if (drugOrder.getDateActivated() == null) + drugOrder.setDateActivated(encounterDate); + } + return this; + } + + public BahmniEncounterTransaction updateDrugOrderIfScheduledDateNotSet(Date date) { + for (EncounterTransaction.DrugOrder drugOrder : getDrugOrders()) { + if (drugOrder.getScheduledDate() == null) + drugOrder.setScheduledDate(date); + } + return this; + } + + public BahmniEncounterTransaction updateDiagnosisDates(Date encounterDate) { + for (BahmniDiagnosis diagnosis : getBahmniDiagnoses()) { + if (diagnosis.getDiagnosisDateTime() == null) + diagnosis.setDiagnosisDateTime(encounterDate); + } + return this; + } + + public BahmniEncounterTransaction updateObservationDates(Date encounterDate) { + for (BahmniObservation observation : getObservations()) { + setObsDate(observation, encounterDate); + } + return this; + } + + private void setObsDate(BahmniObservation observation, Date encounterDate) { + if (observation.getObservationDateTime() == null) + observation.setObservationDateTime(encounterDate); + + for (BahmniObservation childObservation : observation.getGroupMembers()) { + setObsDate(childObservation, encounterDate); + } + } + + + + public static boolean isRetrospectiveEntry(Date encounterDateTime) { + return encounterDateTime != null && new DateTime(encounterDateTime).toDateMidnight().isBefore(new DateTime(new Date()).toDateMidnight()); + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public boolean hasPastDrugOrders() { + List drugOrders = encounterTransaction.getDrugOrders(); + + for(EncounterTransaction.DrugOrder drugOrder: drugOrders){ + if(drugOrder.getScheduledDate().before(this.getEncounterDateTime())){ + return true; + } + } + + return false; + } + + public BahmniEncounterTransaction cloneForPastDrugOrders() { + BahmniEncounterTransaction previousBahmniEncounterTransaction = new BahmniEncounterTransaction(); + previousBahmniEncounterTransaction.setDrugOrders(getDrugOrders()); + previousBahmniEncounterTransaction.setEncounterTypeUuid(getEncounterTypeUuid()); + previousBahmniEncounterTransaction.setLocationUuid(getLocationUuid()); + previousBahmniEncounterTransaction.setPatientUuid(getPatientUuid()); + previousBahmniEncounterTransaction.setProviders(getProviders()); + previousBahmniEncounterTransaction.setVisitType(getVisitType()); + previousBahmniEncounterTransaction.setVisitTypeUuid(getVisitTypeUuid()); + previousBahmniEncounterTransaction.setPatientProgramUuid(getPatientProgramUuid()); + + EncounterTransaction.DrugOrder oldestDrugOrder = getOldestDrugOrder(); + previousBahmniEncounterTransaction.setEncounterDateTime(oldestDrugOrder == null ? null : oldestDrugOrder.getScheduledDate()); + return previousBahmniEncounterTransaction; + } + + public void clearDrugOrders() { + encounterTransaction.setDrugOrders(new ArrayList()); + } + + private EncounterTransaction.DrugOrder getOldestDrugOrder() { + if(getDrugOrders().size()==0) + return null; + + EncounterTransaction.DrugOrder oldestDrugOrder = getDrugOrders().get(0); + for (EncounterTransaction.DrugOrder drugOrder : getDrugOrders()) { + if (drugOrder.getScheduledDate().before(oldestDrugOrder.getScheduledDate())) { + oldestDrugOrder = drugOrder; + } + } + return oldestDrugOrder; + } + + public boolean isAssociatedToPatientProgram() { + return StringUtils.isNotBlank(getPatientProgramUuid()); + } +} + diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java new file mode 100644 index 0000000000..62f85be997 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java @@ -0,0 +1,443 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.contract; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openmrs.Obs; +import org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BahmniObservation implements Comparable{ + + private Date encounterDateTime; + private Date visitStartDateTime; + private ObsRelationship targetObsRelation; + private EncounterTransaction.Observation encounterTransactionObservation; + private Collection groupMembers = new ArrayList<>(); + public Set providers = new HashSet<>(); + private Boolean isAbnormal; + private Long duration; + private String type; + private String encounterUuid; + private String obsGroupUuid; + private String creatorName; + private int conceptSortWeight; + private String parentConceptUuid; + private Double hiNormal; + private Double lowNormal; + private Boolean isUnknown; + private String formNamespace; + private String formFieldPath; + private String interpretation; + private String status; + private String encounterTypeName; + private String conceptFSN; + + @JsonIgnore + private Serializable complexData; + + public BahmniObservation() { + encounterTransactionObservation = new EncounterTransaction.Observation(); + } + + public EncounterTransaction.Concept getConcept() { + return encounterTransactionObservation.getConcept(); + } + + public BahmniObservation setConcept(EncounterTransaction.Concept concept) { + encounterTransactionObservation.setConcept(concept); + return this; + } + + public Object getValue() { + return encounterTransactionObservation.getValue(); + } + + public String getValueAsString() { + Object value = encounterTransactionObservation.getValue(); + if (value != null) { + if (value instanceof EncounterTransaction.Concept) { + EncounterTransaction.Concept concept = (EncounterTransaction.Concept) value; + return (concept.getShortName() == null ? concept.getName() : concept.getShortName()); + } else if(value instanceof EncounterTransaction.Drug){ + EncounterTransaction.Drug drug = (EncounterTransaction.Drug) value; + return drug.getName(); + }else if (value instanceof Boolean) { + return (Boolean) value ? "Yes" : "No"; + } + return String.valueOf(value); + } + return ""; + } + + + public BahmniObservation setValue(Object value) { + encounterTransactionObservation.setValue(value); + return this; + } + + public String getComment() { + return encounterTransactionObservation.getComment(); + } + + public BahmniObservation setComment(String comment) { + encounterTransactionObservation.setComment(comment); + return this; + } + + public BahmniObservation setVoided(boolean voided) { + encounterTransactionObservation.setVoided(voided); + return this; + } + + public boolean getVoided() { + return encounterTransactionObservation.getVoided(); + } + + public String getVoidReason() { + return encounterTransactionObservation.getVoidReason(); + } + + public BahmniObservation setVoidReason(String voidReason) { + encounterTransactionObservation.setVoidReason(voidReason); + return this; + } + + public Collection getGroupMembers() { + return new TreeSet<>(this.groupMembers); + } + + public void setGroupMembers(Collection groupMembers) { + this.groupMembers = groupMembers; + } + + public void addGroupMember(BahmniObservation observation) { + groupMembers.add(observation); + } + + public void removeGroupMembers(Collection observations) { + groupMembers.removeAll(observations); + } + + public String getOrderUuid() { + return encounterTransactionObservation.getOrderUuid(); + } + + public BahmniObservation setOrderUuid(String orderUuid) { + encounterTransactionObservation.setOrderUuid(orderUuid); + return this; + } + + public BahmniObservation setObservationDateTime(Date observationDateTime) { + encounterTransactionObservation.setObservationDateTime(observationDateTime); + return this; + } + + public String getUuid() { + return encounterTransactionObservation.getUuid(); + } + + public BahmniObservation setUuid(String uuid) { + encounterTransactionObservation.setUuid(uuid); + return this; + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getObservationDateTime() { + return encounterTransactionObservation.getObservationDateTime(); + } + + public boolean isSameAs(EncounterTransaction.Observation encounterTransactionObservation) { + return this.getUuid().equals(encounterTransactionObservation.getUuid()); + } + + public ObsRelationship getTargetObsRelation() { + return targetObsRelation; + } + + public void setTargetObsRelation(ObsRelationship targetObsRelation) { + this.targetObsRelation = targetObsRelation; + } + + public EncounterTransaction.Observation toETObservation() { + List observations = new ArrayList<>(); + for (BahmniObservation groupMember : this.groupMembers) { + observations.add(groupMember.toETObservation()); + } + encounterTransactionObservation.setGroupMembers(observations); + return this.encounterTransactionObservation; + } + + public String getConceptUuid() { + return encounterTransactionObservation.getConceptUuid(); + } + + public boolean isSameAs(Obs obs) { + return this.getUuid().equals(obs.getUuid()); + } + + public static List toETObsFromBahmniObs(Collection bahmniObservations) { + List etObservations = new ArrayList<>(); + for (BahmniObservation bahmniObservation : bahmniObservations) { + etObservations.add(bahmniObservation.toETObservation()); + } + return etObservations; + } + + public boolean hasTargetObsRelation() { + return targetObsRelation != null && targetObsRelation.getTargetObs() != null; + } + + public Set getProviders() { + return providers; + } + + public void setProviders(Set providers) { + this.providers = providers; + } + + public void addProvider(EncounterTransaction.Provider provider){ + this.providers.add(provider); + } + public Boolean getIsAbnormal() { + return isAbnormal; + } + + public Double getHiNormal(){ + return this.hiNormal; + } + + public Double getLowNormal(){ + return this.lowNormal; + } + + public void setHiNormal(Double hiNormal){ + this.hiNormal=hiNormal; + } + + public void setLowNormal(Double lowNormal){ + this.lowNormal=lowNormal; + } + + public Boolean isAbnormal() { + return isAbnormal; + } + + public void setAbnormal(Boolean abnormal) { + isAbnormal = abnormal; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Long getDuration() { + return duration; + } + + public void setDuration(Long duration) { + this.duration = duration; + } + + public Date getEncounterDateTime() { + return encounterDateTime; + } + + public void setEncounterDateTime(Date encounterDateTime) { + this.encounterDateTime = encounterDateTime; + } + + public Integer getConceptSortWeight() { + return conceptSortWeight; + } + + public void setConceptSortWeight(Integer conceptSortWeight) { + this.conceptSortWeight = conceptSortWeight; + } + + public void setEncounterTransactionObservation(EncounterTransaction.Observation encounterTransactionObservation) { + this.encounterTransactionObservation = encounterTransactionObservation; + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getVisitStartDateTime() { + return visitStartDateTime; + } + + public void setVisitStartDateTime(Date visitStartDateTime) { + this.visitStartDateTime = visitStartDateTime; + } + + @Override + public int compareTo(BahmniObservation o) { + //ensure you dont give a zero, as TreeSets delete them if there is no sort weight + return getConceptSortWeight() > o.getConceptSortWeight() ? 1 : -1; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + BahmniObservation that = (BahmniObservation) o; + + if (conceptSortWeight != that.conceptSortWeight) return false; + if (duration != null ? !duration.equals(that.duration) : that.duration != null) return false; + if (encounterDateTime != null ? !encounterDateTime.equals(that.encounterDateTime) : that.encounterDateTime != null) + return false; + if (encounterTransactionObservation != null ? !encounterTransactionObservation.equals(that.encounterTransactionObservation) : that.encounterTransactionObservation != null) + return false; + if (groupMembers != null ? !groupMembers.equals(that.groupMembers) : that.groupMembers != null) return false; + if (isAbnormal != null ? !isAbnormal.equals(that.isAbnormal) : that.isAbnormal != null) return false; + if (providers != null ? !providers.equals(that.providers) : that.providers != null) return false; + if (targetObsRelation != null ? !targetObsRelation.equals(that.targetObsRelation) : that.targetObsRelation != null) + return false; + if (type != null ? !type.equals(that.type) : that.type != null) return false; + if (visitStartDateTime != null ? !visitStartDateTime.equals(that.visitStartDateTime) : that.visitStartDateTime != null) + return false; + return isUnknown != null && that.isUnknown != null && isUnknown.equals(that.isUnknown) ; + + } + + public String getParentConceptUuid() { + return parentConceptUuid; + } + + public void setParentConceptUuid(String parentConceptUuid) { + this.parentConceptUuid = parentConceptUuid; + } + + @Override + public int hashCode() { + int result = encounterDateTime != null ? encounterDateTime.hashCode() : 0; + result = 31 * result + (visitStartDateTime != null ? visitStartDateTime.hashCode() : 0); + result = 31 * result + (targetObsRelation != null ? targetObsRelation.hashCode() : 0); + result = 31 * result + (encounterTransactionObservation != null ? encounterTransactionObservation.hashCode() : 0); + result = 31 * result + (groupMembers != null ? groupMembers.hashCode() : 0); + result = 31 * result + (providers != null ? providers.hashCode() : 0); + result = 31 * result + (isAbnormal != null ? isAbnormal.hashCode() : 0); + result = 31 * result + (isUnknown != null ? isUnknown.hashCode() : 0); + result = 31 * result + (duration != null ? duration.hashCode() : 0); + result = 31 * result + (type != null ? type.hashCode() : 0); + result = 31 * result + conceptSortWeight; + return result; + } + + public String getEncounterUuid() { + return encounterUuid; + } + + public void setEncounterUuid(String encounterUuid) { + this.encounterUuid = encounterUuid; + } + + public String getObsGroupUuid() { + return obsGroupUuid; + } + + public void setObsGroupUuid(String obsGroupUuid) { + this.obsGroupUuid = obsGroupUuid; + } + + public String getConceptNameToDisplay() { + return getConcept().getShortName() == null ? getConcept().getName() : getConcept().getShortName(); + } + + public String getCreatorName() { + return creatorName; + } + + public void setCreatorName(String creatorName) { + this.creatorName = creatorName; + } + + public void setUnknown(Boolean isUnknown) { + this.isUnknown = isUnknown; + } + + public Boolean isUnknown() { + return isUnknown; + } + + public String getFormNamespace() { + return encounterTransactionObservation.getFormNamespace(); + } + + public BahmniObservation setFormNamespace(String formNamespace) { + encounterTransactionObservation.setFormNamespace(formNamespace); + this.formNamespace = formNamespace; + return this; + } + + public BahmniObservation setFormFieldPath(String formFieldPath) { + encounterTransactionObservation.setFormFieldPath(formFieldPath); + this.formFieldPath = formFieldPath; + return this; + } + + public String getFormFieldPath() { + return encounterTransactionObservation.getFormFieldPath(); + } + + public String getInterpretation() { + return encounterTransactionObservation.getInterpretation(); + } + + public BahmniObservation setInterpretation(String interpretation) { + encounterTransactionObservation.setInterpretation(interpretation); + this.interpretation = interpretation; + return this; + } + + public String getStatus() { + return encounterTransactionObservation.getStatus(); + } + + public BahmniObservation setStatus(String status) { + encounterTransactionObservation.setStatus(status); + this.status = status; + return this; + } + + @JsonProperty + public Serializable getComplexData() { + return complexData; + } + + @JsonIgnore + public void setComplexData(Serializable complexData) { + this.complexData = complexData; + } + + public String getEncounterTypeName() { + return encounterTypeName; + } + + public void setEncounterTypeName(String encounterTypeName) { + this.encounterTypeName = encounterTypeName; + } + + public void setConceptFSN(String conceptFSN) { + this.conceptFSN = conceptFSN; + } + + public String getConceptFSN() { + return this.conceptFSN; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/handler/BahmniDiagnosisHandler.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/handler/BahmniDiagnosisHandler.java new file mode 100644 index 0000000000..32c8000bd2 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/handler/BahmniDiagnosisHandler.java @@ -0,0 +1,139 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.handler; + +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.diagnosis.helper.BahmniDiagnosisMetadata; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.postprocessor.EncounterTransactionHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; + +@Component +public class BahmniDiagnosisHandler implements EncounterTransactionHandler { + private BahmniDiagnosisMetadata bahmniDiagnosisMetadata; + private ObsService obsService; + private ConceptService conceptService; + + + @Autowired + public BahmniDiagnosisHandler(BahmniDiagnosisMetadata bahmniDiagnosisMetadata, ObsService obsService, ConceptService conceptService) { + this.bahmniDiagnosisMetadata = bahmniDiagnosisMetadata; + this.obsService = obsService; + this.conceptService = conceptService; + } + + @Override + public void forRead(Encounter encounter, EncounterTransaction encounterTransaction) { + + } + + @Override + public void forSave(Encounter encounter, EncounterTransaction encounterTransaction) { + List diagnoses = encounterTransaction.getDiagnoses(); + if (!diagnoses.isEmpty()) { + Set obsAtTopLevel = encounter.getObsAtTopLevel(false); + Concept bahmniDiagnosisStatusConcept = bahmniDiagnosisMetadata.diagnosisSchemaContainsStatus() ? + bahmniDiagnosisMetadata.getBahmniDiagnosisStatusConcept() : null; + Concept bahmniInitialDiagnosisConcept = bahmniDiagnosisMetadata.getBahmniInitialDiagnosisConcept(); + Concept bahmniDiagnosisRevisedConcept = bahmniDiagnosisMetadata.getBahmniDiagnosisRevisedConcept(); + + for (EncounterTransaction.Diagnosis diagnosis : diagnoses) { + BahmniDiagnosisRequest bahmniDiagnosisRequest = (BahmniDiagnosisRequest) diagnosis; + addExtraMetadata(obsAtTopLevel, bahmniDiagnosisRequest, bahmniInitialDiagnosisConcept, + bahmniDiagnosisStatusConcept, bahmniDiagnosisRevisedConcept); + updateRevisedFlagOfPreviousDiagnosis(bahmniDiagnosisRequest, bahmniDiagnosisRevisedConcept); + } + } + } + + private void addExtraMetadata(Set obsAtTopLevel, BahmniDiagnosisRequest bahmniDiagnosisRequest, + Concept bahmniInitialDiagnosisConcept, Concept bahmniDiagnosisStatusConcept, + Concept bahmniDiagnosisRevisedConcept) { + Obs matchingDiagnosisObs = bahmniDiagnosisMetadata.findMatchingDiagnosis(obsAtTopLevel, bahmniDiagnosisRequest); + + updateInitialDiagnosis(matchingDiagnosisObs, bahmniDiagnosisRequest, bahmniInitialDiagnosisConcept); + if (bahmniDiagnosisStatusConcept != null) { + updateDiagnosisStatus(matchingDiagnosisObs, bahmniDiagnosisRequest, bahmniDiagnosisStatusConcept); + } + updateRevisedFlag(matchingDiagnosisObs, false, bahmniDiagnosisRevisedConcept); + } + + private void updateRevisedFlagOfPreviousDiagnosis(BahmniDiagnosisRequest bahmniDiagnosisRequest, + Concept bahmniDiagnosisRevisedConcept) { + if(bahmniDiagnosisRequest.getPreviousObs() ==null){ + return; + } + Obs previousObs = obsService.getObsByUuid(bahmniDiagnosisRequest.getPreviousObs()); + updateRevisedFlag(previousObs, true, bahmniDiagnosisRevisedConcept); + obsService.saveObs(previousObs, "Diagnosis is revised"); + } + + void updateDiagnosisStatus(Obs diagnosisObs, BahmniDiagnosis bahmniDiagnosis, Concept bahmniDiagnosisStatusConcept) { + Obs obs = findOrCreateObs(diagnosisObs, bahmniDiagnosisStatusConcept); + if (bahmniDiagnosis.getDiagnosisStatusConcept() != null) { + Concept statusConcept = conceptService.getConcept(bahmniDiagnosis.getDiagnosisStatusConcept().getName()); + obs.setValueCoded(statusConcept); + addToObsGroup(diagnosisObs, obs); + } + else { + removeStatusFromObsGroup(diagnosisObs, bahmniDiagnosisStatusConcept); + } + } + + private void removeStatusFromObsGroup(Obs diagnosisObs, Concept bahmniDiagnosisStatusConcept) { + + Obs statusObs = diagnosisObs.getGroupMembers().stream() + .filter(member -> member.getConcept().equals(bahmniDiagnosisStatusConcept)) + .findFirst().orElse(null); + + if (statusObs != null) + diagnosisObs.removeGroupMember(statusObs); + } + + + private void updateInitialDiagnosis(Obs diagnosisObs, BahmniDiagnosisRequest bahmniDiagnosis, + Concept bahmniInitialDiagnosisConcept) { + Obs obs = findOrCreateObs(diagnosisObs, bahmniInitialDiagnosisConcept); + String initialDiagnosisUuid = bahmniDiagnosis.getPreviousObs() == null && obs.getId() == null + ? diagnosisObs.getUuid() : + bahmniDiagnosis.getFirstDiagnosis().getExistingObs(); + + obs.setValueText(initialDiagnosisUuid); + addToObsGroup(diagnosisObs, obs); + } + + + private void updateRevisedFlag(Obs diagnosisObs, boolean value, Concept bahmniDiagnosisRevisedConcept) { + Obs obs = findOrCreateObs(diagnosisObs, bahmniDiagnosisRevisedConcept); + obs.setValueBoolean(value); + addToObsGroup(diagnosisObs, obs); + } + + private void addToObsGroup(Obs obsGroup, Obs member) { + member.setPerson(obsGroup.getPerson()); + member.setObsDatetime(obsGroup.getObsDatetime()); + member.setLocation(obsGroup.getLocation()); + member.setEncounter(obsGroup.getEncounter()); + obsGroup.addGroupMember(member); + } + + + private Obs findOrCreateObs(Obs diagnosisObs, Concept concept) { + for (Obs o : diagnosisObs.getGroupMembers()) { + if (concept.equals(o.getConcept())) { + return o; + } + } + Obs obs = new Obs(); + obs.setConcept(concept); + return obs; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImpl.java new file mode 100644 index 0000000000..9af62e65d8 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImpl.java @@ -0,0 +1,253 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.impl; + + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.Encounter; +import org.openmrs.EncounterType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.EncounterService; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.api.impl.BaseOpenmrsService; +import org.openmrs.module.bahmniemrapi.BahmniEmrAPIException; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPostSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPreSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.BahmniEncounterTransactionMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.EncounterTypeIdentifier; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.RetrospectiveEncounterTransactionService; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitIdentificationHelper; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitMatcher; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.module.emrapi.encounter.EmrEncounterService; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.openmrs.module.emrapi.encounter.EncounterSearchParametersBuilder; +import org.openmrs.module.emrapi.encounter.EncounterTransactionMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.matcher.BaseEncounterMatcher; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +@Transactional +public class BahmniEncounterTransactionServiceImpl extends BaseOpenmrsService implements BahmniEncounterTransactionService { + + private BahmniVisitAttributeService bahmniVisitAttributeService; + private EncounterService encounterService; + private EmrEncounterService emrEncounterService; + private EncounterTransactionMapper encounterTransactionMapper; + private EncounterTypeIdentifier encounterTypeIdentifier; + private List encounterDataPostSaveCommands; + private BahmniEncounterTransactionMapper bahmniEncounterTransactionMapper; + private VisitService visitService; + private PatientService patientService; + private LocationService locationService; + private ProviderService providerService; + private BaseEncounterMatcher encounterSessionMatcher; + private BahmniVisitLocationService bahmniVisitLocationService; + private Map visitMatchersMap = new HashMap<>(); + + public BahmniEncounterTransactionServiceImpl(EncounterService encounterService, + EmrEncounterService emrEncounterService, + EncounterTransactionMapper encounterTransactionMapper, + EncounterTypeIdentifier encounterTypeIdentifier, + List encounterDataPostSaveCommands, + BahmniEncounterTransactionMapper bahmniEncounterTransactionMapper, + VisitService visitService, + PatientService patientService, + LocationService locationService, + ProviderService providerService, + BaseEncounterMatcher encounterSessionMatcher, + BahmniVisitLocationService bahmniVisitLocationService, + BahmniVisitAttributeService bahmniVisitAttributeService) { + + this.encounterService = encounterService; + this.emrEncounterService = emrEncounterService; + this.encounterTransactionMapper = encounterTransactionMapper; + this.encounterTypeIdentifier = encounterTypeIdentifier; + this.encounterDataPostSaveCommands = encounterDataPostSaveCommands; + this.bahmniEncounterTransactionMapper = bahmniEncounterTransactionMapper; + this.visitService = visitService; + this.patientService = patientService; + this.locationService = locationService; + this.providerService = providerService; + this.encounterSessionMatcher = encounterSessionMatcher; + this.bahmniVisitLocationService = bahmniVisitLocationService; + this.bahmniVisitAttributeService = bahmniVisitAttributeService; + } + + @Override + public void onStartup() { + super.onStartup(); + List visitMatchers = Context.getRegisteredComponents(VisitMatcher.class); + for (VisitMatcher visitMatcher : visitMatchers) { + visitMatchersMap.put(visitMatcher.getClass().getCanonicalName(), visitMatcher); + } + } + + @Override + public BahmniEncounterTransaction save(BahmniEncounterTransaction bahmniEncounterTransaction, Patient patient, + Date visitStartDate, Date visitEndDate) { + + if (bahmniEncounterTransaction.getEncounterDateTime() == null) { + bahmniEncounterTransaction.setEncounterDateTime(new Date()); + } + + handleDrugOrders(bahmniEncounterTransaction, patient); + + setEncounterTypeUuid(bahmniEncounterTransaction); + setVisitType(bahmniEncounterTransaction); + setEncounterType(bahmniEncounterTransaction); + + List encounterDataPreSaveCommands = Context.getRegisteredComponents(EncounterDataPreSaveCommand.class); + for (EncounterDataPreSaveCommand saveCommand : encounterDataPreSaveCommands) { + saveCommand.update(bahmniEncounterTransaction); + } + VisitMatcher visitMatcher = getVisitMatcher(); + if (BahmniEncounterTransaction.isRetrospectiveEntry(bahmniEncounterTransaction.getEncounterDateTime())) { + bahmniEncounterTransaction = new RetrospectiveEncounterTransactionService(visitMatcher) + .updatePastEncounters(bahmniEncounterTransaction, patient, visitStartDate, visitEndDate); + } + + setVisitTypeUuid(visitMatcher, bahmniEncounterTransaction); + setVisitLocationToEncounterTransaction(bahmniEncounterTransaction); + + EncounterTransaction encounterTransaction = emrEncounterService.save(bahmniEncounterTransaction.toEncounterTransaction()); + //Get the saved encounter transaction from emr-api + String encounterUuid = encounterTransaction.getEncounterUuid(); + Encounter currentEncounter = encounterService.getEncounterByUuid(encounterUuid); + + boolean includeAll = false; + EncounterTransaction updatedEncounterTransaction = encounterTransactionMapper.map(currentEncounter, includeAll); + for (EncounterDataPostSaveCommand saveCommand : encounterDataPostSaveCommands) { + updatedEncounterTransaction = saveCommand.save(bahmniEncounterTransaction, currentEncounter, updatedEncounterTransaction); + } + bahmniVisitAttributeService.save(currentEncounter); + return bahmniEncounterTransactionMapper.map(updatedEncounterTransaction, includeAll); + } + + private void setEncounterTypeUuid(BahmniEncounterTransaction bahmniEncounterTransaction) { + String encounterUuid = bahmniEncounterTransaction.getEncounterUuid(); + if (!StringUtils.isBlank(encounterUuid)) { + Encounter encounterByUuid = encounterService.getEncounterByUuid(encounterUuid); + if (encounterByUuid != null) { + bahmniEncounterTransaction.setEncounterTypeUuid(encounterByUuid.getEncounterType().getUuid()); + } + } + } + + private void setVisitLocationToEncounterTransaction(BahmniEncounterTransaction bahmniEncounterTransaction) { + EncounterTransaction encounterTransaction = bahmniEncounterTransaction.toEncounterTransaction(); + if (encounterTransaction.getLocationUuid() != null) { + String visitLocationUuid = bahmniVisitLocationService.getVisitLocationUuid(encounterTransaction.getLocationUuid()); + encounterTransaction.setVisitLocationUuid(visitLocationUuid); + } + } + + private VisitMatcher getVisitMatcher() { + String globalProperty = Context.getAdministrationService().getGlobalProperty("bahmni.visitMatcher"); + if (visitMatchersMap.get(globalProperty) != null) { + return visitMatchersMap.get(globalProperty); + } + return new VisitIdentificationHelper(visitService, bahmniVisitLocationService); + } + + private void handleDrugOrders(BahmniEncounterTransaction bahmniEncounterTransaction, Patient patient) { + bahmniEncounterTransaction.updateDrugOrderIfScheduledDateNotSet(new Date()); + + if (bahmniEncounterTransaction.hasPastDrugOrders()) { + BahmniEncounterTransaction pastEncounterTransaction = bahmniEncounterTransaction.cloneForPastDrugOrders(); + save(pastEncounterTransaction, patient, null, null); + bahmniEncounterTransaction.clearDrugOrders(); + } + } + + private void setVisitType(BahmniEncounterTransaction bahmniEncounterTransaction) { + if (!StringUtils.isBlank(bahmniEncounterTransaction.getVisitTypeUuid())) { + VisitType visitType = visitService.getVisitTypeByUuid(bahmniEncounterTransaction.getVisitTypeUuid()); + if (visitType == null) { + throw new BahmniEmrAPIException("Cannot find visit type with UUID " + visitType); + } + bahmniEncounterTransaction.setVisitType(visitType.getName()); + } + } + + private void setVisitTypeUuid(VisitMatcher visitMatcher, BahmniEncounterTransaction bahmniEncounterTransaction) { + if(StringUtils.isBlank(bahmniEncounterTransaction.getVisitType())){ + return; + } + VisitType visitType = visitMatcher.getVisitTypeByName(bahmniEncounterTransaction.getVisitType()); + if (visitType != null) { + bahmniEncounterTransaction.setVisitTypeUuid(visitType.getUuid()); + } + } + + @Override + public BahmniEncounterTransaction save(BahmniEncounterTransaction bahmniEncounterTransaction) { + Patient patientByUuid = patientService.getPatientByUuid(bahmniEncounterTransaction.getPatientUuid()); + return save(bahmniEncounterTransaction, patientByUuid, null, null); + } + + @Override + public EncounterTransaction find(BahmniEncounterSearchParameters bahmniEncounterSearchParameters) { + EncounterSearchParametersBuilder searchParametersBuilder = new EncounterSearchParametersBuilder(bahmniEncounterSearchParameters, + this.patientService, this.encounterService, this.locationService, this.providerService, this.visitService); + + Visit visit = null; + if (!BahmniEncounterTransaction.isRetrospectiveEntry(searchParametersBuilder.getEndDate())) { + List visits = this.visitService.getActiveVisitsByPatient(searchParametersBuilder.getPatient()); + visit = bahmniVisitLocationService.getMatchingVisitInLocation(visits, bahmniEncounterSearchParameters.getLocationUuid()); + if (visit == null) return null; + } + EncounterParameters encounterParameters = mapEncounterParameters(searchParametersBuilder, bahmniEncounterSearchParameters); + Encounter encounter = encounterSessionMatcher.findEncounter(visit, encounterParameters); + return encounter != null ? encounterTransactionMapper.map(encounter, bahmniEncounterSearchParameters.getIncludeAll()) : null; + } + + private EncounterParameters mapEncounterParameters(EncounterSearchParametersBuilder encounterSearchParametersBuilder, + BahmniEncounterSearchParameters searchParameters) { + EncounterParameters encounterParameters = EncounterParameters.instance(); + encounterParameters.setPatient(encounterSearchParametersBuilder.getPatient()); + if (encounterSearchParametersBuilder.getEncounterTypes().size() > 0) { + encounterParameters.setEncounterType(encounterSearchParametersBuilder.getEncounterTypes().iterator().next()); + } + encounterParameters.setProviders(new HashSet<>(encounterSearchParametersBuilder.getProviders())); + HashMap context = new HashMap<>(); + context.put("patientProgramUuid", searchParameters.getPatientProgramUuid()); + encounterParameters.setContext(context); + encounterParameters.setEncounterDateTime(encounterSearchParametersBuilder.getEndDate()); + encounterParameters.setLocation(encounterSearchParametersBuilder.getLocation()); + return encounterParameters; + } + + @Override + public void delete(BahmniEncounterTransaction bahmniEncounterTransaction) { + Encounter encounter = encounterService.getEncounterByUuid(bahmniEncounterTransaction.getEncounterUuid()); + encounterService.voidEncounter(encounter, bahmniEncounterTransaction.getReason()); + bahmniVisitAttributeService.save(encounter); + } + + private void setEncounterType(BahmniEncounterTransaction bahmniEncounterTransaction) { + if(StringUtils.isBlank(bahmniEncounterTransaction.getEncounterTypeUuid())) { + EncounterType encounterType = encounterTypeIdentifier.getEncounterTypeFor(bahmniEncounterTransaction.getEncounterType(), + bahmniEncounterTransaction.getLocationUuid()); + if (encounterType == null) { + throw new RuntimeException("Encounter type not found."); + } + bahmniEncounterTransaction.setEncounterTypeUuid(encounterType.getUuid()); + } + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/BahmniComplexDataMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/BahmniComplexDataMapper.java new file mode 100644 index 0000000000..674b6b27b0 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/BahmniComplexDataMapper.java @@ -0,0 +1,11 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.openmrs.Concept; +import org.openmrs.obs.ComplexData; + +import java.io.Serializable; + +public interface BahmniComplexDataMapper { + Serializable map(ComplexData complexData); + boolean canHandle(final Concept concept, ComplexData complexData); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/BahmniEncounterTransactionMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/BahmniEncounterTransactionMapper.java new file mode 100644 index 0000000000..7195871d8f --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/BahmniEncounterTransactionMapper.java @@ -0,0 +1,74 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.openmrs.EncounterType; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.api.EncounterService; +import org.openmrs.api.PatientService; +import org.openmrs.module.bahmniemrapi.accessionnote.mapper.AccessionNotesMapper; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.diagnosis.helper.BahmniDiagnosisMetadata; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class BahmniEncounterTransactionMapper { + private AccessionNotesMapper accessionNotesMapper; + private BahmniDiagnosisMetadata bahmniDiagnosisMetadata; + private ObsRelationshipMapper obsRelationshipMapper; + private PatientService patientService; + private EncounterService encounterService; + private ETObsToBahmniObsMapper fromETObsToBahmniObs; + + @Autowired + public BahmniEncounterTransactionMapper(AccessionNotesMapper accessionNotesMapper, + BahmniDiagnosisMetadata bahmniDiagnosisMetadata, + ObsRelationshipMapper obsRelationshipMapper, + PatientService patientService, + EncounterService encounterService, + ETObsToBahmniObsMapper fromETObsToBahmniObs) { + this.accessionNotesMapper = accessionNotesMapper; + this.bahmniDiagnosisMetadata = bahmniDiagnosisMetadata; + this.obsRelationshipMapper = obsRelationshipMapper; + this.patientService = patientService; + this.encounterService = encounterService; + this.fromETObsToBahmniObs = fromETObsToBahmniObs; + } + + public BahmniEncounterTransaction map(EncounterTransaction encounterTransaction, boolean includeAll) { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(encounterTransaction); + List bahmniDiagnoses = bahmniDiagnosisMetadata.map(encounterTransaction.getDiagnoses(), includeAll); + bahmniEncounterTransaction.setBahmniDiagnoses(bahmniDiagnoses); + bahmniEncounterTransaction.setAccessionNotes(accessionNotesMapper.map(encounterTransaction)); + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterTransaction.getEncounterUuid(), encounterTransaction.getEncounterDateTime(), null,null); + additionalBahmniObservationFields.setProviders(encounterTransaction.getProviders()); + List bahmniObservations = fromETObsToBahmniObs.create(encounterTransaction.getObservations(), additionalBahmniObservationFields); + bahmniEncounterTransaction.setObservations(obsRelationshipMapper.map(bahmniObservations, encounterTransaction.getEncounterUuid())); + addPatientIdentifier(bahmniEncounterTransaction, encounterTransaction); + addEncounterType(encounterTransaction, bahmniEncounterTransaction); + return bahmniEncounterTransaction; + } + + private void addEncounterType(EncounterTransaction encounterTransaction, BahmniEncounterTransaction bahmniEncounterTransaction) { + EncounterType encounterType = encounterService.getEncounterTypeByUuid(encounterTransaction.getEncounterTypeUuid()); + if (encounterType != null) { + bahmniEncounterTransaction.setEncounterType(encounterType.getName()); + } + } + + private void addPatientIdentifier(BahmniEncounterTransaction bahmniEncounterTransaction, EncounterTransaction encounterTransaction) { + Patient patient = patientService.getPatientByUuid(encounterTransaction.getPatientUuid()); + if (patient != null) { + PatientIdentifier patientIdentifier = patient.getPatientIdentifier(); + if(patientIdentifier != null){ + bahmniEncounterTransaction.setPatientId(patientIdentifier.getIdentifier()); + } + } + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ConceptSortWeightUtil.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ConceptSortWeightUtil.java new file mode 100644 index 0000000000..f0751886fa --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ConceptSortWeightUtil.java @@ -0,0 +1,25 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.openmrs.Concept; + +import java.util.Collection; + +public class ConceptSortWeightUtil { + public static int getSortWeightFor(String conceptName, Collection concepts) { + return getSortWeightFor(conceptName, concepts, 0); + } + + private static int getSortWeightFor(String conceptName, Collection concepts, int startSortWeight) { + for (Concept aConcept : concepts) { + startSortWeight++; + if (aConcept.getName().getName().equalsIgnoreCase(conceptName)) { + return startSortWeight; + } else if (aConcept.getSetMembers().size() > 0 && getSortWeightFor(conceptName, aConcept.getSetMembers(), startSortWeight) > 0) { + return getSortWeightFor(conceptName, aConcept.getSetMembers(), startSortWeight); + } else if (aConcept.getSetMembers().size() > 0) { + startSortWeight += aConcept.getSetMembers().size(); + } + } + return 0; + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapper.java new file mode 100644 index 0000000000..bfecd64fb6 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapper.java @@ -0,0 +1,202 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.openmrs.Concept; +import org.openmrs.ConceptNumeric; +import org.openmrs.Obs; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.obs.ComplexData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Component +public class ETObsToBahmniObsMapper { + + public static final String CONCEPT_DETAILS_CONCEPT_CLASS = "Concept Details"; + public static final String ABNORMAL_CONCEPT_CLASS = "Abnormal"; + public static final String DURATION_CONCEPT_CLASS = "Duration"; + public static final String UNKNOWN_CONCEPT_CLASS = "Unknown" ; + public static final String COMPLEX_DATATYPE = "Complex"; + private ConceptService conceptService; + private ObsService obsService; + + List complexDataMappers = new ArrayList<>(); + + @Autowired + public ETObsToBahmniObsMapper(ConceptService conceptService, List complexDataMappers) { + this.conceptService = conceptService; + this.complexDataMappers = complexDataMappers; + } + + public List create(List allObservations, AdditionalBahmniObservationFields additionalBahmniObservationFields) { + List bahmniObservations = new ArrayList<>(); + for (EncounterTransaction.Observation observation : allObservations) { + bahmniObservations.add(create(observation, additionalBahmniObservationFields)); + } + return bahmniObservations; + } + + public BahmniObservation create(EncounterTransaction.Observation observation, AdditionalBahmniObservationFields additionalBahmniObservationFields) { + return map(observation, additionalBahmniObservationFields, + Collections.singletonList(conceptService.getConceptByUuid(observation.getConceptUuid())), + false); + } + + protected BahmniObservation map(EncounterTransaction.Observation observation, AdditionalBahmniObservationFields additionalBahmniObservationFields, List rootConcepts, boolean flatten) { + + BahmniObservation bahmniObservation= createBahmniObservation(observation,additionalBahmniObservationFields,rootConcepts); + + if (validateFormNameSpace(observation) && flatten) { + handleFlattenedConceptDetails(observation,bahmniObservation); + } else if (observation.getGroupMembers().size() > 0) { + for (EncounterTransaction.Observation groupMember : observation.getGroupMembers()) { + AdditionalBahmniObservationFields additionalFields = (AdditionalBahmniObservationFields) additionalBahmniObservationFields.clone(); + additionalFields.setObsGroupUuid(observation.getUuid()); + bahmniObservation.addGroupMember(map(groupMember, additionalFields, rootConcepts, flatten)); + } + } else { + bahmniObservation.setValue(observation.getValue()); + if (isComplexObs(bahmniObservation)) { + bahmniObservation.setComplexData(getComplexObsValue(bahmniObservation)); + } + + bahmniObservation.setType(observation.getConcept().getDataType()); + bahmniObservation.setHiNormal(observation.getConcept().getHiNormal()); + bahmniObservation.setLowNormal(observation.getConcept().getLowNormal()); + } + + for (EncounterTransaction.Provider provider : additionalBahmniObservationFields.getProviders()) { + bahmniObservation.addProvider(provider); + } + if (observation.getCreator() != null) { + bahmniObservation.setCreatorName(observation.getCreator().getPersonName()); + } + return bahmniObservation; + } + + private boolean validateFormNameSpace(EncounterTransaction.Observation observation) { + return observation.getFormNamespace() == null && CONCEPT_DETAILS_CONCEPT_CLASS.equals(observation.getConcept().getConceptClass()); + } + + private Serializable getComplexObsValue(BahmniObservation bahmniObservation) { + if (complexDataMappers.isEmpty()) { + return null; + } + Obs obs = getObsService().getObs(getObsService().getObsByUuid(bahmniObservation.getUuid()).getId()); + ComplexData complexData = obs.getComplexData(); + + BahmniComplexDataMapper dataMapper = null; + for (BahmniComplexDataMapper complexDataMapper : complexDataMappers) { + if (complexDataMapper.canHandle(obs.getConcept(), complexData)) { + dataMapper = complexDataMapper; + break; + } + } + + return dataMapper!=null ? dataMapper.map(complexData) : complexData; + } + + private ObsService getObsService() { + if (this.obsService == null) { + this.obsService = Context.getObsService(); + } + return obsService; + } + + private boolean isComplexObs(BahmniObservation bahmniObservation) { + String conceptDataType = bahmniObservation.getConcept().getDataType(); + if (conceptDataType != null && !conceptDataType.isEmpty()) { + return conceptDataType.equalsIgnoreCase(COMPLEX_DATATYPE); + } + return false; + } + + private void setValueAndType(BahmniObservation bahmniObservation, EncounterTransaction.Observation member) { + if(!bahmniObservation.isUnknown()) { + bahmniObservation.setValue(member.getValue()); + bahmniObservation.setType(member.getConcept().getDataType()); + } + } + + private void handleUnknownConceptClass(BahmniObservation bahmniObservation, EncounterTransaction.Observation etObs) { + Object unknownObsValue = etObs.getValue(); + if(!(unknownObsValue instanceof Boolean) && unknownObsValue == null){ + return; + } + + bahmniObservation.setUnknown((Boolean)unknownObsValue); + if((Boolean)unknownObsValue){ + bahmniObservation.setValue(getConceptName(etObs)); + } + } + + private String getConceptName(EncounterTransaction.Observation etObs) { + return etObs.getConcept().getShortName() != null ? etObs.getConcept().getShortName() : etObs.getConcept().getName(); + } + private void handleAbnormalConceptClass(BahmniObservation bahmniObservation, EncounterTransaction.Observation etObs) { + if (etObs.getValue() instanceof Boolean) { + bahmniObservation.setAbnormal((Boolean) etObs.getValue()); + } else { + if (etObs.getValue() != null) { + bahmniObservation.setAbnormal(Boolean.parseBoolean(((EncounterTransaction.Concept) etObs.getValue()).getName())); + } + } + } + + private void handleFlattenedConceptDetails(EncounterTransaction.Observation observation, BahmniObservation bahmniObservation) { + setHiNormalAndLowNormalForNumericUnknownObs(observation, bahmniObservation); + for (EncounterTransaction.Observation member : observation.getGroupMembers()) { + if (member.getVoided()) { + continue; + } + if (member.getConcept().getConceptClass().equals(ABNORMAL_CONCEPT_CLASS)) { + handleAbnormalConceptClass(bahmniObservation, member); + } else if (member.getConcept().getConceptClass().equals(UNKNOWN_CONCEPT_CLASS)) { + handleUnknownConceptClass(bahmniObservation, member); + } else if (member.getConcept().getConceptClass().equals(DURATION_CONCEPT_CLASS)) { + bahmniObservation.setDuration(new Double(member.getValue().toString()).longValue()); + } else { + setValueAndType(bahmniObservation, member); + bahmniObservation.getConcept().setUnits(member.getConcept().getUnits()); + bahmniObservation.setHiNormal(member.getConcept().getHiNormal()); + bahmniObservation.setLowNormal(member.getConcept().getLowNormal()); + } + } + } + + private void setHiNormalAndLowNormalForNumericUnknownObs(EncounterTransaction.Observation observation, BahmniObservation bahmniObservation) { + if (observation.getGroupMembers().size() == 1 && observation.getGroupMembers().get(0).getConcept().getConceptClass().equals(UNKNOWN_CONCEPT_CLASS)){ + Concept conceptDetailsConcept = conceptService.getConceptByUuid(observation.getConceptUuid()); + + Concept primaryNumericConcept = conceptDetailsConcept.getSetMembers().get(0); + if (primaryNumericConcept.isNumeric()){ + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(primaryNumericConcept.getId()); + bahmniObservation.setHiNormal(conceptNumeric.getHiNormal()); + bahmniObservation.setLowNormal(conceptNumeric.getLowNormal()); + } + } + } + + private BahmniObservation createBahmniObservation(EncounterTransaction.Observation observation, AdditionalBahmniObservationFields additionalBahmniObservationFields, List rootConcepts) { + BahmniObservation bahmniObservation = new BahmniObservation(); + bahmniObservation.setEncounterTransactionObservation(observation); + bahmniObservation.setEncounterDateTime(additionalBahmniObservationFields.getEncounterDateTime()); + bahmniObservation.setVisitStartDateTime(additionalBahmniObservationFields.getVisitDateTime()); + bahmniObservation.setConceptSortWeight(ConceptSortWeightUtil.getSortWeightFor(bahmniObservation.getConcept().getName(), rootConcepts)); + bahmniObservation.setEncounterUuid(additionalBahmniObservationFields.getEncounterUuid()); + bahmniObservation.setObsGroupUuid(additionalBahmniObservationFields.getObsGroupUuid()); + bahmniObservation.setUnknown(false); + bahmniObservation.setEncounterTypeName(additionalBahmniObservationFields.getEncounterTypeName()); + return bahmniObservation; + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTransactionDiagnosisMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTransactionDiagnosisMapper.java new file mode 100644 index 0000000000..20e04ad75f --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTransactionDiagnosisMapper.java @@ -0,0 +1,11 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +public class EncounterTransactionDiagnosisMapper { +// public void populateDiagnosis(BahmniEncounterTransaction bahmniEncounterTransaction) { +// List diagnoses = new ArrayList<>(); +// for (BahmniDiagnosis bahmniDiagnosis : bahmniEncounterTransaction.getBahmniDiagnoses()) { +// diagnoses.add(bahmniDiagnosis); +// } +// bahmniEncounterTransaction.setDiagnoses(diagnoses); +// } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTypeIdentifier.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTypeIdentifier.java new file mode 100644 index 0000000000..4b57b074fc --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTypeIdentifier.java @@ -0,0 +1,62 @@ +/** + * 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.bahmniemrapi.encountertransaction.mapper; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.EncounterType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.EncounterService; +import org.openmrs.module.bahmnimapping.services.BahmniLocationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +public class EncounterTypeIdentifier { + + private BahmniLocationService bahmniLocationService; + private EncounterService encounterService; + private AdministrationService administrationService; + + @Autowired + public EncounterTypeIdentifier(BahmniLocationService bahmniLocationService, EncounterService encounterService, @Qualifier("adminService") AdministrationService administrationService) { + this.bahmniLocationService = bahmniLocationService; + this.encounterService = encounterService; + this.administrationService = administrationService; + } + + public EncounterType getEncounterTypeFor(String encounterTypeString, String locationUuid) { + + if (StringUtils.isNotEmpty(encounterTypeString)) { + return encounterService.getEncounterType(encounterTypeString); + } else { + return getEncounterTypeFor(locationUuid); + } + } + + public EncounterType getEncounterTypeFor(String locationUuid) { + EncounterType encounterType = bahmniLocationService.getEncounterType(locationUuid); + if (encounterType == null){ + return getDefaultEncounterType(); + } + return encounterType; + } + + public EncounterType getDefaultEncounterType() { + String defaultEncounterType = administrationService.getGlobalProperty("bahmni.encounterType.default"); + return encounterService.getEncounterType(defaultEncounterType); + } + + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/LocationComplexDataMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/LocationComplexDataMapper.java new file mode 100644 index 0000000000..09ec3f3fed --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/LocationComplexDataMapper.java @@ -0,0 +1,38 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + + +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.obs.ComplexData; +import org.springframework.stereotype.Component; + +import java.io.Serializable; +import java.util.HashMap; + +@Component +public class LocationComplexDataMapper implements BahmniComplexDataMapper { + @Override + public Serializable map(ComplexData complexData) { + HashMap locationData = new HashMap<>(); + + Location location = (Location) complexData.getData(); + locationData.put("dataType", "Location"); + locationData.put("display", complexData.getTitle()); + + HashMap data = new HashMap<>(); + data.put("id", location.getId()); + data.put("uuid", location.getUuid()); + data.put("name", location.getName()); + locationData.put("data", data); + + return locationData; + } + + @Override + public boolean canHandle(final Concept concept, ComplexData complexData) { + if (complexData.getData() != null) { + return complexData.getData() instanceof Location; + } + return false; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java new file mode 100644 index 0000000000..bf4c88fcff --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java @@ -0,0 +1,94 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.api.ConceptNameType; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniProviderMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; +import org.openmrs.module.emrapi.encounter.ObservationMapper; +import org.openmrs.module.emrapi.encounter.matcher.ObservationTypeMatcher; +import org.openmrs.module.emrapi.utils.HibernateLazyLoader; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +@Component(value = "omrsObsToBahmniObsMapper") +public class OMRSObsToBahmniObsMapper { + private ETObsToBahmniObsMapper etObsToBahmniObsMapper; + private ObservationTypeMatcher observationTypeMatcher; + private BahmniProviderMapper bahmniProviderMapper = new BahmniProviderMapper(); + private ObservationMapper observationMapper; + + @Autowired + public OMRSObsToBahmniObsMapper(ETObsToBahmniObsMapper etObsToBahmniObsMapper, ObservationTypeMatcher observationTypeMatcher, ObservationMapper observationMapper) { + this.etObsToBahmniObsMapper = etObsToBahmniObsMapper; + this.observationTypeMatcher = observationTypeMatcher; + this.observationMapper = observationMapper; + } + + public Collection map(List obsList, Collection rootConcepts) { + Collection bahmniObservations = new ArrayList<>(); + Locale implementationLocale = LocaleUtility.getDefaultLocale(); + for (Obs obs : obsList) { + if(observationTypeMatcher.getObservationType(obs).equals(ObservationTypeMatcher.ObservationType.OBSERVATION)){ + BahmniObservation bahmniObservation = map(obs, implementationLocale); + if(CollectionUtils.isNotEmpty(rootConcepts )){ + bahmniObservation.setConceptSortWeight(ConceptSortWeightUtil.getSortWeightFor(bahmniObservation.getConcept().getName(), rootConcepts)); + } + bahmniObservations.add(bahmniObservation); + } + } + return bahmniObservations; + } + + public BahmniObservation map(Obs obs, Locale implementationLocale) { + if(obs == null) + return null; + String obsGroupUuid = obs.getObsGroup() == null? null : obs.getObsGroup().getUuid(); + AdditionalBahmniObservationFields additionalBahmniObservationFields = + new AdditionalBahmniObservationFields( + obs.getEncounter().getUuid(), + obs.getEncounter().getEncounterDatetime(), + obs.getEncounter().getVisit().getStartDatetime(), + obsGroupUuid); + if(obs.getEncounter().getEncounterType()!=null) { + additionalBahmniObservationFields.setEncounterTypeName(obs.getEncounter().getEncounterType().getName()); + } + for (EncounterProvider encounterProvider : obs.getEncounter().getEncounterProviders()) { + additionalBahmniObservationFields.addProvider(bahmniProviderMapper.map(encounterProvider.getProvider())); + } + BahmniObservation bahmniObservation = etObsToBahmniObsMapper.map(observationMapper.map(obs), additionalBahmniObservationFields, Collections.singletonList(obs.getConcept()), true); + bahmniObservation.setConceptFSN(getConceptFSNInDefaultLocale(obs, implementationLocale)); + return bahmniObservation; + } + + private String getConceptFSNInDefaultLocale(Obs obs, Locale implementationLocale) { + if (obs.getConcept() == null) { + return null; + } + Concept concept = new HibernateLazyLoader().load(obs.getConcept()); + if (implementationLocale == null) { + return concept.getName().getName(); + } + ConceptName fsn = concept.getName(implementationLocale, ConceptNameType.FULLY_SPECIFIED, null); + if (fsn == null) { + fsn = concept.getNames().stream().filter(name -> !name.getVoided() && name.getLocale().equals(implementationLocale) + && name.getConceptNameType().equals(ConceptNameType.FULLY_SPECIFIED)).findFirst().orElse(null); + } + if (fsn != null) { + return fsn.getName(); + } else { + return concept.getName().getName(); + } + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java new file mode 100644 index 0000000000..b7d37510a4 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapper.java @@ -0,0 +1,62 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.EncounterProviderMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class ObsRelationshipMapper { + private ObsRelationService obsRelationService; + private EncounterProviderMapper encounterProviderMapper; + private OMRSObsToBahmniObsMapper OMRSObsToBahmniObsMapper; + + @Autowired + public ObsRelationshipMapper(ObsRelationService obsRelationService, + EncounterProviderMapper encounterProviderMapper, + OMRSObsToBahmniObsMapper OMRSObsToBahmniObsMapper) { + this.obsRelationService = obsRelationService; + this.encounterProviderMapper = encounterProviderMapper; + this.OMRSObsToBahmniObsMapper = OMRSObsToBahmniObsMapper; + } + + public List map(List bahmniObservations, String encounterUuid) { + List obsRelationshipsInEncounter = obsRelationService.getRelationsWhereSourceObsInEncounter(encounterUuid); + for (BahmniObservation bahmniObservation : bahmniObservations) { + for (ObsRelationship obsRelationship : obsRelationshipsInEncounter) { + if (bahmniObservation.isSameAs(obsRelationship.getSourceObs())) { + org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship targetObsRelation = + new org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship(); + targetObsRelation.setRelationshipType(obsRelationship.getObsRelationshipType().getName()); + targetObsRelation.setUuid(obsRelationship.getUuid()); + targetObsRelation.setTargetObs(OMRSObsToBahmniObsMapper.map(obsRelationship.getTargetObs(), null)); + bahmniObservation.setTargetObsRelation(targetObsRelation); +// bahmniObservation.setProviders(providers); + } + } + } + return bahmniObservations; + } + + public List map(List obsRelationships) { + List bahmniObservations = new ArrayList<>(); + for (ObsRelationship obsRelationship : obsRelationships) { + + BahmniObservation sourceObservation = OMRSObsToBahmniObsMapper.map(obsRelationship.getSourceObs(), null); + BahmniObservation targetObservation = OMRSObsToBahmniObsMapper.map(obsRelationship.getTargetObs(), null); + sourceObservation.setProviders(encounterProviderMapper.convert(obsRelationship.getSourceObs().getEncounter().getEncounterProviders())); + + org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship targetObsRelation = + new org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship(targetObservation, obsRelationship.getUuid(), obsRelationship.getObsRelationshipType().getName()); + sourceObservation.setTargetObsRelation(targetObsRelation); + bahmniObservations.add(sourceObservation); + + } + return bahmniObservations; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ProviderComplexDataMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ProviderComplexDataMapper.java new file mode 100644 index 0000000000..891cfa5ccf --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ProviderComplexDataMapper.java @@ -0,0 +1,38 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + + +import org.openmrs.Concept; +import org.openmrs.Provider; +import org.openmrs.obs.ComplexData; +import org.springframework.stereotype.Component; + +import java.io.Serializable; +import java.util.HashMap; + +@Component +public class ProviderComplexDataMapper implements BahmniComplexDataMapper { + @Override + public Serializable map(ComplexData complexData) { + HashMap locationData = new HashMap<>(); + + Provider provider = (Provider) complexData.getData(); + locationData.put("dataType", "Provider"); + locationData.put("display", complexData.getTitle()); + + HashMap data = new HashMap<>(); + data.put("id", provider.getId()); + data.put("uuid", provider.getUuid()); + data.put("name", provider.getName()); + locationData.put("data", data); + + return locationData; + } + + @Override + public boolean canHandle(final Concept concept, ComplexData complexData) { + if (complexData.getData() != null) { + return complexData.getData() instanceof Provider; + } + return false; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/parameters/AdditionalBahmniObservationFields.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/parameters/AdditionalBahmniObservationFields.java new file mode 100644 index 0000000000..fd7a39027a --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/parameters/AdditionalBahmniObservationFields.java @@ -0,0 +1,85 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters; + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +public class AdditionalBahmniObservationFields implements Cloneable { + private String encounterUuid; + private Date encounterDateTime; + private Date visitDateTime; + private Set providers = new HashSet<>(); + private String obsGroupUuid; + private String encounterTypeName; + + public AdditionalBahmniObservationFields(String encounterUuid, Date encounterDateTime, Date visitDateTime,String obsGroupUuid) { + this.encounterUuid = encounterUuid; + this.encounterDateTime = encounterDateTime; + this.visitDateTime = visitDateTime; + this.obsGroupUuid = obsGroupUuid; + } + + public String getEncounterTypeName() { + return encounterTypeName; + } + + public void setEncounterTypeName(String encounterTypeName) { + this.encounterTypeName = encounterTypeName; + } + + public String getEncounterUuid() { + return encounterUuid; + } + + public void setEncounterUuid(String encounterUuid) { + this.encounterUuid = encounterUuid; + } + + public Date getEncounterDateTime() { + return encounterDateTime; + } + + public void setEncounterDateTime(Date encounterDateTime) { + this.encounterDateTime = encounterDateTime; + } + + public Date getVisitDateTime() { + return visitDateTime; + } + + public void setVisitDateTime(Date visitDateTime) { + this.visitDateTime = visitDateTime; + } + + public Set getProviders() { + return providers; + } + + public void setProviders(Set providers) { + this.providers = providers; + } + + + public void addProvider(EncounterTransaction.Provider provider) { + this.providers.add(provider); + } + + public String getObsGroupUuid() { + return obsGroupUuid; + } + + public void setObsGroupUuid(String obsGroupUuid) { + this.obsGroupUuid = obsGroupUuid; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException("unable to clone "+this.getClass().getName(),e); + } + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/matcher/EncounterProviderMatcher.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/matcher/EncounterProviderMatcher.java new file mode 100644 index 0000000000..f2c968e44f --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/matcher/EncounterProviderMatcher.java @@ -0,0 +1,53 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.matcher; + +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.EncounterType; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.openmrs.module.emrapi.encounter.matcher.BaseEncounterMatcher; + +import java.util.Map; +import java.util.Set; + + +public class EncounterProviderMatcher implements BaseEncounterMatcher { + + @Override + public Encounter findEncounter(Visit visit, EncounterParameters encounterParameters) { + EncounterType encounterType = encounterParameters.getEncounterType(); + Provider provider = null; + if (encounterParameters.getProviders() != null && encounterParameters.getProviders().iterator().hasNext()) + provider = encounterParameters.getProviders().iterator().next(); + + if (encounterType == null) { + throw new IllegalArgumentException("Encounter Type not found"); + } + + if (visit.getEncounters() != null) { + for (Encounter encounter : visit.getEncounters()) { + if (encounterType.equals(encounter.getEncounterType()) && isSameProvider(provider, encounter)) { + return encounter; + } + } + } + return null; + } + + private boolean isSameProvider(Provider provider, Encounter encounter) { + final Map> providersByRoles = encounter.getProvidersByRoles(); + if (provider == null || providersByRoles.isEmpty()) { + return false; + } + + for (Set providers : providersByRoles.values()) { + for (Provider encounterProvider : providers) { + if(encounterProvider.getPerson().getId().equals(provider.getPerson().getId())){ + return true; + } + } + } + return false; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/BahmniEncounterTransactionService.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/BahmniEncounterTransactionService.java new file mode 100644 index 0000000000..441a07dc14 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/BahmniEncounterTransactionService.java @@ -0,0 +1,15 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.service; + +import org.openmrs.Patient; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; + +public interface BahmniEncounterTransactionService { + BahmniEncounterTransaction save(BahmniEncounterTransaction encounterTransaction); + BahmniEncounterTransaction save(BahmniEncounterTransaction encounterTransaction, Patient patient, Date visitStartDate, Date visitEndDate); + EncounterTransaction find(BahmniEncounterSearchParameters encounterSearchParameters); + void delete(BahmniEncounterTransaction bahmniEncounterTransaction); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/RetrospectiveEncounterTransactionService.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/RetrospectiveEncounterTransactionService.java new file mode 100644 index 0000000000..5e83e47a48 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/RetrospectiveEncounterTransactionService.java @@ -0,0 +1,35 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.service; + +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +public class RetrospectiveEncounterTransactionService { + protected final VisitMatcher visitMatcher; + + @Autowired + public RetrospectiveEncounterTransactionService(VisitMatcher visitMatcher) { + this.visitMatcher = visitMatcher; + } + + public BahmniEncounterTransaction updatePastEncounters(BahmniEncounterTransaction bahmniEncounterTransaction, Patient patient, Date visitStartDate, Date visitEndDate) { + if (!BahmniEncounterTransaction.isRetrospectiveEntry(bahmniEncounterTransaction.getEncounterDateTime())) { + return bahmniEncounterTransaction; + } + + Visit matchingVisit = visitMatcher.getVisitFor(patient, bahmniEncounterTransaction.getVisitType(), + bahmniEncounterTransaction.getEncounterDateTime(), visitStartDate, visitEndDate, bahmniEncounterTransaction.getLocationUuid()); + bahmniEncounterTransaction.setVisitUuid(matchingVisit.getUuid()); + + // TODO : Mujir - this should not happen here. Just set the visitType. BahmniEncounterTransaction should handle string visitTypes. + bahmniEncounterTransaction.setVisitTypeUuid(matchingVisit.getVisitType().getUuid()); + + return bahmniEncounterTransaction.updateForRetrospectiveEntry(bahmniEncounterTransaction.getEncounterDateTime()); + } +} + diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/VisitIdentificationHelper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/VisitIdentificationHelper.java new file mode 100644 index 0000000000..6972e680d3 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/VisitIdentificationHelper.java @@ -0,0 +1,138 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.service; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.time.DateUtils; +import org.joda.time.DateTime; +import org.openmrs.Encounter; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; + +@Component +public class VisitIdentificationHelper implements VisitMatcher { + protected VisitService visitService; + + private BahmniVisitLocationService bahmniVisitLocationService; + + @Autowired + public VisitIdentificationHelper(VisitService visitService, BahmniVisitLocationService bahmniVisitLocationService) { + this.visitService = visitService; + this.bahmniVisitLocationService = bahmniVisitLocationService; + } + + public Visit getVisitFor(Patient patient, String visitTypeForNewVisit, Date orderDate, Date visitStartDate, Date visitEndDate, String locationUuid) { + bahmniVisitLocationService = bahmniVisitLocationService != null ? bahmniVisitLocationService : Context.getService(BahmniVisitLocationService.class); + String visitLocationUuid = bahmniVisitLocationService.getVisitLocationUuid(locationUuid); + Date nextDate = getEndOfTheDay(orderDate); + List visits = visitService.getVisits(null, Collections.singletonList(patient), null, null, null, nextDate, orderDate, null, null, true, false); + List matchingVisits = getMatchingVisitsFromLocation(visits, visitLocationUuid); + + if (!matchingVisits.isEmpty()) { + Visit matchingVisit = getVisitMatchingOrderDate(orderDate, matchingVisits); + return stretchVisits(orderDate, matchingVisit); + } + return createNewVisit(patient, orderDate, visitTypeForNewVisit, visitStartDate, visitEndDate, visitLocationUuid); + } + + public Visit getVisitFor(Patient patient, String visitTypeForNewVisit, Date orderDate, String locationUuid) { + return getVisitFor(patient, visitTypeForNewVisit, orderDate, null, null, locationUuid); + } + + public boolean hasActiveVisit(Patient patient) { + return CollectionUtils.isNotEmpty(visitService.getActiveVisitsByPatient(patient)); + } + + private List getMatchingVisitsFromLocation(List visits, String locationUuid) { + List matchingVisits = new ArrayList<>(); + for (Visit visit : visits) { + Location location = visit.getLocation(); + if (location != null && locationUuid != null && location.getUuid().equals(locationUuid)) { + matchingVisits.add(visit); + } else if (location == null && locationUuid != null) { + Location visitLocation = Context.getLocationService().getLocationByUuid(locationUuid); + visit.setLocation(visitLocation); + matchingVisits.add(visit); + } + } + return matchingVisits; + } + + private Visit stretchVisits(Date orderDate, Visit matchingVisit) { + if (matchingVisit.getStartDatetime().after(orderDate)) { + matchingVisit.setStartDatetime(orderDate); + } + if (matchingVisit.getStopDatetime() != null && matchingVisit.getStopDatetime().before(orderDate)) { + matchingVisit.setStopDatetime(orderDate); + } + return matchingVisit; + } + + private Visit getVisitMatchingOrderDate(Date orderDate, List visits) { + for (Visit visit : visits) { + Date visitStartDatetime = visit.getStartDatetime(); + Date visitStopDatetime = visit.getStopDatetime(); + if (visitStopDatetime != null) { + if ((orderDate.equals(visitStartDatetime) || visitStartDatetime.before(orderDate)) && + (orderDate.equals(visitStopDatetime) || visitStopDatetime.after(orderDate))) + return visit; + } else { + if (orderDate.equals(visitStartDatetime) || visitStartDatetime.before(orderDate)) + return visit; + } + } + return visits.get(visits.size() - 1); + } + + public Visit createNewVisit(Patient patient, Date date, String visitTypeForNewVisit, Date visitStartDate, Date visitEndDate, String visitLocationUuid) { + + Location location = Context.getLocationService().getLocationByUuid(visitLocationUuid); + VisitType visitTypeByName = getVisitTypeByName(visitTypeForNewVisit); + if (visitTypeByName == null) { + throw new RuntimeException("Visit type:'" + visitTypeForNewVisit + "' not found."); + } + + Visit visit = new Visit(); + visit.setPatient(patient); + visit.setVisitType(visitTypeByName); + visit.setLocation(location); + visit.setStartDatetime(visitStartDate == null ? date : visitStartDate); + if (!DateUtils.isSameDay(date, new Date())) { + if (visitEndDate == null) + visit.setStopDatetime(new DateTime(date).toDateMidnight().toDateTime().plusDays(1).minusSeconds(1).toDate()); + else + visit.setStopDatetime(new DateTime(visitEndDate).toDateMidnight().toDateTime().plusDays(1).minusSeconds(1).toDate()); + } + visit.setEncounters(new HashSet()); + return visitService.saveVisit(visit); + } + + public VisitType getVisitTypeByName(String visitTypeName) { + List visitTypes = visitService.getVisitTypes(visitTypeName); + return visitTypes.isEmpty() ? null : visitTypes.get(0); + } + + private static Date getEndOfTheDay(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.set(Calendar.HOUR_OF_DAY, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + + +} \ No newline at end of file diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/VisitMatcher.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/VisitMatcher.java new file mode 100644 index 0000000000..410f7d28a9 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/VisitMatcher.java @@ -0,0 +1,14 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.service; + +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.VisitType; + +import java.util.Date; + +public interface VisitMatcher { + Visit getVisitFor(Patient patient, String visitTypeForNewVisit, Date orderDate, Date visitStartDate, Date visitEndDate, String locationUuid); + boolean hasActiveVisit(Patient patient); + Visit createNewVisit(Patient patient, Date date, String visitTypeForNewVisit, Date visitStartDate, Date visitEndDate, String locationUuid); + VisitType getVisitTypeByName(String visitTypeName); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResult.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResult.java new file mode 100644 index 0000000000..0a23a2c7f9 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResult.java @@ -0,0 +1,235 @@ +package org.openmrs.module.bahmniemrapi.laborder.contract; + +import org.openmrs.module.bahmniemrapi.accessionnote.contract.AccessionNote; + +import java.util.Date; +import java.util.List; + +public class LabOrderResult { + private String orderUuid; + private String action; + private String accessionUuid; + private Date accessionDateTime; + private Date visitStartTime; + private List accessionNotes; + private String testName; + private String testUnitOfMeasurement; + private String testUuid; + private String panelUuid; + private String panelName; + private Double minNormal; + private Double maxNormal; + private String resultUuid; + private String result; + private String notes; + private Boolean abnormal; + private String provider; + private Boolean referredOut; + private Date resultDateTime; + private String uploadedFileName; + private String preferredTestName; + private String preferredPanelName; + + public LabOrderResult() { + } + + public LabOrderResult(String orderUuid, String action, String accessionUuid, Date accessionDateTime, String testName, String testUnitOfMeasurement, Double minNormal, Double maxNormal, String result, Boolean abnormal, Boolean referredOut, String uploadedFileName, List accessionNotes) { + this.orderUuid = orderUuid; + this.action = action; + this.accessionUuid = accessionUuid; + this.testName = testName; + this.testUnitOfMeasurement = testUnitOfMeasurement; + this.minNormal = minNormal; + this.maxNormal = maxNormal; + this.accessionDateTime = accessionDateTime; + this.result = result; + this.abnormal = abnormal; + this.referredOut = referredOut; + this.uploadedFileName = uploadedFileName; + this.accessionNotes = accessionNotes; + } + + public String getOrderUuid() { + return orderUuid; + } + + public void setOrderUuid(String orderUuid) { + this.orderUuid = orderUuid; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getAccessionUuid() { + return accessionUuid; + } + + public void setAccessionUuid(String accessionUuid) { + this.accessionUuid = accessionUuid; + } + + public Date getAccessionDateTime() { + return accessionDateTime; + } + + public void setAccessionDateTime(Date accessionDateTime) { + this.accessionDateTime = accessionDateTime; + } + + public Date getVisitStartTime() { + return visitStartTime; + } + + public void setVisitStartTime(Date visitStartTime) { + this.visitStartTime = visitStartTime; + } + + public List getAccessionNotes() { + return accessionNotes; + } + + public void setAccessionNotes(List accessionNotes) { + this.accessionNotes = accessionNotes; + } + + public String getTestName() { + return testName; + } + + public void setTestName(String testName) { + this.testName = testName; + } + + public String getTestUnitOfMeasurement() { + return testUnitOfMeasurement; + } + + public void setTestUnitOfMeasurement(String testUnitOfMeasurement) { + this.testUnitOfMeasurement = testUnitOfMeasurement; + } + + public String getTestUuid() { + return testUuid; + } + + public void setTestUuid(String testUuid) { + this.testUuid = testUuid; + } + + public String getPanelUuid() { + return panelUuid; + } + + public void setPanelUuid(String panelUuid) { + this.panelUuid = panelUuid; + } + + public String getPanelName() { + return panelName; + } + + public void setPanelName(String panelName) { + this.panelName = panelName; + } + + public Double getMinNormal() { + return minNormal; + } + + public void setMinNormal(Double minNormal) { + this.minNormal = minNormal; + } + + public Double getMaxNormal() { + return maxNormal; + } + + public void setMaxNormal(Double maxNormal) { + this.maxNormal = maxNormal; + } + + public String getResultUuid() { + return resultUuid; + } + + public void setResultUuid(String resultUuid) { + this.resultUuid = resultUuid; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public Boolean getAbnormal() { + return abnormal; + } + + public void setAbnormal(Boolean abnormal) { + this.abnormal = abnormal; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public Boolean getReferredOut() { + return referredOut; + } + + public void setReferredOut(Boolean referredOut) { + this.referredOut = referredOut; + } + + public Date getResultDateTime() { + return resultDateTime; + } + + public void setResultDateTime(Date resultDateTime) { + this.resultDateTime = resultDateTime; + } + + public String getUploadedFileName() { + return uploadedFileName; + } + + public void setUploadedFileName(String uploadedFileName) { + this.uploadedFileName = uploadedFileName; + } + + public String getPreferredTestName() { + return preferredTestName; + } + + public void setPreferredTestName(String preferredTestName) { + this.preferredTestName = preferredTestName; + } + + public String getPreferredPanelName() { + return preferredPanelName; + } + + public void setPreferredPanelName(String preferredPanelName) { + this.preferredPanelName = preferredPanelName; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java new file mode 100644 index 0000000000..828b99ccae --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResults.java @@ -0,0 +1,70 @@ +package org.openmrs.module.bahmniemrapi.laborder.contract; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; +import org.joda.time.LocalDate; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class LabOrderResults { + private List results = new ArrayList<>(); + private TabularLabOrderResults tabularResult; + + @JsonCreator + public LabOrderResults(@JsonProperty("results")List results) { + this.results = results; + this.tabularResult = this.tabulate(); + } + + private TabularLabOrderResults tabulate() { + Map dateMap = new TreeMap<>(); + Map orderMap = new TreeMap<>(); + List coordinateValues = new ArrayList<>(); + + Integer dateLabelIndexCounter = 0; + Integer testOrderLabelCounter = 0; + + for (LabOrderResult result : results) { + LocalDate orderDate = new LocalDate(result.getAccessionDateTime()); + if(dateMap.get(orderDate) == null) { + dateMap.put(orderDate, new TabularLabOrderResults.DateLabel(dateLabelIndexCounter++, orderDate.toString("dd-MMM-yyyy"))); + } + if(orderMap.get(result.getTestName()) == null) { + orderMap.put(result.getTestName(), new TabularLabOrderResults.TestOrderLabel(testOrderLabelCounter++, result.getTestName(), result.getMinNormal(), result.getMaxNormal(), result.getTestUnitOfMeasurement(), result.getPanelName())); + } + + if(result.getResult() != null || result.getReferredOut() || result.getUploadedFileName() != null) { + TabularLabOrderResults.CoordinateValue coordinateValue = new TabularLabOrderResults.CoordinateValue(); + coordinateValue.setDateIndex(dateMap.get(orderDate).getIndex()); + coordinateValue.setTestOrderIndex(orderMap.get(result.getTestName()).getIndex()); + coordinateValue.setResult(result.getResult()); + coordinateValue.setAbnormal(result.getAbnormal()); + coordinateValue.setReferredOut(result.getReferredOut()); + coordinateValue.setUploadedFileName(result.getUploadedFileName()); + coordinateValue.setAccessionDateTime(result.getAccessionDateTime()); + coordinateValues.add(coordinateValue); + } + } + + return new TabularLabOrderResults(new ArrayList<>(dateMap.values()), new ArrayList<>(orderMap.values()), coordinateValues); + } + + public void setTabularResult(TabularLabOrderResults tabularResult) { + this.tabularResult = tabularResult; + } + + public List getResults() { + return results; + } + + public void setResults(List results) { + this.results = results; + } + + public TabularLabOrderResults getTabularResult() { + return tabularResult; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java new file mode 100644 index 0000000000..3dd72e608e --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/contract/TabularLabOrderResults.java @@ -0,0 +1,213 @@ +package org.openmrs.module.bahmniemrapi.laborder.contract; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class TabularLabOrderResults { + private List dates = new ArrayList<>(); + private List orders = new ArrayList<>(); + private List values = new ArrayList<>(); + + @JsonCreator + public TabularLabOrderResults(@JsonProperty("dates")List dates, + @JsonProperty("orders")List orders, + @JsonProperty("values")List values) { + this.dates = dates; + this.orders = orders; + this.values = values; + } + + public static class DateLabel { + private Integer index; + private String date; + + @JsonCreator + public DateLabel(@JsonProperty("index")Integer index, + @JsonProperty("date")String date) { + this.index = index; + this.date = date; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + } + + public static class TestOrderLabel { + private Integer index; + private String testName; + private Double minNormal; + private Double maxNormal; + private String testUnitOfMeasurement; + private String panelName; + + @JsonCreator + public TestOrderLabel(@JsonProperty("index")Integer index, + @JsonProperty("testName")String testName, + @JsonProperty("minNormal")Double minNormal, + @JsonProperty("maxNormal")Double maxNormal, + @JsonProperty("testUnitOfMeasurement")String testUnitOfMeasurement, + @JsonProperty("panelName")String panelName) { + this.index = index; + this.testName = testName; + this.minNormal = minNormal; + this.maxNormal = maxNormal; + this.testUnitOfMeasurement = testUnitOfMeasurement; + this.panelName = panelName; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public String getTestName() { + return testName; + } + + public void setTestName(String testName) { + this.testName = testName; + } + + public Double getMinNormal() { + return minNormal; + } + + public void setMinNormal(Double minNormal) { + this.minNormal = minNormal; + } + + public Double getMaxNormal() { + return maxNormal; + } + + public void setMaxNormal(Double maxNormal) { + this.maxNormal = maxNormal; + } + + public String getTestUnitOfMeasurement() { + return testUnitOfMeasurement; + } + + public void setTestUnitOfMeasurement(String testUnitOfMeasurement) { + this.testUnitOfMeasurement = testUnitOfMeasurement; + } + + public String getPanelName() { + return panelName; + } + + public void setPanelName(String panelName) { + this.panelName = panelName; + } + } + + public static class CoordinateValue { + private Date accessionDateTime; + private Integer dateIndex; + private Integer testOrderIndex; + private String result; + private Boolean abnormal; + private Boolean referredOut; + private String uploadedFileName; + + public Date getAccessionDateTime() { + return accessionDateTime; + } + + public void setAccessionDateTime(Date accessionDateTime) { + this.accessionDateTime = accessionDateTime; + } + + public Integer getDateIndex() { + return dateIndex; + } + + public void setDateIndex(Integer dateIndex) { + this.dateIndex = dateIndex; + } + + public Integer getTestOrderIndex() { + return testOrderIndex; + } + + public void setTestOrderIndex(Integer testOrderIndex) { + this.testOrderIndex = testOrderIndex; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public Boolean getAbnormal() { + return abnormal; + } + + public void setAbnormal(Boolean abnormal) { + this.abnormal = abnormal; + } + + public Boolean getReferredOut() { + return referredOut; + } + + public void setReferredOut(Boolean referredOut) { + this.referredOut = referredOut; + } + + public String getUploadedFileName() { + return uploadedFileName; + } + + public void setUploadedFileName(String uploadedFileName) { + this.uploadedFileName = uploadedFileName; + } + } + + public List getDates() { + return dates; + } + + public void setDates(List dates) { + this.dates = dates; + } + + public List getOrders() { + return orders; + } + + public void setOrders(List orders) { + this.orders = orders; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java new file mode 100644 index 0000000000..9113a523a2 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapper.java @@ -0,0 +1,112 @@ +package org.openmrs.module.bahmniemrapi.laborder.mapper; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.Concept; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.Date; + +import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +@Component +public class LabOrderResultMapper { + private static final Log log = LogFactory.getLog(LabOrderResultMapper.class); + public static final String LAB_RESULT = "LAB_RESULT"; + public static final String LAB_ABNORMAL = "LAB_ABNORMAL"; + public static final String LAB_MINNORMAL = "LAB_MINNORMAL"; + public static final String LAB_MAXNORMAL = "LAB_MAXNORMAL"; + public static final String LAB_NOTES = "LAB_NOTES"; + public static final String LABRESULTS_CONCEPT = "LABRESULTS_CONCEPT"; + private static final String REFERRED_OUT = "REFERRED_OUT"; + public static final String LAB_REPORT = "LAB_REPORT"; + private ConceptService conceptService; + + @Autowired + public LabOrderResultMapper(ConceptService conceptService) { + this.conceptService = conceptService; + } + + public Obs map(LabOrderResult labOrderResult, Order testOrder, Concept concept) { + try { + Date obsDate = labOrderResult.getResultDateTime(); + Obs topLevelObs = newObs(testOrder, obsDate, concept, null); + Obs labObs = newObs(testOrder, obsDate, concept, null); + topLevelObs.addGroupMember(labObs); + if (isNotBlank(labOrderResult.getResult()) || isNotBlank(labOrderResult.getUploadedFileName())) { + labObs.addGroupMember(newResultObs(testOrder, obsDate, concept, labOrderResult)); + if(BooleanUtils.isTrue(labOrderResult.getAbnormal())) { + labObs.addGroupMember(newObs(testOrder, obsDate, getConceptByName(LAB_ABNORMAL), labOrderResult.getAbnormal().toString())); + } + if (concept.isNumeric() && hasRange(labOrderResult)) { + labObs.addGroupMember(newObs(testOrder, obsDate, getConceptByName(LAB_MINNORMAL), labOrderResult.getMinNormal().toString())); + labObs.addGroupMember(newObs(testOrder, obsDate, getConceptByName(LAB_MAXNORMAL), labOrderResult.getMaxNormal().toString())); + } + } + if (labOrderResult.getReferredOut() != null && labOrderResult.getReferredOut()) { + labObs.addGroupMember(newObs(testOrder, obsDate, getConceptByName(REFERRED_OUT), labOrderResult.getReferredOut().toString())); + } + if (isNotBlank(labOrderResult.getNotes())) { + labObs.addGroupMember(newObs(testOrder, obsDate, getConceptByName(LAB_NOTES), labOrderResult.getNotes())); + } + if (isNotBlank(labOrderResult.getUploadedFileName())) { + labObs.addGroupMember(newObs(testOrder, obsDate, getConceptByName(LAB_REPORT), labOrderResult.getUploadedFileName())); + } + return topLevelObs; + } catch (ParseException e) { + throw new APIException(e); + } + } + + private Obs newResultObs(Order testOrder, Date obsDate, Concept concept, LabOrderResult labOrderResult) throws ParseException { + Obs obs = new Obs(); + obs.setConcept(concept); + obs.setOrder(testOrder); + obs.setObsDatetime(obsDate); + if (concept.getDatatype().getHl7Abbreviation().equals("CWE")) { + String resultUuid = labOrderResult.getResultUuid(); + Concept conceptAnswer = isEmpty(resultUuid) ? null : conceptService.getConceptByUuid(resultUuid); + obs.setValueCoded(conceptAnswer); + if (conceptAnswer == null) { + log.warn(String.format("Concept is not available in OpenMRS for ConceptUuid : [%s] , In Accession : [%s]" + , resultUuid,labOrderResult.getAccessionUuid())); + return null; + } + return obs; + } + + if (isEmpty(labOrderResult.getResult())) { + return null; + } + obs.setValueAsString(labOrderResult.getResult()); + return obs; + } + + private Concept getConceptByName(String conceptName) { + return conceptService.getConceptByName(conceptName); + } + + private Obs newObs(Order order, Date obsDate, Concept concept, String value) throws ParseException { + Obs obs = new Obs(); + obs.setConcept(concept); + obs.setOrder(order); + obs.setObsDatetime(obsDate); + if (isNotBlank(value)) { + obs.setValueAsString(value); + } + return obs; + } + + private boolean hasRange(LabOrderResult labOrderResult) { + return labOrderResult.getMinNormal() != null && labOrderResult.getMaxNormal() != null; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsService.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsService.java new file mode 100644 index 0000000000..09cbb0a45e --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsService.java @@ -0,0 +1,16 @@ +package org.openmrs.module.bahmniemrapi.laborder.service; + +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResults; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +public interface LabOrderResultsService { + LabOrderResults getAll(Patient patient, List visits, int numberOfAccessions); + + List getAllForConcepts(Patient patient, Collection concepts, List visits, Date startDate, Date endDate); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceImpl.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceImpl.java new file mode 100644 index 0000000000..6017956bb3 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceImpl.java @@ -0,0 +1,329 @@ +package org.openmrs.module.bahmniemrapi.laborder.service; + +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.TestOrder; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.db.hibernate.HibernateUtil; +import org.openmrs.module.bahmniemrapi.accessionnote.contract.AccessionNote; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResults; +import org.openmrs.module.emrapi.encounter.EncounterTransactionMapper; +import org.openmrs.module.emrapi.encounter.OrderMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +@Service +public class LabOrderResultsServiceImpl implements LabOrderResultsService { + public static final String LAB_ABNORMAL = "LAB_ABNORMAL"; + public static final String LAB_MINNORMAL = "LAB_MINNORMAL"; + public static final String LAB_MAXNORMAL = "LAB_MAXNORMAL"; + public static final String LAB_NOTES = "LAB_NOTES"; + private static final String REFERRED_OUT = "REFERRED_OUT"; + public static final String LAB_REPORT = "LAB_REPORT"; + private static final String VALIDATION_NOTES_ENCOUNTER_TYPE = "VALIDATION NOTES"; + public static final String LAB_ORDER_TYPE = "Lab Order"; + + @Autowired + private EncounterTransactionMapper encounterTransactionMapper; + + @Autowired + private EncounterService encounterService; + + @Autowired + private OrderMapper orderMapper; + + @Override + @Transactional(readOnly = true) + public LabOrderResults getAll(Patient patient, List visits, int numberOfAccessions) { + List testOrders = new ArrayList<>(); + List observations = new ArrayList<>(); + Map encounterTestOrderUuidMap = new HashMap<>(); + Map encounterObservationMap = new HashMap<>(); + Map> encounterToAccessionNotesMap = new HashMap<>(); + + List encounters = encounterService.getEncounters(patient, null, null, null, null, null, null, null, visits, false); + + int totalEncounters = encounters.size(); + int currentAccession = 0; + for (int count = totalEncounters - 1; count >= 0; count--) { + Encounter encounter = encounters.get(count); + if (currentAccession >= numberOfAccessions) { + break; + } + + EncounterTransaction encounterTransaction = encounterTransactionMapper.map(encounter, false); + List existingTestOrders = filterTestOrders(encounterTransaction, encounter, encounterTestOrderUuidMap, null, null, null); + testOrders.addAll(existingTestOrders); + List nonVoidedObservations = filterObservations(encounterTransaction.getObservations(), null, null); + observations.addAll(nonVoidedObservations); + createAccessionNotesByEncounter(encounterToAccessionNotesMap, encounters, encounter); + mapObservationsWithEncounter(nonVoidedObservations, encounter, encounterObservationMap); + if (existingTestOrders.size() > 0) { + currentAccession++; + } + } + + List labOrderResults = mapOrdersWithObs(testOrders, observations, encounterTestOrderUuidMap, encounterObservationMap, encounterToAccessionNotesMap); + + return new LabOrderResults(filterLabOrderResults(labOrderResults)); + } + + private List filterLabOrderResults(List labOrderResults) { + List filteredResults = new ArrayList<>(); + for (LabOrderResult labOrderResult : labOrderResults) { + if (labOrderResult.getResult() != null) { + filteredResults.add(labOrderResult); + } else if (labOrderResult.getAction().equals(Order.Action.NEW.toString())) { + filteredResults.add(labOrderResult); + } + } + return filteredResults; + } + + @Override + public List getAllForConcepts(Patient patient, Collection concepts, List visits, Date startDate, Date endDate) { + if (concepts != null && !concepts.isEmpty()) { + + List testOrders = new ArrayList<>(); + List observations = new ArrayList<>(); + Map encounterTestOrderUuidMap = new HashMap<>(); + Map encounterObservationMap = new HashMap<>(); + Map> encounterToAccessionNotesMap = new HashMap<>(); + + List encounters = encounterService.getEncounters(patient, null, null, null, null, null, null, null, visits, false); + for (Encounter encounter : encounters) { + EncounterTransaction encounterTransaction = encounterTransactionMapper.map(encounter, false); + testOrders.addAll(filterTestOrders(encounterTransaction, encounter, encounterTestOrderUuidMap, concepts, startDate, endDate)); + List filteredObservations = filterObservations(encounterTransaction.getObservations(), startDate, endDate); + observations.addAll(filteredObservations); + createAccessionNotesByEncounter(encounterToAccessionNotesMap, encounters, encounter); + mapObservationsWithEncounter(filteredObservations, encounter, encounterObservationMap); + } + return mapOrdersWithObs(testOrders, observations, encounterTestOrderUuidMap, encounterObservationMap, encounterToAccessionNotesMap); + } + return new ArrayList<>(); + } + + private void createAccessionNotesByEncounter(Map> encounterToAccessionNotesMap, List encounters, Encounter encounter) { + List accessionNotes = getAccessionNotesFor(encounter, encounters); + if (accessionNotes.size() != 0) { + List existingAccessionNotes = encounterToAccessionNotesMap.get(encounter.getUuid()); + if (existingAccessionNotes != null) { + accessionNotes.addAll(existingAccessionNotes); + } + encounterToAccessionNotesMap.put(encounter.getUuid(), accessionNotes); + } + } + + private List getAccessionNotesFor(Encounter orderEncounter, List encounters) { + for (Encounter encounter : encounters) { + if (VALIDATION_NOTES_ENCOUNTER_TYPE.equals(encounter.getEncounterType().getName()) && hasValidationNotesFor(orderEncounter.getUuid(), encounter)) { + return createAccessionNotesFor(orderEncounter.getUuid(), encounter); + } + } + return new ArrayList<>(); + } + + private List createAccessionNotesFor(String encounterUuid, Encounter accessionNotesEncounter) { + List accessionNotes = new ArrayList<>(); + for (Obs observation : accessionNotesEncounter.getAllObs()) { + if (!encounterUuid.equals(observation.getValueText())) { + AccessionNote accessionNote = new AccessionNote(); + accessionNote.setAccessionUuid(encounterUuid); + accessionNote.setDateTime(observation.getObsDatetime()); + accessionNote.setText(observation.getValueText()); + Collection> providersForRole = accessionNotesEncounter.getProvidersByRoles().values(); + if (providersForRole.size() > 0) { + Provider provider = providersForRole.iterator().next().iterator().next(); + accessionNote.setProviderName(provider.getName()); + } + accessionNotes.add(accessionNote); + } + } + return accessionNotes; + } + + private boolean hasValidationNotesFor(String encounterUuid, Encounter encounter) { + Set observations = encounter.getAllObs(); + for (Obs observation : observations) { + if (encounterUuid.equals(observation.getValueText())) return true; + } + return false; + } + + List filterTestOrders(EncounterTransaction encounterTransaction, Encounter encounter, Map encounterTestOrderUuidMap, Collection concepts, Date startDate, Date endDate) { + List orders = new ArrayList<>(); + for (EncounterTransaction.Order order : encounterTransaction.getOrders()) { + boolean conceptFilter = (concepts == null) || concepts.contains(order.getConcept().getName()); + if ((conceptFilter && LAB_ORDER_TYPE.equals(order.getOrderType())) && !((startDate != null && order.getDateCreated().before(startDate)) + || (endDate != null && order.getDateCreated().after(endDate)))) { + encounterTestOrderUuidMap.put(order.getUuid(), encounter); + orders.add(order); + } + } + // Hack to handle OpenMRS Test Orders from the TestOrder domain as Orders since the EMRAPI's OrderMapper does not handle them + if (orders.isEmpty()) { + for (Order order : encounter.getOrders()) { + order = HibernateUtil.getRealObjectFromProxy(order); + boolean conceptFilter = (concepts == null) || concepts.contains(order.getConcept().getName().getName()); + if (TestOrder.class.equals(order.getClass()) && ((conceptFilter && LAB_ORDER_TYPE.equals(order.getOrderType().getName())) && !((startDate != null && order.getDateCreated().before(startDate)) + || (endDate != null && order.getDateCreated().after(endDate))))) { + encounterTestOrderUuidMap.put(order.getUuid(), encounter); + orders.add(orderMapper.mapOrder(order)); + } + } + } + return orders; + } + + private List filterObservations(List observations, Date startDate, Date endDate) { + List filteredObservations = new ArrayList<>(); + for (EncounterTransaction.Observation observation : observations) { + if (!observation.getVoided() && !((startDate != null && observation.getObservationDateTime().before(startDate)) + || (endDate != null && observation.getObservationDateTime().after(endDate)))) { + filteredObservations.add(observation); + } + } + return filteredObservations; + } + + private void mapObservationsWithEncounter(List observations, Encounter encounter, Map encounterObservationMap) { + for (EncounterTransaction.Observation observation : observations) { + encounterObservationMap.put(observation.getUuid(), encounter); + if (observation.getGroupMembers().size() > 0) { + mapObservationsWithEncounter(observation.getGroupMembers(), encounter, encounterObservationMap); + } + } + } + + List mapOrdersWithObs(List testOrders, List observations, Map encounterTestOrderMap, Map encounterObservationMap, Map> encounterToAccessionNotesMap) { + List labOrderResults = new ArrayList<>(); + for (EncounterTransaction.Order testOrder : testOrders) { + List obsGroups = findObsGroup(observations, testOrder); + if (!obsGroups.isEmpty()) { + for (EncounterTransaction.Observation obsGroup : obsGroups) { + labOrderResults.addAll(mapObs(obsGroup, testOrder, encounterTestOrderMap, encounterObservationMap, encounterToAccessionNotesMap)); + } + } else if (testOrder.getDateStopped() == null) { + EncounterTransaction.Concept orderConcept = testOrder.getConcept(); + Encounter orderEncounter = encounterTestOrderMap.get(testOrder.getUuid()); + LabOrderResult labOrderResult = new LabOrderResult(testOrder.getUuid(), testOrder.getAction(), orderEncounter.getUuid(), orderEncounter.getEncounterDatetime(), orderConcept.getName(), orderConcept.getUnits(), null, null, null, null, false, null, null); + if(testOrder.getConcept().getShortName() != null) { + labOrderResult.setPreferredTestName(testOrder.getConcept().getShortName()); + } + labOrderResult.setVisitStartTime(orderEncounter.getVisit().getStartDatetime()); + labOrderResults.add(labOrderResult); + } + } + return labOrderResults; + } + + private List mapObs(EncounterTransaction.Observation obsGroup, EncounterTransaction.Order testOrder, Map encounterTestOrderMap, Map encounterObservationMap, Map> encounterToAccessionNotesMap) { + List labOrderResults = new ArrayList<>(); + if (isPanel(obsGroup)) { + for (EncounterTransaction.Observation observation : obsGroup.getGroupMembers()) { + LabOrderResult order = createLabOrderResult(observation, testOrder, encounterTestOrderMap, encounterObservationMap, encounterToAccessionNotesMap); + order.setPanelUuid(obsGroup.getConceptUuid()); + if(obsGroup.getConcept().getShortName() != null) { + order.setPanelName(obsGroup.getConcept().getShortName()); + }else{ + order.setPanelName(obsGroup.getConcept().getName()); + } + labOrderResults.add(order); + } + } else { + labOrderResults.add(createLabOrderResult(obsGroup, testOrder, encounterTestOrderMap, encounterObservationMap, encounterToAccessionNotesMap)); + } + return labOrderResults; + } + + private boolean isPanel(EncounterTransaction.Observation obsGroup) { + return obsGroup.getConcept().isSet(); + } + + private LabOrderResult createLabOrderResult(EncounterTransaction.Observation observation, EncounterTransaction.Order testOrder, Map encounterTestOrderMap, Map encounterObservationMap, Map> encounterToAccessionNotesMap) { + LabOrderResult labOrderResult = new LabOrderResult(); + Encounter orderEncounter = encounterTestOrderMap.get(observation.getOrderUuid()); + Object resultValue = getValue(observation, observation.getConcept().getName()); + String notes = (String) getValue(observation, LAB_NOTES); + String uploadedFileName = (String) getValue(observation, LAB_REPORT); + labOrderResult.setAccessionUuid(orderEncounter.getUuid()); + labOrderResult.setAccessionDateTime(orderEncounter.getEncounterDatetime()); + labOrderResult.setProvider(getProviderName(observation, encounterObservationMap)); + labOrderResult.setResultDateTime(observation.getObservationDateTime()); + labOrderResult.setTestUuid(observation.getConceptUuid()); + labOrderResult.setTestName(observation.getConcept().getName()); + labOrderResult.setResult(resultValue != null ? resultValue.toString() : null); + labOrderResult.setAbnormal((Boolean) getValue(observation, LAB_ABNORMAL)); + labOrderResult.setMinNormal((Double) getValue(observation, LAB_MINNORMAL)); + labOrderResult.setMaxNormal((Double) getValue(observation, LAB_MAXNORMAL)); + labOrderResult.setNotes(notes != null && notes.trim().length() > 1 ? notes.trim() : null); + labOrderResult.setReferredOut(getLeafObservation(observation, REFERRED_OUT) != null); + labOrderResult.setTestUnitOfMeasurement(observation.getConcept().getUnits()); + labOrderResult.setUploadedFileName(uploadedFileName != null && uploadedFileName.trim().length() > 0 ? uploadedFileName.trim() : null); + labOrderResult.setVisitStartTime(orderEncounter.getVisit().getStartDatetime()); + labOrderResult.setAccessionNotes(encounterToAccessionNotesMap.get(orderEncounter.getUuid())); + labOrderResult.setAction(testOrder.getAction()); + labOrderResult.setOrderUuid(testOrder.getUuid()); + if(observation.getConcept().getShortName() != null) { + labOrderResult.setPreferredTestName(observation.getConcept().getShortName()); + }else{ + labOrderResult.setTestName(observation.getConcept().getName()); + } + return labOrderResult; + } + + private String getProviderName(EncounterTransaction.Observation observation, Map encounterObservationMap) { + Encounter obsEncounter = encounterObservationMap.get(observation.getUuid()); + ArrayList encounterProviders = new ArrayList<>(obsEncounter.getEncounterProviders()); + return encounterProviders.size() > 0 ? encounterProviders.get(0).getProvider().getName() : null; + } + + private Object getValue(EncounterTransaction.Observation observation, String conceptName) { + EncounterTransaction.Observation leafObservation = getLeafObservation(observation, conceptName); + if (leafObservation != null) { + Object value = leafObservation.getValue(); + return (value instanceof EncounterTransaction.Concept) ? ((EncounterTransaction.Concept) value).getName() : value; + } + return null; + } + + private EncounterTransaction.Observation getLeafObservation(EncounterTransaction.Observation observation, String conceptName) { + for (EncounterTransaction.Observation childObs : observation.getGroupMembers()) { + if (!childObs.getGroupMembers().isEmpty()) { + return getLeafObservation(childObs, conceptName); + } + if (childObs.getConcept().getName().equalsIgnoreCase(conceptName)) { + return childObs; + } + } + return null; + } + + private List findObsGroup(List observations, EncounterTransaction.Order testOrder) { + List obsGroups = new ArrayList<>(); + for (EncounterTransaction.Observation observation : observations) { + if (observation.getOrderUuid() != null && observation.getOrderUuid().equals(testOrder.getUuid())) { + obsGroups.add(observation); + } + } + return obsGroups; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/obscalculator/ObsValueCalculator.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/obscalculator/ObsValueCalculator.java new file mode 100644 index 0000000000..1ae67b7107 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/obscalculator/ObsValueCalculator.java @@ -0,0 +1,7 @@ +package org.openmrs.module.bahmniemrapi.obscalculator; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; + +public interface ObsValueCalculator { + void run(BahmniEncounterTransaction bahmniEncounterTransaction); +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/obsrelation/contract/ObsRelationship.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/obsrelation/contract/ObsRelationship.java new file mode 100644 index 0000000000..9fc0ea46eb --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/obsrelation/contract/ObsRelationship.java @@ -0,0 +1,42 @@ +package org.openmrs.module.bahmniemrapi.obsrelation.contract; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; + +public class ObsRelationship { + private BahmniObservation targetObs; + private String uuid; + private String relationshipType; + + public ObsRelationship() { + } + + public ObsRelationship(BahmniObservation targetObs, String uuid, String relationshipType) { + this.targetObs = targetObs; + this.uuid = uuid; + this.relationshipType = relationshipType; + } + + public BahmniObservation getTargetObs() { + return targetObs; + } + + public void setTargetObs(BahmniObservation targetObs) { + this.targetObs = targetObs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getRelationshipType() { + return relationshipType; + } + + public void setRelationshipType(String relationshipType) { + this.relationshipType = relationshipType; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/order/contract/BahmniOrder.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/order/contract/BahmniOrder.java new file mode 100644 index 0000000000..adf8357360 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/order/contract/BahmniOrder.java @@ -0,0 +1,112 @@ +package org.openmrs.module.bahmniemrapi.order.contract; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Collection; +import java.util.Date; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BahmniOrder { + private String orderUuid; + private String orderNumber; + private String orderTypeUuid; + private String provider; + private String providerUuid; + private Date orderDate; + private EncounterTransaction.Concept concept; + private Boolean hasObservations; + private Collection bahmniObservations; + private String commentToFulfiller; + + private Order.FulfillerStatus fulfillerStatus; + + public String getOrderNumber() { + return orderNumber; + } + + public void setOrderNumber(String orderNumber) { + this.orderNumber = orderNumber; + } + + public Boolean getHasObservations() { + return hasObservations; + } + + public void setHasObservations(Boolean hasObservations) { + this.hasObservations = hasObservations; + } + + public Collection getBahmniObservations() { + return bahmniObservations; + } + + public void setBahmniObservations(Collection bahmniObservations) { + this.bahmniObservations = bahmniObservations; + } + + public String getOrderUuid() { + return orderUuid; + } + + public void setOrderUuid(String orderUuid) { + this.orderUuid = orderUuid; + } + + public String getOrderTypeUuid() { + return orderTypeUuid; + } + + public void setOrderTypeUuid(String orderTypeUuid) { + this.orderTypeUuid = orderTypeUuid; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getProviderUuid() { + return providerUuid; + } + public void setProviderUuid(String providerUuid) { + this.providerUuid = providerUuid; + } + + public Date getOrderDate() { + return orderDate; + } + + public void setOrderDateTime(Date orderDate) { + this.orderDate = orderDate; + } + + public EncounterTransaction.Concept getConcept() { + return concept; + } + + public void setConcept(EncounterTransaction.Concept concept) { + this.concept = concept; + } + + public Order.FulfillerStatus getFulfillerStatus() { + return fulfillerStatus; + } + + public void setFulfillerStatus(Order.FulfillerStatus fulfillerStatus) { + this.fulfillerStatus = fulfillerStatus; + } + + public String getCommentToFulfiller() { + return commentToFulfiller; + } + + public void setCommentToFulfiller(String commentToFulfiller) { + this.commentToFulfiller = commentToFulfiller; + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/patient/PatientContext.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/patient/PatientContext.java new file mode 100644 index 0000000000..dc29364139 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/patient/PatientContext.java @@ -0,0 +1,116 @@ +package org.openmrs.module.bahmniemrapi.patient; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class PatientContext { + private Date birthdate; + private String givenName; + private String middleName; + private String familyName; + private String identifier; + private String uuid; + private String gender; + private Map> personAttributes = new HashMap<>(); + private Map> programAttributes = new HashMap<>(); + private Map additionalPatientIdentifiers = new HashMap<>(); + + public Date getBirthdate() { + return birthdate; + } + + public void setBirthdate(Date birthDate) { + this.birthdate = birthDate; + } + + public String getGivenName() { + return givenName; + } + + public void setGivenName(String givenName) { + this.givenName = givenName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getFamilyName() { + return familyName; + } + + public void setFamilyName(String familyName) { + this.familyName = familyName; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public Map> getPersonAttributes() { + return personAttributes; + } + + public void setPersonAttributes(Map> attributes) { + this.personAttributes = attributes; + } + + public void addPersonAttribute(String key, String description, String value) { + HashMap responseValue = new HashMap<>(); + responseValue.put("value", value); + responseValue.put("description", description); + this.personAttributes.put(key, responseValue); + } + + public Map> getProgramAttributes() { + return programAttributes; + } + + public void setProgramAttributes(Map> programAttributes) { + this.programAttributes = programAttributes; + } + + public void addProgramAttribute(String key, String description, Object value) { + HashMap responseValue = new HashMap<>(); + responseValue.put("value", value); + responseValue.put("description", description); + this.programAttributes.put(key, responseValue); + } + + public Map getAdditionalPatientIdentifiers() { + return additionalPatientIdentifiers; + } + + public void setAdditionalPatientIdentifiers(Map additionalPatientIdentifiers) { + this.additionalPatientIdentifiers = additionalPatientIdentifiers; + } + + public void addAdditionalPatientIdentifier(String type, String value) { + this.additionalPatientIdentifiers.put(type, value); + } +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/pivottable/contract/PivotRow.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/pivottable/contract/PivotRow.java new file mode 100644 index 0000000000..93262eb8e2 --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/pivottable/contract/PivotRow.java @@ -0,0 +1,27 @@ +package org.openmrs.module.bahmniemrapi.pivottable.contract; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class PivotRow { + private Map> columns = new HashMap<>(); + + public void addColumn(String name, BahmniObservation bahmniObservation) { + ArrayList bahmniObs; + bahmniObs = columns.get(name) != null ? columns.get(name) : new ArrayList(); + bahmniObs.add(bahmniObservation); + columns.put(name, bahmniObs); + } + + public ArrayList getValue(String key) { + return columns.get(key); + } + + public Map> getColumns() { + return columns; + } + +} diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/pivottable/contract/PivotTable.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/pivottable/contract/PivotTable.java new file mode 100644 index 0000000000..de3708170d --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/pivottable/contract/PivotTable.java @@ -0,0 +1,33 @@ +package org.openmrs.module.bahmniemrapi.pivottable.contract; + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +public class PivotTable { + private Set headers = new LinkedHashSet<>(); + private List rows = new ArrayList<>(); + + public Set getHeaders() { + return headers; + } + + public void setHeaders(Set headers) { + this.headers = headers; + } + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public void addRow(int index, PivotRow row){ + this.rows.add(index,row); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/visit/contract/VisitData.java b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/visit/contract/VisitData.java new file mode 100644 index 0000000000..4b568b92da --- /dev/null +++ b/bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/visit/contract/VisitData.java @@ -0,0 +1,32 @@ +package org.openmrs.module.bahmniemrapi.visit.contract; + + +import org.openmrs.Visit; + +import java.util.Date; + +public class VisitData { + private String uuid; + private Date startDateTime; + + public VisitData(Visit visit) { + this.uuid = visit.getUuid(); + this.startDateTime = visit.getStartDatetime(); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Date getStartDateTime() { + return startDateTime; + } + + public void setStartDateTime(Date startDateTime) { + this.startDateTime = startDateTime; + } +} diff --git a/bahmni-emr-api/src/main/resources/moduleApplicationContext.xml b/bahmni-emr-api/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..7d3546ff56 --- /dev/null +++ b/bahmni-emr-api/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/BaseIntegrationTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/BaseIntegrationTest.java new file mode 100644 index 0000000000..dd2213dbdc --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/BaseIntegrationTest.java @@ -0,0 +1,8 @@ +package org.openmrs.module.bahmniemrapi; + +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BaseIntegrationTest extends BaseModuleContextSensitiveTest { +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniDiagnosisRequestBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniDiagnosisRequestBuilder.java new file mode 100644 index 0000000000..1f0794d42f --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniDiagnosisRequestBuilder.java @@ -0,0 +1,34 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +public class BahmniDiagnosisRequestBuilder { + private BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + + public BahmniDiagnosisRequestBuilder withCodedAnswer(EncounterTransaction.Concept concept) { + bahmniDiagnosisRequest.setCodedAnswer(concept); + return this; + } + + public BahmniDiagnosisRequest build() { + return bahmniDiagnosisRequest; + } + + public BahmniDiagnosisRequestBuilder withOrder(String order) { + this.bahmniDiagnosisRequest.setOrder(order); + return this; + } + + public BahmniDiagnosisRequestBuilder withCertainty(String certainty) { + this.bahmniDiagnosisRequest.setCertainty(certainty); + return this; + } + + public BahmniDiagnosisRequestBuilder withStatus(EncounterTransaction.Concept statusConcept) { + this.bahmniDiagnosisRequest.setDiagnosisStatusConcept( + statusConcept + ); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniEncounterTransactionBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniEncounterTransactionBuilder.java new file mode 100644 index 0000000000..8f36a59cbb --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniEncounterTransactionBuilder.java @@ -0,0 +1,85 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +public class BahmniEncounterTransactionBuilder { + private BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + + public BahmniEncounterTransactionBuilder withObservation(BahmniObservation... bahmniObservations) { + for (BahmniObservation bahmniObservation : bahmniObservations) { + bahmniEncounterTransaction.addObservation(bahmniObservation); + } + return this; + } + + public BahmniEncounterTransactionBuilder withVisitTypeUuid(String visitTypeUuid) { + bahmniEncounterTransaction.setVisitTypeUuid(visitTypeUuid); + return this; + } + + public BahmniEncounterTransactionBuilder withProviders(Set providerSet) { + bahmniEncounterTransaction.setProviders(providerSet); + return this; + } + + public BahmniEncounterTransactionBuilder withEncounterTypeUuid(String encounterTypeUuid) { + bahmniEncounterTransaction.setEncounterTypeUuid(encounterTypeUuid); + return this; + } + + public BahmniEncounterTransactionBuilder withPatientUuid(String patientUuid) { + bahmniEncounterTransaction.setPatientUuid(patientUuid); + return this; + } + + public BahmniEncounterTransactionBuilder withVisitUuid(String visitUuid) { + bahmniEncounterTransaction.setVisitUuid(visitUuid); + return this; + } + + public BahmniEncounterTransactionBuilder withLocationUuid(String locationUuid) { + bahmniEncounterTransaction.setLocationUuid(locationUuid); + return this; + } + + public BahmniEncounterTransactionBuilder withDrugOrders(List drugOrders) { + bahmniEncounterTransaction.setDrugOrders(drugOrders); + return this; + } + + public BahmniEncounterTransaction build() { + return bahmniEncounterTransaction; + } + + public BahmniEncounterTransactionBuilder withPatientId(String patientId) { + bahmniEncounterTransaction.setPatientId(patientId); + return this; + } + + public BahmniEncounterTransactionBuilder withVisitType(String visitType) { + bahmniEncounterTransaction.setVisitType(visitType); + return this; + } + + public BahmniEncounterTransactionBuilder withEncounterUuid(String encounterUuid) { + bahmniEncounterTransaction.setEncounterUuid(encounterUuid); + return this; + } + + public BahmniEncounterTransactionBuilder withReason(String reason) { + bahmniEncounterTransaction.setReason(reason); + return this; + } + + public BahmniEncounterTransactionBuilder withDiagnoses(BahmniDiagnosisRequest... bahmniDiagnosisRequests){ + bahmniEncounterTransaction.setBahmniDiagnoses(Arrays.asList(bahmniDiagnosisRequests)); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniObservationBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniObservationBuilder.java new file mode 100644 index 0000000000..c23ab08680 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/BahmniObservationBuilder.java @@ -0,0 +1,64 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; + +public class BahmniObservationBuilder { + private BahmniObservation bahmniObservation = new BahmniObservation(); + + public BahmniObservationBuilder withConcept(EncounterTransaction.Concept concept) { + bahmniObservation.setConcept(concept); + return this; + } + + public BahmniObservationBuilder withConcept(String name, boolean isSet) { + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(); + concept.setName(name); + concept.setSet(isSet); + concept.setConceptClass("Misc"); + bahmniObservation.setConcept(concept); + return this; + } + + public BahmniObservationBuilder withValue(Object value) { + bahmniObservation.setValue(value); + return this; + } + + public BahmniObservationBuilder withOrderUuid(String orderUuid) { + bahmniObservation.setOrderUuid(orderUuid); + return this; + } + + public BahmniObservationBuilder withUuid(String uuid) { + bahmniObservation.setUuid(uuid); + return this; + } + + public BahmniObservationBuilder withObsDateTime(Date obsDateTime){ + bahmniObservation.setObservationDateTime(obsDateTime); + return this; + } + + public BahmniObservation build() { + return bahmniObservation; + } + + public BahmniObservationBuilder withGroupMember(BahmniObservation member) { + bahmniObservation.addGroupMember(member); + return this; + } + + public BahmniObservationBuilder withComment(String comment) { + bahmniObservation.setComment(comment); + return this; + } + + public BahmniObservationBuilder withTargetObsRelationship(ObsRelationship obsRelationship) { + bahmniObservation.setTargetObsRelation(obsRelationship); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ConceptBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ConceptBuilder.java new file mode 100644 index 0000000000..287203f6e7 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ConceptBuilder.java @@ -0,0 +1,119 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptName; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; + +import java.util.Arrays; +import java.util.Date; + +public class ConceptBuilder { + private final Concept concept; + + public ConceptBuilder() { + concept = new Concept(); + } + + public Concept build() { + return concept; + } + + public ConceptBuilder withName(String conceptName) { + ConceptName name = new ConceptName(conceptName, LocaleUtility.getDefaultLocale()); + name.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + concept.setPreferredName(name); + return this; + } + + public ConceptBuilder withDataType(String name) { + withDataType(name, "hl7Abbreviation", null); + return this; + } + + public ConceptBuilder withDataType(String name, String hl7Abbreviation) { + withDataType(name, hl7Abbreviation, null); + return this; + } + + public ConceptBuilder withUUID(String uuid) { + concept.setUuid(uuid); + return this; + } + + public ConceptBuilder withClass(String conceptClassName) { + ConceptClass conceptClass = concept.getConceptClass(); + if (conceptClass == null) { + conceptClass = new ConceptClass(); + } + conceptClass.setName(conceptClassName); + concept.setConceptClass(conceptClass); + return this; + } + + public ConceptBuilder withClassUUID(String uuid) { + ConceptClass conceptClass = concept.getConceptClass(); + if (conceptClass == null) { + conceptClass = new ConceptClass(); + } + conceptClass.setUuid(uuid); + concept.setConceptClass(conceptClass); + return this; + } + + + public ConceptBuilder withSetMember(Concept setMember) { + concept.addSetMember(setMember); + return this; + } + + public ConceptBuilder withDataTypeNumeric() { + withDataType("Numeric", ConceptDatatype.NUMERIC, ConceptDatatype.NUMERIC_UUID); + return this; + } + + public ConceptBuilder withCodedDataType() { + withDataType("Coded", ConceptDatatype.CODED, ConceptDatatype.CODED_UUID); + return this; + } + + public ConceptBuilder withDateCreated(Date dateCreated) { + concept.setDateCreated(dateCreated); + return this; + } + + public ConceptBuilder withDateChanged(Date dateChanged) { + concept.setDateChanged(dateChanged); + return this; + } + + public ConceptBuilder withRetired(Boolean retired) { + concept.setRetired(retired); + return this; + } + + public ConceptBuilder withShortName(String name) { + ConceptName conceptName = new ConceptName(name, Context.getLocale()); + concept.setShortName(conceptName); + return this; + } + + private ConceptBuilder withDataType(String name, String hl7Abbreviation, String uuid) { + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setHl7Abbreviation(hl7Abbreviation); + conceptDatatype.setName(name); + conceptDatatype.setUuid(uuid); + concept.setDatatype(conceptDatatype); + return this; + } + + public ConceptBuilder withDescription(String description) { + ConceptDescription conceptDescription = new ConceptDescription(description, Context.getLocale()); + concept.setDescriptions(Arrays.asList(conceptDescription)); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/DrugOrderBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/DrugOrderBuilder.java new file mode 100644 index 0000000000..569c9bff04 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/DrugOrderBuilder.java @@ -0,0 +1,44 @@ +/** + * 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.bahmniemrapi.builder; + +import org.openmrs.Drug; +import org.openmrs.DrugOrder; + +import java.util.UUID; + +public class DrugOrderBuilder { + private DrugOrder order; + + public DrugOrderBuilder() { + this.order = new DrugOrder(); + this.order.setUuid(UUID.randomUUID().toString()); + this.order.setDateCreated(null); + this.order.setDrug(new Drug(123)); + } + + public DrugOrderBuilder withUuid(UUID uuid) { + order.setUuid(String.valueOf(uuid)); + return this; + } + + public DrugOrderBuilder withId(Integer id) { + order.setId(id); + return this; + } + + public DrugOrder build() { + return order; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ETConceptBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ETConceptBuilder.java new file mode 100644 index 0000000000..5daf7106f0 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ETConceptBuilder.java @@ -0,0 +1,35 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +public class ETConceptBuilder { + private EncounterTransaction.Concept concept; + + public ETConceptBuilder() { + concept = new EncounterTransaction.Concept(); + } + + public EncounterTransaction.Concept build() { + return concept; + } + + public ETConceptBuilder withName(String name) { + concept.setName(name); + return this; + } + + public ETConceptBuilder withUuid(String uuid) { + concept.setUuid(uuid); + return this; + } + + public ETConceptBuilder withSet(boolean isSet) { + concept.setSet(isSet); + return this; + } + + public ETConceptBuilder withClass(String className) { + concept.setConceptClass(className); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/EncounterBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/EncounterBuilder.java new file mode 100644 index 0000000000..c1f5b54381 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/EncounterBuilder.java @@ -0,0 +1,105 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.EncounterType; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.VisitType; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public class EncounterBuilder { + private final Encounter encounter; + + public EncounterBuilder() { + encounter = new Encounter(); + Visit visit = new Visit(); + VisitType visitType = new VisitType(); + visitType.setUuid(UUID.randomUUID().toString()); + visit.setVisitType(visitType); + visit.setUuid(UUID.randomUUID().toString()); + encounter.setVisit(visit); + encounter.setUuid(UUID.randomUUID().toString()); + + Patient patient = new Patient(123456); + patient.setUuid(UUID.randomUUID().toString()); + encounter.setPatient(patient); + + EncounterType encounterType = new EncounterType(); + encounterType.setUuid(UUID.randomUUID().toString()); + encounter.setEncounterType(encounterType); + + Location location = new Location(); + location.setUuid(UUID.randomUUID().toString()); + encounter.setLocation(location); + } + + public Encounter build() { + return encounter; + } + + + public EncounterBuilder withVisit(Visit visit) { + encounter.setVisit(visit); + return this; + } + + public EncounterBuilder withPatient(Person person) { + encounter.setPatient(new Patient(person)); + return this; + } + + public EncounterBuilder withUUID(String uuid) { + encounter.setUuid(uuid); + return this; + } + + public EncounterBuilder withDateCreated(Date date) { + encounter.setDateCreated(date); + return this; + } + + public EncounterBuilder withLocation(Location location) { + encounter.setLocation(location); + return this; + } + + public EncounterBuilder withProvider(Person person) { + Provider provider = new Provider(); + provider.setPerson(person); + HashSet encounterProviders = new HashSet<>(); + EncounterProvider encounterProvider = new EncounterProvider(); + encounterProvider.setProvider(provider); + encounterProviders.add(encounterProvider); + encounter.setEncounterProviders(encounterProviders); + return this; + } + + public EncounterBuilder withEncounterType(EncounterType encounterType) { + encounter.setEncounterType(encounterType); + return this; + } + + public EncounterBuilder withDatetime(Date date) { + encounter.setEncounterDatetime(date); + return this; + } + + public EncounterBuilder withEncounterProviders(Set encounterProviders) { + encounter.setEncounterProviders(encounterProviders); + return this; + } + + public EncounterBuilder withCreator(User user) { + encounter.setCreator(user); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/LocationBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/LocationBuilder.java new file mode 100644 index 0000000000..0cddd5b6e6 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/LocationBuilder.java @@ -0,0 +1,27 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.Location; +import org.openmrs.LocationTag; +import org.openmrs.module.emrapi.EmrApiConstants; + +public class LocationBuilder { + private Location location; + + public LocationBuilder() { + this.location = new Location(); + } + + public LocationBuilder withVisitLocationTag() { + location.addTag(new LocationTag(EmrApiConstants.LOCATION_TAG_SUPPORTS_VISITS, "Visit Location")); + return this; + } + + public LocationBuilder withParent(Location parentLocation) { + location.setParentLocation(parentLocation); + return this; + } + + public Location build() { + return location; + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ObsBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ObsBuilder.java new file mode 100644 index 0000000000..f622f59ee1 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/ObsBuilder.java @@ -0,0 +1,82 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.User; +import org.openmrs.util.LocaleUtility; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; + +public class ObsBuilder { + + private final Obs obs; + + public ObsBuilder() { + obs = new Obs(); + } + + public ObsBuilder withPerson(Person person) { + obs.setPerson(person); + return this; + } + + public ObsBuilder withEncounter(Encounter encounter) { + obs.setEncounter(encounter); + return this; + } + + public ObsBuilder withConcept(Concept concept) { + obs.setConcept(concept); + return this; + } + + public ObsBuilder withValue(String value) { + obs.setValueText(value); + return this; + } + + public ObsBuilder withValue(Double value) { + obs.setValueNumeric(value); + return this; + } + + public ObsBuilder withValue(Concept value) { + obs.setValueCoded(value); + setValueCodedName(obs); + return this; + } + + private void setValueCodedName(Obs anObs) { + Concept concept = anObs.getConcept(); + if (concept != null) + anObs.setValueCodedName(concept.getName(LocaleUtility.getDefaultLocale())); + } + + public ObsBuilder withDatetime(Date datetime) { + obs.setObsDatetime(datetime); + return this; + } + + public ObsBuilder withGroupMembers(Obs... groupMember) { + obs.setGroupMembers(new HashSet<>(Arrays.asList(groupMember))); + return this; + } + + public ObsBuilder withCreator(User user){ + obs.setCreator(user); + return this; + } + + public ObsBuilder withVoided() { + obs.setVoided(true); + return this; + } + + public Obs build() { + return obs; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/PersonBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/PersonBuilder.java new file mode 100644 index 0000000000..317f769a4d --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/PersonBuilder.java @@ -0,0 +1,35 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.Person; +import org.openmrs.PersonName; + +import java.util.HashSet; +import java.util.Set; + +public class PersonBuilder { + + private final Person person; + + public PersonBuilder() { + person = new Person(); + } + + public PersonBuilder withUUID(String patientUuid) { + person.setUuid(patientUuid); + return this; + } + + public PersonBuilder withPersonName(String personNameValue) { + PersonName personName = new PersonName(); + personName.setGivenName(personNameValue); + personName.setId(2); + Set personNames = new HashSet<>(); + personNames.add(personName); + person.setNames(personNames); + return this; + } + + public Person build() { + return person; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/TestOrderBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/TestOrderBuilder.java new file mode 100644 index 0000000000..79a21198f7 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/TestOrderBuilder.java @@ -0,0 +1,44 @@ +/** + * 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.bahmniemrapi.builder; + +import org.openmrs.TestOrder; + +import java.util.Date; +import java.util.UUID; + +public class TestOrderBuilder { + private TestOrder order; + + public TestOrderBuilder() { + this.order = new TestOrder(); + this.order.setDateCreated(new Date()); + this.order.setUuid(UUID.randomUUID().toString()); + this.order.setDateCreated(new Date()); + } + + public TestOrderBuilder withUuid(UUID uuid) { + order.setUuid(String.valueOf(uuid)); + return this; + } + + public TestOrderBuilder withId(Integer id) { + order.setId(id); + return this; + } + + public TestOrder build() { + return order; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/VisitBuilder.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/VisitBuilder.java new file mode 100644 index 0000000000..81eb36106a --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/builder/VisitBuilder.java @@ -0,0 +1,50 @@ +package org.openmrs.module.bahmniemrapi.builder; + +import org.openmrs.Encounter; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Visit; + +import java.util.Date; +import java.util.HashSet; + +public class VisitBuilder { + + private final Visit visit; + + public VisitBuilder() { + visit = new Visit(); + } + + public VisitBuilder withPerson(Person person) { + visit.setPatient(new Patient(person)); + return this; + } + + public VisitBuilder withUUID(String uuid) { + visit.setUuid(uuid); + return this; + } + + public VisitBuilder withStartDatetime(Date startDatetime) { + visit.setStartDatetime(startDatetime); + return this; + } + + public VisitBuilder withLocation(Location location) { + visit.setLocation(location); + return this; + } + + public Visit build() { + return visit; + } + + public VisitBuilder withEncounter(Encounter encounter) { + HashSet encounters = new HashSet<>(); + encounters.add(encounter); + visit.setEncounters(encounters); + return this; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosisTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosisTest.java new file mode 100644 index 0000000000..77ea0f5e3b --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/contract/BahmniDiagnosisTest.java @@ -0,0 +1,92 @@ +package org.openmrs.module.bahmniemrapi.diagnosis.contract; + +import org.junit.Test; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class BahmniDiagnosisTest { + @Test + public void isSameReturnsTrueIfCodedAnswersAreSame() { + EncounterTransaction.Concept malariaDiagnosis = new EncounterTransaction.Concept("uuid", "Malaria"); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setCodedAnswer(malariaDiagnosis); + + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + diagnosis.setCodedAnswer(malariaDiagnosis); + + assertTrue("both diagnosis for malaria and are same", bahmniDiagnosis.isSame(diagnosis)); + } + + @Test + public void isSameReturnsFalseIfCodedAnswersAreNotSame() { + EncounterTransaction.Concept malariaDiagnosis = new EncounterTransaction.Concept("uuid1", "Malaria"); + EncounterTransaction.Concept tbDiagnosis = new EncounterTransaction.Concept("uuid2", "TB"); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setCodedAnswer(malariaDiagnosis); + + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + diagnosis.setCodedAnswer(tbDiagnosis); + + assertFalse("diagnoses are not same", bahmniDiagnosis.isSame(diagnosis)); + } + + @Test + public void isSameReturnsTrueIfFreeTextAnswersAreSame() { + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setFreeTextAnswer("Malaria"); + + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + diagnosis.setFreeTextAnswer("Malaria"); + + assertTrue("both diagnosis for malaria and are same", bahmniDiagnosis.isSame(diagnosis)); + } + + @Test + public void isSameReturnsFalseIfFreeTextAnswersAreNotSame() { + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setFreeTextAnswer("Malaria"); + + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + diagnosis.setFreeTextAnswer("TB"); + + assertFalse("diagnoses are not same", bahmniDiagnosis.isSame(diagnosis)); + } + + @Test + public void isSameReturnsFalseWhenCodedAnswerIsNull() { + EncounterTransaction.Concept malariaDiagnosis = new EncounterTransaction.Concept("uuid", "Malaria"); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setCodedAnswer(malariaDiagnosis); + + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + diagnosis.setFreeTextAnswer("Malaria"); + + assertFalse("diagnoses are not same", bahmniDiagnosis.isSame(diagnosis)); + } + + @Test + public void isSameReturnsFalseWhenFreeTextAnswerIsNull() { + EncounterTransaction.Concept malariaDiagnosis = new EncounterTransaction.Concept("uuid", "Malaria"); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setFreeTextAnswer("Malaria"); + + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + diagnosis.setCodedAnswer(malariaDiagnosis); + + assertFalse("diagnoses are not same", bahmniDiagnosis.isSame(diagnosis)); + } + + @Test + public void isSameReturnsFalseWhenBothAreNull() { + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + EncounterTransaction.Diagnosis diagnosis = new EncounterTransaction.Diagnosis(); + + assertFalse("diagnoses are not same", bahmniDiagnosis.isSame(diagnosis)); + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java new file mode 100644 index 0000000000..ed831ba371 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/diagnosis/helper/BahmniDiagnosisMetadataTest.java @@ -0,0 +1,307 @@ +package org.openmrs.module.bahmniemrapi.diagnosis.helper; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.PersonName; +import org.openmrs.User; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.builder.ConceptBuilder; +import org.openmrs.module.bahmniemrapi.builder.ObsBuilder; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.emrapi.EmrApiProperties; +import org.openmrs.module.emrapi.encounter.EncounterTransactionMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@PrepareForTest({Context.class,LocaleUtility.class}) +@RunWith(PowerMockRunner.class) +public class BahmniDiagnosisMetadataTest { + @Mock + private ObsService obsService; + @Mock + private ConceptService conceptService; + @Mock + private EncounterTransactionMapper eTMapper; + + @Mock(answer= Answers.RETURNS_DEEP_STUBS) + private EmrApiProperties properties; + public static final String BOOLEAN_UUID = "8d4a5cca-c2cc-11de-8d13-0010c6dffd0f"; + private static final String BAHMNI_DIAGNOSIS_STATUS = "Bahmni Diagnosis Status"; + private static final String BAHMNI_DIAGNOSIS_REVISED = "Bahmni Diagnosis Revised"; + private static final String BAHMNI_INITIAL_DIAGNOSIS = "Bahmni Initial Diagnosis"; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mockStatic(LocaleUtility.class); + mockStatic(Context.class); + PowerMockito.when(Context.getLocale()).thenReturn(Locale.ENGLISH); + PowerMockito.when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + PowerMockito.when(Context.getConceptService()).thenReturn(conceptService); + + } + + + @Test + public void shouldMatchCodedDiagnosis() { + Concept diagnosisSetConcept = conceptForName("Diagnosis Concept Set"); + Concept codedDiagnosisConcept = conceptForName("Coded Diagnosis"); + when(properties.getDiagnosisMetadata().getDiagnosisSetConcept()).thenReturn(diagnosisSetConcept); + when(properties.getDiagnosisMetadata().getCodedDiagnosisConcept()).thenReturn(codedDiagnosisConcept); + Concept feverConcept = conceptForName("Fever"); + Obs diagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(feverConcept).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + Obs anotherDiagnosis = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(conceptForName("Another diagnosis")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + + Obs randomObs = new ObsBuilder().withConcept(conceptForName("Random Concept")).withValue("Hello World").build(); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setCodedAnswer(new EncounterTransaction.Concept(feverConcept.getUuid(), feverConcept.getName + ().getName(), false)); + + BahmniDiagnosisMetadata bahmniDiagnosisMetadata = new BahmniDiagnosisMetadata(obsService, conceptService, properties, null); + Obs matchingDiagnosis = bahmniDiagnosisMetadata.findMatchingDiagnosis(Arrays.asList(diagnosisObs, + anotherDiagnosis, + randomObs), bahmniDiagnosis); + assertThat(matchingDiagnosis, is(sameInstance(diagnosisObs))); + + } + + @Test + public void shouldMatchNonCodedDiagnosis() { + Concept diagnosisSetConcept = conceptForName("Diagnosis Concept Set"); + Concept codedDiagnosisConcept = conceptForName("Coded Diagnosis"); + Concept nonCodedDiagnosisConcept = conceptForName("Non Coded Diagnosis"); + when(properties.getDiagnosisMetadata().getDiagnosisSetConcept()).thenReturn(diagnosisSetConcept); + when(properties.getDiagnosisMetadata().getCodedDiagnosisConcept()).thenReturn(codedDiagnosisConcept); + when(properties.getDiagnosisMetadata().getNonCodedDiagnosisConcept()).thenReturn(nonCodedDiagnosisConcept); + Obs codedDiagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(conceptForName("Fever")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + Obs nonCodedDiagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(nonCodedDiagnosisConcept) + .withValue("Free text diagnosis").build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + + Obs randomObs = new ObsBuilder().withConcept(conceptForName("Random Concept")).withValue("Hello World").build(); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setFreeTextAnswer("Free text diagnosis"); + + BahmniDiagnosisMetadata bahmniDiagnosisMetadata = new BahmniDiagnosisMetadata(obsService, conceptService, properties, null); + Obs matchingDiagnosis = bahmniDiagnosisMetadata.findMatchingDiagnosis(Arrays.asList(codedDiagnosisObs, + nonCodedDiagnosisObs, + randomObs), bahmniDiagnosis); + assertThat(matchingDiagnosis, is(sameInstance(nonCodedDiagnosisObs))); + + } + + @Rule + public ExpectedException thrown= ExpectedException.none(); + + @Test + public void shouldThrowExceptionWhenMoreThanOneMatchingDiagnosisFound() { + Concept diagnosisSetConcept = conceptForName("Diagnosis Concept Set"); + Concept codedDiagnosisConcept = conceptForName("Coded Diagnosis"); + Concept nonCodedDiagnosisConcept = conceptForName("Non Coded Diagnosis"); + when(properties.getDiagnosisMetadata().getDiagnosisSetConcept()).thenReturn(diagnosisSetConcept); + when(properties.getDiagnosisMetadata().getCodedDiagnosisConcept()).thenReturn(codedDiagnosisConcept); + when(properties.getDiagnosisMetadata().getNonCodedDiagnosisConcept()).thenReturn(nonCodedDiagnosisConcept); + Concept feverConcept = conceptForName("Fever"); + Obs aCodedDiagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(feverConcept).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + Obs anotherCodedDiagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(feverConcept).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + Obs randomObs = new ObsBuilder().withConcept(conceptForName("Random Concept")).withValue("Hello World").build(); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setCodedAnswer(new EncounterTransaction.Concept(feverConcept.getUuid(), feverConcept.getName + ().getName(), false)); + + BahmniDiagnosisMetadata bahmniDiagnosisMetadata = new BahmniDiagnosisMetadata(obsService, conceptService, properties, null); + + thrown.expect(RuntimeException.class); + thrown.expectMessage("The same diagnosis cannot be saved more than once"); + bahmniDiagnosisMetadata.findMatchingDiagnosis( + Arrays.asList(aCodedDiagnosisObs, anotherCodedDiagnosisObs, randomObs), bahmniDiagnosis); + } + + @Test + public void shouldNotConsiderRevisedObsWhileFindingMatchingObs() throws Exception { + Concept diagnosisSetConcept = conceptForName("Diagnosis Concept Set"); + Concept codedDiagnosisConcept = conceptForName("Coded Diagnosis"); + Concept nonCodedDiagnosisConcept = conceptForName("Non Coded Diagnosis"); + Concept conceptTrue = conceptForName("TRUE"); + Concept revised = conceptForName("Revised"); + when(properties.getDiagnosisMetadata().getDiagnosisSetConcept()).thenReturn(diagnosisSetConcept); + when(properties.getDiagnosisMetadata().getCodedDiagnosisConcept()).thenReturn(codedDiagnosisConcept); + when(properties.getDiagnosisMetadata().getNonCodedDiagnosisConcept()).thenReturn(nonCodedDiagnosisConcept); + when(conceptService.getTrueConcept()).thenReturn(conceptTrue); + when(conceptService.getConceptsByName(BAHMNI_DIAGNOSIS_REVISED,Locale.ENGLISH,false)).thenReturn(Arrays.asList(revised)); + Concept feverConcept = conceptForName("Fever"); + Obs aCodedDiagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(feverConcept).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build(), + new ObsBuilder().withConcept(revised) + .withValue(conceptTrue).build()).build(); + Obs anotherCodedDiagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + new ObsBuilder().withConcept(codedDiagnosisConcept) + .withValue(feverConcept).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build() + ).build(); + Obs randomObs = new ObsBuilder().withConcept(conceptForName("Random Concept")).withValue("Hello World").build(); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setCodedAnswer(new EncounterTransaction.Concept(feverConcept.getUuid(), feverConcept.getName + ().getName(), false)); + + BahmniDiagnosisMetadata bahmniDiagnosisMetadata = new BahmniDiagnosisMetadata(obsService, conceptService, properties, null); + Obs matchingDiagnosis = bahmniDiagnosisMetadata.findMatchingDiagnosis( + Arrays.asList(aCodedDiagnosisObs, anotherCodedDiagnosisObs, randomObs), bahmniDiagnosis); + assertNotNull(matchingDiagnosis); + } + + @Test + public void shouldUpdateInitialDiagnosisAsCurrentDiagnosisWhenInitialDiagnosisIsVoided() throws Exception { + Concept initialDiagnosisConcept = conceptForName(BAHMNI_INITIAL_DIAGNOSIS); + String initialDiagnosisUuid = "initial-obs-uuid"; + String existingObsUuid = "existing-obs-uuid"; + Obs initialDiagnosisObs = new ObsBuilder(). + withConcept(conceptForName("Dehydration")).withVoided().build(); + Concept diagnosisSetConcept = conceptForName("Diagnosis Concept Set"); + Concept revised = conceptForName(BAHMNI_DIAGNOSIS_REVISED); + Concept falseConcept = conceptForName("FALSE"); + when(conceptService.getConceptByName(BAHMNI_DIAGNOSIS_REVISED)).thenReturn(revised); + when(conceptService.getFalseConcept()).thenReturn(falseConcept); + when(conceptService.getConceptByName(BAHMNI_INITIAL_DIAGNOSIS)).thenReturn(initialDiagnosisConcept); + when(obsService.getObsByUuid(initialDiagnosisUuid)).thenReturn(initialDiagnosisObs); + EncounterTransaction encounterTransaction = new EncounterTransaction(); + encounterTransaction.addDiagnosis(new EncounterTransaction.Diagnosis().setExistingObs(existingObsUuid)); + when(eTMapper.map(Matchers.any(Encounter.class),eq(false))).thenReturn(encounterTransaction); + Obs diagnosisObs = + new ObsBuilder().withConcept(diagnosisSetConcept) + .withGroupMembers( + + new ObsBuilder().withConcept(conceptForName("Diagnosis Order")) + .withValue(conceptForName("Primary")).build(), + new ObsBuilder().withConcept(conceptForName("Diagnosis Certainty")) + .withValue(conceptForName("Confirmed")).build(), + new ObsBuilder().withConcept(initialDiagnosisConcept) + .withValue(initialDiagnosisUuid).build(), + new ObsBuilder().withConcept(revised) + .withValue(falseConcept).build()) + .withEncounter(new Encounter()) + .withCreator(createUser("Ram")).build(); + diagnosisObs.setUuid(existingObsUuid); + when(obsService.getObsByUuid(existingObsUuid)).thenReturn(diagnosisObs); + + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setExistingObs(existingObsUuid); + BahmniDiagnosisMetadata bahmniDiagnosisMetadata = new BahmniDiagnosisMetadata(obsService, conceptService, properties, eTMapper); + BahmniDiagnosisRequest bahmniDiagnosisRequest = bahmniDiagnosisMetadata.mapBahmniDiagnosis(bahmniDiagnosis, null, true, false, true, true); + + ArgumentCaptor obsArgumentCaptor = ArgumentCaptor.forClass(Obs.class); + verify(obsService).saveObs(obsArgumentCaptor.capture(), eq("Initial obs got voided")); + Obs obs = obsArgumentCaptor.getValue(); + assertThat(obs.getValueText(),is(existingObsUuid)); + assertThat(bahmniDiagnosisRequest.getFirstDiagnosis().getExistingObs(),is(existingObsUuid)); + } + + public Concept conceptForName(String conceptName) { + return new ConceptBuilder().withName(conceptName).build(); + } + + private User createUser(String name){ + Person person = new Person(); + person.addName(new PersonName(name,null,null)); + return new User(person); + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/disposition/mapper/BahmniDispositionMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/disposition/mapper/BahmniDispositionMapperTest.java new file mode 100644 index 0000000000..af9073e254 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/disposition/mapper/BahmniDispositionMapperTest.java @@ -0,0 +1,95 @@ +package org.openmrs.module.bahmniemrapi.disposition.mapper; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.*; +import org.openmrs.api.ConceptService; +import org.openmrs.Person; +import org.openmrs.PersonName; +import org.openmrs.User; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.Locale; + +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniDispositionMapperTest { + + private BahmniDispositionMapper bahmniDispositionMapper; + @Mock + private ConceptService conceptService; + @Mock + private EncounterTransaction.Disposition mockDisposition; + @Mock + private Concept dispositionConcept; + @Mock + private ConceptName conceptName; + + @Before + public void setUp(){ + initMocks(this); + + Locale locale = new Locale("en"); + String conceptNameString = "Absconding"; + when(conceptService.getConcept(conceptNameString)).thenReturn(dispositionConcept); + when(dispositionConcept.getPreferredName(locale)).thenReturn(conceptName); + when(conceptName.getName()).thenReturn(conceptNameString); + bahmniDispositionMapper = new BahmniDispositionMapper(conceptService); + } + + @Test + public void ensureBahmniDispositionIsPopulated(){ + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setName("Sample Provider"); + provider.setUuid("1234Uuid"); + + Set providers = new HashSet(); + providers.add(provider); + + Date dispositionDate = new Date(); + + EncounterTransaction.Disposition disposition= new EncounterTransaction.Disposition(); + disposition.setCode("1234") + .setExistingObs("a26a8c32-6fc1-4f5e-8a96-f5f5b05b87d") + .setVoided(false) + .setVoidReason(null) + .setDispositionDateTime(dispositionDate); + + disposition.setConceptName("Absconding"); + disposition.setAdditionalObs(new ArrayList()); + + + Person person = new Person(); + PersonName personName = new PersonName(); + personName.setGivenName("testPersonName"); + Set personNames = new HashSet<>(); + personNames.add(personName); + person.setNames(personNames); + User user = new User(person); + + + BahmniDisposition bahmniDisposition = bahmniDispositionMapper.map(disposition, providers, user , new Locale("en")); + + Assert.assertEquals("1234",bahmniDisposition.getCode()); + Assert.assertEquals("a26a8c32-6fc1-4f5e-8a96-f5f5b05b87d",bahmniDisposition.getExistingObs()); + Assert.assertFalse(bahmniDisposition.isVoided()); + Assert.assertNull(bahmniDisposition.getVoidReason()); + Assert.assertEquals(dispositionDate,bahmniDisposition.getDispositionDateTime()); + Assert.assertEquals("Absconding", bahmniDisposition.getConceptName()); + Assert.assertEquals(0, bahmniDisposition.getAdditionalObs().size()); + + EncounterTransaction.Provider actualProvider = bahmniDisposition.getProviders().iterator().next(); + Assert.assertEquals("Sample Provider", actualProvider.getName()); + Assert.assertEquals("1234Uuid", actualProvider.getUuid()); + + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionServiceTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionServiceTest.java new file mode 100644 index 0000000000..dae21d3675 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/disposition/service/BahmniDispositionServiceTest.java @@ -0,0 +1,192 @@ +package org.openmrs.module.bahmniemrapi.disposition.service; + +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.EncounterBuilder; +import org.bahmni.test.builder.ObsBuilder; +import org.bahmni.test.builder.VisitBuilder; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; +import org.openmrs.module.bahmniemrapi.disposition.mapper.BahmniDispositionMapper; +import org.openmrs.module.emrapi.encounter.DispositionMapper; +import org.openmrs.module.emrapi.encounter.EncounterProviderMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.matcher.ObservationTypeMatcher; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Locale; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +public class BahmniDispositionServiceTest { + + @Mock + private VisitService visitService; + + @Mock + private DispositionMapper dispositionMapper; + + @Mock + private ObservationTypeMatcher observationTypeMatcher; + + private Visit visit; + + private BahmniDispositionService bahmniDispositionService; + + @Mock + private EncounterProviderMapper encounterProviderMapper; + + @Mock + private BahmniDispositionMapper bahmniDispositionMapper; + + + private Obs height = null; + + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + Concept heightConcept = new ConceptBuilder().withName("HEIGHT").build(); + height = new ObsBuilder().withConcept(heightConcept).withValue(150.9).build(); + + Set allObs = new HashSet<>(); + allObs.add(height); + + Encounter encounter = new EncounterBuilder().build(); + encounter.setObs(allObs); + + visit = new VisitBuilder().withEncounter(encounter).build(); + + bahmniDispositionService = new BahmniDispositionServiceImpl(visitService, dispositionMapper, observationTypeMatcher, + encounterProviderMapper, bahmniDispositionMapper); + + } + + @Test + public void shouldReturnEmptyDispositionListWhenVisitNotAvailable() { + when(visitService.getVisitByUuid("visitUuid")).thenReturn(null); + List actualDispositions = bahmniDispositionService.getDispositionByVisitUuid("visitUuid"); + + Assert.assertNotNull(actualDispositions); + assertEquals(0, actualDispositions.size()); + } + + @Test + public void shouldReturnDispositionsWhenVisitIsValid() { + + Set eTProvider = new HashSet<>(); + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setName("Sample"); + provider.setUuid("uuid"); + eTProvider.add(provider); + + EncounterTransaction.Disposition eTDisposition = new EncounterTransaction.Disposition(); + eTDisposition.setCode("1234") + .setExistingObs("a26a8c32-6fc1-4f5e-8a96-f5f5b05b87d") + .setVoided(false) + .setVoidReason(null) + .setDispositionDateTime(new Date()); + + eTDisposition.setConceptName("Absconding"); + eTDisposition.setAdditionalObs(new ArrayList()); + + BahmniDisposition bahmniDisposition = new BahmniDisposition(); + bahmniDisposition.setCode("1234"); + + when(visitService.getVisitByUuid("visitUuid")).thenReturn(visit); + when(encounterProviderMapper.convert(new HashSet())).thenReturn(eTProvider); + when(observationTypeMatcher.getObservationType(height)).thenReturn(ObservationTypeMatcher.ObservationType.DISPOSITION); + when(dispositionMapper.getDisposition(height)).thenReturn(eTDisposition); + when(bahmniDispositionMapper.map(eTDisposition, eTProvider, null ,new Locale("en"))).thenReturn(bahmniDisposition); + + List actualDispositions = bahmniDispositionService.getDispositionByVisitUuid("visitUuid"); + + assertEquals(1, actualDispositions.size()); + assertEquals(bahmniDisposition, actualDispositions.get(0)); + + } + + @Test + public void shouldReturnEmptyDispositionListWhenNoneOfObservationsAreDispositions() { + Set eTProvider = new HashSet<>(); + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setName("Sample"); + provider.setUuid("uuid"); + eTProvider.add(provider); + + when(visitService.getVisitByUuid("visitUuid")).thenReturn(visit); + when(encounterProviderMapper.convert(new HashSet())).thenReturn(eTProvider); + when(observationTypeMatcher.getObservationType(height)).thenReturn(ObservationTypeMatcher.ObservationType.DIAGNOSIS); + + List actualDispositions = bahmniDispositionService.getDispositionByVisitUuid("visitUuid"); + + assertEquals(0, actualDispositions.size()); + } + + @Test + public void shouldReturnEmptyDispositionListWhenObservationsAreVoided() { + Set eTProvider = new HashSet<>(); + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setName("Sample"); + provider.setUuid("uuid"); + eTProvider.add(provider); + + when(visitService.getVisitByUuid("visitUuid")).thenReturn(visit); + when(encounterProviderMapper.convert(new HashSet())).thenReturn(eTProvider); + when(observationTypeMatcher.getObservationType(height)).thenReturn(ObservationTypeMatcher.ObservationType.DISPOSITION); + when(dispositionMapper.getDisposition(height)).thenReturn(null); + + + List actualDispositions = bahmniDispositionService.getDispositionByVisitUuid("visitUuid", new Locale("en")); + + assertEquals(0, actualDispositions.size()); + } + + @Test + public void shouldReturnDispositionForMultipleVisits() { + Set eTProvider = new HashSet<>(); + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setName("Sample"); + provider.setUuid("uuid"); + eTProvider.add(provider); + + EncounterTransaction.Disposition eTDisposition = new EncounterTransaction.Disposition(); + eTDisposition.setCode("1234") + .setExistingObs("a26a8c32-6fc1-4f5e-8a96-f5f5b05b87d") + .setVoided(false) + .setVoidReason(null) + .setDispositionDateTime(new Date()); + + eTDisposition.setConceptName("Absconding"); + eTDisposition.setAdditionalObs(new ArrayList()); + + BahmniDisposition bahmniDisposition = new BahmniDisposition(); + bahmniDisposition.setCode("1234"); + + + when(encounterProviderMapper.convert(new HashSet())).thenReturn(eTProvider); + when(observationTypeMatcher.getObservationType(height)).thenReturn(ObservationTypeMatcher.ObservationType.DISPOSITION); + when(dispositionMapper.getDisposition(height)).thenReturn(eTDisposition); + when(bahmniDispositionMapper.map(eTDisposition, eTProvider, null , new Locale("en"))).thenReturn(bahmniDisposition); + + List actualDispositions = bahmniDispositionService.getDispositionByVisits(Arrays.asList(visit)); + + assertEquals(1, actualDispositions.size()); + assertEquals(bahmniDisposition, actualDispositions.get(0)); + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImplIT.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImplIT.java new file mode 100644 index 0000000000..1ed7c69c27 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/document/service/impl/VisitDocumentServiceImplIT.java @@ -0,0 +1,551 @@ +package org.openmrs.module.bahmniemrapi.document.service.impl; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ObsService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.BaseIntegrationTest; +import org.openmrs.module.bahmniemrapi.document.contract.Document; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentRequest; +import org.openmrs.module.bahmniemrapi.document.service.VisitDocumentService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Set; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class VisitDocumentServiceImplIT extends BaseIntegrationTest { + + public static final String FIRST_LOCATION_UUID = "8d6c993e-c2cc-11de-8d13-0040c6dffd0f"; + private static final String patientUUID = "86526ed5-3c11-11de-a0ba-001e378eb67a"; + private final String firstVisitUuid = "ad41fb41-a41a-4ad6-8835-2f59099acf5a"; + private final String secondVisitUuid = "d794516f-210d-4c4e-8978-467d97969f31"; + private final String visitTypeUUID = "f01c54cb-2225-471a-9cd5-d348552c337c"; + private final String firstEncounterTypeUUID = "759799ab-c9a5-435e-b671-77773ada74e4"; + private final String secondEncounterTypeUUID = "4ee21921-01cc-4720-a6bf-a61a17c4d05b"; + private final String firstProviderUuid = "331c6bf8-7846-11e3-a96a-0800271c1b75"; + private final String secondProviderUuid = "331c6bf8-7846-11e3-a96a-0800271c1333"; + private final String secondLocationUuid = "899c993e-c2cc-11de-8d13-0040c6dffd0f"; + private final String firstEncounterUuid = "6d0ae386-707a-4629-9850-f15206e63ab0"; + private final String secondEncounterUuid = "6d0ae386-707a-4629-9850-f15206e63222"; + private final String conceptUuid = "4f596de5-5caa-11e3-a4c0-0800271c1b75"; + + @Autowired + private VisitDocumentService visitDocumentService; + @Autowired + private EncounterService encounterService; + @Autowired + private ObsService obsService; + @Autowired + private VisitService visitService; + @Autowired + private ConceptService conceptService; + @Autowired + private ObsRelationService obsRelationService; + + private VisitDocumentRequest visitDocumentRequest; + + @Before + public void setUp() throws Exception { + executeDataSet("visitDocumentData.xml"); + } + + @Test + public void shouldDeleteObservationsOfPreviousEncounters() throws ParseException { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + + List documents = new ArrayList<>(); + String testUuid = "3f596de5-5caa-11e3-a4c0-0800271c1b75"; + String obsUuid = "6d0ae386-707a-4629-9850-f15206e63j8s"; + String providerUuid = "331c6bf8-7846-11e3-a96a-0800271c1b75"; + documents.add(new Document("/patient_file", null, testUuid, obsUuid, encounterDate, true)); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + firstEncounterTypeUUID, + encounterDate, + documents, + providerUuid, null, null); + visitDocumentService.upload(visitDocumentRequest); + + Context.flushSession(); + Context.clearSession(); + + Encounter encounter = encounterService.getEncounterByUuid(firstEncounterUuid); + for (Obs obs : encounter.getAllObs(true)) { + if (obs.getUuid().equals(obsUuid)) { + assertThat(obs.getVoided(), is(true)); + assertThat(obs.getGroupMembers(true).iterator().next().getVoided(), is(true)); + } + } + } + + @Test + public void shouldNotChangeObservationsIfSameDetailsProvidedOnceAgain() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/foo.jpg", null, conceptUuid, "6d0ae386-707a-4629-9850-f15206e63kj0", encounterDate, false)); + + + VisitDocumentRequest visitDocumentRequest = new VisitDocumentRequest(patientUUID, + firstVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + secondProviderUuid, secondLocationUuid, null); + visitDocumentService.upload(visitDocumentRequest); + + Context.flushSession(); + Context.clearSession(); + + Encounter encounter = encounterService.getEncounterByUuid(secondEncounterUuid); + + Obs savedDoc = getSavedDocument(encounter.getAllObs(), conceptUuid); + + assertNotNull(savedDoc); + Set groupMembers = savedDoc.getGroupMembers(); + assertThat(groupMembers.size(), is(equalTo(1))); + assertThat(groupMembers.iterator().next().getValueText(), is("/radiology/foo.jpg")); + assertThat(groupMembers.iterator().next().getUuid(), is("6d0ae386-707a-4629-9850-f15606e63666")); + } + + @Test + public void shouldPreferVoidOverUpdateWhenEditingADocument() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + + List documents = new ArrayList<>(); + String obsUuid = "6d0ae386-707a-4629-9850-f15206e63kj0"; + documents.add(new Document("/radiology/foo.jpg", null, "3f596de5-5caa-11e3-a4c0-0800271c1b75", obsUuid, encounterDate, true)); + + + VisitDocumentRequest visitDocumentRequest = new VisitDocumentRequest(patientUUID, + firstVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + secondProviderUuid, secondLocationUuid,null); + visitDocumentService.upload(visitDocumentRequest); + + Context.flushSession(); + Context.clearSession(); + + Encounter encounter = encounterService.getEncounterByUuid(secondEncounterUuid); + + Obs savedObs = obsService.getObsByUuid(obsUuid); + assertTrue("Observation is not voided", savedObs.getVoided()); + assertTrue("Observation is not voided", savedObs.getGroupMembers(true).iterator().next().getVoided()); + + + Obs savedDoc = getSavedDocument(encounter.getAllObs(), "3f596de5-5caa-11e3-a4c0-0800271c1b75"); + + assertNull(savedDoc); + } + + @Test + public void shouldChangeObservationsOfPreviousEncounters() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/foo.jpg", null, "5f596de5-5caa-11e3-a4c0-0800271c1b75", + "6d0ae386-707a-4629-9850-f15206e63kj0", encounterDate, false)); + + + VisitDocumentRequest visitDocumentRequest = new VisitDocumentRequest(patientUUID, + firstVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + secondProviderUuid, secondLocationUuid, null); + executeDataSet("visitDocumentData.xml"); + visitDocumentService.upload(visitDocumentRequest); + + Context.flushSession(); + Context.clearSession(); + + Encounter encounter = encounterService.getEncounterByUuid(secondEncounterUuid); + for (Obs obs : encounter.getAllObs(true)) { + if (obs.getUuid().equals("6d0ae386-707a-4629-9850-f15606e63666") || + obs.getUuid().equals("6d0ae386-707a-4629-9850-f15206e63kj0")) { + assertThat(obs.getVoided(), is(true)); + } + } + + Obs savedDoc = getSavedDocument(encounter.getAllObs(), "5f596de5-5caa-11e3-a4c0-0800271c1b75"); + + assertNotNull(savedDoc); + assertThat(savedDoc.getConcept().getId(), is(333)); + assertThat(savedDoc.getGroupMembers().iterator().next().getValueText(), is("/radiology/foo.jpg")); + assertEquals(FIRST_LOCATION_UUID, encounter.getLocation().getUuid()); + } + + @Test + public void shouldCreateObservations() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + Date obsDate = getDateFromString("2014-06-24 00:10:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, null, obsDate, false)); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + firstEncounterTypeUUID, + encounterDate, + documents, + firstProviderUuid, FIRST_LOCATION_UUID, null); + + visitDocumentService.upload(visitDocumentRequest); + + Context.flushSession(); + Context.clearSession(); + + Encounter encounter = encounterService.getEncounterByUuid(firstEncounterUuid); + + Obs savedDoc = getSavedDocument(encounter.getAllObs(), conceptUuid); + + assertNotNull(savedDoc); + assertThat(savedDoc.getConcept().getId(), is(222)); + assertThat(savedDoc.getGroupMembers().iterator().next().getValueText(), is("/radiology/fooo-bar.jpg")); + assertEquals(FIRST_LOCATION_UUID, encounter.getLocation().getUuid()); + } + + @Test + public void shouldUploadImagesInOrderOfRequest() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + Date obsDate = getDateFromString("2014-06-24 00:10:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/1.jpg", null, conceptUuid, null, obsDate, false)); + documents.add(new Document("/radiology/2.jpg", null, conceptUuid, null, obsDate, false)); + documents.add(new Document("/radiology/3.jpg", null, conceptUuid, null, obsDate, false)); + documents.add(new Document("/radiology/4.jpg", null, conceptUuid, null, obsDate, false)); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + firstEncounterTypeUUID, + encounterDate, + documents, + firstProviderUuid, FIRST_LOCATION_UUID, null); + visitDocumentService.upload(visitDocumentRequest); + + Context.flushSession(); + Context.clearSession(); + + Encounter encounter = encounterService.getEncounterByUuid(firstEncounterUuid); + List savedDocuments = getSavedDocuments(encounter.getAllObs(), conceptUuid); + assertEquals(4, savedDocuments.size()); + assertEquals("/radiology/1.jpg", getImageName(savedDocuments.get(0))); + assertEquals("/radiology/2.jpg", getImageName(savedDocuments.get(1))); + assertEquals("/radiology/3.jpg", getImageName(savedDocuments.get(2))); + assertEquals("/radiology/4.jpg", getImageName(savedDocuments.get(3))); + } + + private String getImageName(Obs obs) { + Set groupMembers = obs.getGroupMembers(); + return groupMembers.iterator().hasNext()?groupMembers.iterator().next().getValueText():null; + } + + @Test + public void shouldUseVisitStartTimeAsEncounterDateTimeForPreviousVisits() throws Exception { + Date visitStartDate = getDateFromString("2010-09-22 00:00:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/foo-lalala.jpg", null, "3f596de5-5caa-11e3-a4c0-0800271c1b75", null, null, false)); + + + VisitDocumentRequest visitDocumentRequest = new VisitDocumentRequest(patientUUID, + firstVisitUuid, + visitTypeUUID, + null, + null, + firstEncounterTypeUUID, + null, + documents, + secondProviderUuid, null, null); + executeDataSet("visitDocumentData.xml"); + +// Date currentDate = new Date(System.currentTimeMillis() - 1000); + visitDocumentService.upload(visitDocumentRequest); + Context.flushSession(); + Context.clearSession(); + + Visit visit = visitService.getVisit(1); + Set encounters = visit.getEncounters(); + Encounter encounter = getEncounterByTypeUuid(encounters, firstEncounterTypeUUID); + boolean condition = encounter.getEncounterDatetime().compareTo(visitStartDate) >= 0; + assertTrue(condition); + + Set allObs = encounter.getAllObs(); + Obs savedDocument = getSavedDocument(allObs, "3f596de5-5caa-11e3-a4c0-0800271c1b75"); + assertTrue(savedDocument.getObsDatetime().compareTo(visitStartDate) == 0); + } + + @Test + public void shouldUseNewDateAsEncounterDateTimeForActiveVisits() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + Date obsDate = getDateFromString("2014-06-24 00:10:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, null, obsDate, false)); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + firstProviderUuid, null, null); + + Date currentDate = new Date(System.currentTimeMillis() - 1000); + visitDocumentService.upload(visitDocumentRequest); + Context.flushSession(); + Context.clearSession(); + + Visit visit = visitService.getVisit(2); + Set encounters = visit.getEncounters(); + Encounter encounter = getEncounterByTypeUuid(encounters, secondEncounterTypeUUID); + boolean condition = encounter.getEncounterDatetime().compareTo(currentDate) >= 0; + assertTrue(condition); + + Set allObs = encounter.getAllObs(); + Obs savedDocument = getSavedDocument(allObs, conceptUuid); + assertTrue(savedDocument.getObsDatetime().compareTo(currentDate) >= 0); + } + + @Test + public void shouldAddCommentsToObservationIfDocumentContainsComments() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + Date obsDate = getDateFromString("2014-06-24 00:10:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, null, obsDate, false, "something went wrong")); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + firstProviderUuid, null, null); + + Date currentDate = new Date(System.currentTimeMillis() - 1000); + visitDocumentService.upload(visitDocumentRequest); + Visit visit = visitService.getVisit(2); + Set encounters = visit.getEncounters(); + Encounter encounter = getEncounterByTypeUuid(encounters, secondEncounterTypeUUID); + boolean condition = encounter.getEncounterDatetime().compareTo(currentDate) >= 0; + assertTrue(condition); + + Set allObs = encounter.getAllObs(); + Obs savedDocument = getSavedDocument(allObs, conceptUuid); + assertEquals("something went wrong", savedDocument.getGroupMembers().iterator().next().getComment()); + } + + @Test + public void shouldUpdateTheCommentsOnTheObservationIfDocumentContainsCommentsAndSavedObservationDoesntHaveComments() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + Date obsDate = getDateFromString("2014-06-24 00:10:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, null, obsDate, false)); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + firstProviderUuid, null, null); + + visitDocumentService.upload(visitDocumentRequest); + Visit visit = visitService.getVisit(2); + Set encounters = visit.getEncounters(); + Encounter encounter = getEncounterByTypeUuid(encounters, secondEncounterTypeUUID); + Set allObs = encounter.getAllObs(); + Obs savedDocument = getSavedDocument(allObs, conceptUuid); + String obsUuid = savedDocument.getUuid(); + + + List modifiedDocuments = new ArrayList<>(); + modifiedDocuments.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, obsUuid, obsDate, false, "comment on second save")); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + modifiedDocuments, + firstProviderUuid, null, null); + + visitDocumentService.upload(visitDocumentRequest); + Visit finalVisit = visitService.getVisit(2); + Set finalVisitEncounters = finalVisit.getEncounters(); + Encounter finalEncounter = getEncounterByTypeUuid(finalVisitEncounters, secondEncounterTypeUUID); + + Set finalAllObs = finalEncounter.getAllObs(); + Obs finalSavedDocument = getSavedDocument(finalAllObs, conceptUuid); + assertEquals("comment on second save", finalSavedDocument.getGroupMembers().iterator().next().getComment()); + } + + @Test + public void shouldUpdateTheCommentsAndObsRelationshipOnTheObservationIfDocumentContainsCommentsAndSavedObservationDoesntHaveComments() throws Exception { + Date visitStartDate = getDateFromString("2014-06-22 00:00:00"); + Date encounterDate = getDateFromString("2014-06-23 00:00:00"); + Date obsDate = getDateFromString("2014-06-24 00:10:00"); + + List documents = new ArrayList<>(); + documents.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, null, obsDate, false)); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + documents, + firstProviderUuid, null, null); + + visitDocumentService.upload(visitDocumentRequest); + Visit visit = visitService.getVisit(2); + Set encounters = visit.getEncounters(); + Encounter encounter = getEncounterByTypeUuid(encounters, secondEncounterTypeUUID); + Set allObs = encounter.getAllObs(); + Obs savedDocument = getSavedDocument(allObs, conceptUuid); + String obsUuid = savedDocument.getUuid(); + + Obs impressionObs = obsService.getObs(1031); + ObsRelationshipType obsRelationshipType = obsRelationService.getRelationshipTypeByName("qualified-by"); + ObsRelationship obsRelationship = new ObsRelationship(); + obsRelationship.setObsRelationshipType(obsRelationshipType); + obsRelationship.setTargetObs(savedDocument.getGroupMembers().iterator().next()); + obsRelationship.setSourceObs(impressionObs); + ObsRelationship savedObsRelation = obsRelationService.saveOrUpdate(obsRelationship); + + assertEquals(1031, savedObsRelation.getSourceObs().getObsId().intValue()); + + assertEquals(savedDocument.getGroupMembers().iterator().next().getId(), savedObsRelation.getTargetObs().getObsId()); + List modifiedDocuments = new ArrayList<>(); + modifiedDocuments.add(new Document("/radiology/fooo-bar.jpg", null, conceptUuid, obsUuid, obsDate, false, "comment on second save")); + + visitDocumentRequest = new VisitDocumentRequest(patientUUID, + secondVisitUuid, + visitTypeUUID, + visitStartDate, + null, + secondEncounterTypeUUID, + encounterDate, + modifiedDocuments, + firstProviderUuid, null, null); + + visitDocumentService.upload(visitDocumentRequest); + + Visit finalVisit = visitService.getVisit(2); + Set finalVisitEncounters = finalVisit.getEncounters(); + Encounter finalEncounter = getEncounterByTypeUuid(finalVisitEncounters, secondEncounterTypeUUID); + + Set finalAllObs = finalEncounter.getAllObs(); + Obs finalSavedDocument = getSavedDocument(finalAllObs, conceptUuid); + assertEquals("comment on second save", finalSavedDocument.getGroupMembers().iterator().next().getComment()); + + ObsRelationship editedObsRelation = obsRelationService.getRelationByUuid(savedObsRelation.getUuid()); + + assertEquals(1031, editedObsRelation.getSourceObs().getObsId().intValue()); + assertEquals(finalSavedDocument.getGroupMembers().iterator().next().getId(), editedObsRelation.getTargetObs().getId()); + } + + private Encounter getEncounterByTypeUuid(Set encounters, String encounterUuid) { + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getUuid().equals(encounterUuid)) { + return encounter; + } + } + return null; + } + + private List getSavedDocuments(Set allObs, String conceptUuid) { + List obsList = new ArrayList<>(); + for (Obs obs : allObs) { + if (obs.getConcept().getUuid().equals(conceptUuid)) { + obsList.add(obs); + } + } + Collections.sort(obsList, new IdBasedComparator()); + return obsList; + } + + private Obs getSavedDocument(Set allObs, String conceptUuid) { + List savedDocuments = getSavedDocuments(allObs, conceptUuid); + return savedDocuments.size() == 0 ? null : savedDocuments.get(0); + } + + private Date getDateFromString(String date) throws ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + return simpleDateFormat.parse(date); + } + + class IdBasedComparator implements Comparator { + @Override + public int compare(Obs o1, Obs o2) { + return o1.getId().compareTo(o2.getId()); + } + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugogram/contract/RegimenRowTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugogram/contract/RegimenRowTest.java new file mode 100644 index 0000000000..71ba27c5b3 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugogram/contract/RegimenRowTest.java @@ -0,0 +1,22 @@ +package org.openmrs.module.bahmniemrapi.drugogram.contract; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + + +public class RegimenRowTest { + + @Test + public void shouldReturnEmptyStringWhenDrugValueIsAbsent() { + RegimenRow regimenRow = new RegimenRow(); + assertEquals("", regimenRow.getDrugValue("Paracetamol")); + } + + @Test + public void shouldGetDrugValueForDrugConceptName() { + RegimenRow regimenRow = new RegimenRow(); + regimenRow.addDrugs("Paracetamol", "300.0"); + assertEquals("300.0", regimenRow.getDrugValue("Paracetamol")); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TreatmentRegimenTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TreatmentRegimenTest.java new file mode 100644 index 0000000000..62d095df6b --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugogram/contract/TreatmentRegimenTest.java @@ -0,0 +1,33 @@ +package org.openmrs.module.bahmniemrapi.drugogram.contract; + +import org.junit.Test; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import static org.junit.Assert.assertEquals; + + +public class TreatmentRegimenTest { + + @Test + public void shouldAddRowToRegimenWhenRowForThatDateIsAbsent() throws ParseException { + TreatmentRegimen treatmentRegimen = new TreatmentRegimen(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + treatmentRegimen.addRow(simpleDateFormat.parse("2016-01-01")); + + assertEquals(1,treatmentRegimen.getRows().size()); + } + + + @Test + public void shouldNotAddRowToRegimenWhenRowForThatDateIsPresent() throws ParseException { + TreatmentRegimen treatmentRegimen = new TreatmentRegimen(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + treatmentRegimen.addRow(simpleDateFormat.parse("2016-01-01")); + treatmentRegimen.addRow(simpleDateFormat.parse("2016-01-01")); + treatmentRegimen.addRow(simpleDateFormat.parse("2016-01-02")); + + assertEquals(2,treatmentRegimen.getRows().size()); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniProviderMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniProviderMapperTest.java new file mode 100644 index 0000000000..c1093f1301 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/BahmniProviderMapperTest.java @@ -0,0 +1,22 @@ +package org.openmrs.module.bahmniemrapi.drugorder.mapper; + +import org.junit.Test; +import org.openmrs.Provider; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class BahmniProviderMapperTest { + + @Test + public void shouldMapOpenMRSProviderToEncounterTransactionProvider() { + Provider openMRSProvider = new Provider(); + openMRSProvider.setUuid("86526ed5-3c11-11de-a0ba-001e378eb671"); + openMRSProvider.setName("Superman"); + EncounterTransaction.Provider provider = new BahmniProviderMapper().map(openMRSProvider); + assertThat(provider.getUuid(), is(equalTo(openMRSProvider.getUuid()))); + assertThat(provider.getName(), is(equalTo(openMRSProvider.getName()))); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/OrderAttributesMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/OrderAttributesMapperTest.java new file mode 100644 index 0000000000..a9777546d2 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/drugorder/mapper/OrderAttributesMapperTest.java @@ -0,0 +1,38 @@ +package org.openmrs.module.bahmniemrapi.drugorder.mapper; + +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class OrderAttributesMapperTest { + + @Test + public void shouldMapRelatedObservationsWithOrders(){ + List bahmniObservationList = new ArrayList<>(); + EncounterTransaction.Concept concept = new EncounterTransaction.Concept("Concept_uuid", "dispensed", true, "Concept_dataType", "Concept_units", "Concept_conceptClass", null, null); + + BahmniObservation dispensedObservation =new BahmniObservationBuilder().withUuid("obs-uuid").withConcept(concept).withOrderUuid("Order_uuid").withValue("true").build(); + + bahmniObservationList.add(dispensedObservation); + + BahmniDrugOrder bahmniDrugOrder = new BahmniDrugOrder(); + EncounterTransaction.DrugOrder drugOrder = new EncounterTransaction.DrugOrder(); + drugOrder.setUuid("Order_uuid"); + bahmniDrugOrder.setDrugOrder(drugOrder); + List bahmniDrugOrderList = new ArrayList<>(); + bahmniDrugOrderList.add(bahmniDrugOrder); + + bahmniDrugOrderList = new OrderAttributesMapper().map(bahmniDrugOrderList, bahmniObservationList); + + assertEquals(1,bahmniDrugOrderList.get(0).getOrderAttributes().size()); + assertEquals("dispensed", bahmniDrugOrderList.get(0).getOrderAttributes().get(0).getName()); + assertEquals("obs-uuid", bahmniDrugOrderList.get(0).getOrderAttributes().get(0).getObsUuid()); + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/advice/BahmniEncounterTransactionUpdateAdviceTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/advice/BahmniEncounterTransactionUpdateAdviceTest.java new file mode 100644 index 0000000000..c935884ed8 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/advice/BahmniEncounterTransactionUpdateAdviceTest.java @@ -0,0 +1,77 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.advice; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.util.OpenmrsUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; +import static org.powermock.api.mockito.PowerMockito.when; + +import org.apache.commons.lang.StringUtils; +; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ Context.class, OpenmrsUtil.class}) +public class BahmniEncounterTransactionUpdateAdviceTest { + private static String DEFAULT_ENCOUNTER_UUID = "defaultEncounterUuid"; + private static final String BAHMNI_EXECUTE_GROOVY_SCRIPT = "bahmni.executeGroovyObsValueCalculator" ; + + @Mock + private AdministrationService administrationService; + + @Test + public void shouldExecuteObsValueCalculatorFromApplicationDataDirectory() throws Throwable { + PowerMockito.mockStatic(OpenmrsUtil.class); + when(OpenmrsUtil.getApplicationDataDirectory()).thenReturn(getClass().getClassLoader().getResource("").getPath()); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(BAHMNI_EXECUTE_GROOVY_SCRIPT)).thenReturn("true"); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + new BahmniEncounterTransactionUpdateAdvice().before(null, new BahmniEncounterTransaction[]{bahmniEncounterTransaction}, null); + + assertThat(bahmniEncounterTransaction.getEncounterUuid(), is(equalTo(DEFAULT_ENCOUNTER_UUID))); + } + + @Test + public void shouldLoadpplicationDataDirectoryPath() throws Throwable { + PowerMockito.mockStatic(OpenmrsUtil.class); + String path = getClass().getClassLoader().getResource("").getPath(); + // remove the trailing "/" + path = StringUtils.chop(path); + System.out.println(path); + when(OpenmrsUtil.getApplicationDataDirectory()).thenReturn(path); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(BAHMNI_EXECUTE_GROOVY_SCRIPT)).thenReturn("true"); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + new BahmniEncounterTransactionUpdateAdvice().before(null, new BahmniEncounterTransaction[]{bahmniEncounterTransaction}, null); + + assertThat(bahmniEncounterTransaction.getEncounterUuid(), is(equalTo(DEFAULT_ENCOUNTER_UUID))); + } + + @Test + public void shouldNotFailIfobscalculatorDirectoryDoesNotExist() throws Throwable { + PowerMockito.mockStatic(OpenmrsUtil.class); + when(OpenmrsUtil.getApplicationDataDirectory()).thenReturn(getClass().getClassLoader().getResource("").getPath() + "nonExistentDirectory"); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getGlobalProperty(BAHMNI_EXECUTE_GROOVY_SCRIPT)).thenReturn("true"); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + new BahmniEncounterTransactionUpdateAdvice().before(null, new BahmniEncounterTransaction[]{bahmniEncounterTransaction}, null); + + assertThat(bahmniEncounterTransaction.getEncounterUuid(), is(not(equalTo(DEFAULT_ENCOUNTER_UUID)))); + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniObservationSaveCommandImplTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniObservationSaveCommandImplTest.java new file mode 100644 index 0000000000..17aeb5160c --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/BahmniObservationSaveCommandImplTest.java @@ -0,0 +1,162 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.ObsService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniObservationSaveCommandImplTest { + @Mock + private ObsService obsService; + @Mock + private ObsRelationService obsRelationService; + + private BahmniObservationSaveCommandImpl bahmniObservationSaveCommand; + @Before + public void setUp() throws Exception { + initMocks(this); + bahmniObservationSaveCommand = new BahmniObservationSaveCommandImpl(obsRelationService, obsService); + } + + @Test + public void shouldSaveObsRelationsForTheGivenObservations(){ + Date obsDate = new Date(); + List bahmniObservations = new ArrayList<>(); + ObsRelationship targetObs = createObsRelationShip("relationTypeName", createBahmniObservation("target-uuid", "target-value", createConcept("target-concept-uuid", "target-concept-name"), obsDate, null)); + BahmniObservation srcObs = createBahmniObservation("obs-uuid", "obs-value", createConcept("concept-uuid", "concept-name"), obsDate, targetObs); + bahmniObservations.add(srcObs); + BahmniEncounterTransaction bahmniEncounterTransaction = createBahmniEncounterTransaction(bahmniObservations); + + Encounter currentEncounter = new Encounter(); + Set obsList = new HashSet<>(); + obsList.add(createObs("obs-uuid","obs-value", obsDate)); + obsList.add(createObs("obs-uuid2","obs-value", obsDate)); + obsList.add(createObs("target-uuid", "target-value", obsDate)); + currentEncounter.setObs(obsList); + + ObsRelationshipType obsRelationshipType = new ObsRelationshipType(); + obsRelationshipType.setName("relationTypeName"); + when(obsRelationService.getRelationshipTypeByName(anyString())).thenReturn(obsRelationshipType); + + bahmniObservationSaveCommand.save(bahmniEncounterTransaction, currentEncounter, null); + +// verify(obsService).getObsByUuid("target-uuid"); + ArgumentCaptor obsRelationshipArgument = ArgumentCaptor.forClass(org.bahmni.module.obsrelationship.model.ObsRelationship.class); + verify(obsRelationService).saveOrUpdate(obsRelationshipArgument.capture()); + + assertEquals("obs-uuid",obsRelationshipArgument.getValue().getSourceObs().getUuid()); + assertEquals("obs-uuid",obsRelationshipArgument.getValue().getSourceObs().getUuid()); + assertEquals(obsDate,obsRelationshipArgument.getValue().getSourceObs().getObsDatetime()); + + assertEquals("target-uuid",obsRelationshipArgument.getValue().getTargetObs().getUuid()); + assertEquals("target-value",obsRelationshipArgument.getValue().getTargetObs().getValueText()); + assertEquals(obsDate,obsRelationshipArgument.getValue().getTargetObs().getObsDatetime()); + + assertEquals("relationTypeName",obsRelationshipArgument.getValue().getObsRelationshipType().getName()); + } + + @Test + public void shouldSaveObsRelationsWhenTargetObsNotInCurrentEncounter(){ + Date obsDate = new Date(); + List bahmniObservations = new ArrayList<>(); + ObsRelationship targetObs = createObsRelationShip("relationTypeName", createBahmniObservation("target-uuid", "target-value", createConcept("target-concept-uuid", "target-concept-name"), obsDate, null)); + BahmniObservation srcObs = createBahmniObservation("obs-uuid", "obs-value", createConcept("concept-uuid", "concept-name"), obsDate, targetObs); + bahmniObservations.add(srcObs); + BahmniEncounterTransaction bahmniEncounterTransaction = createBahmniEncounterTransaction(bahmniObservations); + + Encounter currentEncounter = new Encounter(); + Set obsList = new HashSet<>(); + obsList.add(createObs("obs-uuid","obs-value", obsDate)); + obsList.add(createObs("obs-uuid2","obs-value", obsDate)); + Obs targetObsOpenmrs = createObs("target-uuid", "target-value", obsDate); + currentEncounter.setObs(obsList); + + ObsRelationshipType obsRelationshipType = new ObsRelationshipType(); + obsRelationshipType.setName("relationTypeName"); + when(obsService.getObsByUuid("target-uuid")).thenReturn(targetObsOpenmrs); + when(obsRelationService.getRelationshipTypeByName(anyString())).thenReturn(obsRelationshipType); + + bahmniObservationSaveCommand.save(bahmniEncounterTransaction, currentEncounter, null); + + verify(obsService).getObsByUuid("target-uuid"); + ArgumentCaptor obsRelationshipArgument = ArgumentCaptor.forClass(org.bahmni.module.obsrelationship.model.ObsRelationship.class); + verify(obsRelationService).saveOrUpdate(obsRelationshipArgument.capture()); + + assertEquals("obs-uuid",obsRelationshipArgument.getValue().getSourceObs().getUuid()); + assertEquals("obs-uuid",obsRelationshipArgument.getValue().getSourceObs().getUuid()); + assertEquals(obsDate,obsRelationshipArgument.getValue().getSourceObs().getObsDatetime()); + + assertEquals("target-uuid",obsRelationshipArgument.getValue().getTargetObs().getUuid()); + assertEquals("target-value",obsRelationshipArgument.getValue().getTargetObs().getValueText()); + assertEquals(obsDate,obsRelationshipArgument.getValue().getTargetObs().getObsDatetime()); + + assertEquals("relationTypeName",obsRelationshipArgument.getValue().getObsRelationshipType().getName()); + } + + private Obs createObs(String uuid, String value, Date obsDate) { + Obs obs = new Obs(); + obs.setUuid(uuid); + obs.setValueText(value); + obs.setConcept(new Concept(1)); + obs.setObsDatetime(obsDate); + return obs; + } + + private ObsRelationship createObsRelationShip(String relationTypeName, BahmniObservation bahmniObservation) { + ObsRelationship obsRelationship = new ObsRelationship(); + obsRelationship.setRelationshipType(relationTypeName); + obsRelationship.setTargetObs(bahmniObservation); + return obsRelationship; + } + + private BahmniEncounterTransaction createBahmniEncounterTransaction(List bahmniObservations) { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setObservations(bahmniObservations); + return bahmniEncounterTransaction; + } + + + private EncounterTransaction.Concept createConcept(String conceptUuid, String conceptName) { + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(); + concept.setUuid(conceptUuid); + concept.setName(conceptName); + return concept; + } + + private BahmniObservation createBahmniObservation(String uuid, String value, EncounterTransaction.Concept concept, Date obsDate, ObsRelationship targetObs) { + BahmniObservation bahmniObservation = new BahmniObservation(); + bahmniObservation.setUuid(uuid); + bahmniObservation.setValue(value); + bahmniObservation.setConcept(concept); + bahmniObservation.setComment("comment"); + bahmniObservation.setObservationDateTime(obsDate); + bahmniObservation.setOrderUuid("order-uuid"); + bahmniObservation.setVoided(true); + bahmniObservation.setVoidReason("chumma"); + bahmniObservation.setTargetObsRelation(targetObs); + return bahmniObservation; + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/DrugOrderSaveCommandImplTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/DrugOrderSaveCommandImplTest.java new file mode 100644 index 0000000000..2d7f4953ee --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/DrugOrderSaveCommandImplTest.java @@ -0,0 +1,145 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.apache.commons.lang3.time.DateUtils; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptMapType; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.ConceptSource; +import org.openmrs.Duration; +import org.openmrs.OrderFrequency; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.drugorder.DrugOrderUtil; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.service.OrderMetadataService; +import org.openmrs.module.emrapi.encounter.builder.DrugOrderBuilder; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class DrugOrderSaveCommandImplTest { + @Mock + private OrderMetadataService orderMetadataService; + + @Mock + private ConceptService conceptService; + + public static final String DAY_DURATION_UNIT = "Day"; + public static final String ONCE_A_DAY_CONCEPT_NAME = "Once A Day"; + public static final String SNOMED_CT_DAYS_CODE = "258703001"; + + + private DrugOrderSaveCommandImpl drugOrderSaveCommand; + + @Before + public void setUp() throws Exception { + initMocks(this); + drugOrderSaveCommand = new DrugOrderSaveCommandImpl(orderMetadataService, conceptService); + } + + private static ConceptMap getConceptMap(String sourceHl7Code, String code, String mapTypeUuid) { + ConceptMap conceptMap = new ConceptMap(); + ConceptReferenceTerm conceptReferenceTerm = new ConceptReferenceTerm(); + ConceptSource conceptSource = new ConceptSource(); + conceptSource.setHl7Code(sourceHl7Code); + conceptReferenceTerm.setConceptSource(conceptSource); + conceptReferenceTerm.setCode(code); + conceptMap.setConceptReferenceTerm(conceptReferenceTerm); + ConceptMapType conceptMapType = new ConceptMapType(); + if (mapTypeUuid != null) { + conceptMapType.setUuid(mapTypeUuid); + } else { + conceptMapType.setUuid(ConceptMapType.SAME_AS_MAP_TYPE_UUID); + } + conceptMap.setConceptMapType(conceptMapType); + return conceptMap; + } + + @Test + public void shouldSetDatesForDrugOrderConflictingWithCurrentDateOrders() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + Concept dayConcept = new Concept(); + dayConcept.addConceptMapping(getConceptMap(Duration.SNOMED_CT_CONCEPT_SOURCE_HL7_CODE, Duration.SNOMED_CT_DAYS_CODE, "35543629-7d8c-11e1-909d-c80aa9edcf4e")); + + when(conceptService.getConceptByName(DAY_DURATION_UNIT)).thenReturn(dayConcept); + OrderFrequency orderFrequency = new OrderFrequency(); + when(orderMetadataService.getDurationUnitsConceptByName(DAY_DURATION_UNIT)).thenReturn(dayConcept); + when(orderMetadataService.getOrderFrequencyByName("day", false)).thenReturn(orderFrequency); + + + List drugOrders = new ArrayList<>(); + Date today = new Date(); + EncounterTransaction.DrugOrder drugOrder1 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(null).withFrequency(DAY_DURATION_UNIT).build(); + + drugOrders.add(drugOrder1); + EncounterTransaction.DrugOrder drugOrder2 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(DateUtils.addDays(today, 10)).withFrequency(DAY_DURATION_UNIT).build(); + drugOrders.add(drugOrder2); + EncounterTransaction.DrugOrder drugOrder3 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(DateUtils.addDays(today, 2)).withFrequency(DAY_DURATION_UNIT).build(); + drugOrders.add(drugOrder3); + bahmniEncounterTransaction.setDrugOrders(drugOrders); + BahmniEncounterTransaction updatedEncounterTransaction = drugOrderSaveCommand.update(bahmniEncounterTransaction); + assertEquals(updatedEncounterTransaction.getDrugOrders().size(), 3); + + + EncounterTransaction.DrugOrder currentDrugOrder = updatedEncounterTransaction.getDrugOrders().get(0); + EncounterTransaction.DrugOrder overlappingOrderWithCurrentDateOrder = updatedEncounterTransaction.getDrugOrders().get(2); + + Date expectedStopDateForCurrentOrder = DrugOrderUtil.calculateAutoExpireDate(currentDrugOrder.getDuration(), dayConcept, null, currentDrugOrder.getScheduledDate(), orderMetadataService.getOrderFrequencyByName(currentDrugOrder.getDosingInstructions().getFrequency(), false)); + assertEquals(currentDrugOrder.getAutoExpireDate(), expectedStopDateForCurrentOrder); + assertTrue(currentDrugOrder.getAutoExpireDate().before(overlappingOrderWithCurrentDateOrder.getScheduledDate())); + + } + + @Test + public void shouldSetDatesForDrugOrdersChainedConflictsWithCurrentDateOrders() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + Concept dayConcept = new Concept(); + dayConcept.addConceptMapping(getConceptMap(Duration.SNOMED_CT_CONCEPT_SOURCE_HL7_CODE, Duration.SNOMED_CT_DAYS_CODE, "35543629-7d8c-11e1-909d-c80aa9edcf4e")); + + when(conceptService.getConceptByName(DAY_DURATION_UNIT)).thenReturn(dayConcept); + OrderFrequency orderFrequency = new OrderFrequency(); + when(orderMetadataService.getDurationUnitsConceptByName(DAY_DURATION_UNIT)).thenReturn(dayConcept); + when(orderMetadataService.getOrderFrequencyByName("day", false)).thenReturn(orderFrequency); + + + List drugOrders = new ArrayList<>(); + Date today = new Date(); + EncounterTransaction.DrugOrder drugOrder1 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(null).withFrequency(DAY_DURATION_UNIT).build(); + + drugOrders.add(drugOrder1); + EncounterTransaction.DrugOrder drugOrder2 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(DateUtils.addDays(today, 10)).withFrequency(DAY_DURATION_UNIT).build(); + drugOrders.add(drugOrder2); + EncounterTransaction.DrugOrder drugOrder3 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(DateUtils.addDays(today, 2)).withFrequency(DAY_DURATION_UNIT).build(); + drugOrders.add(drugOrder3); + EncounterTransaction.DrugOrder drugOrder4 = new DrugOrderBuilder().withDrugUuid("drug-uuid1").withScheduledDate(DateUtils.addDays(today, 4)).withFrequency(DAY_DURATION_UNIT).build(); + drugOrders.add(drugOrder4); + bahmniEncounterTransaction.setDrugOrders(drugOrders); + BahmniEncounterTransaction updatedEncounterTransaction = drugOrderSaveCommand.update(bahmniEncounterTransaction); + assertEquals(updatedEncounterTransaction.getDrugOrders().size(), 4); + + + EncounterTransaction.DrugOrder currentDrugOrder = updatedEncounterTransaction.getDrugOrders().get(0); + EncounterTransaction.DrugOrder overlappingOrderWithCurrentDateOrder = updatedEncounterTransaction.getDrugOrders().get(2); + EncounterTransaction.DrugOrder chainedOverlappingOrder = updatedEncounterTransaction.getDrugOrders().get(3); + + Date expectedStopDateForCurrentOrder = DrugOrderUtil.calculateAutoExpireDate(currentDrugOrder.getDuration(), dayConcept, null, currentDrugOrder.getScheduledDate(), orderMetadataService.getOrderFrequencyByName(currentDrugOrder.getDosingInstructions().getFrequency(), false)); + Date expectedStopDateForOverlappingOrder = DrugOrderUtil.calculateAutoExpireDate(overlappingOrderWithCurrentDateOrder.getDuration(), dayConcept, null, overlappingOrderWithCurrentDateOrder.getScheduledDate(), orderMetadataService.getOrderFrequencyByName(overlappingOrderWithCurrentDateOrder.getDosingInstructions().getFrequency(), false)); + + assertEquals(currentDrugOrder.getAutoExpireDate(), expectedStopDateForCurrentOrder); + assertEquals(overlappingOrderWithCurrentDateOrder.getAutoExpireDate(), expectedStopDateForOverlappingOrder); + assertTrue(currentDrugOrder.getAutoExpireDate().before(overlappingOrderWithCurrentDateOrder.getScheduledDate())); + + assertTrue(overlappingOrderWithCurrentDateOrder.getAutoExpireDate().before(chainedOverlappingOrder.getScheduledDate())); + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/OrderSaveCommandImplTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/OrderSaveCommandImplTest.java new file mode 100644 index 0000000000..90a9eb9f4e --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/OrderSaveCommandImplTest.java @@ -0,0 +1,50 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.joda.time.DateTime; +import org.joda.time.Seconds; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.api.AdministrationService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class OrderSaveCommandImplTest { + @Mock + private AdministrationService adminService; + + public static final String DAY_DURATION_UNIT = "Day"; + public static final String ONCE_A_DAY_CONCEPT_NAME = "Once A Day"; + public static final String SNOMED_CT_DAYS_CODE = "258703001"; + + + private OrderSaveCommandImpl orderSaveCommand; + + @Before + public void setUp() throws Exception { + initMocks(this); + orderSaveCommand = new OrderSaveCommandImpl(adminService); + } + + @Test + public void shouldSetAutoExpireDateForTestOrders(){ + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + List testOrders = Arrays.asList(new EncounterTransaction.Order()); + bahmniEncounterTransaction.setOrders(testOrders); + when(adminService.getGlobalProperty("bahmni.encountersession.duration")).thenReturn("60"); + + orderSaveCommand.update(bahmniEncounterTransaction); + + assertTrue(Math.abs(Seconds.secondsBetween(DateTime.now().plusMinutes(60), new DateTime(bahmniEncounterTransaction.getOrders().get(0).getAutoExpireDate())).getSeconds()) < 3); + } + + + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/ParentConceptSaveCommandImplTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/ParentConceptSaveCommandImplTest.java new file mode 100644 index 0000000000..3ee43e7b98 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/ParentConceptSaveCommandImplTest.java @@ -0,0 +1,43 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.command.impl; + +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +public class ParentConceptSaveCommandImplTest { + + @Test + public void ensureBahmniObsIsUpdatedWithParentConceptUuid() throws Exception { + + EncounterTransaction.Concept vitals = new EncounterTransaction.Concept(); + vitals.setUuid("vitals"); + + EncounterTransaction.Concept height = new EncounterTransaction.Concept(); + height.setUuid("height"); + + BahmniObservation heightObs = new BahmniObservation(); + heightObs.setUuid("heightUuid"); + heightObs.setConcept(height); + + BahmniObservation vitalsObs = new BahmniObservation(); + vitalsObs.setUuid("parentUuid"); + vitalsObs.setConcept(vitals); + vitalsObs.setGroupMembers(Arrays.asList(heightObs)); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setObservations(Arrays.asList(vitalsObs)); + + ParentConceptSaveCommandImpl updateConcept = new ParentConceptSaveCommandImpl(); + bahmniEncounterTransaction = updateConcept.update(bahmniEncounterTransaction); + + assertEquals(1,bahmniEncounterTransaction.getObservations().size()); + BahmniObservation actualObs = bahmniEncounterTransaction.getObservations().iterator().next(); + assertEquals("vitals",actualObs.getParentConceptUuid()); + assertEquals("vitals",actualObs.getGroupMembers().iterator().next().getParentConceptUuid()); //Height + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterTransactionTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterTransactionTest.java new file mode 100644 index 0000000000..82ee01cbe6 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniEncounterTransactionTest.java @@ -0,0 +1,272 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.contract; + +import org.apache.commons.lang.time.DateUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship; +import org.openmrs.module.emrapi.diagnosis.Diagnosis; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.io.File; +import java.io.IOException; +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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class BahmniEncounterTransactionTest { + + private final Date obsDate = new Date(); + + @Test + public void shouldConvertBahmniEncounterTransactionToET() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setBahmniDiagnoses(createBahmniDiagnoses()); + bahmniEncounterTransaction.setObservations(createBahmniObservations()); + bahmniEncounterTransaction.setExtensions(createExtensions()); + EncounterTransaction encounterTransaction = bahmniEncounterTransaction.toEncounterTransaction(); + + assertEquals(2, encounterTransaction.getDiagnoses().size()); + + EncounterTransaction.Diagnosis diagnosis1 = encounterTransaction.getDiagnoses().get(0); + assertEquals(Diagnosis.Certainty.CONFIRMED.name(), diagnosis1.getCertainty()); + assertEquals(Diagnosis.Order.PRIMARY.name(), diagnosis1.getOrder()); + assertEquals("d102c80f-1yz9-4da3-bb88-8122ce8868dh", diagnosis1.getCodedAnswer().getUuid()); + + EncounterTransaction.Diagnosis diagnosis2 = encounterTransaction.getDiagnoses().get(1); + assertEquals(Diagnosis.Certainty.PRESUMED.name(), diagnosis2.getCertainty()); + assertEquals(Diagnosis.Order.SECONDARY.name(), diagnosis2.getOrder()); + assertEquals("e102c80f-1yz9-4da3-bb88-8122ce8868dh", diagnosis2.getCodedAnswer().getUuid()); + + assertEquals(2, encounterTransaction.getObservations().size()); + + EncounterTransaction.Observation observation1 = encounterTransaction.getObservations().get(0); + assertEquals("comment", observation1.getComment()); + assertEquals("obs-uuid", observation1.getUuid()); + assertEquals("concept-uuid", observation1.getConceptUuid()); + assertEquals("order-uuid", observation1.getOrderUuid()); + assertEquals(obsDate, observation1.getObservationDateTime()); + assertEquals("obs-value1", observation1.getValue()); + assertEquals(true, observation1.getVoided()); + assertEquals("chumma", observation1.getVoidReason()); + + EncounterTransaction.Observation observation2 = encounterTransaction.getObservations().get(1); + assertEquals("comment", observation2.getComment()); + assertEquals("obs-uuid-1", observation2.getUuid()); + assertEquals("concept-uuid-2", observation2.getConceptUuid()); + assertEquals("order-uuid", observation2.getOrderUuid()); + assertEquals(obsDate, observation2.getObservationDateTime()); + assertEquals("obs-value2", observation2.getValue()); + assertEquals(true, observation2.getVoided()); + assertEquals("chumma", observation2.getVoidReason()); + + assertNotNull(encounterTransaction.getExtensions()); + assertEquals(1, encounterTransaction.getExtensions().size()); + assertTrue(encounterTransaction.getExtensions().containsKey("extension")); + assertEquals("Any Object Here", encounterTransaction.getExtensions().get("extension")); + } + + private Map createExtensions() { + Map test = new HashMap<>(); + test.put("extension", "Any Object Here"); + return test; + } + + @Test + public void isRetrospectiveEntryShouldReturnTrueIfTheEncounterDateTimeIsBeforeToday() throws Exception { + assertEquals(true, BahmniEncounterTransaction.isRetrospectiveEntry(DateUtils.addDays(new Date(), -2))); + } + + @Test + public void isRetrospectiveEntryShouldReturnFalseIfTheEncounterDateTimeIsNull() throws Exception { + assertEquals(false, BahmniEncounterTransaction.isRetrospectiveEntry(null)); + } + + @Test + public void isRetrospectiveEntryShouldReturnFalseIfTheEncounterDateTimeSameAsToday() throws Exception { + assertEquals(false, BahmniEncounterTransaction.isRetrospectiveEntry(new Date())); + } + + @Test + public void shouldClearDrugOrderFromExistingET() { + EncounterTransaction.DrugOrder firstDrugOrder = new EncounterTransaction.DrugOrder(); + EncounterTransaction.DrugOrder secondDrugOrder = new EncounterTransaction.DrugOrder(); + List drugOrders = Arrays.asList(firstDrugOrder, secondDrugOrder); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setDrugOrders(drugOrders); + + bahmniEncounterTransaction.clearDrugOrders(); + + assertEquals(new ArrayList(), bahmniEncounterTransaction.getDrugOrders()); + } + + @Test + public void shouldReturnTrueIfThereAreAnyPastDrugOrders() { + DateTime dateTime = new DateTime(); + dateTime = dateTime.plusDays(-2); + EncounterTransaction.DrugOrder drugOrder = new EncounterTransaction.DrugOrder(); + drugOrder.setScheduledDate(dateTime.toDate()); //This is a past drug order + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setEncounterDateTime(new Date()); + bahmniEncounterTransaction.setDrugOrders(Arrays.asList(drugOrder)); + Assert.assertEquals(true, bahmniEncounterTransaction.hasPastDrugOrders()); + } + + @Test + public void shouldReturnTrueIfThereAreSomePastAndSomeFutureDrugOrders() { + DateTime dateTime = new DateTime(); + dateTime = dateTime.plusDays(-2); + + DateTime scheduledDate = new DateTime(); + scheduledDate = scheduledDate.plusDays(2); + + EncounterTransaction.DrugOrder drugOrder = new EncounterTransaction.DrugOrder(); + drugOrder.setScheduledDate(dateTime.toDate()); //This is a past drug order + + EncounterTransaction.DrugOrder drugOrder1 = new EncounterTransaction.DrugOrder(); + drugOrder1.setScheduledDate(scheduledDate.toDate()); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setEncounterDateTime(new Date()); + bahmniEncounterTransaction.setDrugOrders(Arrays.asList(drugOrder, drugOrder1)); + Assert.assertEquals(true, bahmniEncounterTransaction.hasPastDrugOrders()); + } + + private ArrayList createBahmniObservations() { + final BahmniObservation targetObs = createBahmniObservation("target-uuid", "target-value", + createConcept("target-concept-uuid", "target-obs-concept"), obsDate, null); + final BahmniObservation targetObs2 = createBahmniObservation("target-uuid-2", "target-value-2", + createConcept("target-concept-uuid", "target-obs-concept"), obsDate, null); + return new ArrayList() {{ + this.add(createBahmniObservation("obs-uuid", "obs-value1", createConcept("concept-uuid", "obs-concept"), obsDate, + createObsRelationShip("obs-relation", targetObs))); + this.add(createBahmniObservation("obs-uuid-1", "obs-value2", createConcept("concept-uuid-2", "obs-concept-2"), + obsDate, createObsRelationShip("obs-relation-2", targetObs2))); + }}; + } + + @Test + public void shouldReturnFalseIfThereAreNoDrugs() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + + assertEquals(false, bahmniEncounterTransaction.hasPastDrugOrders()); + } + + @Test + public void shouldCopyRequiredFieldsOnCloneForDrugOrders() { + String PATIENT_PROGRAM_UUID = "patientProgramUuid"; + + Set providers = new HashSet(); + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setUuid("providerUuid"); + providers.add(provider); + + DateTime pastDateActivated = new DateTime(); + pastDateActivated.plusDays(-2); + DateTime futureDateActivated = new DateTime(); + futureDateActivated.plusDays(2); + + EncounterTransaction.DrugOrder drugOrder = new EncounterTransaction.DrugOrder(); + drugOrder.setScheduledDate(futureDateActivated.toDate()); + EncounterTransaction.DrugOrder drugOrder1 = new EncounterTransaction.DrugOrder(); + drugOrder1.setScheduledDate(pastDateActivated.toDate()); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setDrugOrders(Arrays.asList(drugOrder, drugOrder1)); + bahmniEncounterTransaction.setEncounterTypeUuid("encounterTypeUuid"); + bahmniEncounterTransaction.setLocationUuid("locationUuid"); + bahmniEncounterTransaction.setPatientUuid("patientUuid"); + bahmniEncounterTransaction.setPatientProgramUuid(PATIENT_PROGRAM_UUID); + bahmniEncounterTransaction.setProviders(providers); + + BahmniEncounterTransaction clonedEncounterTransaction = bahmniEncounterTransaction.cloneForPastDrugOrders(); + List drugOrders = clonedEncounterTransaction.getDrugOrders(); + + assertEquals(drugOrder, drugOrders.get(0)); + assertEquals(drugOrder1, drugOrders.get(1)); + + assertEquals(pastDateActivated.toDate(), clonedEncounterTransaction.getEncounterDateTime()); + assertEquals("encounterTypeUuid", clonedEncounterTransaction.getEncounterTypeUuid()); + assertEquals("locationUuid", clonedEncounterTransaction.getLocationUuid()); + assertEquals("patientUuid", clonedEncounterTransaction.getPatientUuid()); + assertEquals(PATIENT_PROGRAM_UUID, clonedEncounterTransaction.getPatientProgramUuid()); + assertEquals(providers, clonedEncounterTransaction.getProviders()); + } + + @Test + public void shouldDeserializeBahmniEncounterTransactionFromJson() throws IOException { + ClassLoader classLoader = getClass().getClassLoader(); + File file = new File(classLoader.getResource("sampleEncounterTransaction.json").getFile()); + + BahmniEncounterTransaction encounterTransaction = new ObjectMapper().readValue(file, BahmniEncounterTransaction.class); + assertNotNull(encounterTransaction); + assertEquals("253a5353-46b6-4668-97bb-8d1967ef3418", encounterTransaction.getPatientProgramUuid()); + } + + private ArrayList createBahmniDiagnoses() { + return new ArrayList() { + + { + this.add(new BahmniDiagnosisRequest() {{ + this.setCertainty(Diagnosis.Certainty.CONFIRMED.name()); + this.setOrder(Diagnosis.Order.PRIMARY.name()); + this.setCodedAnswer(new EncounterTransaction.Concept("d102c80f-1yz9-4da3-bb88-8122ce8868dh")); + this.setDiagnosisStatusConcept(new EncounterTransaction.Concept(null, "Ruled Out")); + this.setComments("comments"); + this.setEncounterUuid("enc-uuid"); + + }}); + + this.add(new BahmniDiagnosisRequest() {{ + this.setCertainty(Diagnosis.Certainty.PRESUMED.name()); + this.setOrder(Diagnosis.Order.SECONDARY.name()); + this.setCodedAnswer(new EncounterTransaction.Concept("e102c80f-1yz9-4da3-bb88-8122ce8868dh")); + this.setDiagnosisStatusConcept(new EncounterTransaction.Concept(null, "Ruled Out")); + this.setEncounterUuid("enc-uuid"); + }}); + + } + }; + } + + private BahmniObservation createBahmniObservation(String uuid, String value, EncounterTransaction.Concept concept, + Date obsDate, ObsRelationship targetObs) { + BahmniObservation bahmniObservation = new BahmniObservation(); + bahmniObservation.setUuid(uuid); + bahmniObservation.setValue(value); + bahmniObservation.setConcept(concept); + bahmniObservation.setComment("comment"); + bahmniObservation.setObservationDateTime(obsDate); + bahmniObservation.setOrderUuid("order-uuid"); + bahmniObservation.setVoided(true); + bahmniObservation.setVoidReason("chumma"); + bahmniObservation.setTargetObsRelation(targetObs); + return bahmniObservation; + } + + private ObsRelationship createObsRelationShip(String relationTypeName, BahmniObservation bahmniObservation) { + ObsRelationship obsRelationship = new ObsRelationship(); + obsRelationship.setRelationshipType(relationTypeName); + obsRelationship.setTargetObs(bahmniObservation); + return obsRelationship; + } + + private EncounterTransaction.Concept createConcept(String conceptUuid, String conceptName) { + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(); + concept.setUuid(conceptUuid); + concept.setName(conceptName); + return concept; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservationTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservationTest.java new file mode 100644 index 0000000000..c7a97beea2 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservationTest.java @@ -0,0 +1,166 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.contract; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.User; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.ETObsToBahmniObsMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class}) +public class BahmniObservationTest { + private EncounterTransaction.Observation eTObservation; + + @Mock + private ConceptService conceptService; + + @Mock + private User authenticatedUser; + + @Before + public void setUp() throws Exception { + eTObservation = new EncounterTransaction.Observation(); + initMocks(this); + mockStatic(Context.class); + Mockito.when(Context.getAuthenticatedUser()).thenReturn(authenticatedUser); + } + + @Test + public void shouldCreateBahmniObservationFromETObservation(){ + Date obsDate = new Date(); + EncounterTransaction.Concept concept = createConcept("concept-uuid", "concept-name"); + Concept conceptFromService = PowerMockito.mock(Concept.class); + conceptFromService.setUuid("concept-uuid"); + ConceptName conceptNameFromService = new ConceptName(); + conceptNameFromService.setName("concept-name"); + + when(conceptFromService.getName()).thenReturn(conceptNameFromService); + when(conceptService.getConceptByUuid("concept-uuid")).thenReturn(conceptFromService); + + eTObservation = createETObservation("obs-uuid", "obs-value", concept, obsDate); + + eTObservation.addGroupMember(createETObservation("child-uuid", "child-value", concept, obsDate)); + + BahmniObservation observation = new ETObsToBahmniObsMapper(conceptService, Arrays.asList()).create(eTObservation, new AdditionalBahmniObservationFields("encounter-uuid",new Date(),null,"obs-Group-Uuid")); + assertEquals("comment", observation.getComment()); + assertEquals("obs-uuid", observation.getUuid()); + assertEquals("concept-uuid",observation.getConceptUuid()); + assertEquals("order-uuid", observation.getOrderUuid()); + assertEquals(obsDate,observation.getObservationDateTime()); + Collection groupMembers = observation.getGroupMembers(); + assertEquals(1, groupMembers.size()); + assertEquals("obs-value",observation.getValue()); + assertEquals(true, observation.getVoided()); + assertEquals("void reason", observation.getVoidReason()); + assertEquals("encounter-uuid",observation.getEncounterUuid()); + assertEquals("obs-Group-Uuid",observation.getObsGroupUuid()); + + BahmniObservation child = groupMembers.iterator().next(); + assertEquals("child-uuid", child.getUuid()); + assertEquals("child-value", child.getValue()); + assertEquals("encounter-uuid",child.getEncounterUuid()); + } + + @Test + public void shouldReturnTrueIfBahmniObservationIsSameAsETObservation() throws Exception { + eTObservation.setUuid("uuid"); + BahmniObservation bahmniObservation = new BahmniObservation(); + bahmniObservation.setUuid("uuid"); + + boolean isSame = bahmniObservation.isSameAs(eTObservation); + + Assert.assertTrue(isSame); + } + + @Test + public void shouldConvertBahmniObservationToETObservation() throws Exception { + Date obsDateTime = new Date(); + EncounterTransaction.Concept concept = createConcept("concept-uuid", "concept-name"); + BahmniObservation bahmniObservation = createBahmniObservation("obs-uuid", "obs-value", concept, obsDateTime, "parentConceptUuid"); + bahmniObservation.addGroupMember(createBahmniObservation("child-uuid", "child-value", concept, obsDateTime, "parentConceptUuid")); + + EncounterTransaction.Observation observation = bahmniObservation.toETObservation(); + + assertEquals("comment",observation.getComment()); + assertEquals("obs-uuid",observation.getUuid()); + assertEquals("concept-uuid",observation.getConceptUuid()); + assertEquals("order-uuid",observation.getOrderUuid()); + assertEquals(obsDateTime,observation.getObservationDateTime()); + assertEquals(1,observation.getGroupMembers().size()); + assertEquals("obs-value",observation.getValue()); + assertEquals(true,observation.getVoided()); + assertEquals("void reason", observation.getVoidReason()); + assertEquals("child-uuid", observation.getGroupMembers().get(0).getUuid()); + assertEquals("child-value", observation.getGroupMembers().get(0).getValue()); + assertEquals("formUuid", observation.getFormNamespace()); + assertEquals("formFieldPath", observation.getFormFieldPath()); + } + + @Test + public void testBahmniObservationCreation() { + Date obsDateTime = new Date(); + EncounterTransaction.Concept concept = createConcept("concept-uuid", "concept-name"); + BahmniObservation bahmniObservation = createBahmniObservation("obs-uuid", "obs-value", concept, obsDateTime, "parentConceptUuid"); + + assertEquals("concept-name", bahmniObservation.getConceptNameToDisplay()); + assertEquals("formUuid", bahmniObservation.getFormNamespace()); + assertEquals("formFieldPath", bahmniObservation.getFormFieldPath()); + } + + private EncounterTransaction.Concept createConcept(String conceptUuid, String conceptName) { + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(); + concept.setUuid(conceptUuid); + concept.setName(conceptName); + return concept; + } + + private BahmniObservation createBahmniObservation(String uuid,String value,EncounterTransaction.Concept concept,Date obsDate, String parentConceptUuid) { + BahmniObservation bahmniObservation1 = new BahmniObservation(); + bahmniObservation1.setUuid(uuid); + bahmniObservation1.setValue(value); + bahmniObservation1.setConcept(concept); + bahmniObservation1.setComment("comment"); + bahmniObservation1.setObservationDateTime(obsDate); + bahmniObservation1.setOrderUuid("order-uuid"); + bahmniObservation1.setVoided(true); + bahmniObservation1.setVoidReason("void reason"); + bahmniObservation1.setParentConceptUuid(parentConceptUuid); + bahmniObservation1.setFormNamespace("formUuid"); + bahmniObservation1.setFormFieldPath("formFieldPath"); + return bahmniObservation1; + } + + private EncounterTransaction.Observation createETObservation(String uuid,String value,EncounterTransaction.Concept concept,final Date obsDate) { + EncounterTransaction.Observation etObservation = new EncounterTransaction.Observation(); + etObservation.setUuid(uuid); + etObservation.setValue(value); + etObservation.setConcept(concept); + etObservation.setComment("comment"); + etObservation.setObservationDateTime(obsDate); + etObservation.setOrderUuid("order-uuid"); + etObservation.setVoided(true); + etObservation.setVoidReason("void reason"); + return etObservation; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/handler/BahmniDiagnosisHandlerTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/handler/BahmniDiagnosisHandlerTest.java new file mode 100644 index 0000000000..a11c051d07 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/handler/BahmniDiagnosisHandlerTest.java @@ -0,0 +1,219 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.handler; + +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.builder.ConceptBuilder; +import org.openmrs.module.bahmniemrapi.builder.EncounterBuilder; +import org.openmrs.module.bahmniemrapi.builder.ObsBuilder; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.diagnosis.helper.BahmniDiagnosisMetadata; +import org.openmrs.module.emrapi.EmrApiProperties; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Set; +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@PrepareForTest({Context.class}) +@RunWith(PowerMockRunner.class) + +public class BahmniDiagnosisHandlerTest { + + public static final String BOOLEAN_DATATYPE_UUID = "8d4a5cca-c2cc-11de-8d13-0010c6dffd0f"; + @Mock + private BahmniDiagnosisMetadata bahmniDiagnosisMetadata; + private Concept statusConcept = new Concept(); + private Concept revisedConcept = new Concept(); + private Concept initialDiagnosisConcept = new Concept(); + @Mock + private ConceptService conceptService; + @Mock + private EmrApiProperties emrApiProperties; + @Mock + private ObsService obsService; + + @Before + public void setup() { + initMocks(this); + mockStatic(Context.class); + ConceptDatatype booleanDataType = new ConceptDatatype(); + booleanDataType.setUuid(BOOLEAN_DATATYPE_UUID); + revisedConcept.setDatatype(booleanDataType); + PowerMockito.when(Context.getConceptService()).thenReturn(conceptService); + Concept trueConcept = new Concept(); + when(conceptService.getTrueConcept()).thenReturn(trueConcept); + when(conceptService.getFalseConcept()).thenReturn(new Concept()); + + statusConcept.setUuid(String.valueOf(UUID.randomUUID())); + revisedConcept.setUuid(String.valueOf(UUID.randomUUID())); + initialDiagnosisConcept.setUuid(String.valueOf(UUID.randomUUID())); + + when(bahmniDiagnosisMetadata.getBahmniDiagnosisStatusConcept()).thenReturn(statusConcept); + when(bahmniDiagnosisMetadata.getBahmniDiagnosisRevisedConcept()).thenReturn(revisedConcept); + when(bahmniDiagnosisMetadata.getBahmniInitialDiagnosisConcept()).thenReturn(initialDiagnosisConcept); + } + + @Test + public void shouldSaveStatusWhenFirstSave() { + EncounterTransaction encounterTransaction = new EncounterTransaction(); + + + BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + bahmniDiagnosisRequest.setCertainty("CONFIRMED"); + EncounterTransaction.Concept codedAnswer = new EncounterTransaction.Concept(); + codedAnswer.setName("Fever"); + EncounterTransaction.Concept etStatusConcept = new EncounterTransaction.Concept(); + String RULED_OUT_CONCEPT = "Ruled out"; + etStatusConcept.setName(RULED_OUT_CONCEPT); + bahmniDiagnosisRequest.setCodedAnswer(codedAnswer); + bahmniDiagnosisRequest.setDiagnosisStatusConcept(etStatusConcept); + encounterTransaction.addDiagnosis(bahmniDiagnosisRequest); + + Encounter encounter = new EncounterBuilder().build(); + Obs diagnosisObs = new ObsBuilder() + .withConcept(new ConceptBuilder().withName("Diagnosis Concept Set").build()) + .withGroupMembers(new Obs[]{}) + .build(); + encounter.addObs(diagnosisObs); + + when(bahmniDiagnosisMetadata.findMatchingDiagnosis(encounter.getObs(), bahmniDiagnosisRequest)).thenReturn + (diagnosisObs); + + when(bahmniDiagnosisMetadata.diagnosisSchemaContainsStatus()).thenReturn(true); + Concept ruledOutConcept = new Concept(); + when(conceptService.getConcept(RULED_OUT_CONCEPT)).thenReturn(ruledOutConcept); + + + + new BahmniDiagnosisHandler(bahmniDiagnosisMetadata, obsService, conceptService).forSave(encounter, + encounterTransaction); + + Set groupMembers = diagnosisObs.getGroupMembers(); + assertEquals(3, groupMembers.size()); + assertThat(groupMembers, hasItem(containsObsWith(statusConcept, ruledOutConcept))); + assertThat(groupMembers, hasItem(containsObsWith(revisedConcept, conceptService.getFalseConcept()))); + assertThat(groupMembers, hasItem(containsObsWith(initialDiagnosisConcept, diagnosisObs.getUuid()))); + } + + @Test + public void shouldUpdateValueOfRevisedInPreviousDiagnosisWithTrue() { + EncounterTransaction encounterTransaction = new EncounterTransaction(); + + + BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + bahmniDiagnosisRequest.setCertainty("CONFIRMED"); + EncounterTransaction.Concept codedAnswer = new EncounterTransaction.Concept(); + codedAnswer.setName("Fever"); + EncounterTransaction.Concept etStatusConcept = new EncounterTransaction.Concept(); + String RULED_OUT_CONCEPT = "Ruled out"; + etStatusConcept.setName(RULED_OUT_CONCEPT); + bahmniDiagnosisRequest.setCodedAnswer(codedAnswer); + bahmniDiagnosisRequest.setDiagnosisStatusConcept(etStatusConcept); + bahmniDiagnosisRequest.setPreviousObs(String.valueOf(UUID.randomUUID())); + BahmniDiagnosis firstDiagnosis = new BahmniDiagnosis(); + firstDiagnosis.setExistingObs("i dont care"); + bahmniDiagnosisRequest.setFirstDiagnosis(firstDiagnosis); + + encounterTransaction.addDiagnosis(bahmniDiagnosisRequest); + + Encounter encounter = new EncounterBuilder().build(); + Obs diagnosisObs = new ObsBuilder() + .withConcept(new ConceptBuilder().withName("Diagnosis Concept Set").build()) + .withGroupMembers(new Obs[]{}) + .build(); + encounter.addObs(diagnosisObs); + + when(bahmniDiagnosisMetadata.findMatchingDiagnosis(encounter.getObs(), bahmniDiagnosisRequest)).thenReturn + (diagnosisObs); + when(bahmniDiagnosisMetadata.diagnosisSchemaContainsStatus()).thenReturn(true); + Concept ruledOutConcept = new Concept(); + when(conceptService.getConcept(RULED_OUT_CONCEPT)).thenReturn(ruledOutConcept); + Obs nonRevisedConcept = new ObsBuilder() + .withConcept(revisedConcept) + .withValue(conceptService.getFalseConcept()).build(); + Obs previousObs = new ObsBuilder().withGroupMembers( + nonRevisedConcept + ).build(); + when(obsService.getObsByUuid(bahmniDiagnosisRequest.getPreviousObs())).thenReturn(previousObs); + + + new BahmniDiagnosisHandler(bahmniDiagnosisMetadata, obsService, conceptService).forSave(encounter, + encounterTransaction); + + Set groupMembers = diagnosisObs.getGroupMembers(); + assertEquals(3, groupMembers.size()); + assertThat(groupMembers, hasItem(containsObsWith(statusConcept, ruledOutConcept))); + assertThat(groupMembers, hasItem(containsObsWith(revisedConcept, conceptService.getFalseConcept()))); + assertThat(groupMembers, hasItem(containsObsWith(initialDiagnosisConcept, + bahmniDiagnosisRequest.getFirstDiagnosis().getExistingObs()))); + assertThat(nonRevisedConcept.getValueCoded(), is(equalTo(conceptService.getTrueConcept()))); + verify(obsService).saveObs(previousObs, "Diagnosis is revised"); + } + + @Test + public void shouldHaveTheSameInitialDiagnosisAcrossMultipleSave() { + EncounterTransaction encounterTransaction = new EncounterTransaction(); + String existingObsUUid = "ExistingObsUUID"; + + BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + BahmniDiagnosis firstDiagnosis = new BahmniDiagnosis(); + firstDiagnosis.setExistingObs(existingObsUUid); + bahmniDiagnosisRequest.setFirstDiagnosis(firstDiagnosis); + encounterTransaction.addDiagnosis(bahmniDiagnosisRequest); + Encounter encounter = new EncounterBuilder().build(); + Obs initialObs =new ObsBuilder().withConcept(initialDiagnosisConcept).withGroupMembers(new Obs[]{}).build(); + initialObs.setId(123); + Obs diagnosisObs = new ObsBuilder() + .withConcept(new ConceptBuilder().withName("Diagnosis Concept Set").build()) + .withGroupMembers(initialObs) + .build(); + encounter.addObs(diagnosisObs); + + when(bahmniDiagnosisMetadata.findMatchingDiagnosis(encounter.getObsAtTopLevel(false), bahmniDiagnosisRequest)).thenReturn + (diagnosisObs); + + new BahmniDiagnosisHandler(bahmniDiagnosisMetadata, obsService, conceptService).forSave(encounter, + encounterTransaction); + + Set groupMembers = diagnosisObs.getGroupMembers(); + assertEquals(2, groupMembers.size()); + assertThat(groupMembers, hasItem(containsObsWith(revisedConcept, conceptService.getFalseConcept()))); + assertThat(groupMembers, hasItem(containsObsWith(initialDiagnosisConcept, existingObsUUid))); + } + + private Matcher> containsObsWith(Concept concept, Concept value) { + return Matchers.allOf(hasProperty("concept", is(equalTo(concept))) + , hasProperty("valueCoded", is(equalTo(value)))); + } + + private Matcher> containsObsWith(Concept concept, String value) { + return Matchers.allOf(hasProperty("concept", is(equalTo(concept))) + , hasProperty("valueText", is(equalTo(value)))); + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImplIT.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImplIT.java new file mode 100644 index 0000000000..2d9f0a42ba --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImplIT.java @@ -0,0 +1,759 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.impl; + +import org.apache.commons.lang.time.DateUtils; +import org.joda.time.DateTime; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.VisitAttribute; +import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.BaseIntegrationTest; +import org.openmrs.module.bahmniemrapi.builder.BahmniDiagnosisRequestBuilder; +import org.openmrs.module.bahmniemrapi.builder.BahmniEncounterTransactionBuilder; +import org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder; +import org.openmrs.module.bahmniemrapi.builder.ETConceptBuilder; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitIdentificationHelper; +import org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship; +import org.openmrs.module.emrapi.CareSettingType; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.parameter.EncounterSearchCriteria; +import org.openmrs.parameter.EncounterSearchCriteriaBuilder; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class BahmniEncounterTransactionServiceImplIT extends BaseIntegrationTest { + + private final String VISIT_UUID = "4e663d66-6b78-11e0-93c3-18a905e044dc"; + private final String PATIENT_UUID = "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"; + private final String LOCATION_UUID = "l3602jn5-9fhb-4f20-866b-0ece24561525"; + private final String ENCOUNTER_TYPE_UUID = "07000be2-26b6-4cce-8b40-866d8435b613"; + private final String VISIT_TYPE_UUID = "c0c579b0-8e59-401d-8a4a-976a0b183593"; + private final String VISIT_UUID1 = "1e5d5d48-6b78-11e0-93c3-18a905e044ce"; + private final String DISCHARGE_ENCOUNTER_TYPE_UUID = "02c533ab-b74b-4ee4-b6e5-ffb6d09a0ad0"; + + @Autowired + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + @Autowired + private VisitService visitService; + + @Autowired + private EncounterService encounterService; + + @Autowired + private PatientService patientService; + + @Autowired + private OrderService orderService; + + @Autowired + private MockEncounterTransactionHandler mockEncounterTransactionHandler; + + @Before + public void setUp() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("obsRelationshipDataset.xml"); + executeDataSet("visitAttributeDataSet.xml"); + executeDataSet("drugOrderTestData.xml"); + executeDataSet("concepts.xml"); + } + + @Test + public void shouldSaveFutureDrugOrdersInEncounterTransaction() { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + + Patient patient = patientService.getPatientByUuid(PATIENT_UUID); + List originalOrders = orderService.getActiveOrders(patient, orderService.getOrderTypeByName("Drug Order"), + orderService.getCareSettingByName("OUTPATIENT"), null); + + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setUuid(Context.getProviderService().getProvider(1).getUuid()); + Set providerSet = new HashSet<>(); + providerSet.add(provider); + + EncounterTransaction.Concept concept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(concept) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + EncounterTransaction.DrugOrder etDrugOrder = createETDrugOrder("1ce527b5-d6de-43f0-bc62-4616abacd77e", null, null, + new DateTime().plusDays(2).toDate()); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withObservation(bahmniObservation) + .withVisitTypeUuid(VISIT_TYPE_UUID) + .withProviders(providerSet) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .withDrugOrders(Arrays.asList(etDrugOrder)) + .build(); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + List latestOrders = orderService.getActiveOrders(patient, orderService.getOrderTypeByName("Drug Order"), + orderService.getCareSettingByName("OUTPATIENT"), null); + assertEquals(originalOrders.size() + 1, latestOrders.size()); + assertEquals(Order.Action.NEW, latestOrders.get(originalOrders.size()).getAction()); + assertEquals(1, encounterTransaction.getDrugOrders().size()); + } + + @Test + public void shouldSavePastDrugOrdersInEncounterTransaction() throws ParseException { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + + Patient patient = patientService.getPatientByUuid(PATIENT_UUID); + List originalOrders = orderService.getActiveOrders(patient, orderService.getOrderTypeByName("Drug Order"), + orderService.getCareSettingByName("OUTPATIENT"), null); + + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setUuid(Context.getProviderService().getProvider(1).getUuid()); + Set providerSet = new HashSet<>(); + providerSet.add(provider); + + EncounterTransaction.Concept concept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(concept) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + Date pastScheduledDateForDrugOrder = new DateTime().minusDays(2).toDate(); + EncounterTransaction.DrugOrder etDrugOrder = createETDrugOrder("1ce527b5-d6de-43f0-bc62-4616abacd77e", + null, null, pastScheduledDateForDrugOrder); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withObservation(bahmniObservation) + .withVisitTypeUuid(VISIT_TYPE_UUID) + .withProviders(providerSet) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .withLocationUuid(LOCATION_UUID) + .withDrugOrders(Arrays.asList(etDrugOrder)) + .build(); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + List latestOrders = orderService.getActiveOrders(patient, orderService.getOrderTypeByName("Drug Order"), + orderService.getCareSettingByName("OUTPATIENT"), null); + assertEquals(originalOrders.size() + 1, latestOrders.size()); + assertEquals(Order.Action.NEW, latestOrders.get(originalOrders.size()).getAction()); + assertEquals(0, encounterTransaction.getDrugOrders().size()); + + //we are dropping millis here because DropMillisecondsHibernateInterceptor drops the milliseconds of objects before saving + Date pastScheduledDateWithoutMillis = DateUtils.setMilliseconds(pastScheduledDateForDrugOrder, 0); + //Ensure that two encounters are created. + EncounterSearchCriteria encounterSearchCriteria = new EncounterSearchCriteriaBuilder() + .setPatient(patient) + .setFromDate(pastScheduledDateWithoutMillis) + .setIncludeVoided(false) + .createEncounterSearchCriteria(); + List encounters = encounterService.getEncounters(encounterSearchCriteria); + + + assertEquals(2, encounters.size()); + assertEquals(1, encounters.get(0).getOrders().size()); + assertEquals(0, encounters.get(1).getOrders().size()); + assertEquals(1, encounterTransaction.getObservations().size()); + assertEquals(obsUuid, encounterTransaction.getObservations().iterator().next().getUuid()); + + } + + @Test + public void shouldSavePastDrugOrdersInEncounterTransactionWhenThereIsNoRetrospectiveVisit() throws ParseException { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + + Patient patient = patientService.getPatientByUuid(PATIENT_UUID); + + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setUuid(Context.getProviderService().getProvider(1).getUuid()); + Set providerSet = new HashSet<>(); + providerSet.add(provider); + + EncounterTransaction.Concept concept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(concept) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + Date pastScheduledDateForDrugOrder = new DateTime().minusYears(12).toDate(); + EncounterTransaction.DrugOrder etDrugOrder = createETDrugOrder("1ce527b5-d6de-43f0-bc62-4616abacd77e", null, null, pastScheduledDateForDrugOrder); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder().withObservation(bahmniObservation) + .withVisitTypeUuid(VISIT_TYPE_UUID) + .withProviders(providerSet) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .withLocationUuid(LOCATION_UUID) + .withDrugOrders(Arrays.asList(etDrugOrder)) + .build(); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + //we are dropping millis here because DropMillisecondsHibernateInterceptor drops the milliseconds of objects before saving + Date pastScheduledDateWithoutMillis = DateUtils.setMilliseconds(pastScheduledDateForDrugOrder, 0); + + //Ensure that two encounters are created. + EncounterSearchCriteria encounterSearchCriteria = new EncounterSearchCriteriaBuilder() + .setPatient(patient) + .setFromDate(pastScheduledDateWithoutMillis) + .setToDate(pastScheduledDateWithoutMillis) + .setIncludeVoided(false) + .createEncounterSearchCriteria(); + List encounters = encounterService.getEncounters(encounterSearchCriteria); + + assertEquals(1, encounters.size()); + assertEquals(1, encounters.get(0).getOrders().size()); + DrugOrder order = (DrugOrder) encounters.get(0).getOrders().iterator().next(); + assertEquals("1ce527b5-d6de-43f0-bc62-4616abacd77e", order.getDrug().getUuid()); + assertEquals(1, encounterTransaction.getObservations().size()); + BahmniObservation next = encounterTransaction.getObservations().iterator().next(); + assertEquals(obsUuid, next.getUuid()); + + } + + + @Test + public void shouldSaveBahmniEncounterTransactionWithBahmniObservationsWithGivenUuid() { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + + EncounterTransaction.Concept build = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(build) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withObservation(bahmniObservation) + .withVisitTypeUuid(VISIT_TYPE_UUID) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .build(); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + assertNotNull(encounterTransaction); + assertEquals(1, encounterTransaction.getObservations().size()); + assertEquals(bahmniObservation.getValue(), encounterTransaction.getObservations().iterator().next().getValue()); + assertEquals(obsUuid, encounterTransaction.getObservations().iterator().next().getUuid()); + assertEquals("OPD", bahmniEncounterTransaction.getVisitType()); + } + + @Test + public void shouldNotCreateANewVisitIfThereIsAnActiveVisit() { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + String patientUuid = PATIENT_UUID; + String visitType = "OPD"; + Patient patientByUuid = patientService.getPatientByUuid(patientUuid); + VisitIdentificationHelper visitIdentificationHelper = new VisitIdentificationHelper(visitService, null); + + EncounterTransaction.Concept concept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(concept) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withObservation(bahmniObservation) + .withPatientId("4") + .withPatientUuid(patientUuid) + .withEncounterTypeUuid("02c533ab-b74b-4ee4-b6e5-ffb6d09a0ad1") + .withVisitType(visitType) + .build(); + + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + assertNotNull(visitIdentificationHelper.hasActiveVisit(patientByUuid)); + assertNotNull(savedEncounterTransaction); + assertEquals(savedEncounterTransaction.getObservations().iterator().next().getUuid(), bahmniObservation.getUuid()); + } + + + @Test + public void shouldCreateANewVisitAndSetVisitLocationToVisitIfNoActiveVisit() throws Exception { + executeDataSet("VisitLocationDataSet.xml"); + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + String visitType = "Emergency"; + String locationUuid = "l3602jn5-9fhb-4f20-866b-0ece24561526"; + String encounterTypeUuid = "02c533ab-b74b-4ee4-b6e5-ffb6d09a0ad1"; + + EncounterTransaction.Concept concept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(concept) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder().withPatientId("4") + .withLocationUuid(locationUuid) + .withPatientUuid(patientUuid) + .withEncounterTypeUuid(encounterTypeUuid) + .withVisitType(visitType) + .withObservation(bahmniObservation) + .build(); + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + Visit visit = Context.getVisitService().getVisitByUuid(savedEncounterTransaction.toEncounterTransaction().getVisitUuid()); + assertEquals(locationUuid, visit.getLocation().getUuid()); + } + + @Test + public void shouldCreateVisitAttributeOfVisitStatusAsOpdIrrespectiveOfVisitType() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withVisitUuid(VISIT_UUID1) + .withPatientUuid(PATIENT_UUID).withEncounterTypeUuid(ENCOUNTER_TYPE_UUID).build(); + + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + Visit visit = visitService.getVisitByUuid(savedEncounterTransaction.getVisitUuid()); + assertNotNull(visit); + assertEquals(1, visit.getAttributes().size()); + assertEquals("OPD", visit.getAttributes().iterator().next().getValue()); + } + + @Test + public void shouldCreateVisitAttributeOfVisitStatusAsIpdIfTheEncounterIsOfAdmissionType() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withVisitUuid(VISIT_UUID1) + .withPatientUuid(PATIENT_UUID) + .withEncounterTypeUuid("02c533ab-b74b-4ee4-b6e5-ffb6d09a0ad9") + .build(); + + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + Visit visit = visitService.getVisitByUuid(savedEncounterTransaction.getVisitUuid()); + assertNotNull(visit); + assertEquals(2, visit.getAttributes().size()); + assertEquals("IPD", visit.getAttributes().iterator().next().getValue()); + } + + @Test + public void shouldCreateVisitAttributeOfAdmissionStatusAsAdmittedIfTheEncounterIsOfAdmissionType() throws Exception { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withVisitUuid(VISIT_UUID1) + .withPatientUuid(PATIENT_UUID) + .withEncounterTypeUuid("02c533ab-b74b-4ee4-b6e5-ffb6d09a0ad9") + .build(); + + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + Visit visit = visitService.getVisitByUuid(savedEncounterTransaction.getVisitUuid()); + assertNotNull(visit); + assertEquals(2, visit.getAttributes().size()); + Iterator visitAttributeIterator = visit.getAttributes().iterator(); + assertEquals("IPD", visitAttributeIterator.next().getValue()); + assertEquals("Admitted", visitAttributeIterator.next().getValue()); + } + + @Test + public void shouldCreateVisitAttributeOfAdmissionStatusAsDischargedIfTheEncounterIsOfDischargeType() throws Exception { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withVisitUuid(VISIT_UUID1) + .withPatientUuid(PATIENT_UUID) + .withEncounterTypeUuid(DISCHARGE_ENCOUNTER_TYPE_UUID) + .build(); + + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + Visit visit = visitService.getVisitByUuid(savedEncounterTransaction.getVisitUuid()); + assertNotNull(visit); + assertEquals(2, visit.getAttributes().size()); + Iterator visitAttributeIterator = visit.getAttributes().iterator(); + assertEquals("OPD", visitAttributeIterator.next().getValue()); + assertEquals("Discharged", visitAttributeIterator.next().getValue()); + } + + @Test + public void shouldNotCreateVisitAttributeOfAdmissionStatusIfTheEncounterTypeIsOfOtherThanAdmissionAndDischarged() + throws Exception { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withVisitUuid(VISIT_UUID1) + .withPatientUuid(PATIENT_UUID) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .build(); + + BahmniEncounterTransaction savedEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + Visit visit = visitService.getVisitByUuid(savedEncounterTransaction.getVisitUuid()); + assertNotNull(visit); + assertEquals(1, visit.getAttributes().size()); + Iterator visitAttributeIterator = visit.getAttributes().iterator(); + assertEquals("OPD", visitAttributeIterator.next().getValue()); + } + + @Test + public void shouldCreateVisitAttributeWhenTheDischargeIsRolledBack() { + String encounterUuid = "bb0af6767-707a-4629-9850-f1529a163ab0"; + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder().withEncounterTypeUuid(DISCHARGE_ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID1) + .withEncounterUuid(encounterUuid) + .withReason("Undo Discharge") + .build(); + + bahmniEncounterTransactionService.delete(bahmniEncounterTransaction); + + Encounter encounter = encounterService.getEncounterByUuid("bb0af6767-707a-4629-9850-f1529a163ab0"); + assertTrue(encounter.isVoided()); + + Visit visit = visitService.getVisitByUuid(VISIT_UUID1); + assertNotNull(visit); + + VisitAttribute visitAttribute = getAdmittedVisitAttribute(visit); + assertNotNull(visitAttribute); + assertEquals("Admitted", visitAttribute.getValue()); + } + + private VisitAttribute getAdmittedVisitAttribute(Visit visit) { + for (VisitAttribute visitAttribute : visit.getAttributes()) { + if (visitAttribute.getAttributeType().getName().equalsIgnoreCase("Admission Status")) { + return visitAttribute; + } + } + return null; + } + + @Test + public void shouldSaveObsRelationShipWhenBothObservationsAreInSameEncounter() { + Date obsDate = new Date(); + String srcObsUuid = UUID.randomUUID().toString(); + String targetObsUuid = UUID.randomUUID().toString(); + + EncounterTransaction.Concept targetConcept = new ETConceptBuilder() + .withUuid("c607c80f-1ea9-4da3-bb88-6276ce8868dd") + .withName("WEIGHT (KG)") + .build(); + BahmniObservation targetObs = new BahmniObservationBuilder().withUuid(targetObsUuid).withConcept(targetConcept) + .withObsDateTime(obsDate) + .withComment("comment") + .withTargetObsRelationship(new ObsRelationship(null, null, "qualified-by")) + .withValue(150.0) + .build(); + + EncounterTransaction.Concept srcConcept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation srcObs = new BahmniObservationBuilder().withUuid(srcObsUuid).withConcept(srcConcept) + .withObsDateTime(obsDate) + .withComment("comment") + .withTargetObsRelationship(new ObsRelationship(targetObs, null, "qualified-by")) + .withValue("src-value") + .build(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withVisitUuid(VISIT_UUID) + .withPatientUuid(PATIENT_UUID) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withObservation(srcObs, targetObs) + .build(); + + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + assertEquals(2, encounterTransaction.getObservations().size()); + + BahmniObservation savedSrcObs = getObservationByConceptUuid(encounterTransaction.getObservations(), + srcConcept.getUuid()); + assertEquals(srcObs.getValue(), savedSrcObs.getValue()); + assertEquals(srcObsUuid, savedSrcObs.getUuid()); + assertEquals(srcConcept.getUuid(), savedSrcObs.getConceptUuid()); + + assertEquals(targetObs.getValue(), savedSrcObs.getTargetObsRelation().getTargetObs().getValue()); + assertEquals(targetObsUuid, savedSrcObs.getTargetObsRelation().getTargetObs().getUuid()); + assertEquals(targetConcept.getUuid(), savedSrcObs.getTargetObsRelation().getTargetObs().getConceptUuid()); + } + + @Test + public void shouldSaveObsRelationShipWhenBothObservationsAreInDifferentEncounter() throws ParseException { + Date obsDate = new Date(); + String srcObsUuid = UUID.randomUUID().toString(); + String targetObsUuid = "f6ec1267-8eac-415f-a3f0-e47be2c8bb67"; + + + EncounterTransaction.Concept targetConcept = new ETConceptBuilder() + .withUuid("a09ab2c5-878e-4905-b25d-5784167d0216") + .withName("CD4 COUNT") + .build(); + BahmniObservation targetObs = new BahmniObservationBuilder().withUuid(targetObsUuid).withConcept(targetConcept) + .withObsDateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse("2008-08-15 00:00:00.0")) + .withComment("comment") + .withTargetObsRelationship(new ObsRelationship(null, null, "qualified-by")) + .withValue(175d) + .build(); + + EncounterTransaction.Concept srcConcept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation srcObs = new BahmniObservationBuilder().withUuid(srcObsUuid).withConcept(srcConcept) + .withObsDateTime(obsDate) + .withComment("comment") + .withTargetObsRelationship(new ObsRelationship(targetObs, null, "qualified-by")) + .withValue("src-value") + .build(); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder().withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID).withObservation(srcObs).build(); + + BahmniEncounterTransaction mappedBahmniEncounterTransaction = bahmniEncounterTransactionService + .save(bahmniEncounterTransaction); + + assertEquals(1, mappedBahmniEncounterTransaction.getObservations().size()); + BahmniObservation savedSrcObs = mappedBahmniEncounterTransaction.getObservations().iterator().next(); + assertEquals(srcObs.getValue(), savedSrcObs.getValue()); + assertEquals(srcObsUuid, savedSrcObs.getUuid()); + assertEquals(srcObs.getConcept().getUuid(), savedSrcObs.getConceptUuid()); + assertEquals(targetObs.getValue(), savedSrcObs.getTargetObsRelation().getTargetObs().getValue()); + assertEquals(targetObs.getUuid(), savedSrcObs.getTargetObsRelation().getTargetObs().getUuid()); + assertEquals(targetConcept.getUuid(), savedSrcObs.getTargetObsRelation().getTargetObs().getConceptUuid()); + assertEquals(targetObs.getObservationDateTime(), + savedSrcObs.getTargetObsRelation().getTargetObs().getObservationDateTime()); + } + + @Test + public void shouldSavePastDrugOrdersInEncounterTransactionWhenThereIsNoRetrospectiveVisitWithNoVisitTypeUuid() throws ParseException { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + + Patient patient = patientService.getPatientByUuid(PATIENT_UUID); + + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setUuid(Context.getProviderService().getProvider(1).getUuid()); + Set providerSet = new HashSet(); + providerSet.add(provider); + + EncounterTransaction.Concept obsConcept = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(obsConcept) + .withObsDateTime(obsDate) + .withComment("comment") + .withTargetObsRelationship(new ObsRelationship(null, null, "qualified-by")) + .withValue("obs-value") + .build(); + Date pastScheduledDateForDrugOrder = new DateTime().minusYears(12).toDate(); + EncounterTransaction.DrugOrder etDrugOrder = createETDrugOrder("1ce527b5-d6de-43f0-bc62-4616abacd77e", null, null, pastScheduledDateForDrugOrder); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withObservation(bahmniObservation) + .withVisitType("Hospitalization") + .withProviders(providerSet) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .withLocationUuid(LOCATION_UUID) + .withDrugOrders(Arrays.asList(etDrugOrder)) + .build(); + + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + //we are dropping millis here because DropMillisecondsHibernateInterceptor drops the milliseconds of objects before saving + Date pastScheduledDateWithoutMillis = DateUtils.setMilliseconds(pastScheduledDateForDrugOrder, 0); + + //Ensure that two encounters are created. + EncounterSearchCriteria encounterSearchCriteria = new EncounterSearchCriteriaBuilder() + .setPatient(patient) + .setFromDate(pastScheduledDateWithoutMillis) + .setToDate(pastScheduledDateWithoutMillis) + .setIncludeVoided(false) + .createEncounterSearchCriteria(); + List encounters = encounterService.getEncounters(encounterSearchCriteria); + + + assertEquals(1, encounters.size()); + Encounter encounter = encounters.get(0); + + assertEquals(1, encounter.getOrders().size()); + DrugOrder order = (DrugOrder) encounter.getOrders().iterator().next(); + assertEquals("1ce527b5-d6de-43f0-bc62-4616abacd77e", order.getDrug().getUuid()); + assertEquals(1, encounterTransaction.getObservations().size()); + assertEquals(obsUuid, encounterTransaction.getObservations().iterator().next().getUuid()); + + } + + @Test + public void shouldSaveDiagnoses(){ + EncounterTransaction.Concept feverConcept = new ETConceptBuilder().withName("Fever") + .withUuid("9169366f-3c7f-11e3-8f4c-005056823ee3") + .build(); + BahmniDiagnosisRequest bahmniDiagnosis = new BahmniDiagnosisRequestBuilder() + .withCodedAnswer(feverConcept) + .withOrder("PRIMARY") + .withCertainty("PRESUMED") + .withStatus(new ETConceptBuilder() + .withUuid("d102c80f-1yz9-4da3-bb88-8122ce8868eg") + .withName("Ruled Out").build()) + .build(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withDiagnoses(bahmniDiagnosis) + .withVisitTypeUuid(VISIT_TYPE_UUID) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .build(); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + Context.flushSession(); + Context.clearSession(); + + assertThat(encounterTransaction.getBahmniDiagnoses().size(), is(equalTo(1))); + BahmniDiagnosis diagnosis = encounterTransaction.getBahmniDiagnoses().get(0); + assertThat(diagnosis.getCertainty(), is(equalTo("PRESUMED"))); + assertThat(diagnosis.getOrder(), is(equalTo("PRIMARY"))); + assertThat(diagnosis.getCodedAnswer().getName(), is(equalTo("Fever"))); + Encounter savedEncounter = Context.getEncounterService().getEncounterByUuid(encounterTransaction + .getEncounterUuid()); + assertThat(savedEncounter.getObsAtTopLevel(true).size(), is(equalTo(1))); + assertThat(savedEncounter.getAllObs(true).size(), is(equalTo(6))); + + encounterTransaction.getBahmniDiagnoses().get(0).setCertainty("CONFIRMED"); + + + encounterTransaction = bahmniEncounterTransactionService.save(encounterTransaction); + Context.flushSession(); + Context.clearSession(); + + assertThat(encounterTransaction.getBahmniDiagnoses().size(), is(equalTo(1))); + diagnosis = encounterTransaction.getBahmniDiagnoses().get(0); + assertThat(diagnosis.getCertainty(), is(equalTo("CONFIRMED"))); + assertThat(diagnosis.getOrder(), is(equalTo("PRIMARY"))); + assertThat(diagnosis.getCodedAnswer().getName(), is(equalTo("Fever"))); + savedEncounter = Context.getEncounterService().getEncounterByUuid(encounterTransaction + .getEncounterUuid()); + assertThat(savedEncounter.getObsAtTopLevel(true).size(), is(equalTo(1))); + assertThat(savedEncounter.getAllObs(true).size(), is(equalTo(7))); + assertThat(savedEncounter.getAllObs(false).size(), is(equalTo(6))); + } + + @Test + public void shouldRunAllRegisteredHandlers() { + Date obsDate = new Date(); + String obsUuid = UUID.randomUUID().toString(); + + EncounterTransaction.Concept build = new ETConceptBuilder() + .withUuid("96408258-000b-424e-af1a-403919332938") + .withName("FAVORITE FOOD, NON-CODED") + .build(); + BahmniObservation bahmniObservation = new BahmniObservationBuilder().withUuid(obsUuid).withConcept(build) + .withObsDateTime(obsDate) + .withValue("obs-value") + .build(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransactionBuilder() + .withObservation(bahmniObservation) + .withVisitTypeUuid(VISIT_TYPE_UUID) + .withEncounterTypeUuid(ENCOUNTER_TYPE_UUID) + .withPatientUuid(PATIENT_UUID) + .withVisitUuid(VISIT_UUID) + .build(); + + int numberOfTimesSaveWasCalled = mockEncounterTransactionHandler.numberOfTimesSaveWasCalled; + bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + assertThat(mockEncounterTransactionHandler.numberOfTimesSaveWasCalled, is(equalTo(numberOfTimesSaveWasCalled + + 1))); + } + + private BahmniObservation getObservationByConceptUuid(Collection bahmniObservations, + String conceptUuid) { + for (BahmniObservation bahmniObservation : bahmniObservations) { + if (conceptUuid.equals(bahmniObservation.getConceptUuid())) { + return bahmniObservation; + } + } + return null; + } + + private EncounterTransaction.DrugOrder createETDrugOrder(String drugUuid, String action, String previousOrderUuid, + Date scheduledDate) { + EncounterTransaction.Drug encounterTransactionDrug = new EncounterTransaction.Drug(); + encounterTransactionDrug.setUuid(drugUuid); + + EncounterTransaction.DrugOrder drugOrder = new EncounterTransaction.DrugOrder(); + drugOrder.setCareSetting(CareSettingType.OUTPATIENT); + drugOrder.setAction(action); + drugOrder.setOrderType("Drug Order"); + drugOrder.setPreviousOrderUuid(previousOrderUuid); + drugOrder.setDrug(encounterTransactionDrug); + drugOrder.setDosingInstructionType( + "org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions.FlexibleDosingInstructions"); + drugOrder.setDuration(10); + drugOrder.setDurationUnits("Days"); + + drugOrder.setScheduledDate(scheduledDate); + drugOrder.setDateActivated(null); + drugOrder.setVoided(false); + + EncounterTransaction.DosingInstructions dosingInstructions = new EncounterTransaction.DosingInstructions(); + dosingInstructions.setAdministrationInstructions("{\"instructions\":\"As directed\"}"); + dosingInstructions.setAsNeeded(false); + dosingInstructions.setDose(1.0); + dosingInstructions.setDoseUnits("tab (s)"); + dosingInstructions.setFrequency("1/day x 7 days/week"); + dosingInstructions.setNumberOfRefills(0); + dosingInstructions.setQuantity(10.0); + dosingInstructions.setQuantityUnits(Context.getConceptService().getConcept(51).getName().getName()); + dosingInstructions.setRoute("UNKNOWN"); + drugOrder.setDosingInstructions(dosingInstructions); + + return drugOrder; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImplTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImplTest.java new file mode 100644 index 0000000000..4c58849182 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/BahmniEncounterTransactionServiceImplTest.java @@ -0,0 +1,167 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.impl; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.openmrs.Encounter; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.LocationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.openmrs.module.emrapi.encounter.EncounterTransactionMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.matcher.BaseEncounterMatcher; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniEncounterTransactionServiceImplTest { + + @Mock + private BaseEncounterMatcher baseEncounterMatcher; + + @Mock + private VisitService visitService; + + @Mock + private LocationService locationService; + + @Mock + private EncounterService encounterService; + + @Mock + private PatientService patientService; + + @Mock + private EncounterTransactionMapper encounterTransactionMapper; + + @Mock + private BahmniVisitLocationService bahmniVisitLocationService; + + @Mock + private BahmniVisitAttributeService bahmniVisitAttributeService; + + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + @Before + public void setUp() throws Exception { + initMocks(this); + bahmniEncounterTransactionService = new BahmniEncounterTransactionServiceImpl(encounterService,null,encounterTransactionMapper,null,null, null,visitService,patientService + ,locationService,null,baseEncounterMatcher,bahmniVisitLocationService, bahmniVisitAttributeService); + + } + + @Test + public void shouldReturnTheEncounterFromTheVisitThatIsOpenedInThatVisitLocation() throws Exception { + + Patient patient = new Patient(); + + EncounterTransaction encounterTransaction = new EncounterTransaction(); + encounterTransaction.setEncounterUuid("encounter-uuid"); + + Location loginLocation = new Location(); + loginLocation.setUuid("login-location-uuid"); + + Location location = new Location(); + location.setUuid("visit-location-uuid"); + Visit visit = new Visit(); + visit.setLocation(location); + visit.setUuid("visit-uuid"); + + Encounter encounter = new Encounter(); + encounter.setLocation(location); + encounter.setUuid("encounter-uuid"); + HashSet encounters = new HashSet<>(); + encounters.add(encounter); + visit.setEncounters(encounters); + + BahmniEncounterSearchParameters encounterSearchParameters = new BahmniEncounterSearchParameters(); + encounterSearchParameters.setLocationUuid(loginLocation.getUuid()); + encounterSearchParameters.setPatientUuid("patient-uuid"); + encounterSearchParameters.setEncounterTypeUuids(Arrays.asList("encounter-type-uuid")); + when(baseEncounterMatcher.findEncounter(any(Visit.class), any(EncounterParameters.class))).thenReturn(encounter); + List visits = Arrays.asList(visit); + when(locationService.getLocationByUuid(loginLocation.getUuid())).thenReturn(loginLocation); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + when(visitService.getActiveVisitsByPatient(any(Patient.class))).thenReturn(visits); + when(encounterService.getEncounterByUuid(anyString())).thenReturn(null); + when(bahmniVisitLocationService.getVisitLocationUuid(anyString())).thenReturn("visit-location-uuid"); + when(bahmniVisitLocationService.getMatchingVisitInLocation(visits, "login-location-uuid")).thenReturn(visit); + when(encounterTransactionMapper.map(any(Encounter.class),anyBoolean())).thenReturn(encounterTransaction); + bahmniEncounterTransactionService.find(encounterSearchParameters); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Visit.class); + ArgumentCaptor argument = ArgumentCaptor.forClass(EncounterParameters.class); + verify(baseEncounterMatcher).findEncounter(argumentCaptor.capture(), argument.capture()); + assertEquals(argumentCaptor.getValue().getUuid(), "visit-uuid"); + } + + @Test + public void shouldReturnTheEncounterFromTheVisitThatIsOpenedInThatVisitLocationIfThereAreTwoVisitsInDiffLocations() throws Exception { + Patient patient = new Patient(); + + EncounterTransaction encounterTransaction = new EncounterTransaction(); + encounterTransaction.setEncounterUuid("encounter-uuid"); + + Location loginLocation = new Location(); + loginLocation.setUuid("login-location-uuid"); + + Location location = new Location(); + location.setUuid("visit-location-uuid"); + + Visit visitOne = new Visit(); + visitOne.setLocation(location); + visitOne.setUuid("visit-uuid-one"); + + Location locationTwo = new Location(); + locationTwo.setUuid("visit-location-uuid-two"); + + Visit visitTwo = new Visit(); + visitTwo.setUuid("visit-uuid-two"); + visitTwo.setLocation(locationTwo); + + Encounter encounter = new Encounter(); + encounter.setLocation(location); + encounter.setUuid("encounter-uuid"); + HashSet encounters = new HashSet<>(); + encounters.add(encounter); + visitTwo.setEncounters(encounters); + + BahmniEncounterSearchParameters encounterSearchParameters = new BahmniEncounterSearchParameters(); + encounterSearchParameters.setLocationUuid("login-location-uuid"); + encounterSearchParameters.setPatientUuid("patient-uuid"); + encounterSearchParameters.setEncounterTypeUuids(Arrays.asList("encounter-type-uuid")); + when(locationService.getLocationByUuid(loginLocation.getUuid())).thenReturn(loginLocation); + when(baseEncounterMatcher.findEncounter(any(Visit.class), any(EncounterParameters.class))).thenReturn(encounter); + List visits = Arrays.asList(visitOne, visitTwo); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + when(visitService.getActiveVisitsByPatient(any(Patient.class))).thenReturn(visits); + when(encounterService.getEncounterByUuid(anyString())).thenReturn(null); + when(bahmniVisitLocationService.getVisitLocationUuid(anyString())).thenReturn("visit-location-uuid-two"); + when(bahmniVisitLocationService.getMatchingVisitInLocation(visits, "login-location-uuid")).thenReturn(visitTwo); + + bahmniEncounterTransactionService.find(encounterSearchParameters); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Visit.class); + ArgumentCaptor argument = ArgumentCaptor.forClass(EncounterParameters.class); + verify(baseEncounterMatcher).findEncounter(argumentCaptor.capture(), argument.capture()); + assertEquals(argumentCaptor.getValue().getUuid(), "visit-uuid-two"); + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/DummyEncounterSessionMatcher.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/DummyEncounterSessionMatcher.java new file mode 100644 index 0000000000..16481b5f86 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/DummyEncounterSessionMatcher.java @@ -0,0 +1,15 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.impl; + +import org.openmrs.Encounter; +import org.openmrs.Visit; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.openmrs.module.emrapi.encounter.matcher.BaseEncounterMatcher; +import org.springframework.stereotype.Component; + +@Component +public class DummyEncounterSessionMatcher implements BaseEncounterMatcher{ + @Override + public Encounter findEncounter(Visit visit, EncounterParameters encounterParameters) { + return null; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/MockEncounterTransactionHandler.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/MockEncounterTransactionHandler.java new file mode 100644 index 0000000000..9316b48009 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/MockEncounterTransactionHandler.java @@ -0,0 +1,21 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.impl; + +import org.openmrs.Encounter; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.postprocessor.EncounterTransactionHandler; +import org.springframework.stereotype.Component; + +@Component +public class MockEncounterTransactionHandler implements EncounterTransactionHandler { + public int numberOfTimesSaveWasCalled = 0; + + @Override + public void forRead(Encounter encounter, EncounterTransaction encounterTransaction) { + + } + + @Override + public void forSave(Encounter encounter, EncounterTransaction encounterTransaction) { + numberOfTimesSaveWasCalled++; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/OpenMRSUpgradeTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/OpenMRSUpgradeTest.java new file mode 100644 index 0000000000..09779638b0 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/impl/OpenMRSUpgradeTest.java @@ -0,0 +1,129 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.impl; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.api.context.Context; +import org.openmrs.test.BaseModuleContextSensitiveTest; + +import java.text.ParseException; +import java.util.Arrays; +import java.util.Date; + +import static org.junit.Assert.assertEquals; + +@Ignore +public class OpenMRSUpgradeTest extends BaseModuleContextSensitiveTest { + + // Vitals (61) -> Pulse (62) + // Blood Pressure (63) -> Systolic (64) + + Obs vitals = null; + Obs bp = null; + Obs systolic = null; + Obs pulse = null; + + @Before + public void setUp() throws Exception { + executeDataSet("openmrsUpgradeTestData.xml"); + +// Encounter encounter = Context.getEncounterService().getEncounter(7); +// vitals = createObs(Context.getConceptService().getConcept(61), null); +// bp = createObs(Context.getConceptService().getConcept(63), null); +// systolic = createObs(Context.getConceptService().getConcept(64), 120.0); +// pulse = createObs(Context.getConceptService().getConcept(62), 72.0); +// +// bp.addGroupMember(systolic); +// +// vitals.addGroupMember(pulse); +// vitals.addGroupMember(bp); +// +// encounter.addObs(vitals); +// Context.getEncounterService().saveEncounter(encounter); + } + + @Test + public void shouldAddGroupMemberToTopLevelObsAndValidateCount() throws ParseException { + Encounter encounter = Context.getEncounterService().getEncounter(7); + + Obs exisitingVitalsObs = encounter.getAllObs().iterator().next(); + Obs diastolicObs = createObs(Context.getConceptService().getConcept(65), 80.0); + diastolicObs.setPerson(Context.getPersonService().getPerson(2)); + diastolicObs.setObsDatetime(new Date()); + exisitingVitalsObs.addGroupMember(diastolicObs); //Added a new obs to the top level obs. + encounter.addObs(exisitingVitalsObs); + + Context.getEncounterService().saveEncounter(encounter); + Context.flushSession(); + Context.clearSession(); + + encounter = Context.getEncounterService().getEncounter(7); + + int afterEditing = encounter.getAllObs(true).size(); + + //Full Obs hirearchy should not be re-created + assertEquals(5, afterEditing); + } + + @Test + public void shouldAddGroupMemberToChildLevelObsAndValidateCount() throws ParseException { + Encounter encounter = Context.getEncounterService().getEncounter(7); + int before = encounter.getAllObs(true).size(); + assertEquals(4, before); + + Obs bpObsInEncounter = Context.getObsService().getObservations(null, Arrays.asList(encounter),Arrays.asList( + Context.getConceptService().getConcept(63)),null,null,null,null,1,null,null,null,false).get(0); + + Obs diastolicObs = createObs(Context.getConceptService().getConcept(65), 80.0); + diastolicObs.setPerson(new Person(2)); + diastolicObs.setObsDatetime(new Date()); + bpObsInEncounter.addGroupMember(diastolicObs); //Added a new diastolic obs to the bpObsInEncounter + encounter.addObs(bpObsInEncounter); + + Context.getEncounterService().saveEncounter(encounter); + Context.flushSession(); + Context.clearSession(); + + encounter = Context.getEncounterService().getEncounter(7); + int afterEditing = encounter.getAllObs(true).size(); + + //Full Obs hirearchy should not be re-created + assertEquals(5, afterEditing); + } + + @Test + public void shouldUpdateValueOfLeafObsAndValidateCount() throws Exception { + + Encounter encounter = Context.getEncounterService().getEncounter(7); + Obs vitalObs = encounter.getObsAtTopLevel(true).iterator().next(); + Obs pulseObs = vitalObs.getGroupMembers().stream().filter(obs -> obs.getId().equals(19)).findFirst().get(); + pulseObs.setValueNumeric(90.0); + encounter.addObs(vitalObs); + + Context.getEncounterService().saveEncounter(encounter); + Context.flushSession(); + Context.clearSession(); + + encounter = Context.getEncounterService().getEncounter(7); + //only pulse obs should be voided and recreated + assertEquals(5, encounter.getAllObs(true).size()); + assertEquals(4, encounter.getAllObs().size()); + + } + + private Obs createObs(Concept concept, Double value) throws ParseException { + Obs obs = new Obs(); + obs.setConcept(concept); + if(value != null){ + obs.setValueNumeric(value); + } + + return obs; + } + + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ConceptSortWeightUtilTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ConceptSortWeightUtilTest.java new file mode 100644 index 0000000000..08b3e318ce --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ConceptSortWeightUtilTest.java @@ -0,0 +1,57 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import junit.framework.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.Concept; +import org.openmrs.module.bahmniemrapi.builder.ConceptBuilder; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.Locale; + +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(LocaleUtility.class) +public class ConceptSortWeightUtilTest { + + @Before + public void setUp() throws Exception { + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + } + + @Test + public void shouldComputeSortWeight() throws Exception { + Concept c1 = new ConceptBuilder().withName("c1").withDataType("N/A").build(); + Concept c11 = new ConceptBuilder().withName("c11").withDataType("N/A").build(); + c1.addSetMember(c11); + Concept c2 = new ConceptBuilder().withName("c2").withDataType("N/A").build(); + Concept c21 = new ConceptBuilder().withName("c21").withDataType("N/A").build(); + Concept c22 = new ConceptBuilder().withName("c22").withDataType("N/A").build(); + c2.addSetMember(c21); + c2.addSetMember(c22); + + Assert.assertEquals(1, ConceptSortWeightUtil.getSortWeightFor("c1", Arrays.asList(c1, c2))); + Assert.assertEquals(2, ConceptSortWeightUtil.getSortWeightFor("c11", Arrays.asList(c1, c2))); + Assert.assertEquals(3, ConceptSortWeightUtil.getSortWeightFor("c2", Arrays.asList(c1, c2))); + Assert.assertEquals(4, ConceptSortWeightUtil.getSortWeightFor("c21", Arrays.asList(c1, c2))); + Assert.assertEquals(5, ConceptSortWeightUtil.getSortWeightFor("c22", Arrays.asList(c1, c2))); + } + + @Test + public void shouldReturnZeroSortWeightWhenConceptDoesNotExists() { + Concept c1 = new ConceptBuilder().withName("c1").withDataType("N/A").build(); + Concept c11 = new ConceptBuilder().withName("c11").withDataType("N/A").build(); + c1.addSetMember(c11); + Concept c2 = new ConceptBuilder().withName("c2").withDataType("N/A").build(); + + Assert.assertEquals(0, ConceptSortWeightUtil.getSortWeightFor("goobe", Arrays.asList(c1, c2))); + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapperTest.java new file mode 100644 index 0000000000..cc581713ff --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapperTest.java @@ -0,0 +1,334 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.bahmni.test.builder.ConceptNumericBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.openmrs.Concept; +import org.openmrs.ConceptNumeric; +import org.openmrs.User; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.parameters.AdditionalBahmniObservationFields; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.openmrs.util.OpenmrsConstants; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({LocaleUtility.class, Context.class}) + +public class ETObsToBahmniObsMapperTest { + + @Mock + private ConceptService conceptService; + + @Mock + private AdministrationService administrationService; + + @Mock + private User authenticatedUser; + + private ETObsToBahmniObsMapper etObsToBahmniObsMapper; + private String person1name = "superman"; + private String person2name = "RajSingh"; + private String encounterUuid = "encounter-uuid"; + private String obsGroupUuid = "obs-group-uuid"; + private String etParentConceptClass = "Misc"; + private String etValueConceptClass = "Misc"; + private String etDataType = "N/A"; + + @Before + public void setUp() throws Exception { + initMocks(this); + etObsToBahmniObsMapper = new ETObsToBahmniObsMapper(conceptService, Arrays.asList()); + mockStatic(LocaleUtility.class); + mockStatic(Context.class); + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + Mockito.when(Context.getAuthenticatedUser()).thenReturn(authenticatedUser); + Mockito.when(Context.getLocale()).thenReturn(Locale.ENGLISH); + Mockito.when(Context.getAdministrationService()).thenReturn(administrationService); + } + + private EncounterTransaction.User createETUser(String personname) { + + EncounterTransaction.User user = new EncounterTransaction.User(); + user.setPersonName(personname); + return user; + } + + private EncounterTransaction.Concept createETConcept(String dataType, String etConceptClass,String name, String shortName, String uuid) { + + EncounterTransaction.Concept etConcept = new EncounterTransaction.Concept(); + etConcept.setDataType(dataType); + etConcept.setConceptClass(etConceptClass); + etConcept.setName(name); + etConcept.setShortName(shortName); + etConcept.setUuid(uuid); + return etConcept; + } + + private EncounterTransaction.Observation createETObservation(String UUID, EncounterTransaction.User user, Object value, EncounterTransaction.Concept concept, String formNameSpace) { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid(UUID); + observation.setCreator(user); + observation.setFormNamespace(formNameSpace); + if (concept.getConceptClass().equals("Unknown")) { + observation.setValue(Boolean.parseBoolean((String)value)); + } else if (value != null) { + observation.setValue(value); + } + observation.setConcept(concept); + return observation; + } + + private Concept createConcept(String name, String dataType, String UUID, String conceptClass, String shortName) { + + Concept concept = new org.openmrs.module.bahmniemrapi.builder.ConceptBuilder().withName(name).withDataType(dataType).withUUID(UUID).withClass(conceptClass).withShortName(shortName).build(); + return concept; + } + + private Concept createConceptNumeric(Integer id, String name, String conceptClass, Double highNormal, Double lowNormal) { + return new ConceptNumericBuilder() + .withId(id) + .withName(name) + .withClass(conceptClass) + .withHiNormal(highNormal) + .withLowNormal(lowNormal) + .build(); + } + + @Test + public void testCreate() throws Exception { + EncounterTransaction.User user1 = createETUser(person1name); + EncounterTransaction.User user2 = createETUser(person2name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, etParentConceptClass, "concept1Name", "concept1ShortName", "uuid1"); + EncounterTransaction.Concept etValueConcept = createETConcept(etDataType, etValueConceptClass, "concept1Name", "concept2ShortName", "uuid2"); + + Concept concept1 = createConcept("concept1Name", "text", "uuid1", "", "concept1ShortName"); + Concept concept2 = createConcept("concept2Name", "text", "uuid2", "", "concept2ShortName"); + Mockito.when(conceptService.getConceptByUuid("uuid1")).thenReturn(concept1); + Mockito.when(conceptService.getConceptByUuid("uuid2")).thenReturn(concept2); + + EncounterTransaction.Observation observation1 = createETObservation("obs1-uuid", user1, "notes", etValueConcept, null); + EncounterTransaction.Observation observation2 = createETObservation("obs2-uuid", user2, null, etParentConcept, null); + + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + List actualObs = etObsToBahmniObsMapper.create(asList(observation1, observation2), additionalBahmniObservationFields); + assertEquals(2, actualObs.size()); + + BahmniObservation obs = etObsToBahmniObsMapper.create(observation1, additionalBahmniObservationFields); + assertEquals(observation1.getConcept().getName(),obs.getConcept().getName()); + } + + @Test + public void testMap() throws Exception { + + EncounterTransaction.User user1 = createETUser(person1name); + EncounterTransaction.User user2 = createETUser(person2name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, etParentConceptClass, "parentName", "parentShortName" , null); + EncounterTransaction.Concept etValueConcept = createETConcept(etDataType, etValueConceptClass, "valueName", "valueShortName", null); + + + Concept valueConcept = createConcept("valueConcept", "text", "cuuid2", "", null); + Concept parentConcept = createConcept("parentConcept", "N/A", null, null, null); + parentConcept.addSetMember(valueConcept); + + EncounterTransaction.Observation observation1 = createETObservation("obs1-uuid", user1, "notes", etValueConcept, null); + EncounterTransaction.Observation observation2 = createETObservation("obs2-uuid", user2, null, etParentConcept, null); + observation2.setGroupMembers(asList(observation1)); + + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + BahmniObservation actualObs = etObsToBahmniObsMapper.map(observation2, additionalBahmniObservationFields, asList(parentConcept), false); + + assertEquals(person2name, actualObs.getCreatorName()); + assertEquals(encounterUuid, actualObs.getEncounterUuid()); + assertEquals(obsGroupUuid, actualObs.getObsGroupUuid()); + BahmniObservation actualValueObs = actualObs.getGroupMembers().iterator().next(); + assertEquals(person1name, actualValueObs.getCreatorName()); + assertEquals("obs2-uuid", actualValueObs.getObsGroupUuid()); + } + + @Test + public void testMapObservationValueWithUnknownConceptShortName() throws Exception { + + EncounterTransaction.User user1 = createETUser(person1name); + EncounterTransaction.User user2 = createETUser(person2name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, "Concept Details", "parentName", "parentShortName", null); + EncounterTransaction.Concept etValueConcept = createETConcept("text", etValueConceptClass, "valueName", "valueShortName", null); + EncounterTransaction.Concept etUnknownConcept = createETConcept("Boolean", "Unknown", "Unknown", "Unknown", null); + + + Concept valueConcept = createConcept("valueConcept", "text", "cuuid2", "", null); + Concept parentConcept = createConcept("parentConcept", "N/A", null, null, null); + parentConcept.addSetMember(valueConcept); + Concept unknownConcept = createConcept("unknownConcept", "Boolean", "cuuid3", "Unknown", "Unknown"); + parentConcept.addSetMember(unknownConcept); + + + EncounterTransaction.Observation observation1 = createETObservation("obs1-uuid", user1, "notes", etValueConcept, null); + EncounterTransaction.Observation observation2 = createETObservation("obs2-uuid", user2, null, etParentConcept, null); + EncounterTransaction.Observation observation3 = createETObservation("obs3-uuid", user1, "true", etUnknownConcept, null); + observation2.setGroupMembers(asList(observation1, observation3)); + + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + BahmniObservation actualObs = etObsToBahmniObsMapper.map(observation2, additionalBahmniObservationFields, asList(parentConcept), true); + + assertEquals("Unknown", actualObs.getValueAsString()); + assertEquals(true, actualObs.isUnknown()); + } + + + @Test + public void testMapObservationValueToUnknownConceptFullNameWhenShortNameIsNull() throws Exception { + + EncounterTransaction.User user1 = createETUser(person1name); + EncounterTransaction.User user2 = createETUser(person2name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etValueConcept = createETConcept("text", etValueConceptClass, "parentName", "parentShortName", null); + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, "Concept Details", "valueName", "valueShortName", null); + EncounterTransaction.Concept etUnknownConcept = createETConcept("Boolean", "Unknown", "Unknown", "unknownConcept", null); + + Concept parentConcept = createConcept("parentConcept", "N/A", null, null, null); + Concept unknownConcept = createConcept("unknownConcept", "Boolean", "cuuid3", "Unknown", null); + parentConcept.addSetMember(unknownConcept); + + EncounterTransaction.Observation observation1 = createETObservation("obs1-uuid", user1, "notes", etValueConcept, null); + EncounterTransaction.Observation observation2 = createETObservation("obs2-uuid", user2, null, etParentConcept, null); + EncounterTransaction.Observation observation3 = createETObservation("obs3-uuid", user1, "true", etUnknownConcept, null); + observation2.setGroupMembers(asList(observation1, observation3)); + + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + BahmniObservation actualObs = etObsToBahmniObsMapper.map(observation2, additionalBahmniObservationFields, asList(parentConcept), true); + + assertEquals("unknownConcept", actualObs.getValueAsString()); + assertEquals(true, actualObs.isUnknown()); + } + + @Test + public void testObsMapToBahmniObsWithNotNullNameSpace() { + + EncounterTransaction.User user1 = createETUser(person1name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, "Concept Details", "valueName", "valueShortName", null); + EncounterTransaction.Concept etChildConcept1 = createETConcept("text", etValueConceptClass, "parentName", "parentShortName", null); + EncounterTransaction.Concept etChildConcept2 = createETConcept("Boolean", "Unknown", "Unknown", "unknownConcept", null); + + Concept parentConcept = createConcept("parentConcept", "N/A", null, null, null); + Concept unknownConcept = createConcept("unknownConcept", "Boolean", "cuuid3", "Unknown", null); + parentConcept.addSetMember(unknownConcept); + + // due to not null namespace it will map Obs to BahmniObs as it is + EncounterTransaction.Observation observation1 = createETObservation("obs1-uuid", user1, "notes", etChildConcept1, "test"); + EncounterTransaction.Observation observation2 = createETObservation("obs3-uuid", user1, "true", etChildConcept1, "test"); + EncounterTransaction.Observation observation3 = createETObservation("obs2-uuid", user1, null, etParentConcept, "test"); + observation3.setGroupMembers(asList(observation1, observation2)); + + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + + BahmniObservation actualObs = etObsToBahmniObsMapper.map(observation3, additionalBahmniObservationFields, asList(parentConcept), true); + + assertEquals(2, actualObs.getGroupMembers().size()); + assertEquals(etParentConcept.getName(), actualObs.getConcept().getName()); + } + + @Test + public void testMapObservationWithValueObservationFirstAndFollowedByUnknownObservation() throws Exception { + + EncounterTransaction.User user1 = createETUser(person1name); + EncounterTransaction.User user2 = createETUser(person2name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, "Concept Details", "parentName", "parentShortName", null); + EncounterTransaction.Concept etValueConcept = createETConcept("text", etValueConceptClass, "valueName", "valueShortName", null); + EncounterTransaction.Concept etUnknownConcept = createETConcept("Boolean", "Unknown", "Unknown", "Unknown", null); + + Concept valueConcept = createConcept("valueConcept", "text", "cuuid2", "", null); + Concept parentConcept = createConcept("parentConcept", "N/A", null, null, null); + parentConcept.addSetMember(valueConcept); + Concept unknownConcept = createConcept("unknownConcept", "Boolean", "cuuid3", "Unknown", "Unknown"); + parentConcept.addSetMember(unknownConcept); + + EncounterTransaction.Observation observation1 = createETObservation("obs1-uuid", user1, "notes", etValueConcept, null); + EncounterTransaction.Observation observation2 = createETObservation("obs2-uuid", user2, null, etParentConcept, null); + EncounterTransaction.Observation observation3 = createETObservation("obs3-uuid", user1, "false", etUnknownConcept, null); + observation2.setGroupMembers(asList(observation1, observation3)); + + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + BahmniObservation actualObs = etObsToBahmniObsMapper.map(observation2, additionalBahmniObservationFields, asList(parentConcept), true); + + assertEquals("notes", actualObs.getValueAsString()); + assertEquals(false, actualObs.isUnknown()); + + EncounterTransaction.Observation observation4 = createETObservation("obs3-uuid", user1, "true", etUnknownConcept, null); + observation2.setGroupMembers(asList(observation1, observation4)); + actualObs = etObsToBahmniObsMapper.map(observation2, additionalBahmniObservationFields, asList(parentConcept), true); + + assertEquals("Unknown", actualObs.getValueAsString()); + assertEquals(true, actualObs.isUnknown()); + } + + @Test + public void testSetHiNormalAndLowNormalWithBahmniObservationIfNumericConcept() { + + EncounterTransaction.User user1 = createETUser(person1name); + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("fr"); + + EncounterTransaction.Concept etParentConcept = createETConcept(etDataType, "Concept Details", "parentName", "parentShortName", "PulseDataUuid"); + EncounterTransaction.Concept etUnknownConcept = createETConcept("Boolean", "Unknown", "Unknown", "Unknown", null); + + EncounterTransaction.Observation parentObservation = createETObservation("obs2-uuid", user1, null, etParentConcept, null); + EncounterTransaction.Observation unknownObservation = createETObservation("obs3-uuid", user1, "true", etUnknownConcept, null); + parentObservation.setGroupMembers(asList(unknownObservation)); + + ConceptNumeric valueConcept = (ConceptNumeric) createConceptNumeric(1, "Pulse", "Misc", 100.0, 50.0); + Concept parentConcept = createConcept("Pulse Data", "N/A", "PulseDataUuid", null, null); + parentConcept.addSetMember(valueConcept); + Concept unknownConcept = createConcept("Unknown", "Boolean", "unknownConceptUuid", "Unknown", "Unknown"); + parentConcept.addSetMember(unknownConcept); + + when(conceptService.getConceptByUuid("PulseDataUuid")).thenReturn(parentConcept); + when(conceptService.getConceptNumeric(1)).thenReturn(valueConcept); + AdditionalBahmniObservationFields additionalBahmniObservationFields = new AdditionalBahmniObservationFields(encounterUuid, new Date(), new Date(), obsGroupUuid); + BahmniObservation bahmniObservation = etObsToBahmniObsMapper.map(parentObservation, additionalBahmniObservationFields, asList(parentConcept), true); + + assertEquals("Unknown", bahmniObservation.getValueAsString()); + assertEquals(true, bahmniObservation.isUnknown()); + assertTrue(bahmniObservation.getHiNormal().equals(100.0)); + assertTrue(bahmniObservation.getLowNormal().equals(50.0)); + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTypeIdentifierTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTypeIdentifierTest.java new file mode 100644 index 0000000000..699927c55a --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/EncounterTypeIdentifierTest.java @@ -0,0 +1,111 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.openmrs.EncounterType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.EncounterService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmnimapping.services.BahmniLocationService; + +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class EncounterTypeIdentifierTest { + + @Mock + private BahmniLocationService bahmniLocationService; + @Mock + private EncounterService encounterService; + @Mock + private AdministrationService administrationService; + private EncounterTypeIdentifier identifier; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Before + public void setUp() { + initMocks(this); + identifier = new EncounterTypeIdentifier(bahmniLocationService, encounterService, administrationService); + } + + @Test + public void shouldGetEncounterTypeBasedOnLocationWhenEncounterTypeNameIsNotSet() throws Exception { + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + String locationUuid = UUID.randomUUID().toString(); + encounterTransaction.setEncounterTypeUuid(null); + encounterTransaction.setEncounterType(null); + encounterTransaction.setLocationUuid(locationUuid); + EncounterType encounterTypeMappedToLocation = new EncounterType(); + encounterTypeMappedToLocation.setUuid(UUID.randomUUID().toString()); + when(bahmniLocationService.getEncounterType(locationUuid)).thenReturn(encounterTypeMappedToLocation); + + EncounterType actualEncounterType = identifier.getEncounterTypeFor(encounterTransaction.getEncounterType(), encounterTransaction.getLocationUuid()); + + assertEquals(encounterTypeMappedToLocation, actualEncounterType); + } + + @Test + public void shouldGetEncounterTypeWhenEncounterTypeNameIsSet() throws Exception { + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + String locationUuid = UUID.randomUUID().toString(); + encounterTransaction.setEncounterTypeUuid(null); + encounterTransaction.setEncounterType("Consultation"); + encounterTransaction.setLocationUuid(locationUuid); + + identifier.getEncounterTypeFor(encounterTransaction.getEncounterType(), encounterTransaction.getLocationUuid()); + + assertEquals(null, encounterTransaction.getEncounterTypeUuid()); + verify(encounterService).getEncounterType("Consultation"); + verifyZeroInteractions(bahmniLocationService); + } + + @Test + public void shouldGetDefaultEncounterTypeWhenNoEncounterTypeFoundForLocationAndEncounterTypeNameIsNotSet() throws Exception { + String locationUuid = "location-uuid"; + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + EncounterType defaultEncounterType = new EncounterType(); + encounterTransaction.setEncounterTypeUuid(null); + encounterTransaction.setEncounterType(null); + encounterTransaction.setLocationUuid(locationUuid); + when(bahmniLocationService.getEncounterType(locationUuid)).thenReturn(null); + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("Field Consultation"); + when(encounterService.getEncounterType("Field Consultation")).thenReturn(defaultEncounterType); + + EncounterType actualEncounterType = identifier.getEncounterTypeFor(encounterTransaction.getEncounterType(), encounterTransaction.getLocationUuid()); + + assertEquals(defaultEncounterType, actualEncounterType); + verify(bahmniLocationService).getEncounterType(locationUuid); + verify(administrationService).getGlobalProperty("bahmni.encounterType.default"); + verify(encounterService).getEncounterType("Field Consultation"); + } + + @Test + public void shouldReturnNullWhenNoEncounterTypeFoundForDefaultEncounterTypeGlobalProperty() throws Exception { + String locationUuid = "location-uuid"; + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + encounterTransaction.setEncounterTypeUuid(null); + encounterTransaction.setEncounterType(null); + encounterTransaction.setLocationUuid(locationUuid); + when(bahmniLocationService.getEncounterType(locationUuid)).thenReturn(null); + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("Field Consultation"); + when(encounterService.getEncounterType("Field Consultation")).thenReturn(null); + + EncounterType actualEncounterType = identifier.getEncounterTypeFor(encounterTransaction.getEncounterType(), encounterTransaction.getLocationUuid()); + + assertNull(actualEncounterType); + verify(bahmniLocationService).getEncounterType(locationUuid); + verify(administrationService).getGlobalProperty("bahmni.encounterType.default"); + } + +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapperTest.java new file mode 100644 index 0000000000..130df25fba --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapperTest.java @@ -0,0 +1,145 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.builder.ConceptBuilder; +import org.openmrs.module.bahmniemrapi.builder.EncounterBuilder; +import org.openmrs.module.bahmniemrapi.builder.ObsBuilder; +import org.openmrs.module.bahmniemrapi.builder.PersonBuilder; +import org.openmrs.module.bahmniemrapi.builder.VisitBuilder; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.ObservationMapper; +import org.openmrs.module.emrapi.encounter.mapper.DrugMapper1_12; +import org.openmrs.module.emrapi.encounter.mapper.UserMapper; +import org.openmrs.module.emrapi.encounter.matcher.ObservationTypeMatcher; +import org.openmrs.test.TestUtil; +import org.openmrs.util.LocaleUtility; +import org.openmrs.util.OpenmrsConstants; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Locale; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({LocaleUtility.class, Context.class}) +public class OMRSObsToBahmniObsMapperTest { + + @Mock + private ObservationTypeMatcher observationTypeMatcher; + @Mock + private User authenticatedUser; + private ObservationMapper observationMapper; + + @Mock + private AdministrationService administrationService; + + @Before + public void setUp() throws Exception { + initMocks(this); + mockStatic(LocaleUtility.class); + mockStatic(Context.class); + when(Context.getLocale()).thenReturn(Locale.ENGLISH); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + when(Context.getAuthenticatedUser()).thenReturn(authenticatedUser); + when(observationTypeMatcher.getObservationType(any(Obs.class))).thenReturn(ObservationTypeMatcher.ObservationType.OBSERVATION); + observationMapper = new ObservationMapper(new ConceptMapper(), new DrugMapper1_12(), new UserMapper()); + } + + @Test + public void returnMappedObservationsForAbnormalObservationStructure() throws Exception { + + Mockito.when(authenticatedUser.getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)).thenReturn("en"); + Mockito.when(LocaleUtility.fromSpecification("en")).thenReturn(Locale.ENGLISH); + Mockito.when(administrationService.getGlobalProperty("default_locale")).thenReturn("en"); + Mockito.when(LocaleUtility.fromSpecification("en")).thenReturn(Locale.ENGLISH); + + Date date = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse("January 2, 2010"); + Person person = new PersonBuilder().withUUID("puuid").withPersonName("testPersonName").build(); + User user = new User(person); + Visit visit = new VisitBuilder().withPerson(person).withUUID("vuuid").withStartDatetime(date).build(); + Encounter encounter = new EncounterBuilder().withVisit(visit).withPatient(person).withUUID("euuid").withDatetime(date).build(); + + Concept conceptDetailsConceptSet = new ConceptBuilder().withName("conceptDetailsConceptSet").withDataType("cdatatype", "hl7abbrev").withUUID("cuuid").withClass(ETObsToBahmniObsMapper.CONCEPT_DETAILS_CONCEPT_CLASS).build(); + Concept abnormalConcept = new ConceptBuilder().withName("abnormalConcept").withCodedDataType().withUUID("cuuid1").withClass(ETObsToBahmniObsMapper.ABNORMAL_CONCEPT_CLASS).build(); + Concept durationConcept = new ConceptBuilder().withName("durationConcept").withDataTypeNumeric().withUUID("cuuid2").withClass(ETObsToBahmniObsMapper.DURATION_CONCEPT_CLASS).build(); + Concept trueConcept = new ConceptBuilder().withName("True").withDataType("cdatatype", "hl7abbrev").withUUID("cuuid11").withClass("").build(); + Concept valueConcept = new ConceptBuilder().withName("valueConcept").withDataType("cdatatype", "hl7abbrev").withUUID("cuuid2").withClass("").build(); + conceptDetailsConceptSet.addSetMember(abnormalConcept); + conceptDetailsConceptSet.addSetMember(durationConcept); + conceptDetailsConceptSet.addSetMember(valueConcept); + + Concept valueConcept2 = new ConceptBuilder().withName("valueConcept2").withDataType("cdatatype", "hl7abbrev").withUUID("cuuid2").withClass("").build(); + + Concept parentConcept = new ConceptBuilder().withName("parentConcept").withDataType("N/A").build(); + parentConcept.addSetMember(conceptDetailsConceptSet); + parentConcept.addSetMember(valueConcept2); + + Obs abnormalObs = new ObsBuilder().withPerson(person).withEncounter(encounter).withConcept(abnormalConcept).withValue(trueConcept).withDatetime(date).withCreator(user).build(); + Obs durationObs = new ObsBuilder().withPerson(person).withEncounter(encounter).withConcept(durationConcept).withValue(10.0).withDatetime(date).withCreator(user).build(); + Obs valueObs = new ObsBuilder().withPerson(person).withEncounter(encounter).withConcept(valueConcept).withValue("ovalue").withDatetime(date).withCreator(user).build(); + Obs obs1 = new ObsBuilder().withConcept(conceptDetailsConceptSet).withGroupMembers(valueObs, abnormalObs, durationObs).withCreator(user).build(); + Obs obs2 = new ObsBuilder().withConcept(valueConcept2).withValue("ovalue2").withCreator(user).build(); + Obs parentObs = new ObsBuilder().withPerson(person).withEncounter(encounter).withConcept(parentConcept).withDatetime(date).withGroupMembers(obs1, obs2).withCreator(user).build(); + + Collection parentsObservations = new OMRSObsToBahmniObsMapper(new ETObsToBahmniObsMapper(null, Arrays.asList()), observationTypeMatcher, observationMapper).map(asList(parentObs), Arrays.asList(parentConcept)); + assertEquals(1, parentsObservations.size()); + BahmniObservation parentObservation = parentsObservations.iterator().next(); + assertEquals("parentConcept", parentObservation.getConcept().getName()); + Collection childObservations = parentObservation.getGroupMembers(); + assertEquals(2, childObservations.size()); + assertEquals(1, parentObservation.getConceptSortWeight().intValue()); + + BahmniObservation childObservation1 = getObservation(obs1.getUuid(), childObservations); + assertEquals("ovalue", childObservation1.getValue()); + assertEquals("cdatatype", childObservation1.getType()); + assertEquals(2, childObservation1.getConceptSortWeight().intValue()); + assertTrue(childObservation1.isAbnormal()); + assertEquals(10L, childObservation1.getDuration().longValue()); + + BahmniObservation childObservation2 = getObservation(obs2.getUuid(), childObservations); + assertEquals("ovalue2", childObservation2.getValue()); + assertEquals("cdatatype", childObservation2.getType()); + assertEquals(6, childObservation2.getConceptSortWeight().intValue()); + assertNull(childObservation2.isAbnormal()); + assertNull(childObservation2.getDuration()); + assertEquals(TestUtil.createDateTime("2010-01-02"), childObservation1.getVisitStartDateTime()); + assertEquals(TestUtil.createDateTime("2010-01-02"), childObservation2.getVisitStartDateTime()); + assertEquals(TestUtil.createDateTime("2010-01-02"), parentObservation.getVisitStartDateTime()); + } + + private BahmniObservation getObservation(String uuid, Collection childObservations) { + for (BahmniObservation o : childObservations) { + if (o.getUuid().equals(uuid)) { + return o; + } + } + return null; + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java new file mode 100644 index 0000000000..350e6abde9 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ObsRelationshipMapperTest.java @@ -0,0 +1,167 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.mapper; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.EncounterProviderMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PrepareForTest(LocaleUtility.class) +@RunWith(PowerMockRunner.class) +public class ObsRelationshipMapperTest { + + @Mock + private ObsRelationService obsrelationService; + @Mock + private EncounterProviderMapper encounterProviderMapper; + + private ObsRelationshipMapper obsRelationshipMapper; + + @Mock + private OMRSObsToBahmniObsMapper OMRSObsToBahmniObsMapper; + + @Before + public void setUp() throws Exception { + PowerMockito.mockStatic(LocaleUtility.class); + PowerMockito.when(LocaleUtility.getLocalesInOrder()).thenReturn(new HashSet<>(Arrays.asList(Locale.getDefault()))); + + initMocks(this); + obsRelationshipMapper = new ObsRelationshipMapper(obsrelationService, encounterProviderMapper, OMRSObsToBahmniObsMapper); + } + + @Test + public void shouldMapObsRelationshipForBahmniObservations() { + String sourceObsUuid = "source-obs-uuid"; + String targetObsUuid = "target-obs-uuid"; + + Obs sourceObs = createObs(sourceObsUuid); + Obs targetObs = createObs(targetObsUuid); + + List obsRelationShips = new ArrayList<>(); + obsRelationShips.add(createObsRelationship(sourceObs, targetObs)); + + + when(obsrelationService.getRelationsWhereSourceObsInEncounter("encounter-uuid")).thenReturn(obsRelationShips); + + BahmniObservation sourceObservation = getBahmniObservation(sourceObsUuid); + BahmniObservation targetObservation = getBahmniObservation(targetObsUuid); + + when(OMRSObsToBahmniObsMapper.map(targetObs, null)).thenReturn(targetObservation); + + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(sourceObservation); + bahmniObservations.add(targetObservation); + + List mappedBahmniObservations = obsRelationshipMapper.map(bahmniObservations, "encounter-uuid"); + + verify(obsrelationService).getRelationsWhereSourceObsInEncounter("encounter-uuid"); + verify(OMRSObsToBahmniObsMapper, times(1)).map(targetObs, null); + assertEquals(2, mappedBahmniObservations.size()); + assertEquals(sourceObsUuid, mappedBahmniObservations.get(0).getUuid()); + assertEquals(targetObsUuid, mappedBahmniObservations.get(0).getTargetObsRelation().getTargetObs().getUuid()); + assertEquals("obsRelationType", mappedBahmniObservations.get(0).getTargetObsRelation().getRelationshipType()); + } + + @Test + public void shouldMapMultipleObsRelationshipForBahmniObservations() { + String sourceObs1Uuid = "source1-obs-uuid"; + String targetObs1Uuid = "target1-obs-uuid"; + + String sourceObs2Uuid = "source2-obs-uuid"; + String targetObs2Uuid = "target2-obs-uuid"; + + Obs sourceObs1 = createObs(sourceObs1Uuid); + Obs sourceObs2 = createObs(sourceObs2Uuid); + Obs targetObs1 = createObs(targetObs1Uuid); + Obs targetObs2 = createObs(targetObs2Uuid); + + List obsRelationShips = new ArrayList<>(); + obsRelationShips.add(createObsRelationship(sourceObs1, targetObs1)); + obsRelationShips.add(createObsRelationship(sourceObs2, targetObs2)); + + when(obsrelationService.getRelationsWhereSourceObsInEncounter("encounter-uuid")).thenReturn(obsRelationShips); + + BahmniObservation sourceObservation1 = getBahmniObservation(sourceObs1Uuid); + BahmniObservation sourceObservation2 = getBahmniObservation(sourceObs2Uuid); + BahmniObservation targetObservation1 = getBahmniObservation(targetObs1Uuid); + BahmniObservation targetObservation2 = getBahmniObservation(targetObs2Uuid); + + when(OMRSObsToBahmniObsMapper.map(targetObs1, null)).thenReturn(targetObservation1); + when(OMRSObsToBahmniObsMapper.map(targetObs2, null)).thenReturn(targetObservation2); + + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(sourceObservation1); + bahmniObservations.add(sourceObservation2); + bahmniObservations.add(targetObservation1); + bahmniObservations.add(targetObservation2); + + List mappedBahmniObservations = obsRelationshipMapper.map(bahmniObservations, "encounter-uuid"); + + verify(obsrelationService).getRelationsWhereSourceObsInEncounter("encounter-uuid"); + verify(OMRSObsToBahmniObsMapper, times(2)).map(any(Obs.class), any()); + assertEquals(4, mappedBahmniObservations.size()); + assertEquals(sourceObs1Uuid, mappedBahmniObservations.get(0).getUuid()); + assertEquals(targetObs1Uuid, mappedBahmniObservations.get(0).getTargetObsRelation().getTargetObs().getUuid()); + assertEquals(sourceObs2Uuid, mappedBahmniObservations.get(1).getUuid()); + assertEquals(targetObs2Uuid, mappedBahmniObservations.get(1).getTargetObsRelation().getTargetObs().getUuid()); + assertEquals("obsRelationType", mappedBahmniObservations.get(0).getTargetObsRelation().getRelationshipType()); + assertEquals("obsRelationType", mappedBahmniObservations.get(1).getTargetObsRelation().getRelationshipType()); + } + + private BahmniObservation getBahmniObservation(String sourceObsUuid) { + BahmniObservation sourceObservation = new BahmniObservation(); + sourceObservation.setUuid(sourceObsUuid); + EncounterTransaction.Concept concept = new EncounterTransaction.Concept("random-uuid", "Random Concept"); + sourceObservation.setConcept(concept); + return sourceObservation; + } + + private ObsRelationship createObsRelationship(Obs sourceObs, Obs targetObs) { + ObsRelationshipType obsRelationshipType = new ObsRelationshipType(); + obsRelationshipType.setName("obsRelationType"); + + ObsRelationship obsRelationship = new ObsRelationship(); + obsRelationship.setObsRelationshipType(obsRelationshipType); + obsRelationship.setSourceObs(sourceObs); + obsRelationship.setTargetObs(targetObs); + return obsRelationship; + } + + private Obs createObs(String obsUuid) { + Obs sourceObs = new Obs(); + sourceObs.setUuid(obsUuid); + Concept concept = new Concept(); + concept.setFullySpecifiedName(new ConceptName("Random Concept", Locale.ENGLISH)); + sourceObs.setConcept(concept); + Encounter encounter = new Encounter(); + encounter.setUuid("encounterUuid"); + sourceObs.setEncounter(encounter); + return sourceObs; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/RetrospectiveEncounterTransactionServiceTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/RetrospectiveEncounterTransactionServiceTest.java new file mode 100644 index 0000000000..8982e27572 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/service/RetrospectiveEncounterTransactionServiceTest.java @@ -0,0 +1,154 @@ +package org.openmrs.module.bahmniemrapi.encountertransaction.service; + +import org.bahmni.test.builder.VisitBuilder; +import org.joda.time.DateTime; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Date; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class RetrospectiveEncounterTransactionServiceTest { + + @Mock + private VisitIdentificationHelper mockVisitIdentificationHelper; + + @Before + public void setUp(){ + initMocks(this); + } + + @Test + public void updateAPastEncounterWithMatchingVisitDetailsIfExists() { + Date jan1_2011 = new DateTime(2014, 1, 1, 10, 0, 0).toDate(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setEncounterDateTime(jan1_2011); + + Visit existingVisit = getExistingVisit(); + + when(mockVisitIdentificationHelper.getVisitFor(null, null, jan1_2011, null, null, null)).thenReturn(existingVisit); + + RetrospectiveEncounterTransactionService retrospectiveService = new RetrospectiveEncounterTransactionService(mockVisitIdentificationHelper); + BahmniEncounterTransaction updatedEncounterTransaction = retrospectiveService.updatePastEncounters(bahmniEncounterTransaction, null, null, null); + + assertEquals("visit uuid", updatedEncounterTransaction.getVisitUuid()); + assertEquals("visit-type-uuid", updatedEncounterTransaction.getVisitTypeUuid()); + } + + @Test + public void updateObservationDatesAtAllLevelsToEncounterDateForPastEncounters() { + RetrospectiveEncounterTransactionService retrospectiveService = new RetrospectiveEncounterTransactionService(mockVisitIdentificationHelper); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + BahmniObservation parentObs = new BahmniObservation(); + parentObs.addGroupMember(new BahmniObservation()); + bahmniEncounterTransaction.addObservation(parentObs); + Date jan1_2011 = new DateTime(2014, 1, 1, 10, 0, 0).toDate(); + bahmniEncounterTransaction.setEncounterDateTime(jan1_2011); + + when(mockVisitIdentificationHelper.getVisitFor(null, null, jan1_2011, null, null, null)).thenReturn(getExistingVisit()); + + BahmniEncounterTransaction updatedEncounter = retrospectiveService.updatePastEncounters(bahmniEncounterTransaction, null, null, null); + + assertEquals(jan1_2011, updatedEncounter.getObservations().iterator().next().getObservationDateTime()); + assertEquals(jan1_2011, (updatedEncounter.getObservations().iterator().next()).getGroupMembers().iterator().next().getObservationDateTime()); + } + + @Test + public void doNotUpdateObservationDatesWhenSet() { + RetrospectiveEncounterTransactionService retrospectiveService = new RetrospectiveEncounterTransactionService(mockVisitIdentificationHelper); + + Date now = new Date(); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + BahmniObservation childObs = new BahmniObservation(); + childObs.setObservationDateTime(now); + BahmniObservation parentObs = new BahmniObservation(); + parentObs.addGroupMember(childObs); + bahmniEncounterTransaction.addObservation(parentObs); + + Date jan1_2011 = new DateTime(2014, 1, 1, 10, 0, 0).toDate(); + bahmniEncounterTransaction.setEncounterDateTime(jan1_2011); + + when(mockVisitIdentificationHelper.getVisitFor(null, null, jan1_2011, null, null, null)).thenReturn(getExistingVisit()); + + BahmniEncounterTransaction updatedEncounter = retrospectiveService.updatePastEncounters(bahmniEncounterTransaction, null, null, null); + + assertEquals(jan1_2011, updatedEncounter.getObservations().iterator().next().getObservationDateTime()); + assertEquals(now, updatedEncounter.getObservations().iterator().next().getGroupMembers().iterator().next().getObservationDateTime()); + } + + @Test + public void updateDiagnosisDatesToEncounterDateForPastEncounters() { + RetrospectiveEncounterTransactionService retrospectiveService = new RetrospectiveEncounterTransactionService(mockVisitIdentificationHelper); + + BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.addBahmniDiagnosis(bahmniDiagnosisRequest); + Date jan1_2011 = new DateTime(2014, 1, 1, 10, 0, 0).toDate(); + bahmniEncounterTransaction.setEncounterDateTime(jan1_2011); + + when(mockVisitIdentificationHelper.getVisitFor(null, null, jan1_2011, null, null, null)).thenReturn(getExistingVisit()); + + BahmniEncounterTransaction updatedEncounter = retrospectiveService.updatePastEncounters(bahmniEncounterTransaction, null, null, null); + + assertEquals(jan1_2011, updatedEncounter.getBahmniDiagnoses().get(0).getDiagnosisDateTime()); + } + + @Test + public void updateDrugOrderActivationDateToEncounterDateForPastEncounters() { + RetrospectiveEncounterTransactionService retrospectiveService = new RetrospectiveEncounterTransactionService(mockVisitIdentificationHelper); + + EncounterTransaction.DrugOrder drugOrder = new EncounterTransaction.DrugOrder(); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.addDrugOrder(drugOrder); + Date jan1_2011 = new DateTime(2014, 1, 1, 10, 0, 0).toDate(); + bahmniEncounterTransaction.setEncounterDateTime(jan1_2011); + + when(mockVisitIdentificationHelper.getVisitFor(null, null, jan1_2011, null, null, null)).thenReturn(getExistingVisit()); + + BahmniEncounterTransaction updatedEncounter = retrospectiveService.updatePastEncounters(bahmniEncounterTransaction, null, null, null); + + assertEquals(jan1_2011, updatedEncounter.getDrugOrders().get(0).getDateActivated()); + } + + @Test + public void updateDispositionDateToEncounterDateForPastEncounters() { + RetrospectiveEncounterTransactionService retrospectiveService = new RetrospectiveEncounterTransactionService(mockVisitIdentificationHelper); + + EncounterTransaction.Disposition disposition = new EncounterTransaction.Disposition(); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setDisposition(disposition); + Date jan1_2011 = new DateTime(2014, 1, 1, 10, 0, 0).toDate(); + bahmniEncounterTransaction.setEncounterDateTime(jan1_2011); + + when(mockVisitIdentificationHelper.getVisitFor(null, null, jan1_2011, null, null, null)).thenReturn(getExistingVisit()); + + BahmniEncounterTransaction updatedEncounter = retrospectiveService.updatePastEncounters(bahmniEncounterTransaction, null, null, null); + + assertEquals(jan1_2011, updatedEncounter.getDisposition().getDispositionDateTime()); + } + + private Visit getExistingVisit() { + return new VisitBuilder().withUUID("visit uuid").withVisitType(getExistingVisitType()).build(); + } + + private VisitType getExistingVisitType() { + VisitType existingVisitType = new VisitType(10); + existingVisitType.setUuid("visit-type-uuid"); + return existingVisitType; + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResultsTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResultsTest.java new file mode 100644 index 0000000000..db6d941e22 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/contract/LabOrderResultsTest.java @@ -0,0 +1,33 @@ +package org.openmrs.module.bahmniemrapi.laborder.contract; + +import org.joda.time.DateTime; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class LabOrderResultsTest { + @Test + public void shouldCreateSparseMatrixForLabOrderResultAndDates() throws Exception { + List results = Arrays.asList( + new LabOrderResult(null, null, "uuid1", new DateTime(2014, 2, 10, 0, 0).toDate(), "Haemoglobin", "ppm", 15.0, 20.0, "17.0", false, false, "uploadedFile", null), + new LabOrderResult(null, null, "uuid1", new DateTime(2014, 2, 12, 0, 0).toDate(), "Haemoglobin", "ppm", 15.0, 20.0, "19.0", false, false, null, null), + new LabOrderResult(null, null, "uuid1", new DateTime(2014, 1, 14, 0, 0, 1, 0).toDate(), "Haemoglobin", "ppm", 15.0, 20.0, "9.0", true, false, null, null), + new LabOrderResult(null, null, "uuid1", new DateTime(2014, 1, 14, 1, 0, 0, 0).toDate(), "Haemoglobin", "ppm", 15.0, 20.0, "9.2", true, false, null, null), + new LabOrderResult(null, null, "uuid2", new DateTime(2014, 5, 15, 0, 0).toDate(), "ESR", "gm/L", 100.0, 200.0, "50.0", false, false, null, null), + new LabOrderResult(null, null, "uuid2", new DateTime(2014, 5, 16, 0, 0).toDate(), "ESR", "gm/L", 100.0, 200.0, "51.0", false, false, null, null), + new LabOrderResult(null, null, "uuid3", new DateTime(2014, 5, 17, 0, 0).toDate(), "ESR", null, null, null, null, null, false, null, null), + new LabOrderResult(null, null, "uuid3", new DateTime(2014, 5, 18, 0, 0).toDate(), "ESR", null, null, null, null, null, true, null, null) + ); + + LabOrderResults labOrderResults = new LabOrderResults(results); + TabularLabOrderResults table = labOrderResults.getTabularResult(); + + assertEquals(7, table.getDates().size()); + assertEquals(2, table.getOrders().size()); + assertEquals(7, table.getValues().size()); + assertEquals("uploadedFile", table.getValues().get(0).getUploadedFileName()); + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapperTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapperTest.java new file mode 100644 index 0000000000..5df25a6719 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/mapper/LabOrderResultMapperTest.java @@ -0,0 +1,170 @@ +package org.openmrs.module.bahmniemrapi.laborder.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.emrapi.test.builder.ConceptDataTypeBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class LabOrderResultMapperTest { + private LabOrderResultMapper labOrderResultMapper; + @Mock + private ConceptService conceptService; + + @Before + public void setUp() throws Exception { + initMocks(this); + ConceptDatatype coded = new ConceptDataTypeBuilder().text(); + Concept labReportConcept = new Concept(); + labReportConcept.setDatatype(coded); + when(conceptService.getConceptByName(LabOrderResultMapper.LAB_REPORT)).thenReturn(labReportConcept); + labOrderResultMapper = new LabOrderResultMapper(conceptService); + } + + + @Test + public void shouldMapTestOrderAndLabOrderResultToObs() throws Exception { + LabOrderResult labOrderResult = new LabOrderResult(); + String resultUuid = "abcd-1234"; + labOrderResult.setResultUuid(resultUuid); + labOrderResult.setResult("A+ve"); + labOrderResult.setAccessionUuid("accession-uuid"); + labOrderResult.setTestName("Blood Group"); + + ConceptDatatype codedDataType = new ConceptDataTypeBuilder().coded(); + Concept testConcept = new Concept(1); + testConcept.setDatatype(codedDataType); + Concept resultConcept = new Concept(2); + resultConcept.setDatatype(codedDataType); + + Order testOrder = new Order(1); + when(conceptService.getConceptByUuid(resultUuid)).thenReturn(resultConcept); + + Obs topLevelObs = labOrderResultMapper.map(labOrderResult, testOrder, testConcept); + + assertEquals(testConcept, topLevelObs.getConcept()); + assertEquals(testOrder, topLevelObs.getOrder()); + List testObs = new ArrayList<>(topLevelObs.getGroupMembers()); + List resultObs = new ArrayList<>(testObs.get(0).getGroupMembers()); + assertEquals(1, resultObs.size()); + assertEquals(testConcept.getId(), resultObs.get(0).getConcept().getId()); + assertEquals(testOrder, resultObs.get(0).getOrder()); + assertEquals(resultConcept, resultObs.get(0).getValueCoded()); + assertNull(resultObs.get(0).getValueText()); + } + + @Test + public void shouldNotAddObsIfResultIsNotAnswerForCodedConcept() throws Exception { + LabOrderResult labOrderResult = new LabOrderResult(); + labOrderResult.setResultUuid(null); + labOrderResult.setResult("A+ve"); + labOrderResult.setAccessionUuid("accession-uuid"); + labOrderResult.setTestName("Blood Group"); + + ConceptDatatype coded = new ConceptDataTypeBuilder().coded(); + Concept testConcept = new Concept(1); + testConcept.setDatatype(coded); + Order testOrder = new Order(1); + + Obs topLevelObs = labOrderResultMapper.map(labOrderResult, testOrder, testConcept); + + List testObs = new ArrayList<>(topLevelObs.getGroupMembers()); + Set resultObs = testObs.get(0).getGroupMembers(); + assertEquals(1, testObs.size()); + assertTrue(CollectionUtils.isEmpty(resultObs)); + + } + + @Test + public void shouldMapTestOrderAndLabOrderResultToObsForNumericConcepts() throws Exception { + LabOrderResult labOrderResult = new LabOrderResult(); + labOrderResult.setResultUuid(null); + labOrderResult.setResult("15"); + labOrderResult.setAccessionUuid("accession-uuid"); + labOrderResult.setTestName("Haemoglobin"); + + ConceptDatatype coded = new ConceptDataTypeBuilder().numeric(); + Concept testConcept = new Concept(1); + testConcept.setDatatype(coded); + Order testOrder = new Order(1); + + Obs topLevelObs = labOrderResultMapper.map(labOrderResult, testOrder, testConcept); + + assertEquals(testConcept, topLevelObs.getConcept()); + assertEquals(testOrder, topLevelObs.getOrder()); + List testObs = new ArrayList<>(topLevelObs.getGroupMembers()); + List resultObs = new ArrayList<>(testObs.get(0).getGroupMembers()); + assertEquals(1, resultObs.size()); + assertEquals(testConcept, resultObs.get(0).getConcept()); + assertEquals(testOrder, resultObs.get(0).getOrder()); + assertEquals(new Double(15), resultObs.get(0).getValueNumeric()); + } + + @Test + public void shouldNotAddEmptyObsWhenResultIsNotPresent() throws Exception { + LabOrderResult labOrderResult = new LabOrderResult(); + labOrderResult.setResultUuid(null); + labOrderResult.setResult(null); + labOrderResult.setAccessionUuid("accession-uuid"); + labOrderResult.setTestName("Haemoglobin"); + + ConceptDatatype coded = new ConceptDataTypeBuilder().numeric(); + Concept testConcept = new Concept(1); + testConcept.setDatatype(coded); + Order testOrder = new Order(1); + + Obs topLevelObs = labOrderResultMapper.map(labOrderResult, testOrder, testConcept); + + assertEquals(testConcept, topLevelObs.getConcept()); + assertEquals(testOrder, topLevelObs.getOrder()); + List testObs = new ArrayList<>(topLevelObs.getGroupMembers()); + Set resultObs = testObs.get(0).getGroupMembers(); + assertEquals(1, testObs.size()); + assertTrue(CollectionUtils.isEmpty(resultObs)); + + } + + @Test + public void shouldMapFileNameEvenEvenWhenResultIsNotPresent() throws Exception { + String uploadedFileName = "ResultsDoc"; + LabOrderResult labOrderResult = new LabOrderResult(); + labOrderResult.setResultUuid(null); + labOrderResult.setResult(null); + labOrderResult.setUploadedFileName(uploadedFileName); + labOrderResult.setAccessionUuid("accession-uuid"); + labOrderResult.setTestName("Haemoglobin"); + + ConceptDatatype coded = new ConceptDataTypeBuilder().numeric(); + Concept testConcept = new Concept(1); + testConcept.setDatatype(coded); + Order testOrder = new Order(1); + + Obs topLevelObs = labOrderResultMapper.map(labOrderResult, testOrder, testConcept); + + assertEquals(testConcept, topLevelObs.getConcept()); + assertEquals(testOrder, topLevelObs.getOrder()); + List testObs = new ArrayList<>(topLevelObs.getGroupMembers()); + List resultObs = new ArrayList<>(testObs.get(0).getGroupMembers()); + + assertEquals(1, testObs.size()); + assertEquals(1, resultObs.size()); + assertEquals(uploadedFileName, resultObs.get(0).getValueText()); + } + +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceIT.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceIT.java new file mode 100644 index 0000000000..16d0eeea92 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceIT.java @@ -0,0 +1,203 @@ +package org.openmrs.module.bahmniemrapi.laborder.service; + +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.BaseIntegrationTest; +import org.openmrs.module.bahmniemrapi.accessionnote.contract.AccessionNote; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResults; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +public class LabOrderResultsServiceIT extends BaseIntegrationTest { + + @Autowired + private LabOrderResultsService labOrderResultsService; + + @Test + public void shouldMapTestOrdersAndResultsForAllVisits() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + Patient patient = Context.getPatientService().getPatient(1000000); + + LabOrderResults results = labOrderResultsService.getAll(patient, null, Integer.MAX_VALUE); + List labOrderResults = results.getResults(); + + assertNotNull(labOrderResults); + assertEquals(6, labOrderResults.size()); + + assertOrderPresent(labOrderResults, "Haemoglobin", "Blood Panel", 16, "System OpenMRS", "99.0", 200.0, 300.0, true, null, true, null); + assertOrderPresent(labOrderResults, "ESR", "Blood Panel", 16, "System OpenMRS", "10.0", null, null, false, "Some Notes", false, null); + assertOrderPresent(labOrderResults, "Urea Nitrogen", null, 16, "System OpenMRS", "20.0", null, null, null, null, false, "8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg"); + assertOrderPresent(labOrderResults, "HIV ELISA", null, 16, null, null, null, null, null, null, false, null); + assertOrderPresent(labOrderResults, "PS for Malaria", null, 16, "System OpenMRS", null, null, null, null, null, true, null); + assertOrderPresent(labOrderResults, "PS for Malaria", null, 17, "System OpenMRS", "Result for PS Malaria", null, null, null, null, false, null); + assertFalse(isOrderPresent(labOrderResults, "Chest X-Ray", 16)); + } + + @Test + public void shouldMapAccessionNotesForAGivenVisit() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + + Patient patient = Context.getPatientService().getPatient(1000000); + Visit visit = Context.getVisitService().getVisit(4); + + LabOrderResults results = labOrderResultsService.getAll(patient, Arrays.asList(visit), Integer.MAX_VALUE); + List labOrderResults = results.getResults(); + + assertEquals(1, labOrderResults.size()); + List accessionNotes = labOrderResults.get(0).getAccessionNotes(); + assertNotNull(accessionNotes); + assertThat(accessionNotes.size(), is(equalTo(1))); + AccessionNote accessionNote = accessionNotes.get(0); + assertThat(accessionNote.getAccessionUuid(), is(equalTo("b0a81566-0c0c-11e4-bb80-f18addb6f9bb"))); + assertThat(accessionNote.getProviderName(), is(equalTo("System OpenMRS"))); + assertThat(accessionNote.getText(), is(equalTo("Notes from Lab Manager"))); + + assertOrderPresent(labOrderResults, "PS for Malaria", null, 17, "System OpenMRS", "Result for PS Malaria", null, null, null, null, false, null); + } + + @Test + public void shouldGetLabOrdersForParticularConcepts() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + + Patient patient = Context.getPatientService().getPatient(1000000); + + Collection concepts = new ArrayList<>(); + concepts.add("Blood Panel"); + + List results = labOrderResultsService.getAllForConcepts(patient, concepts, null, null, null); + + assertEquals(results.size(), 2); + assertOrderPresent(results, "Haemoglobin", "Blood Panel", 16, "System OpenMRS", "99.0", 200.0, 300.0, true, null, true, null); + assertOrderPresent(results, "ESR", "Blood Panel", 16, "System OpenMRS", "10.0", null, null, false, "Some Notes", false, null); + + } + + @Test + public void shouldGetLabOrdersForParticularConceptsWithinGivenDateRange() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); + Date startDate = simpleDateFormat.parse("2008-08-17T00:00:00.000"); + Date endDate = simpleDateFormat.parse("2008-08-20T00:00:00.000"); + + Patient patient = Context.getPatientService().getPatient(1000000); + + Collection concepts = new ArrayList<>(); + concepts.add("Blood Panel"); + concepts.add("Urea Nitrogen"); + + List results = labOrderResultsService.getAllForConcepts(patient, concepts, null, startDate, endDate); + + assertEquals(results.size(), 3); + assertOrderPresent(results, "Haemoglobin", "Blood Panel", 16, "System OpenMRS", "99.0", 200.0, 300.0, true, null, true, null); + assertOrderPresent(results, "ESR", "Blood Panel", 16, "System OpenMRS", "10.0", null, null, false, "Some Notes", false, null); + assertOrderPresent(results, "Urea Nitrogen", null, 16, null, null, null, null, null, null, false, null); + } + + + @Test + public void shouldMapTestOrdersAndResultsForGivenVisit() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + Patient patient = Context.getPatientService().getPatient(1000000); + Visit visit = Context.getVisitService().getVisit(4); + + LabOrderResults results = labOrderResultsService.getAll(patient, Arrays.asList(visit), Integer.MAX_VALUE); + List labOrderResults = results.getResults(); + + assertNotNull(labOrderResults); + assertEquals(1, labOrderResults.size()); + + assertOrderPresent(labOrderResults, "PS for Malaria", null, 17, "System OpenMRS", "Result for PS Malaria", null, null, null, null, false, null); + } + + @Test + public void shouldMapTestOrdersRecordedInTestOrderTableWithTheirResultsForGivenVisit() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + executeDataSet("labOrderAssociatedWithTestOrderData.xml"); + Patient patient = Context.getPatientService().getPatient(1000000); + Visit visit = Context.getVisitService().getVisit(4); + + LabOrderResults results = labOrderResultsService.getAll(patient, Arrays.asList(visit), Integer.MAX_VALUE); + List labOrderResults = results.getResults(); + + assertNotNull(labOrderResults); + assertEquals(1, labOrderResults.size()); + + assertOrderPresent(labOrderResults, "PS for Malaria", null, 17, "System OpenMRS", "Result for PS Malaria", null, null, null, null, false, null); + } + + @Test + public void shouldGetLabOrdersWithResultsEvenIfItIsDiscontinued() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("labOrderTestData.xml"); + Patient patient = Context.getPatientService().getPatient(1000001); + + Visit visit = Context.getVisitService().getVisit(5); + + LabOrderResults labOrderResults = labOrderResultsService.getAll(patient, Arrays.asList(visit), Integer.MAX_VALUE); + List labResults = labOrderResults.getResults(); + + assertEquals(6, labResults.size()); + } + + private void assertOrderPresent(List labOrderResults, String testName, String panelName, Integer accessionEncounterId, String provider, String value, Double minNormal, Double maxNormal, Boolean abnormal, String notes, Boolean referredOut, String uploadedFileName) { + Encounter accessionEncounter = Context.getEncounterService().getEncounter(accessionEncounterId); + for (LabOrderResult labOrderResult : labOrderResults) { + if (labOrderResult.getTestName().equals(testName) && labOrderResult.getAccessionUuid().equals(accessionEncounter.getUuid())) { + assertEquals(panelName, labOrderResult.getPanelName()); + assertEquals(accessionEncounter.getEncounterDatetime(), labOrderResult.getAccessionDateTime()); + assertEquals(value, labOrderResult.getResult()); + assertEquals(minNormal, labOrderResult.getMinNormal()); + assertEquals(maxNormal, labOrderResult.getMaxNormal()); + assertEquals(abnormal, labOrderResult.getAbnormal()); + assertEquals(notes, labOrderResult.getNotes()); + assertEquals(referredOut, labOrderResult.getReferredOut()); + assertEquals(provider, labOrderResult.getProvider()); + assertEquals(uploadedFileName, labOrderResult.getUploadedFileName()); + return; + } + } + fail(); + } + + private boolean isOrderPresent(List labOrderResults, String testName, Integer accessionEncounterId) { + Encounter accessionEncounter = Context.getEncounterService().getEncounter(accessionEncounterId); + for (LabOrderResult labOrderResult : labOrderResults) { + if (labOrderResult.getTestName().equals(testName) && labOrderResult.getAccessionUuid().equals(accessionEncounter.getUuid())) { + return true; + } + } + return false; + } +} diff --git a/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceImplTest.java b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceImplTest.java new file mode 100644 index 0000000000..0623533b17 --- /dev/null +++ b/bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/laborder/service/LabOrderResultsServiceImplTest.java @@ -0,0 +1,132 @@ +package org.openmrs.module.bahmniemrapi.laborder.service; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class LabOrderResultsServiceImplTest { + + @Mock + private EncounterTransaction encounterTransaction; + + @Mock + private Encounter encounter; + + @InjectMocks + private LabOrderResultsServiceImpl labOrderResultsServiceImpl; + + @Before + public void init() { + initMocks(this); + when(encounter.getVisit()).thenReturn(new Visit()); + } + + @Test + public void filterTestOrdersEvenWhenTheyAreDiscontinued() throws Exception { + List concepts = Arrays.asList("concept1", "concept2","concept3"); + Map encounterTestOrderUuidMap = new HashMap<>(); + EncounterTransaction.Order order1 = createOrder("uuid1","concept1", Order.Action.NEW.toString(), null); + EncounterTransaction.Order order2 = createOrder("uuid2", "concept2", Order.Action.REVISE.toString(), null); + EncounterTransaction.Order order3 = createOrder("uuid3", "concept3", Order.Action.NEW.toString(), new Date()); + when(encounterTransaction.getOrders()).thenReturn(Arrays.asList(order1, order2, order3)); + + List orders = labOrderResultsServiceImpl.filterTestOrders(encounterTransaction, encounter, encounterTestOrderUuidMap, concepts, null, null); + + assertEquals(3, orders.size()); + } + + @Test + public void filterTestOrdersShouldNotFilterByConcept() throws Exception { + Map encounterTestOrderUuidMap = new HashMap<>(); + EncounterTransaction.Order order1 = createOrder("uuid1","concept1", Order.Action.NEW.toString(), null); + when(encounterTransaction.getOrders()).thenReturn(Arrays.asList(order1)); + + List orders = labOrderResultsServiceImpl.filterTestOrders(encounterTransaction, encounter, encounterTestOrderUuidMap, null, null, null); + + assertEquals(1, orders.size()); + } + + @Test + public void mapOrdersWithObsShouldMapAllObservationsToLabOrderResults() { + EncounterTransaction.Order order1 = createOrder("uuid1","concept1", Order.Action.NEW.toString(), null); + EncounterTransaction.Order order2 = createOrder("uuid2", "concept2", Order.Action.REVISE.toString(), null); + List testOrders = Arrays.asList(order1, order2); + EncounterTransaction.Observation order1_Obs1 = createObservation("obsuuid1", order1.getUuid()); + EncounterTransaction.Observation order1_Obs2 = createObservation("obsuuid2", order1.getUuid()); + EncounterTransaction.Observation order2_Obs1 = createObservation("obsuuid3", order2.getUuid()); + List observations = Arrays.asList(order1_Obs1, order1_Obs2, order2_Obs1); + Map orderToEncounterMapping = new HashMap<>(); + orderToEncounterMapping.put(order1.getUuid(), encounter); + orderToEncounterMapping.put(order2.getUuid(), encounter); + Map observationToEncounterMapping = new HashMap<>(); + observationToEncounterMapping.put(order1_Obs1.getUuid(), encounter); + observationToEncounterMapping.put(order1_Obs2.getUuid(), encounter); + observationToEncounterMapping.put(order2_Obs1.getUuid(), encounter); + + List results = labOrderResultsServiceImpl.mapOrdersWithObs(testOrders, observations, orderToEncounterMapping, observationToEncounterMapping, new HashMap()); + + assertEquals(3, results.size()); + } + + @Test + public void mapOrdersWithObsShouldMapLabTestWithoutResultToLabOrderResult() { + EncounterTransaction.Order order1 = createOrder("uuid1","concept1", Order.Action.NEW.toString(), null); + List testOrders = Arrays.asList(order1); + Map orderToEncounterMapping = new HashMap<>(); + orderToEncounterMapping.put(order1.getUuid(), encounter); + + List results = labOrderResultsServiceImpl.mapOrdersWithObs(testOrders, new ArrayList(), orderToEncounterMapping, new HashMap(), new HashMap()); + + assertEquals(1, results.size()); + } + + @Test + public void mapOrdersWithObsShouldNotMapDiscontinuedLabTestWithoutResultsToLabOrderResult() { + EncounterTransaction.Order discontinuedOrder = createOrder("uuid1","concept1", Order.Action.NEW.toString(), new Date()); + List testOrders = Arrays.asList(discontinuedOrder); + Map orderToEncounterMapping = new HashMap<>(); + orderToEncounterMapping.put(discontinuedOrder.getUuid(), encounter); + + List results = labOrderResultsServiceImpl.mapOrdersWithObs(testOrders, new ArrayList(), orderToEncounterMapping, new HashMap(), new HashMap()); + + assertEquals(0, results.size()); + } + + private EncounterTransaction.Order createOrder(String uuid, String conceptName, String action, Date dateStopped) { + EncounterTransaction.Order order = new EncounterTransaction.Order(); + EncounterTransaction.Concept concept = new EncounterTransaction.Concept(); + concept.setName(conceptName); + order.setConcept(concept); + order.setAction(action); + order.setDateStopped(dateStopped); + order.setUuid(uuid); + order.setOrderType(LabOrderResultsServiceImpl.LAB_ORDER_TYPE); + return order; + } + + private EncounterTransaction.Observation createObservation(String uuid, String orderUuid) { + EncounterTransaction.Observation observation = new EncounterTransaction.Observation(); + observation.setUuid(uuid); + observation.setOrderUuid(orderUuid); + observation.setConcept(new EncounterTransaction.Concept()); + return observation; + } + +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/resources/TestingApplicationContext.xml b/bahmni-emr-api/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..7513246114 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,48 @@ + + + + + + + + classpath:hibernate.cfg.xml + classpath:test-hibernate.cfg.xml + + + + + + + + org.openmrs + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/VisitLocationDataSet.xml b/bahmni-emr-api/src/test/resources/VisitLocationDataSet.xml new file mode 100644 index 0000000000..d7282e2296 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/VisitLocationDataSet.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmni-emr-api/src/test/resources/concepts.xml b/bahmni-emr-api/src/test/resources/concepts.xml new file mode 100644 index 0000000000..c9d310fd92 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/concepts.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/bahmni-emr-api/src/test/resources/diagnosisMetadata.xml b/bahmni-emr-api/src/test/resources/diagnosisMetadata.xml new file mode 100644 index 0000000000..1f874ffeab --- /dev/null +++ b/bahmni-emr-api/src/test/resources/diagnosisMetadata.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/dispositionMetadata.xml b/bahmni-emr-api/src/test/resources/dispositionMetadata.xml new file mode 100644 index 0000000000..edf8d0328f --- /dev/null +++ b/bahmni-emr-api/src/test/resources/dispositionMetadata.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/drugOrderTestData.xml b/bahmni-emr-api/src/test/resources/drugOrderTestData.xml new file mode 100644 index 0000000000..2320d792e0 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/drugOrderTestData.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/labOrderAssociatedWithTestOrderData.xml b/bahmni-emr-api/src/test/resources/labOrderAssociatedWithTestOrderData.xml new file mode 100644 index 0000000000..b0ef7e35f2 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/labOrderAssociatedWithTestOrderData.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/bahmni-emr-api/src/test/resources/labOrderTestData.xml b/bahmni-emr-api/src/test/resources/labOrderTestData.xml new file mode 100644 index 0000000000..9df04e9a56 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/labOrderTestData.xml @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/obsRelationshipDataset.xml b/bahmni-emr-api/src/test/resources/obsRelationshipDataset.xml new file mode 100644 index 0000000000..f727aaf937 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/obsRelationshipDataset.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/obscalculator/BahmniObsValueCalculator.groovy b/bahmni-emr-api/src/test/resources/obscalculator/BahmniObsValueCalculator.groovy new file mode 100644 index 0000000000..b8f89b260b --- /dev/null +++ b/bahmni-emr-api/src/test/resources/obscalculator/BahmniObsValueCalculator.groovy @@ -0,0 +1,15 @@ +package obscalculator + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction +import org.openmrs.module.bahmniemrapi.obscalculator.ObsValueCalculator + +public class TestObsValueCalculator implements ObsValueCalculator { + + public static String DEFAULT_ENCOUNTER_UUID = "defaultEncounterUuid" + + @Override + void run(BahmniEncounterTransaction bahmniEncounterTransaction) { + bahmniEncounterTransaction.setEncounterUuid(DEFAULT_ENCOUNTER_UUID) + + } +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/resources/openmrsUpgradeTestData.xml b/bahmni-emr-api/src/test/resources/openmrsUpgradeTestData.xml new file mode 100644 index 0000000000..0f43b1c811 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/openmrsUpgradeTestData.xml @@ -0,0 +1,67 @@ + + + + + ' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/sampleEncounterTransaction.json b/bahmni-emr-api/src/test/resources/sampleEncounterTransaction.json new file mode 100644 index 0000000000..efcca5216a --- /dev/null +++ b/bahmni-emr-api/src/test/resources/sampleEncounterTransaction.json @@ -0,0 +1,21725 @@ +{ + "locationUuid": "c1e42932-3f10-11e4-adec-0800271c1b75", + "patientUuid": "213d707d-7ae7-4c94-9649-dbe971120094", + "encounterUuid": null, + "visitUuid": null, + "context": { + "patientProgramUuid":"253a5353-46b6-4668-97bb-8d1967ef3418" + }, + "providers": [ + { + "uuid": "c1c26908-3f10-11e4-adec-0800271c1b75" + } + ], + "encounterDateTime": null, + "extensions": { + "mdrtbSpecimen": [ + { + "dateCollected": "2016-02-09", + "existingObs": null, + "identifier": "123", + "sample": {}, + "report": {}, + "type": { + "uuid": "7c10a797-bea6-43a2-baaa-f61ae4829e70", + "name": "Bacteriology Sample, Sputum", + "shortName": "Sputum", + "description": null, + "dataType": null, + "conceptClass": null, + "displayString": "Sputum" + } + } + ] + }, + "visitType": "OPD", + "bahmniDiagnoses": [ + { + "codedAnswer": { + "uuid": "e9b6897e-4e14-11e4-8a57-0800271c1b75" + }, + "order": "PRIMARY", + "certainty": "CONFIRMED", + "existingObs": null, + "diagnosisDateTime": null, + "diagnosisStatusConcept": null, + "comments": "" + } + ], + "orders": [ + { + "concept": { + "uuid": "2e0967e0-687a-4d2e-aa63-7f0e832c8f46" + } + } + ], + "drugOrders": [ + { + "careSetting": "OUTPATIENT", + "drug": { + "name": "Paracetamol 500mg", + "form": "Tablet", + "uuid": "d9c230a5-89d8-4e4d-b08b-2af3b1234c80" + }, + "orderType": "Drug Order", + "dosingInstructionType": "org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions.FlexibleDosingInstructions", + "dosingInstructions": { + "dose": 2, + "doseUnits": "Tablet(s)", + "route": "Oral", + "frequency": "Immediately", + "asNeeded": false, + "administrationInstructions": "{\"instructions\":\"As directed\"}", + "quantity": 4, + "quantityUnits": "Tablet(s)", + "numberOfRefills": 0 + }, + "duration": 2, + "durationUnits": "Day(s)", + "scheduledDate": "2016-02-09T06:37:23.043Z", + "autoExpireDate": null, + "dateStopped": null + } + ], + "disposition": { + "dispositionDateTime": null, + "additionalObs": [ + { + "concept": { + "uuid": "81d4a9dc-3f10-11e4-adec-0800271c1b75" + }, + "value": "Create admit disposition" + } + ], + "code": "ADMIT", + "conceptName": "Admit Patient" + }, + "observations": [ + { + "concept": { + "uuid": "c393fd1d-3f10-11e4-adec-0800271c1b75", + "name": "History and Examination", + "dataType": "N/A" + }, + "units": null, + "label": "History and Examination", + "possibleAnswers": [], + "groupMembers": [ + { + "concept": { + "uuid": "c3949eb6-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint Data", + "dataType": "N/A" + }, + "units": null, + "label": "Chief Complaint", + "possibleAnswers": [], + "groupMembers": [ + { + "concept": { + "uuid": "c3959ab5-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint", + "dataType": "Coded" + }, + "units": null, + "label": "Chief Complaint", + "possibleAnswers": [ + { + "uuid": "1dfb0948-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Pain", + "uuid": "1dfb4057-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abcdef", + "uuid": "06f553b7-1bb1-4fdc-8ce5-c1be5431a726", + "name": "Abcdef", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1dfe7928-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal Lump", + "uuid": "1dfea86c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal Lump", + "resourceVersion": "1.9" + }, + { + "uuid": "1e01664e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anorexia", + "uuid": "1e0193e9-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anorexia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anasarca", + "uuid": "1e0391a9-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anasarca", + "resourceVersion": "1.9" + }, + { + "uuid": "1e078201-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anxiety states", + "uuid": "1e07b285-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anxiety states", + "resourceVersion": "1.9" + }, + { + "uuid": "1e09fa6a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Bleeding, rectal", + "uuid": "1e0b5e02-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Bleeding, rectal", + "resourceVersion": "1.9" + }, + { + "uuid": "1e0f4158-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Chest Pain", + "uuid": "1e10c198-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Chest Pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1e1f19ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cleft Palate", + "uuid": "1e1f4c18-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cleft Palate", + "resourceVersion": "1.9" + }, + { + "uuid": "1e233bb7-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Constipation", + "uuid": "1e237f07-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Constipation", + "resourceVersion": "1.9" + }, + { + "uuid": "1e272149-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Convulsions", + "uuid": "1e275637-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Convulsions", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2918fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cough", + "uuid": "1e29e270-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cough", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2d7883-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Crying, infant, excessive", + "uuid": "1e2daa20-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Crying, infant, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "1e31dff9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dental caries", + "uuid": "1e321dfd-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dental caries", + "resourceVersion": "1.9" + }, + { + "uuid": "1e35fb1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dysphagia", + "uuid": "1e362d8f-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dysphagia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e39b082-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Edema, localized, NOS", + "uuid": "1e39f14a-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Edema, localized, NOS", + "resourceVersion": "1.9" + }, + { + "uuid": "1e3d5749-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Epistaxis", + "uuid": "1e3d94cc-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Epistaxis", + "resourceVersion": "1.9" + }, + { + "uuid": "1e6f31a6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Failure to thrive, child", + "uuid": "1e6f6cee-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Failure to thrive, child", + "resourceVersion": "1.9" + }, + { + "uuid": "1ec7b018-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fatigue and malaise, other", + "uuid": "1ec7ebb0-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fatigue and malaise, other", + "resourceVersion": "1.9" + }, + { + "uuid": "1f090668-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f095bc6-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Feeding problem, infant/elderly", + "resourceVersion": "1.9" + }, + { + "uuid": "1f0f8ec6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fever", + "uuid": "9b6d70b7-01a0-4921-b443-32d43e7d1c11", + "name": "Fever", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fever", + "resourceVersion": "1.9" + }, + { + "uuid": "1f139595-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fracture upper arm", + "uuid": "1f13c7ad-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fracture upper arm", + "resourceVersion": "1.9" + }, + { + "uuid": "1f17bb4b-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gas/bloating", + "uuid": "1f19fe18-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gas/bloating", + "resourceVersion": "1.9" + }, + { + "uuid": "1f1c29f6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gingival and periodontal diseases", + "uuid": "1f1c5c7a-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gingival and periodontal diseases", + "resourceVersion": "1.9" + }, + { + "uuid": "1f592562-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "HDACHE", + "uuid": "b44e015e-f9da-4a66-8758-27571e85f629", + "name": "HDACHE", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Headache", + "uuid": "1f5955e9-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Headache", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5b3d0e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hearing loss", + "uuid": "1f5bb99f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hearing loss", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5e563c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Heartburn", + "uuid": "1f5ea764-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Heartburn", + "resourceVersion": "1.9" + }, + { + "uuid": "1f635f1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Blood in vomiting", + "uuid": "1f639b78-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Blood in vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6685c0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f66ba49-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemiplegia and hemiparesis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6a5ea9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemoptysis", + "uuid": "1f6a998c-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemoptysis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6ee168-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hiccups", + "uuid": "1f6f1593-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hiccups", + "resourceVersion": "1.9" + }, + { + "uuid": "1f70f0e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hoarseness", + "uuid": "1f71227a-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hoarseness", + "resourceVersion": "1.9" + }, + { + "uuid": "1fa53cd0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Infertility", + "uuid": "1fa57591-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Infertility", + "resourceVersion": "1.9" + }, + { + "uuid": "1faa5af3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Injury", + "uuid": "1faa9085-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Injury", + "resourceVersion": "1.9" + }, + { + "uuid": "1fad62aa-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Irregular menstrual cycle", + "uuid": "1fad93de-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Irregular menstrual cycle", + "resourceVersion": "1.9" + }, + { + "uuid": "1fb39d05-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Joint swelling, single", + "uuid": "1fb3cb0f-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Joint swelling, single", + "resourceVersion": "1.9" + }, + { + "uuid": "1fefe32c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff01b27-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Localized swelling/mass, superficial", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff55e9c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Lump in breast", + "uuid": "1ff71aeb-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Lump in breast", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff9d6fc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Swelling", + "uuid": "1ffa0ac8-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Swelling", + "resourceVersion": "1.9" + }, + { + "uuid": "1ffe2cde-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Malaise and fatigue", + "uuid": "1ffe57c4-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Malaise and fatigue", + "resourceVersion": "1.9" + }, + { + "uuid": "200275e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Memory loss", + "uuid": "2002ae5a-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Memory loss", + "resourceVersion": "1.9" + }, + { + "uuid": "20052626-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Mental status changes", + "uuid": "200555c9-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Mental status changes", + "resourceVersion": "1.9" + }, + { + "uuid": "203d9e67-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea w/ vomiting", + "uuid": "2078e7ba-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea w/ vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "207d0654-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea", + "uuid": "936618b8-4ddb-4b75-b282-e75536177069", + "name": "Nausea", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea", + "resourceVersion": "1.9" + }, + { + "uuid": "20b7d029-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nocturia", + "uuid": "20b8032c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nocturia", + "resourceVersion": "1.9" + }, + { + "uuid": "20bb55e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Obstructed labor", + "uuid": "20bb8674-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Obstructed labor", + "resourceVersion": "1.9" + }, + { + "uuid": "20bed4ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, chronic, due to trauma", + "uuid": "20bf055a-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, chronic, due to trauma", + "resourceVersion": "1.9" + }, + { + "uuid": "20f7020d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, knee", + "uuid": "20f73ab4-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, knee", + "resourceVersion": "1.9" + }, + { + "uuid": "212927fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Low backache", + "uuid": "21295f74-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Low backache", + "resourceVersion": "1.9" + }, + { + "uuid": "212d295f-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Palpitations", + "uuid": "212d56e9-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Palpitations", + "resourceVersion": "1.9" + }, + { + "uuid": "212ffc94-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Polyuria", + "uuid": "21302f71-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Polyuria", + "resourceVersion": "1.9" + }, + { + "uuid": "2134b7e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "216f1228-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Rash, nonvesicular, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "2173b7d9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Something coming out of anus", + "uuid": "2173ebb7-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Something coming out of anus", + "resourceVersion": "1.9" + }, + { + "uuid": "2178d694-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Seizures, convulsions, other", + "uuid": "21790758-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, convulsions, other", + "resourceVersion": "1.9" + }, + { + "uuid": "217d6872-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "simple", + "uuid": "d7ee60cc-2509-4d19-91c2-93cbc2a369ec", + "name": "simple", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures", + "uuid": "77f57803-5a4c-4cf8-a693-9294c4d42d68", + "name": "Seizures", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, simple, febrile, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "21835173-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Shortness of breath", + "uuid": "2183846d-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of breath", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Shortness of Breath", + "resourceVersion": "1.9" + }, + { + "uuid": "21880af9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sickle-cell anemia", + "uuid": "21883d78-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sickle-cell anemia", + "resourceVersion": "1.9" + }, + { + "uuid": "21bdb6cf-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bdf75e-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Somethingcoming out per vaginum", + "resourceVersion": "1.9" + }, + { + "uuid": "21c2aedc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Stomatitis and mucositis", + "uuid": "21c2e109-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Stomatitis and mucositis", + "resourceVersion": "1.9" + }, + { + "uuid": "21c6e70d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sweating, excessive", + "uuid": "21c76a88-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sweating, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "21cacfb0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Throat pain", + "uuid": "21cafdf3-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Throat pain", + "resourceVersion": "1.9" + }, + { + "uuid": "220fc2a9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Ulcer of lower limbs", + "uuid": "220ff355-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Ulcer of lower limbs", + "resourceVersion": "1.9" + }, + { + "uuid": "2216e20d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Vomiting", + "uuid": "221711de-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "22479fd3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Walking difficulty", + "uuid": "2247d410-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Walking difficulty", + "resourceVersion": "1.9" + }, + { + "uuid": "224b7592-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Wheezing", + "uuid": "224bb61c-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Wheezing", + "resourceVersion": "1.9" + }, + { + "uuid": "62b91692-0641-45b1-9233-3c9609c6b6a8", + "name": { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Thingy", + "uuid": "5b16ebdb-4140-47c8-adf5-a73504125fb7", + "name": "Thingy", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Paracetamol 500mg", + "resourceVersion": "1.9" + } + ], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": { + "freeTextAutocomplete": true, + "durationRequired": false, + "allowAddMore": true + }, + "uniqueId": "observation_1", + "erroneousValue": null, + "value": { + "label": "Anasarca", + "value": "Anasarca", + "concept": { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + }, + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca" + }, + "_value": { + "label": "Anasarca", + "value": "Anasarca", + "concept": { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + }, + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca" + }, + "observationDateTime": null, + "nonCodedAnswer": false, + "voided": false + }, + { + "concept": { + "uuid": "c3975851-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint Duration", + "dataType": "Numeric" + }, + "units": null, + "label": "Chief Complaint Duration", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": [], + "uniqueId": "observation_3", + "erroneousValue": false, + "value": 2, + "_value": 2, + "voided": false + } + ], + "comment": null, + "value": "Anasarca", + "primaryObs": { + "concept": { + "uuid": "c3959ab5-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint", + "shortName": "Chief Complaint", + "description": null, + "set": false, + "dataType": "Coded", + "hiAbsolute": null, + "lowAbsolute": null, + "hiNormal": null, + "handler": null, + "lowNormal": null, + "conceptClass": "Misc", + "answers": [ + { + "uuid": "1dfb0948-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Pain", + "uuid": "1dfb4057-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abcdef", + "uuid": "06f553b7-1bb1-4fdc-8ce5-c1be5431a726", + "name": "Abcdef", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1dfe7928-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal Lump", + "uuid": "1dfea86c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal Lump", + "resourceVersion": "1.9" + }, + { + "uuid": "1e01664e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anorexia", + "uuid": "1e0193e9-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anorexia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anasarca", + "uuid": "1e0391a9-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anasarca", + "resourceVersion": "1.9" + }, + { + "uuid": "1e078201-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anxiety states", + "uuid": "1e07b285-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anxiety states", + "resourceVersion": "1.9" + }, + { + "uuid": "1e09fa6a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Bleeding, rectal", + "uuid": "1e0b5e02-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Bleeding, rectal", + "resourceVersion": "1.9" + }, + { + "uuid": "1e0f4158-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Chest Pain", + "uuid": "1e10c198-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Chest Pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1e1f19ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cleft Palate", + "uuid": "1e1f4c18-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cleft Palate", + "resourceVersion": "1.9" + }, + { + "uuid": "1e233bb7-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Constipation", + "uuid": "1e237f07-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Constipation", + "resourceVersion": "1.9" + }, + { + "uuid": "1e272149-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Convulsions", + "uuid": "1e275637-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Convulsions", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2918fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cough", + "uuid": "1e29e270-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cough", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2d7883-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Crying, infant, excessive", + "uuid": "1e2daa20-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Crying, infant, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "1e31dff9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dental caries", + "uuid": "1e321dfd-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dental caries", + "resourceVersion": "1.9" + }, + { + "uuid": "1e35fb1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dysphagia", + "uuid": "1e362d8f-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dysphagia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e39b082-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Edema, localized, NOS", + "uuid": "1e39f14a-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Edema, localized, NOS", + "resourceVersion": "1.9" + }, + { + "uuid": "1e3d5749-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Epistaxis", + "uuid": "1e3d94cc-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Epistaxis", + "resourceVersion": "1.9" + }, + { + "uuid": "1e6f31a6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Failure to thrive, child", + "uuid": "1e6f6cee-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Failure to thrive, child", + "resourceVersion": "1.9" + }, + { + "uuid": "1ec7b018-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fatigue and malaise, other", + "uuid": "1ec7ebb0-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fatigue and malaise, other", + "resourceVersion": "1.9" + }, + { + "uuid": "1f090668-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f095bc6-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Feeding problem, infant/elderly", + "resourceVersion": "1.9" + }, + { + "uuid": "1f0f8ec6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fever", + "uuid": "9b6d70b7-01a0-4921-b443-32d43e7d1c11", + "name": "Fever", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fever", + "resourceVersion": "1.9" + }, + { + "uuid": "1f139595-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fracture upper arm", + "uuid": "1f13c7ad-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fracture upper arm", + "resourceVersion": "1.9" + }, + { + "uuid": "1f17bb4b-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gas/bloating", + "uuid": "1f19fe18-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gas/bloating", + "resourceVersion": "1.9" + }, + { + "uuid": "1f1c29f6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gingival and periodontal diseases", + "uuid": "1f1c5c7a-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gingival and periodontal diseases", + "resourceVersion": "1.9" + }, + { + "uuid": "1f592562-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "HDACHE", + "uuid": "b44e015e-f9da-4a66-8758-27571e85f629", + "name": "HDACHE", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Headache", + "uuid": "1f5955e9-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Headache", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5b3d0e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hearing loss", + "uuid": "1f5bb99f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hearing loss", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5e563c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Heartburn", + "uuid": "1f5ea764-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Heartburn", + "resourceVersion": "1.9" + }, + { + "uuid": "1f635f1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Blood in vomiting", + "uuid": "1f639b78-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Blood in vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6685c0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f66ba49-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemiplegia and hemiparesis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6a5ea9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemoptysis", + "uuid": "1f6a998c-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemoptysis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6ee168-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hiccups", + "uuid": "1f6f1593-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hiccups", + "resourceVersion": "1.9" + }, + { + "uuid": "1f70f0e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hoarseness", + "uuid": "1f71227a-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hoarseness", + "resourceVersion": "1.9" + }, + { + "uuid": "1fa53cd0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Infertility", + "uuid": "1fa57591-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Infertility", + "resourceVersion": "1.9" + }, + { + "uuid": "1faa5af3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Injury", + "uuid": "1faa9085-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Injury", + "resourceVersion": "1.9" + }, + { + "uuid": "1fad62aa-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Irregular menstrual cycle", + "uuid": "1fad93de-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Irregular menstrual cycle", + "resourceVersion": "1.9" + }, + { + "uuid": "1fb39d05-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Joint swelling, single", + "uuid": "1fb3cb0f-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Joint swelling, single", + "resourceVersion": "1.9" + }, + { + "uuid": "1fefe32c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff01b27-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Localized swelling/mass, superficial", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff55e9c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Lump in breast", + "uuid": "1ff71aeb-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Lump in breast", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff9d6fc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Swelling", + "uuid": "1ffa0ac8-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Swelling", + "resourceVersion": "1.9" + }, + { + "uuid": "1ffe2cde-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Malaise and fatigue", + "uuid": "1ffe57c4-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Malaise and fatigue", + "resourceVersion": "1.9" + }, + { + "uuid": "200275e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Memory loss", + "uuid": "2002ae5a-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Memory loss", + "resourceVersion": "1.9" + }, + { + "uuid": "20052626-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Mental status changes", + "uuid": "200555c9-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Mental status changes", + "resourceVersion": "1.9" + }, + { + "uuid": "203d9e67-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea w/ vomiting", + "uuid": "2078e7ba-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea w/ vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "207d0654-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea", + "uuid": "936618b8-4ddb-4b75-b282-e75536177069", + "name": "Nausea", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea", + "resourceVersion": "1.9" + }, + { + "uuid": "20b7d029-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nocturia", + "uuid": "20b8032c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nocturia", + "resourceVersion": "1.9" + }, + { + "uuid": "20bb55e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Obstructed labor", + "uuid": "20bb8674-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Obstructed labor", + "resourceVersion": "1.9" + }, + { + "uuid": "20bed4ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, chronic, due to trauma", + "uuid": "20bf055a-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, chronic, due to trauma", + "resourceVersion": "1.9" + }, + { + "uuid": "20f7020d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, knee", + "uuid": "20f73ab4-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, knee", + "resourceVersion": "1.9" + }, + { + "uuid": "212927fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Low backache", + "uuid": "21295f74-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Low backache", + "resourceVersion": "1.9" + }, + { + "uuid": "212d295f-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Palpitations", + "uuid": "212d56e9-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Palpitations", + "resourceVersion": "1.9" + }, + { + "uuid": "212ffc94-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Polyuria", + "uuid": "21302f71-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Polyuria", + "resourceVersion": "1.9" + }, + { + "uuid": "2134b7e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "216f1228-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Rash, nonvesicular, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "2173b7d9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Something coming out of anus", + "uuid": "2173ebb7-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Something coming out of anus", + "resourceVersion": "1.9" + }, + { + "uuid": "2178d694-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Seizures, convulsions, other", + "uuid": "21790758-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, convulsions, other", + "resourceVersion": "1.9" + }, + { + "uuid": "217d6872-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "simple", + "uuid": "d7ee60cc-2509-4d19-91c2-93cbc2a369ec", + "name": "simple", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures", + "uuid": "77f57803-5a4c-4cf8-a693-9294c4d42d68", + "name": "Seizures", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, simple, febrile, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "21835173-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Shortness of breath", + "uuid": "2183846d-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of breath", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Shortness of Breath", + "resourceVersion": "1.9" + }, + { + "uuid": "21880af9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sickle-cell anemia", + "uuid": "21883d78-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sickle-cell anemia", + "resourceVersion": "1.9" + }, + { + "uuid": "21bdb6cf-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bdf75e-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Somethingcoming out per vaginum", + "resourceVersion": "1.9" + }, + { + "uuid": "21c2aedc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Stomatitis and mucositis", + "uuid": "21c2e109-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Stomatitis and mucositis", + "resourceVersion": "1.9" + }, + { + "uuid": "21c6e70d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sweating, excessive", + "uuid": "21c76a88-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sweating, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "21cacfb0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Throat pain", + "uuid": "21cafdf3-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Throat pain", + "resourceVersion": "1.9" + }, + { + "uuid": "220fc2a9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Ulcer of lower limbs", + "uuid": "220ff355-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Ulcer of lower limbs", + "resourceVersion": "1.9" + }, + { + "uuid": "2216e20d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Vomiting", + "uuid": "221711de-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "22479fd3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Walking difficulty", + "uuid": "2247d410-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Walking difficulty", + "resourceVersion": "1.9" + }, + { + "uuid": "224b7592-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Wheezing", + "uuid": "224bb61c-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Wheezing", + "resourceVersion": "1.9" + }, + { + "uuid": "62b91692-0641-45b1-9233-3c9609c6b6a8", + "name": { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Thingy", + "uuid": "5b16ebdb-4140-47c8-adf5-a73504125fb7", + "name": "Thingy", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Paracetamol 500mg", + "resourceVersion": "1.9" + } + ], + "units": null, + "displayString": "Chief Complaint" + }, + "units": null, + "label": "Chief Complaint", + "possibleAnswers": [ + { + "uuid": "1dfb0948-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Pain", + "uuid": "1dfb4057-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abcdef", + "uuid": "06f553b7-1bb1-4fdc-8ce5-c1be5431a726", + "name": "Abcdef", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1dfe7928-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal Lump", + "uuid": "1dfea86c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal Lump", + "resourceVersion": "1.9" + }, + { + "uuid": "1e01664e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anorexia", + "uuid": "1e0193e9-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anorexia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anasarca", + "uuid": "1e0391a9-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anasarca", + "resourceVersion": "1.9" + }, + { + "uuid": "1e078201-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anxiety states", + "uuid": "1e07b285-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anxiety states", + "resourceVersion": "1.9" + }, + { + "uuid": "1e09fa6a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Bleeding, rectal", + "uuid": "1e0b5e02-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Bleeding, rectal", + "resourceVersion": "1.9" + }, + { + "uuid": "1e0f4158-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Chest Pain", + "uuid": "1e10c198-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Chest Pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1e1f19ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cleft Palate", + "uuid": "1e1f4c18-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cleft Palate", + "resourceVersion": "1.9" + }, + { + "uuid": "1e233bb7-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Constipation", + "uuid": "1e237f07-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Constipation", + "resourceVersion": "1.9" + }, + { + "uuid": "1e272149-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Convulsions", + "uuid": "1e275637-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Convulsions", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2918fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cough", + "uuid": "1e29e270-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cough", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2d7883-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Crying, infant, excessive", + "uuid": "1e2daa20-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Crying, infant, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "1e31dff9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dental caries", + "uuid": "1e321dfd-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dental caries", + "resourceVersion": "1.9" + }, + { + "uuid": "1e35fb1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dysphagia", + "uuid": "1e362d8f-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dysphagia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e39b082-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Edema, localized, NOS", + "uuid": "1e39f14a-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Edema, localized, NOS", + "resourceVersion": "1.9" + }, + { + "uuid": "1e3d5749-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Epistaxis", + "uuid": "1e3d94cc-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Epistaxis", + "resourceVersion": "1.9" + }, + { + "uuid": "1e6f31a6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Failure to thrive, child", + "uuid": "1e6f6cee-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Failure to thrive, child", + "resourceVersion": "1.9" + }, + { + "uuid": "1ec7b018-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fatigue and malaise, other", + "uuid": "1ec7ebb0-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fatigue and malaise, other", + "resourceVersion": "1.9" + }, + { + "uuid": "1f090668-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f095bc6-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Feeding problem, infant/elderly", + "resourceVersion": "1.9" + }, + { + "uuid": "1f0f8ec6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fever", + "uuid": "9b6d70b7-01a0-4921-b443-32d43e7d1c11", + "name": "Fever", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fever", + "resourceVersion": "1.9" + }, + { + "uuid": "1f139595-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fracture upper arm", + "uuid": "1f13c7ad-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fracture upper arm", + "resourceVersion": "1.9" + }, + { + "uuid": "1f17bb4b-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gas/bloating", + "uuid": "1f19fe18-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gas/bloating", + "resourceVersion": "1.9" + }, + { + "uuid": "1f1c29f6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gingival and periodontal diseases", + "uuid": "1f1c5c7a-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gingival and periodontal diseases", + "resourceVersion": "1.9" + }, + { + "uuid": "1f592562-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "HDACHE", + "uuid": "b44e015e-f9da-4a66-8758-27571e85f629", + "name": "HDACHE", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Headache", + "uuid": "1f5955e9-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Headache", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5b3d0e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hearing loss", + "uuid": "1f5bb99f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hearing loss", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5e563c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Heartburn", + "uuid": "1f5ea764-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Heartburn", + "resourceVersion": "1.9" + }, + { + "uuid": "1f635f1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Blood in vomiting", + "uuid": "1f639b78-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Blood in vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6685c0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f66ba49-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemiplegia and hemiparesis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6a5ea9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemoptysis", + "uuid": "1f6a998c-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemoptysis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6ee168-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hiccups", + "uuid": "1f6f1593-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hiccups", + "resourceVersion": "1.9" + }, + { + "uuid": "1f70f0e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hoarseness", + "uuid": "1f71227a-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hoarseness", + "resourceVersion": "1.9" + }, + { + "uuid": "1fa53cd0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Infertility", + "uuid": "1fa57591-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Infertility", + "resourceVersion": "1.9" + }, + { + "uuid": "1faa5af3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Injury", + "uuid": "1faa9085-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Injury", + "resourceVersion": "1.9" + }, + { + "uuid": "1fad62aa-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Irregular menstrual cycle", + "uuid": "1fad93de-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Irregular menstrual cycle", + "resourceVersion": "1.9" + }, + { + "uuid": "1fb39d05-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Joint swelling, single", + "uuid": "1fb3cb0f-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Joint swelling, single", + "resourceVersion": "1.9" + }, + { + "uuid": "1fefe32c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff01b27-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Localized swelling/mass, superficial", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff55e9c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Lump in breast", + "uuid": "1ff71aeb-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Lump in breast", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff9d6fc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Swelling", + "uuid": "1ffa0ac8-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Swelling", + "resourceVersion": "1.9" + }, + { + "uuid": "1ffe2cde-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Malaise and fatigue", + "uuid": "1ffe57c4-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Malaise and fatigue", + "resourceVersion": "1.9" + }, + { + "uuid": "200275e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Memory loss", + "uuid": "2002ae5a-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Memory loss", + "resourceVersion": "1.9" + }, + { + "uuid": "20052626-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Mental status changes", + "uuid": "200555c9-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Mental status changes", + "resourceVersion": "1.9" + }, + { + "uuid": "203d9e67-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea w/ vomiting", + "uuid": "2078e7ba-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea w/ vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "207d0654-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea", + "uuid": "936618b8-4ddb-4b75-b282-e75536177069", + "name": "Nausea", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea", + "resourceVersion": "1.9" + }, + { + "uuid": "20b7d029-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nocturia", + "uuid": "20b8032c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nocturia", + "resourceVersion": "1.9" + }, + { + "uuid": "20bb55e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Obstructed labor", + "uuid": "20bb8674-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Obstructed labor", + "resourceVersion": "1.9" + }, + { + "uuid": "20bed4ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, chronic, due to trauma", + "uuid": "20bf055a-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, chronic, due to trauma", + "resourceVersion": "1.9" + }, + { + "uuid": "20f7020d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, knee", + "uuid": "20f73ab4-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, knee", + "resourceVersion": "1.9" + }, + { + "uuid": "212927fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Low backache", + "uuid": "21295f74-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Low backache", + "resourceVersion": "1.9" + }, + { + "uuid": "212d295f-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Palpitations", + "uuid": "212d56e9-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Palpitations", + "resourceVersion": "1.9" + }, + { + "uuid": "212ffc94-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Polyuria", + "uuid": "21302f71-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Polyuria", + "resourceVersion": "1.9" + }, + { + "uuid": "2134b7e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "216f1228-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Rash, nonvesicular, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "2173b7d9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Something coming out of anus", + "uuid": "2173ebb7-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Something coming out of anus", + "resourceVersion": "1.9" + }, + { + "uuid": "2178d694-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Seizures, convulsions, other", + "uuid": "21790758-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, convulsions, other", + "resourceVersion": "1.9" + }, + { + "uuid": "217d6872-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "simple", + "uuid": "d7ee60cc-2509-4d19-91c2-93cbc2a369ec", + "name": "simple", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures", + "uuid": "77f57803-5a4c-4cf8-a693-9294c4d42d68", + "name": "Seizures", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, simple, febrile, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "21835173-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Shortness of breath", + "uuid": "2183846d-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of breath", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Shortness of Breath", + "resourceVersion": "1.9" + }, + { + "uuid": "21880af9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sickle-cell anemia", + "uuid": "21883d78-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sickle-cell anemia", + "resourceVersion": "1.9" + }, + { + "uuid": "21bdb6cf-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bdf75e-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Somethingcoming out per vaginum", + "resourceVersion": "1.9" + }, + { + "uuid": "21c2aedc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Stomatitis and mucositis", + "uuid": "21c2e109-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Stomatitis and mucositis", + "resourceVersion": "1.9" + }, + { + "uuid": "21c6e70d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sweating, excessive", + "uuid": "21c76a88-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sweating, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "21cacfb0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Throat pain", + "uuid": "21cafdf3-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Throat pain", + "resourceVersion": "1.9" + }, + { + "uuid": "220fc2a9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Ulcer of lower limbs", + "uuid": "220ff355-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Ulcer of lower limbs", + "resourceVersion": "1.9" + }, + { + "uuid": "2216e20d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Vomiting", + "uuid": "221711de-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "22479fd3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Walking difficulty", + "uuid": "2247d410-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Walking difficulty", + "resourceVersion": "1.9" + }, + { + "uuid": "224b7592-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Wheezing", + "uuid": "224bb61c-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Wheezing", + "resourceVersion": "1.9" + }, + { + "uuid": "62b91692-0641-45b1-9233-3c9609c6b6a8", + "name": { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Thingy", + "uuid": "5b16ebdb-4140-47c8-adf5-a73504125fb7", + "name": "Thingy", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Paracetamol 500mg", + "resourceVersion": "1.9" + } + ], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": { + "freeTextAutocomplete": true, + "durationRequired": false, + "allowAddMore": true + }, + "uniqueId": "observation_1", + "erroneousValue": null, + "value": { + "label": "Anasarca", + "value": "Anasarca", + "concept": { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + }, + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca" + }, + "_value": { + "label": "Anasarca", + "value": "Anasarca", + "concept": { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + }, + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca" + }, + "observationDateTime": null, + "nonCodedAnswer": false, + "voided": false + }, + "conceptUIConfig": { + "freeTextAutocomplete": true, + "durationRequired": false, + "allowAddMore": true + }, + "markedAsNonCoded": false, + "isObservationNode": true, + "uniqueId": "observation_4", + "durationObs": { + "concept": { + "uuid": "c3975851-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint Duration", + "shortName": "Chief Complaint Duration", + "description": null, + "set": false, + "dataType": "Numeric", + "hiAbsolute": null, + "lowAbsolute": null, + "hiNormal": null, + "handler": null, + "lowNormal": null, + "conceptClass": "Duration", + "answers": [], + "units": null, + "displayString": "Chief Complaint Duration" + }, + "units": null, + "label": "Chief Complaint Duration", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": [], + "uniqueId": "observation_3", + "erroneousValue": false, + "value": 2, + "_value": 2 + }, + "freeTextPrimaryObs": { + "concept": { + "uuid": "c3966752-3f10-11e4-adec-0800271c1b75", + "name": "Non-Coded Chief Complaint", + "shortName": "Non-Coded Chief Complaint", + "description": null, + "set": false, + "dataType": "Text", + "hiAbsolute": null, + "lowAbsolute": null, + "hiNormal": null, + "handler": null, + "lowNormal": null, + "conceptClass": "Misc", + "answers": [], + "units": null, + "displayString": "Non-Coded Chief Complaint" + }, + "units": null, + "label": "Non-Coded Chief Complaint", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": { + "freeTextAutocomplete": true, + "durationRequired": false + }, + "uniqueId": "observation_2", + "erroneousValue": null, + "voided": false, + "observationDateTime": null, + "nonCodedAnswer": false + }, + "codedPrimaryObs": { + "concept": { + "uuid": "c3959ab5-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint", + "shortName": "Chief Complaint", + "description": null, + "set": false, + "dataType": "Coded", + "hiAbsolute": null, + "lowAbsolute": null, + "hiNormal": null, + "handler": null, + "lowNormal": null, + "conceptClass": "Misc", + "answers": [ + { + "uuid": "1dfb0948-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Pain", + "uuid": "1dfb4057-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abcdef", + "uuid": "06f553b7-1bb1-4fdc-8ce5-c1be5431a726", + "name": "Abcdef", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1dfe7928-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal Lump", + "uuid": "1dfea86c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal Lump", + "resourceVersion": "1.9" + }, + { + "uuid": "1e01664e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anorexia", + "uuid": "1e0193e9-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anorexia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anasarca", + "uuid": "1e0391a9-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anasarca", + "resourceVersion": "1.9" + }, + { + "uuid": "1e078201-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anxiety states", + "uuid": "1e07b285-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anxiety states", + "resourceVersion": "1.9" + }, + { + "uuid": "1e09fa6a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Bleeding, rectal", + "uuid": "1e0b5e02-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Bleeding, rectal", + "resourceVersion": "1.9" + }, + { + "uuid": "1e0f4158-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Chest Pain", + "uuid": "1e10c198-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Chest Pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1e1f19ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cleft Palate", + "uuid": "1e1f4c18-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cleft Palate", + "resourceVersion": "1.9" + }, + { + "uuid": "1e233bb7-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Constipation", + "uuid": "1e237f07-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Constipation", + "resourceVersion": "1.9" + }, + { + "uuid": "1e272149-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Convulsions", + "uuid": "1e275637-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Convulsions", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2918fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cough", + "uuid": "1e29e270-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cough", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2d7883-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Crying, infant, excessive", + "uuid": "1e2daa20-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Crying, infant, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "1e31dff9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dental caries", + "uuid": "1e321dfd-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dental caries", + "resourceVersion": "1.9" + }, + { + "uuid": "1e35fb1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dysphagia", + "uuid": "1e362d8f-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dysphagia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e39b082-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Edema, localized, NOS", + "uuid": "1e39f14a-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Edema, localized, NOS", + "resourceVersion": "1.9" + }, + { + "uuid": "1e3d5749-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Epistaxis", + "uuid": "1e3d94cc-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Epistaxis", + "resourceVersion": "1.9" + }, + { + "uuid": "1e6f31a6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Failure to thrive, child", + "uuid": "1e6f6cee-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Failure to thrive, child", + "resourceVersion": "1.9" + }, + { + "uuid": "1ec7b018-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fatigue and malaise, other", + "uuid": "1ec7ebb0-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fatigue and malaise, other", + "resourceVersion": "1.9" + }, + { + "uuid": "1f090668-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f095bc6-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Feeding problem, infant/elderly", + "resourceVersion": "1.9" + }, + { + "uuid": "1f0f8ec6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fever", + "uuid": "9b6d70b7-01a0-4921-b443-32d43e7d1c11", + "name": "Fever", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fever", + "resourceVersion": "1.9" + }, + { + "uuid": "1f139595-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fracture upper arm", + "uuid": "1f13c7ad-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fracture upper arm", + "resourceVersion": "1.9" + }, + { + "uuid": "1f17bb4b-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gas/bloating", + "uuid": "1f19fe18-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gas/bloating", + "resourceVersion": "1.9" + }, + { + "uuid": "1f1c29f6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gingival and periodontal diseases", + "uuid": "1f1c5c7a-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gingival and periodontal diseases", + "resourceVersion": "1.9" + }, + { + "uuid": "1f592562-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "HDACHE", + "uuid": "b44e015e-f9da-4a66-8758-27571e85f629", + "name": "HDACHE", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Headache", + "uuid": "1f5955e9-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Headache", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5b3d0e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hearing loss", + "uuid": "1f5bb99f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hearing loss", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5e563c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Heartburn", + "uuid": "1f5ea764-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Heartburn", + "resourceVersion": "1.9" + }, + { + "uuid": "1f635f1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Blood in vomiting", + "uuid": "1f639b78-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Blood in vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6685c0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f66ba49-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemiplegia and hemiparesis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6a5ea9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemoptysis", + "uuid": "1f6a998c-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemoptysis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6ee168-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hiccups", + "uuid": "1f6f1593-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hiccups", + "resourceVersion": "1.9" + }, + { + "uuid": "1f70f0e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hoarseness", + "uuid": "1f71227a-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hoarseness", + "resourceVersion": "1.9" + }, + { + "uuid": "1fa53cd0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Infertility", + "uuid": "1fa57591-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Infertility", + "resourceVersion": "1.9" + }, + { + "uuid": "1faa5af3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Injury", + "uuid": "1faa9085-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Injury", + "resourceVersion": "1.9" + }, + { + "uuid": "1fad62aa-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Irregular menstrual cycle", + "uuid": "1fad93de-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Irregular menstrual cycle", + "resourceVersion": "1.9" + }, + { + "uuid": "1fb39d05-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Joint swelling, single", + "uuid": "1fb3cb0f-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Joint swelling, single", + "resourceVersion": "1.9" + }, + { + "uuid": "1fefe32c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff01b27-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Localized swelling/mass, superficial", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff55e9c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Lump in breast", + "uuid": "1ff71aeb-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Lump in breast", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff9d6fc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Swelling", + "uuid": "1ffa0ac8-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Swelling", + "resourceVersion": "1.9" + }, + { + "uuid": "1ffe2cde-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Malaise and fatigue", + "uuid": "1ffe57c4-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Malaise and fatigue", + "resourceVersion": "1.9" + }, + { + "uuid": "200275e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Memory loss", + "uuid": "2002ae5a-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Memory loss", + "resourceVersion": "1.9" + }, + { + "uuid": "20052626-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Mental status changes", + "uuid": "200555c9-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Mental status changes", + "resourceVersion": "1.9" + }, + { + "uuid": "203d9e67-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea w/ vomiting", + "uuid": "2078e7ba-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea w/ vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "207d0654-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea", + "uuid": "936618b8-4ddb-4b75-b282-e75536177069", + "name": "Nausea", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea", + "resourceVersion": "1.9" + }, + { + "uuid": "20b7d029-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nocturia", + "uuid": "20b8032c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nocturia", + "resourceVersion": "1.9" + }, + { + "uuid": "20bb55e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Obstructed labor", + "uuid": "20bb8674-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Obstructed labor", + "resourceVersion": "1.9" + }, + { + "uuid": "20bed4ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, chronic, due to trauma", + "uuid": "20bf055a-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, chronic, due to trauma", + "resourceVersion": "1.9" + }, + { + "uuid": "20f7020d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, knee", + "uuid": "20f73ab4-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, knee", + "resourceVersion": "1.9" + }, + { + "uuid": "212927fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Low backache", + "uuid": "21295f74-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Low backache", + "resourceVersion": "1.9" + }, + { + "uuid": "212d295f-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Palpitations", + "uuid": "212d56e9-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Palpitations", + "resourceVersion": "1.9" + }, + { + "uuid": "212ffc94-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Polyuria", + "uuid": "21302f71-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Polyuria", + "resourceVersion": "1.9" + }, + { + "uuid": "2134b7e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "216f1228-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Rash, nonvesicular, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "2173b7d9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Something coming out of anus", + "uuid": "2173ebb7-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Something coming out of anus", + "resourceVersion": "1.9" + }, + { + "uuid": "2178d694-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Seizures, convulsions, other", + "uuid": "21790758-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, convulsions, other", + "resourceVersion": "1.9" + }, + { + "uuid": "217d6872-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "simple", + "uuid": "d7ee60cc-2509-4d19-91c2-93cbc2a369ec", + "name": "simple", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures", + "uuid": "77f57803-5a4c-4cf8-a693-9294c4d42d68", + "name": "Seizures", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, simple, febrile, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "21835173-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Shortness of breath", + "uuid": "2183846d-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of breath", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Shortness of Breath", + "resourceVersion": "1.9" + }, + { + "uuid": "21880af9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sickle-cell anemia", + "uuid": "21883d78-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sickle-cell anemia", + "resourceVersion": "1.9" + }, + { + "uuid": "21bdb6cf-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bdf75e-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Somethingcoming out per vaginum", + "resourceVersion": "1.9" + }, + { + "uuid": "21c2aedc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Stomatitis and mucositis", + "uuid": "21c2e109-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Stomatitis and mucositis", + "resourceVersion": "1.9" + }, + { + "uuid": "21c6e70d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sweating, excessive", + "uuid": "21c76a88-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sweating, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "21cacfb0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Throat pain", + "uuid": "21cafdf3-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Throat pain", + "resourceVersion": "1.9" + }, + { + "uuid": "220fc2a9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Ulcer of lower limbs", + "uuid": "220ff355-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Ulcer of lower limbs", + "resourceVersion": "1.9" + }, + { + "uuid": "2216e20d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Vomiting", + "uuid": "221711de-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "22479fd3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Walking difficulty", + "uuid": "2247d410-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Walking difficulty", + "resourceVersion": "1.9" + }, + { + "uuid": "224b7592-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Wheezing", + "uuid": "224bb61c-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Wheezing", + "resourceVersion": "1.9" + }, + { + "uuid": "62b91692-0641-45b1-9233-3c9609c6b6a8", + "name": { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Thingy", + "uuid": "5b16ebdb-4140-47c8-adf5-a73504125fb7", + "name": "Thingy", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Paracetamol 500mg", + "resourceVersion": "1.9" + } + ], + "units": null, + "displayString": "Chief Complaint" + }, + "units": null, + "label": "Chief Complaint", + "possibleAnswers": [ + { + "uuid": "1dfb0948-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Pain", + "uuid": "1dfb4057-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfb4057-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abcdef", + "uuid": "06f553b7-1bb1-4fdc-8ce5-c1be5431a726", + "name": "Abcdef", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/06f553b7-1bb1-4fdc-8ce5-c1be5431a726?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal pain", + "uuid": "1dfc6c0c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfb0948-4e15-11e4-8a57-0800271c1b75/name/1dfc6c0c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1dfe7928-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Abdominal Lump", + "uuid": "1dffa6ee-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dffa6ee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Abdominal Lump", + "uuid": "1dfea86c-4e15-11e4-8a57-0800271c1b75", + "name": "Abdominal Lump", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1dfe7928-4e15-11e4-8a57-0800271c1b75/name/1dfea86c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Abdominal Lump", + "resourceVersion": "1.9" + }, + { + "uuid": "1e01664e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anorexia", + "uuid": "1e01f0cd-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e01f0cd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anorexia", + "uuid": "1e0193e9-4e15-11e4-8a57-0800271c1b75", + "name": "Anorexia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e01664e-4e15-11e4-8a57-0800271c1b75/name/1e0193e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anorexia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anasarca", + "uuid": "1e0391a9-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e0391a9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anasarca", + "resourceVersion": "1.9" + }, + { + "uuid": "1e078201-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Anxiety states", + "uuid": "1e084f23-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e084f23-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Anxiety states", + "uuid": "1e07b285-4e15-11e4-8a57-0800271c1b75", + "name": "Anxiety states", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e078201-4e15-11e4-8a57-0800271c1b75/name/1e07b285-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Anxiety states", + "resourceVersion": "1.9" + }, + { + "uuid": "1e09fa6a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Bleeding, rectal", + "uuid": "1e0b5e02-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0b5e02-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Bleeding, rectal", + "uuid": "1e0d7878-4e15-11e4-8a57-0800271c1b75", + "name": "Bleeding, rectal", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e09fa6a-4e15-11e4-8a57-0800271c1b75/name/1e0d7878-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Bleeding, rectal", + "resourceVersion": "1.9" + }, + { + "uuid": "1e0f4158-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Chest Pain", + "uuid": "1e1aabad-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e1aabad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Chest Pain", + "uuid": "1e10c198-4e15-11e4-8a57-0800271c1b75", + "name": "Chest Pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e0f4158-4e15-11e4-8a57-0800271c1b75/name/1e10c198-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Chest Pain", + "resourceVersion": "1.9" + }, + { + "uuid": "1e1f19ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cleft Palate", + "uuid": "1e1f4c18-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1f4c18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cleft Palate", + "uuid": "1e1fd3b5-4e15-11e4-8a57-0800271c1b75", + "name": "Cleft Palate", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e1f19ef-4e15-11e4-8a57-0800271c1b75/name/1e1fd3b5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cleft Palate", + "resourceVersion": "1.9" + }, + { + "uuid": "1e233bb7-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Constipation", + "uuid": "1e237f07-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e237f07-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Constipation", + "uuid": "1e254721-4e15-11e4-8a57-0800271c1b75", + "name": "Constipation", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e233bb7-4e15-11e4-8a57-0800271c1b75/name/1e254721-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Constipation", + "resourceVersion": "1.9" + }, + { + "uuid": "1e272149-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Convulsions", + "uuid": "1e27b809-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e27b809-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Convulsions", + "uuid": "1e275637-4e15-11e4-8a57-0800271c1b75", + "name": "Convulsions", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e272149-4e15-11e4-8a57-0800271c1b75/name/1e275637-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Convulsions", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2918fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Cough", + "uuid": "1e2baa5f-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e2baa5f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Cough", + "uuid": "1e29e270-4e15-11e4-8a57-0800271c1b75", + "name": "Cough", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2918fb-4e15-11e4-8a57-0800271c1b75/name/1e29e270-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Cough", + "resourceVersion": "1.9" + }, + { + "uuid": "1e2d7883-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Crying, infant, excessive", + "uuid": "1e2daa20-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2daa20-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Crying, infant, excessive", + "uuid": "1e2e67a7-4e15-11e4-8a57-0800271c1b75", + "name": "Crying, infant, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e2d7883-4e15-11e4-8a57-0800271c1b75/name/1e2e67a7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Crying, infant, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "1e31dff9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dental caries", + "uuid": "1e32c958-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e32c958-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dental caries", + "uuid": "1e321dfd-4e15-11e4-8a57-0800271c1b75", + "name": "Dental caries", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e31dff9-4e15-11e4-8a57-0800271c1b75/name/1e321dfd-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dental caries", + "resourceVersion": "1.9" + }, + { + "uuid": "1e35fb1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Dysphagia", + "uuid": "1e362d8f-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e362d8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Dysphagia", + "uuid": "1e3691ce-4e15-11e4-8a57-0800271c1b75", + "name": "Dysphagia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e35fb1a-4e15-11e4-8a57-0800271c1b75/name/1e3691ce-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Dysphagia", + "resourceVersion": "1.9" + }, + { + "uuid": "1e39b082-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Edema, localized, NOS", + "uuid": "1e39f14a-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e39f14a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Edema, localized, NOS", + "uuid": "1e3ac671-4e15-11e4-8a57-0800271c1b75", + "name": "Edema, localized, NOS", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e39b082-4e15-11e4-8a57-0800271c1b75/name/1e3ac671-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Edema, localized, NOS", + "resourceVersion": "1.9" + }, + { + "uuid": "1e3d5749-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Epistaxis", + "uuid": "1e3d94cc-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3d94cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Epistaxis", + "uuid": "1e3dfba5-4e15-11e4-8a57-0800271c1b75", + "name": "Epistaxis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e3d5749-4e15-11e4-8a57-0800271c1b75/name/1e3dfba5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Epistaxis", + "resourceVersion": "1.9" + }, + { + "uuid": "1e6f31a6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Failure to thrive, child", + "uuid": "1eabf81b-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1eabf81b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Failure to thrive, child", + "uuid": "1e6f6cee-4e15-11e4-8a57-0800271c1b75", + "name": "Failure to thrive, child", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e6f31a6-4e15-11e4-8a57-0800271c1b75/name/1e6f6cee-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Failure to thrive, child", + "resourceVersion": "1.9" + }, + { + "uuid": "1ec7b018-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fatigue and malaise, other", + "uuid": "1ec7ebb0-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec7ebb0-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fatigue and malaise, other", + "uuid": "1ec8dcd8-4e15-11e4-8a57-0800271c1b75", + "name": "Fatigue and malaise, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ec7b018-4e15-11e4-8a57-0800271c1b75/name/1ec8dcd8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fatigue and malaise, other", + "resourceVersion": "1.9" + }, + { + "uuid": "1f090668-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f095bc6-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f095bc6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Feeding problem, infant/elderly", + "uuid": "1f0a3514-4e15-11e4-8a57-0800271c1b75", + "name": "Feeding problem, infant/elderly", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f090668-4e15-11e4-8a57-0800271c1b75/name/1f0a3514-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Feeding problem, infant/elderly", + "resourceVersion": "1.9" + }, + { + "uuid": "1f0f8ec6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fever", + "uuid": "58168723-2ba1-493a-abed-53a1e5879183", + "name": "Fever", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/58168723-2ba1-493a-abed-53a1e5879183?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fever", + "uuid": "9b6d70b7-01a0-4921-b443-32d43e7d1c11", + "name": "Fever", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f0f8ec6-4e15-11e4-8a57-0800271c1b75/name/9b6d70b7-01a0-4921-b443-32d43e7d1c11?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fever", + "resourceVersion": "1.9" + }, + { + "uuid": "1f139595-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Fracture upper arm", + "uuid": "1f15ec18-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f15ec18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Fracture upper arm", + "uuid": "1f13c7ad-4e15-11e4-8a57-0800271c1b75", + "name": "Fracture upper arm", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f139595-4e15-11e4-8a57-0800271c1b75/name/1f13c7ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Fracture upper arm", + "resourceVersion": "1.9" + }, + { + "uuid": "1f17bb4b-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gas/bloating", + "uuid": "1f1a7d80-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f1a7d80-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gas/bloating", + "uuid": "1f19fe18-4e15-11e4-8a57-0800271c1b75", + "name": "Gas/bloating", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f17bb4b-4e15-11e4-8a57-0800271c1b75/name/1f19fe18-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gas/bloating", + "resourceVersion": "1.9" + }, + { + "uuid": "1f1c29f6-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Gingival and periodontal diseases", + "uuid": "1f1c5c7a-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f1c5c7a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Gingival and periodontal diseases", + "uuid": "1f5591cb-4e15-11e4-8a57-0800271c1b75", + "name": "Gingival and periodontal diseases", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f1c29f6-4e15-11e4-8a57-0800271c1b75/name/1f5591cb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Gingival and periodontal diseases", + "resourceVersion": "1.9" + }, + { + "uuid": "1f592562-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Headache", + "uuid": "1f59b2a5-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f59b2a5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "HDACHE", + "uuid": "b44e015e-f9da-4a66-8758-27571e85f629", + "name": "HDACHE", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/b44e015e-f9da-4a66-8758-27571e85f629?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Headache", + "uuid": "1f5955e9-4e15-11e4-8a57-0800271c1b75", + "name": "Headache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f592562-4e15-11e4-8a57-0800271c1b75/name/1f5955e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Headache", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5b3d0e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hearing loss", + "uuid": "1f5bb99f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5bb99f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hearing loss", + "uuid": "1f5c984f-4e15-11e4-8a57-0800271c1b75", + "name": "Hearing loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5b3d0e-4e15-11e4-8a57-0800271c1b75/name/1f5c984f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hearing loss", + "resourceVersion": "1.9" + }, + { + "uuid": "1f5e563c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Heartburn", + "uuid": "1f5f0678-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5f0678-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Heartburn", + "uuid": "1f5ea764-4e15-11e4-8a57-0800271c1b75", + "name": "Heartburn", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f5e563c-4e15-11e4-8a57-0800271c1b75/name/1f5ea764-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Heartburn", + "resourceVersion": "1.9" + }, + { + "uuid": "1f635f1a-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Blood in vomiting", + "uuid": "1f639b78-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f639b78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Blood in vomiting", + "uuid": "1f645f26-4e15-11e4-8a57-0800271c1b75", + "name": "Blood in vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f635f1a-4e15-11e4-8a57-0800271c1b75/name/1f645f26-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Blood in vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6685c0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f66ba49-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f66ba49-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemiplegia and hemiparesis", + "uuid": "1f68b246-4e15-11e4-8a57-0800271c1b75", + "name": "Hemiplegia and hemiparesis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6685c0-4e15-11e4-8a57-0800271c1b75/name/1f68b246-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemiplegia and hemiparesis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6a5ea9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hemoptysis", + "uuid": "1f6a998c-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6a998c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hemoptysis", + "uuid": "1f6b6a6a-4e15-11e4-8a57-0800271c1b75", + "name": "Hemoptysis", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6a5ea9-4e15-11e4-8a57-0800271c1b75/name/1f6b6a6a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hemoptysis", + "resourceVersion": "1.9" + }, + { + "uuid": "1f6ee168-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hiccups", + "uuid": "1f6f1593-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f1593-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hiccups", + "uuid": "1f6f7b8f-4e15-11e4-8a57-0800271c1b75", + "name": "Hiccups", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f6ee168-4e15-11e4-8a57-0800271c1b75/name/1f6f7b8f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hiccups", + "resourceVersion": "1.9" + }, + { + "uuid": "1f70f0e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Hoarseness", + "uuid": "1f71227a-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1f71227a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Hoarseness", + "uuid": "1fa17cab-4e15-11e4-8a57-0800271c1b75", + "name": "Hoarseness", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1f70f0e3-4e15-11e4-8a57-0800271c1b75/name/1fa17cab-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Hoarseness", + "resourceVersion": "1.9" + }, + { + "uuid": "1fa53cd0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Infertility", + "uuid": "1fa57591-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa57591-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Infertility", + "uuid": "1fa5df30-4e15-11e4-8a57-0800271c1b75", + "name": "Infertility", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fa53cd0-4e15-11e4-8a57-0800271c1b75/name/1fa5df30-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Infertility", + "resourceVersion": "1.9" + }, + { + "uuid": "1faa5af3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Injury", + "uuid": "1fabbf11-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1fabbf11-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Injury", + "uuid": "1faa9085-4e15-11e4-8a57-0800271c1b75", + "name": "Injury", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1faa5af3-4e15-11e4-8a57-0800271c1b75/name/1faa9085-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Injury", + "resourceVersion": "1.9" + }, + { + "uuid": "1fad62aa-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Irregular menstrual cycle", + "uuid": "1faf5f13-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1faf5f13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Irregular menstrual cycle", + "uuid": "1fad93de-4e15-11e4-8a57-0800271c1b75", + "name": "Irregular menstrual cycle", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fad62aa-4e15-11e4-8a57-0800271c1b75/name/1fad93de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Irregular menstrual cycle", + "resourceVersion": "1.9" + }, + { + "uuid": "1fb39d05-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Joint swelling, single", + "uuid": "1fb49125-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb49125-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Joint swelling, single", + "uuid": "1fb3cb0f-4e15-11e4-8a57-0800271c1b75", + "name": "Joint swelling, single", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fb39d05-4e15-11e4-8a57-0800271c1b75/name/1fb3cb0f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Joint swelling, single", + "resourceVersion": "1.9" + }, + { + "uuid": "1fefe32c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff01b27-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff01b27-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Localized swelling/mass, superficial", + "uuid": "1ff2b9a8-4e15-11e4-8a57-0800271c1b75", + "name": "Localized swelling/mass, superficial", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1fefe32c-4e15-11e4-8a57-0800271c1b75/name/1ff2b9a8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Localized swelling/mass, superficial", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff55e9c-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Lump in breast", + "uuid": "1ff811cc-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff811cc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Lump in breast", + "uuid": "1ff71aeb-4e15-11e4-8a57-0800271c1b75", + "name": "Lump in breast", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff55e9c-4e15-11e4-8a57-0800271c1b75/name/1ff71aeb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Lump in breast", + "resourceVersion": "1.9" + }, + { + "uuid": "1ff9d6fc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Swelling", + "uuid": "1ffa0ac8-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffa0ac8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Swelling", + "uuid": "1ffbe507-4e15-11e4-8a57-0800271c1b75", + "name": "Swelling", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ff9d6fc-4e15-11e4-8a57-0800271c1b75/name/1ffbe507-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Swelling", + "resourceVersion": "1.9" + }, + { + "uuid": "1ffe2cde-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Malaise and fatigue", + "uuid": "1fff58d1-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1fff58d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Malaise and fatigue", + "uuid": "1ffe57c4-4e15-11e4-8a57-0800271c1b75", + "name": "Malaise and fatigue", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1ffe2cde-4e15-11e4-8a57-0800271c1b75/name/1ffe57c4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Malaise and fatigue", + "resourceVersion": "1.9" + }, + { + "uuid": "200275e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Memory loss", + "uuid": "20033fcb-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/20033fcb-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Memory loss", + "uuid": "2002ae5a-4e15-11e4-8a57-0800271c1b75", + "name": "Memory loss", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/200275e4-4e15-11e4-8a57-0800271c1b75/name/2002ae5a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Memory loss", + "resourceVersion": "1.9" + }, + { + "uuid": "20052626-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Mental status changes", + "uuid": "203b4d13-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/203b4d13-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Mental status changes", + "uuid": "200555c9-4e15-11e4-8a57-0800271c1b75", + "name": "Mental status changes", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20052626-4e15-11e4-8a57-0800271c1b75/name/200555c9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Mental status changes", + "resourceVersion": "1.9" + }, + { + "uuid": "203d9e67-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea w/ vomiting", + "uuid": "2079d0c8-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2079d0c8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea w/ vomiting", + "uuid": "2078e7ba-4e15-11e4-8a57-0800271c1b75", + "name": "Nausea w/ vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/203d9e67-4e15-11e4-8a57-0800271c1b75/name/2078e7ba-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea w/ vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "207d0654-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nausea", + "uuid": "46b64703-c5a6-4507-9e1a-81cd9c8f7554", + "name": "Nausea", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/46b64703-c5a6-4507-9e1a-81cd9c8f7554?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nausea", + "uuid": "936618b8-4ddb-4b75-b282-e75536177069", + "name": "Nausea", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/207d0654-4e15-11e4-8a57-0800271c1b75/name/936618b8-4ddb-4b75-b282-e75536177069?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nausea", + "resourceVersion": "1.9" + }, + { + "uuid": "20b7d029-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Nocturia", + "uuid": "20b9c36c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b9c36c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Nocturia", + "uuid": "20b8032c-4e15-11e4-8a57-0800271c1b75", + "name": "Nocturia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20b7d029-4e15-11e4-8a57-0800271c1b75/name/20b8032c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Nocturia", + "resourceVersion": "1.9" + }, + { + "uuid": "20bb55e4-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Obstructed labor", + "uuid": "20bb8674-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bb8674-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Obstructed labor", + "uuid": "20bc90fe-4e15-11e4-8a57-0800271c1b75", + "name": "Obstructed labor", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bb55e4-4e15-11e4-8a57-0800271c1b75/name/20bc90fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Obstructed labor", + "resourceVersion": "1.9" + }, + { + "uuid": "20bed4ef-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, chronic, due to trauma", + "uuid": "20bf055a-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20bf055a-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, chronic, due to trauma", + "uuid": "20c0b6ad-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, chronic, due to trauma", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20bed4ef-4e15-11e4-8a57-0800271c1b75/name/20c0b6ad-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, chronic, due to trauma", + "resourceVersion": "1.9" + }, + { + "uuid": "20f7020d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Pain, knee", + "uuid": "20f73ab4-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f73ab4-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Pain, knee", + "uuid": "20f7e3d1-4e15-11e4-8a57-0800271c1b75", + "name": "Pain, knee", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/20f7020d-4e15-11e4-8a57-0800271c1b75/name/20f7e3d1-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Pain, knee", + "resourceVersion": "1.9" + }, + { + "uuid": "212927fb-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Low backache", + "uuid": "2129ff3f-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/2129ff3f-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Low backache", + "uuid": "21295f74-4e15-11e4-8a57-0800271c1b75", + "name": "Low backache", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212927fb-4e15-11e4-8a57-0800271c1b75/name/21295f74-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Low backache", + "resourceVersion": "1.9" + }, + { + "uuid": "212d295f-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Palpitations", + "uuid": "212dc063-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212dc063-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Palpitations", + "uuid": "212d56e9-4e15-11e4-8a57-0800271c1b75", + "name": "Palpitations", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212d295f-4e15-11e4-8a57-0800271c1b75/name/212d56e9-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Palpitations", + "resourceVersion": "1.9" + }, + { + "uuid": "212ffc94-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Polyuria", + "uuid": "2131c7e5-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/2131c7e5-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Polyuria", + "uuid": "21302f71-4e15-11e4-8a57-0800271c1b75", + "name": "Polyuria", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/212ffc94-4e15-11e4-8a57-0800271c1b75/name/21302f71-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Polyuria", + "resourceVersion": "1.9" + }, + { + "uuid": "2134b7e3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "216f1228-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/216f1228-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Rash, nonvesicular, unspec.", + "uuid": "21702c6d-4e15-11e4-8a57-0800271c1b75", + "name": "Rash, nonvesicular, unspec.", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2134b7e3-4e15-11e4-8a57-0800271c1b75/name/21702c6d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Rash, nonvesicular, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "2173b7d9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Something coming out of anus", + "uuid": "21750f93-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/21750f93-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Something coming out of anus", + "uuid": "2173ebb7-4e15-11e4-8a57-0800271c1b75", + "name": "Something coming out of anus", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2173b7d9-4e15-11e4-8a57-0800271c1b75/name/2173ebb7-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Something coming out of anus", + "resourceVersion": "1.9" + }, + { + "uuid": "2178d694-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Seizures, convulsions, other", + "uuid": "21790758-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/21790758-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, convulsions, other", + "uuid": "217a0292-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, convulsions, other", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2178d694-4e15-11e4-8a57-0800271c1b75/name/217a0292-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, convulsions, other", + "resourceVersion": "1.9" + }, + { + "uuid": "217d6872-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "simple", + "uuid": "d7ee60cc-2509-4d19-91c2-93cbc2a369ec", + "name": "simple", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/d7ee60cc-2509-4d19-91c2-93cbc2a369ec?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures", + "uuid": "77f57803-5a4c-4cf8-a693-9294c4d42d68", + "name": "Seizures", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/77f57803-5a4c-4cf8-a693-9294c4d42d68?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Seizures, simple, febrile, unspec.", + "uuid": "218011f8-4e15-11e4-8a57-0800271c1b75", + "name": "Seizures, simple, febrile, unspec.", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/217d6872-4e15-11e4-8a57-0800271c1b75/name/218011f8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Seizures, simple, febrile, unspec.", + "resourceVersion": "1.9" + }, + { + "uuid": "21835173-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Shortness of Breath", + "uuid": "2185eea6-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of Breath", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2185eea6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Shortness of breath", + "uuid": "2183846d-4e15-11e4-8a57-0800271c1b75", + "name": "Shortness of breath", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21835173-4e15-11e4-8a57-0800271c1b75/name/2183846d-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Shortness of Breath", + "resourceVersion": "1.9" + }, + { + "uuid": "21880af9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sickle-cell anemia", + "uuid": "21891233-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21891233-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sickle-cell anemia", + "uuid": "21883d78-4e15-11e4-8a57-0800271c1b75", + "name": "Sickle-cell anemia", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21880af9-4e15-11e4-8a57-0800271c1b75/name/21883d78-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sickle-cell anemia", + "resourceVersion": "1.9" + }, + { + "uuid": "21bdb6cf-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bdf75e-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bdf75e-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Somethingcoming out per vaginum", + "uuid": "21bf0cbc-4e15-11e4-8a57-0800271c1b75", + "name": "Somethingcoming out per vaginum", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21bdb6cf-4e15-11e4-8a57-0800271c1b75/name/21bf0cbc-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Somethingcoming out per vaginum", + "resourceVersion": "1.9" + }, + { + "uuid": "21c2aedc-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Stomatitis and mucositis", + "uuid": "21c3e3fe-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c3e3fe-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Stomatitis and mucositis", + "uuid": "21c2e109-4e15-11e4-8a57-0800271c1b75", + "name": "Stomatitis and mucositis", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c2aedc-4e15-11e4-8a57-0800271c1b75/name/21c2e109-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Stomatitis and mucositis", + "resourceVersion": "1.9" + }, + { + "uuid": "21c6e70d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Sweating, excessive", + "uuid": "21c76a88-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c76a88-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Sweating, excessive", + "uuid": "21c80777-4e15-11e4-8a57-0800271c1b75", + "name": "Sweating, excessive", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21c6e70d-4e15-11e4-8a57-0800271c1b75/name/21c80777-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Sweating, excessive", + "resourceVersion": "1.9" + }, + { + "uuid": "21cacfb0-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Throat pain", + "uuid": "21cd80e8-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cd80e8-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Throat pain", + "uuid": "21cafdf3-4e15-11e4-8a57-0800271c1b75", + "name": "Throat pain", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/21cacfb0-4e15-11e4-8a57-0800271c1b75/name/21cafdf3-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Throat pain", + "resourceVersion": "1.9" + }, + { + "uuid": "220fc2a9-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Ulcer of lower limbs", + "uuid": "220ff355-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/220ff355-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Ulcer of lower limbs", + "uuid": "22110638-4e15-11e4-8a57-0800271c1b75", + "name": "Ulcer of lower limbs", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/220fc2a9-4e15-11e4-8a57-0800271c1b75/name/22110638-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Ulcer of lower limbs", + "resourceVersion": "1.9" + }, + { + "uuid": "2216e20d-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Vomiting", + "uuid": "2245dff6-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/2245dff6-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Vomiting", + "uuid": "221711de-4e15-11e4-8a57-0800271c1b75", + "name": "Vomiting", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/2216e20d-4e15-11e4-8a57-0800271c1b75/name/221711de-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Vomiting", + "resourceVersion": "1.9" + }, + { + "uuid": "22479fd3-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Walking difficulty", + "uuid": "22486f2b-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/22486f2b-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Walking difficulty", + "uuid": "2247d410-4e15-11e4-8a57-0800271c1b75", + "name": "Walking difficulty", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/22479fd3-4e15-11e4-8a57-0800271c1b75/name/2247d410-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Walking difficulty", + "resourceVersion": "1.9" + }, + { + "uuid": "224b7592-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Wheezing", + "uuid": "224bb61c-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": false, + "conceptNameType": "SHORT", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224bb61c-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Wheezing", + "uuid": "224c23ff-4e15-11e4-8a57-0800271c1b75", + "name": "Wheezing", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/224b7592-4e15-11e4-8a57-0800271c1b75/name/224c23ff-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Wheezing", + "resourceVersion": "1.9" + }, + { + "uuid": "62b91692-0641-45b1-9233-3c9609c6b6a8", + "name": { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + "names": [ + { + "display": "Paracetamol 500mg", + "uuid": "c2952220-626d-4cad-8ad3-39c3db8db017", + "name": "Paracetamol 500mg", + "locale": "en", + "localePreferred": true, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/c2952220-626d-4cad-8ad3-39c3db8db017?v=full" + } + ], + "resourceVersion": "1.9" + }, + { + "display": "Thingy", + "uuid": "5b16ebdb-4140-47c8-adf5-a73504125fb7", + "name": "Thingy", + "locale": "en", + "localePreferred": false, + "conceptNameType": null, + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/62b91692-0641-45b1-9233-3c9609c6b6a8/name/5b16ebdb-4140-47c8-adf5-a73504125fb7?v=full" + } + ], + "resourceVersion": "1.9" + } + ], + "displayString": "Paracetamol 500mg", + "resourceVersion": "1.9" + } + ], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": { + "freeTextAutocomplete": true, + "durationRequired": false, + "allowAddMore": true + }, + "uniqueId": "observation_1", + "erroneousValue": null, + "value": { + "label": "Anasarca", + "value": "Anasarca", + "concept": { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + }, + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca" + }, + "_value": { + "label": "Anasarca", + "value": "Anasarca", + "concept": { + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": { + "display": "Anasarca", + "uuid": "1e03fb73-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca", + "locale": "en", + "localePreferred": false, + "conceptNameType": "FULLY_SPECIFIED", + "links": [ + { + "rel": "self", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75" + }, + { + "rel": "full", + "uri": "NEED-TO-CONFIGURE/ws/rest/v1/concept/1e035d7e-4e15-11e4-8a57-0800271c1b75/name/1e03fb73-4e15-11e4-8a57-0800271c1b75?v=full" + } + ], + "resourceVersion": "1.9" + } + }, + "uuid": "1e035d7e-4e15-11e4-8a57-0800271c1b75", + "name": "Anasarca" + }, + "observationDateTime": null, + "nonCodedAnswer": false, + "voided": false + }, + "voided": false + }, + { + "concept": { + "uuid": "c398a4be-3f10-11e4-adec-0800271c1b75", + "name": "Chief Complaint Notes", + "dataType": "Text" + }, + "units": null, + "label": "Chief Complaint Notes", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": [], + "uniqueId": "observation_5", + "erroneousValue": null, + "value": "Its really a sorry situation", + "_value": "Its really a sorry situation", + "voided": false + }, + { + "concept": { + "uuid": "c39a35e2-3f10-11e4-adec-0800271c1b75", + "name": "Examination Notes", + "dataType": "Text" + }, + "units": null, + "label": "Examination Notes", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": { + "conciseText": true + }, + "uniqueId": "observation_7", + "erroneousValue": null, + "value": "Copied over", + "_value": "Copied over", + "voided": false + }, + { + "concept": { + "uuid": "c2a43174-c9db-4e54-8516-17372c83537f", + "name": "Smoking History", + "dataType": "Boolean" + }, + "units": null, + "label": "Smoking History", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": { + "Chief Complaint Data": { + "allowAddMore": true + }, + "Chief Complaint": { + "freeTextAutocomplete": true, + "durationRequired": false, + "allowAddMore": true + }, + "Posture": { + "buttonSelect": true + }, + "Non-Coded Chief Complaint": { + "freeTextAutocomplete": true, + "durationRequired": false + }, + "P/A Presenting Part": { + "multiSelect": true + }, + "FHS": { + "buttonSelect": true + }, + "P/S (Per Speculum) - Cervix": { + "grid": true + }, + "Anaemia, Stopped Since When": { + "conciseText": true + }, + "Examination Notes": { + "conciseText": true + }, + "Tuberculosis Intake Template": { + "computeDrugs": true + }, + "Set1": { + "allowAddMore": true + }, + "Set2": { + "allowAddMore": true + }, + "Coded3": { + "multiSelect": true + }, + "Image": { + "allowAddMore": true + }, + "Gynaecology, Gravida": { + "stepper": true + }, + "Accepted Family Planning methods": { + "multiSelect": true + }, + "defaults": { + "Number of living children": 1, + "Accepted Family Planning methods": [ + "Condoms", + "Pills" + ], + "Pain management given": true, + "Safe Abortion, Remarks": "Remarks", + "Malaria, Death Date": "2015-12-01" + } + }, + "uniqueId": "observation_8", + "erroneousValue": null, + "value": true, + "isBoolean": true, + "voided": false + }, + { + "concept": { + "uuid": "c2f3a270-03ac-4be3-9642-98afa4895416", + "name": "MyConcept123", + "dataType": "Date" + }, + "units": null, + "label": "shortname in english", + "possibleAnswers": [], + "groupMembers": [], + "comment": null, + "isObservation": true, + "conceptUIConfig": [], + "uniqueId": "observation_14", + "erroneousValue": null, + "value": "2016-02-09", + "_value": "2016-02-09", + "voided": false + } + ], + "comment": null, + "isObservation": true, + "conceptUIConfig": [], + "uniqueId": "observation_15", + "erroneousValue": null, + "conceptSetName": "History and Examination", + "voided": false + }, + { + "concept": { + "uuid": "81d6e852-3f10-11e4-adec-0800271c1b75" + }, + "value": "Consultation note", + "observationDateTime": null, + "groupMembers": [], + "voided": false + } + ], + "encounterTypeUuid": "81852aee-3f10-11e4-adec-0800271c1b75" +} \ No newline at end of file diff --git a/bahmni-emr-api/src/test/resources/test-hibernate.cfg.xml b/bahmni-emr-api/src/test/resources/test-hibernate.cfg.xml new file mode 100644 index 0000000000..3d2be5af34 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/test-hibernate.cfg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/bahmni-emr-api/src/test/resources/visitAttributeDataSet.xml b/bahmni-emr-api/src/test/resources/visitAttributeDataSet.xml new file mode 100644 index 0000000000..bae5642f62 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/visitAttributeDataSet.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmni-emr-api/src/test/resources/visitDocumentData.xml b/bahmni-emr-api/src/test/resources/visitDocumentData.xml new file mode 100644 index 0000000000..5499142aa7 --- /dev/null +++ b/bahmni-emr-api/src/test/resources/visitDocumentData.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-mapping/pom.xml b/bahmni-mapping/pom.xml new file mode 100644 index 0000000000..0625d9428d --- /dev/null +++ b/bahmni-mapping/pom.xml @@ -0,0 +1,76 @@ + + 4.0.0 + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + bahmni-mapping + jar + Bahmni Mapping + + + + org.openmrs.test + openmrs-test + pom + test + + + org.openmrs.api + openmrs-api + jar + + + + org.openmrs.api + openmrs-api + test-jar + test + + + junit + junit + test + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.10 + + + BRANCH + COVEREDRATIO + 0.37 + + + + + + + + + + + diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/EntityMappingDao.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/EntityMappingDao.java new file mode 100644 index 0000000000..53fc695b36 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/EntityMappingDao.java @@ -0,0 +1,13 @@ +package org.openmrs.module.bahmnimapping.dao; + +import org.openmrs.module.bahmnimapping.model.EntityMapping; +import org.openmrs.module.bahmnimapping.model.EntityMappingType; + +import java.util.List; + +public interface EntityMappingDao { + List getMappingsOfEntity(String entity1Uuid, String mappingTypeName); + List getAllEntityMappings(String mappingTypeName); + EntityMappingType getEntityMappingTypeByName(String name); + +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/LocationEncounterTypeMapDao.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/LocationEncounterTypeMapDao.java new file mode 100644 index 0000000000..4c0a40f11d --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/LocationEncounterTypeMapDao.java @@ -0,0 +1,23 @@ +/** + * 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.bahmnimapping.dao; + + +import org.openmrs.EncounterType; + +import java.util.List; + +public interface LocationEncounterTypeMapDao { + List getEncounterTypes(String locationUuid); +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/impl/EntityMappingDaoImpl.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/impl/EntityMappingDaoImpl.java new file mode 100644 index 0000000000..f4faabf8d4 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/impl/EntityMappingDaoImpl.java @@ -0,0 +1,59 @@ +package org.openmrs.module.bahmnimapping.dao.impl; + +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.openmrs.module.bahmnimapping.dao.EntityMappingDao; +import org.openmrs.module.bahmnimapping.model.EntityMapping; +import org.openmrs.module.bahmnimapping.model.EntityMappingType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class EntityMappingDaoImpl implements EntityMappingDao { + + @Autowired + private SessionFactory sessionFactory; + + @Override + public List getMappingsOfEntity(String entity1Uuid, String mappingTypeName) { + Session currentSession = sessionFactory.getCurrentSession(); + + Query query = currentSession.createQuery( + "select em " + + "from EntityMapping em, EntityMappingType emt " + + "where em.entityMappingType = emt.id " + + "and emt.name = :mappingTypeName " + + "and em.entity1Uuid = :entity1Uuid " + ); + query.setParameter("mappingTypeName", mappingTypeName); + query.setParameter("entity1Uuid", entity1Uuid); + return (List)query.list(); + } + + @Override + public List getAllEntityMappings(String mappingTypeName) { + Session currentSession = sessionFactory.getCurrentSession(); + + Query query = currentSession.createQuery( + "select em " + + "from EntityMapping em, EntityMappingType emt " + + "where em.entityMappingType = emt.id " + + "and emt.name = :mappingTypeName " + + ); + query.setParameter("mappingTypeName", mappingTypeName); + return (List)query.list(); + } + + @Override + public EntityMappingType getEntityMappingTypeByName(String name) { + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery("from EntityMappingType where name = :name"); + query.setParameter("name",name); + List list = query.list(); + return list.size()>0? (EntityMappingType) list.get(0) :null; + } +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/impl/LocationEncounterTypeMapDaoImpl.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/impl/LocationEncounterTypeMapDaoImpl.java new file mode 100644 index 0000000000..a02894348e --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/dao/impl/LocationEncounterTypeMapDaoImpl.java @@ -0,0 +1,42 @@ +/** + * 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.bahmnimapping.dao.impl; + +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.openmrs.EncounterType; +import org.openmrs.module.bahmnimapping.dao.LocationEncounterTypeMapDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class LocationEncounterTypeMapDaoImpl implements LocationEncounterTypeMapDao { + + @Autowired + private SessionFactory sessionFactory; + + @Override + public List getEncounterTypes(String locationUuid) { + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select et from EncounterType et, Location l, LocationEncounterTypeMap map " + + "where map.encounterType = et.encounterTypeId and map.location = l.locationId and l.uuid = :locationUuid " + + "and map.voided = false and et.retired = false and l.retired = false"); + query.setParameter("locationUuid", locationUuid); + return (List) query.list(); + } +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/EntityMapping.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/EntityMapping.java new file mode 100644 index 0000000000..f49aa79456 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/EntityMapping.java @@ -0,0 +1,62 @@ +package org.openmrs.module.bahmnimapping.model; + +public class EntityMapping { + private Integer id; + private String uuid; + private String entity1Uuid; + private String entity2Uuid; + private EntityMappingType entityMappingType; + + public EntityMapping() { + } + + public EntityMapping(Integer id, String uuid, String entity1Uuid, String entity2Uuid, EntityMappingType entityMappingType) { + this.id = id; + this.uuid = uuid; + this.entity1Uuid = entity1Uuid; + this.entity2Uuid = entity2Uuid; + this.entityMappingType = entityMappingType; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getEntity1Uuid() { + return entity1Uuid; + } + + public void setEntity1Uuid(String entity1Uuid) { + this.entity1Uuid = entity1Uuid; + } + + public String getEntity2Uuid() { + return entity2Uuid; + } + + public void setEntity2Uuid(String entity2Uuid) { + this.entity2Uuid = entity2Uuid; + } + + public EntityMappingType getEntityMappingType() { + return entityMappingType; + } + + public void setEntityMappingType(EntityMappingType entityMappingType) { + this.entityMappingType = entityMappingType; + } +} + + diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/EntityMappingType.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/EntityMappingType.java new file mode 100644 index 0000000000..2153b32fe7 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/EntityMappingType.java @@ -0,0 +1,60 @@ +package org.openmrs.module.bahmnimapping.model; + +public class EntityMappingType { + private Integer id; + private String uuid; + private String name; + private String entity1Type; + private String entity2Type; + + public EntityMappingType() { + } + + public EntityMappingType(Integer id, String uuid, String name, String entity1Type, String entity2Type) { + this.id = id; + this.uuid = uuid; + this.name = name; + this.entity1Type = entity1Type; + this.entity2Type = entity2Type; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEntity1Type() { + return entity1Type; + } + + public void setEntity1Type(String entity1Type) { + this.entity1Type = entity1Type; + } + + public String getEntity2Type() { + return entity2Type; + } + + public void setEntity2Type(String entity2Type) { + this.entity2Type = entity2Type; + } +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/LocationEncounterTypeMap.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/LocationEncounterTypeMap.java new file mode 100644 index 0000000000..b05543b5c9 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/model/LocationEncounterTypeMap.java @@ -0,0 +1,50 @@ +/** + * 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.bahmnimapping.model; + +import org.openmrs.BaseOpenmrsData; +import org.openmrs.EncounterType; +import org.openmrs.Location; + +public class LocationEncounterTypeMap extends BaseOpenmrsData { + private Integer id; + private EncounterType encounterType; + private Location location; + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public EncounterType getEncounterType() { + return encounterType; + } + + public void setEncounterType(EncounterType encounterType) { + this.encounterType = encounterType; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/services/BahmniLocationService.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/services/BahmniLocationService.java new file mode 100644 index 0000000000..0f8b308233 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/services/BahmniLocationService.java @@ -0,0 +1,23 @@ +/** + * 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.bahmnimapping.services; + +import org.openmrs.EncounterType; + +import java.util.List; + +public interface BahmniLocationService { + List getEncounterTypes(String locationUuid); + EncounterType getEncounterType(String locationUuid); +} diff --git a/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/services/impl/BahmniLocationServiceImpl.java b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/services/impl/BahmniLocationServiceImpl.java new file mode 100644 index 0000000000..71f0490866 --- /dev/null +++ b/bahmni-mapping/src/main/java/org/openmrs/module/bahmnimapping/services/impl/BahmniLocationServiceImpl.java @@ -0,0 +1,53 @@ +/** + * 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.bahmnimapping.services.impl; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.EncounterType; +import org.openmrs.api.APIException; +import org.openmrs.module.bahmnimapping.dao.LocationEncounterTypeMapDao; +import org.openmrs.module.bahmnimapping.services.BahmniLocationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class BahmniLocationServiceImpl implements BahmniLocationService { + private LocationEncounterTypeMapDao locationEncounterTypeMapDao; + + @Autowired + public BahmniLocationServiceImpl(LocationEncounterTypeMapDao locationEncounterTypeMapDao) { + this.locationEncounterTypeMapDao = locationEncounterTypeMapDao; + } + + @Override + public List getEncounterTypes(String locationUuid) { + if(StringUtils.isBlank(locationUuid)) return new ArrayList<>(); + return locationEncounterTypeMapDao.getEncounterTypes(locationUuid); + } + + @Override + public EncounterType getEncounterType(String locationUuid) { + List encounterTypes = getEncounterTypes(locationUuid); + if (encounterTypes.size() == 1) { + return encounterTypes.get(0); + } + if (encounterTypes.size() > 1){ + throw new APIException("The location is mapped to multiple encounter types. Please specify a encounter type for encounter"); + } + return null; + } +} diff --git a/bahmni-mapping/src/main/resources/EntityMapping.hbm.xml b/bahmni-mapping/src/main/resources/EntityMapping.hbm.xml new file mode 100644 index 0000000000..3f2c545212 --- /dev/null +++ b/bahmni-mapping/src/main/resources/EntityMapping.hbm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmni-mapping/src/main/resources/EntityMappingType.hbm.xml b/bahmni-mapping/src/main/resources/EntityMappingType.hbm.xml new file mode 100644 index 0000000000..c4f9cf5286 --- /dev/null +++ b/bahmni-mapping/src/main/resources/EntityMappingType.hbm.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmni-mapping/src/main/resources/LocationEncounterTypeMap.hbm.xml b/bahmni-mapping/src/main/resources/LocationEncounterTypeMap.hbm.xml new file mode 100644 index 0000000000..c05230555d --- /dev/null +++ b/bahmni-mapping/src/main/resources/LocationEncounterTypeMap.hbm.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmni-mapping/src/main/resources/moduleApplicationContext.xml b/bahmni-mapping/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..8afb112892 --- /dev/null +++ b/bahmni-mapping/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/dao/impl/EntityMappingDaoImplIT.java b/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/dao/impl/EntityMappingDaoImplIT.java new file mode 100644 index 0000000000..814a7761bc --- /dev/null +++ b/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/dao/impl/EntityMappingDaoImplIT.java @@ -0,0 +1,63 @@ +package org.openmrs.module.bahmnimapping.dao.impl; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmnimapping.dao.EntityMappingDao; +import org.openmrs.module.bahmnimapping.model.EntityMapping; +import org.openmrs.module.bahmnimapping.model.EntityMappingType; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class EntityMappingDaoImplIT extends BaseModuleContextSensitiveTest { + + @Autowired + private EntityMappingDao entityMappingDao; + + @Before + public void setupData() throws Exception { + executeDataSet("entityMappingData.xml"); + } + + @Test + public void shouldGetAllTheMappingsForTheGivenMappedEntity() { + List entityMappings = entityMappingDao.getMappingsOfEntity("uuid1", "program_obstemplates"); + + assertEquals(2, entityMappings.size()); + EntityMapping firstEntity = entityMappings.get(0); + assertEquals("uuid1", firstEntity.getEntity1Uuid()); + assertEquals("uuid2", firstEntity.getEntity2Uuid()); + assertEquals("program_obstemplates", firstEntity.getEntityMappingType().getName()); + EntityMapping secondEntity = entityMappings.get(1); + assertEquals("uuid1", secondEntity.getEntity1Uuid()); + assertEquals("uuid3", secondEntity.getEntity2Uuid()); + assertEquals("program_obstemplates", secondEntity.getEntityMappingType().getName()); + } + + @Test + public void shouldGetNoMappingsForTheGivenNonMappedEntity(){ + List entityMappings = entityMappingDao.getMappingsOfEntity("uuid100", "program_obstemplates"); + + assertEquals(0,entityMappings.size()); + } + + @Test + public void shouldGetNoMappingsForTheGivenNonExistingMappingType(){ + List entityMappings = entityMappingDao.getMappingsOfEntity("uuid1", "some_random_non_existing mapping type"); + + assertEquals(0,entityMappings.size()); + } + + @Test + public void shouldGetEntityMappingTypeByName(){ + EntityMappingType programObstemplateRelationship = entityMappingDao.getEntityMappingTypeByName("program_obstemplates"); + assertNotNull(programObstemplateRelationship); + assertEquals(programObstemplateRelationship.getEntity1Type(), "org.openmrs.Program"); + assertEquals(programObstemplateRelationship.getEntity2Type(), "org.openmrs.Obs"); + } +} \ No newline at end of file diff --git a/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/dao/impl/LocationEncounterTypeMapDaoImplIT.java b/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/dao/impl/LocationEncounterTypeMapDaoImplIT.java new file mode 100644 index 0000000000..de26d5b78c --- /dev/null +++ b/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/dao/impl/LocationEncounterTypeMapDaoImplIT.java @@ -0,0 +1,45 @@ +package org.openmrs.module.bahmnimapping.dao.impl; + +import org.junit.Test; +import org.openmrs.EncounterType; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class LocationEncounterTypeMapDaoImplIT extends BaseModuleContextSensitiveTest { + + @Autowired + private LocationEncounterTypeMapDaoImpl locationEncounterTypeMapDao; + + @Test + public void shouldGetEncounterTypesForMappedLocation() throws Exception { + executeDataSet("locationEncounterTypeMapData.xml"); + + List encounterTypes = locationEncounterTypeMapDao.getEncounterTypes("c36006e5-9fbb-4f20-866b-0ece245615a1"); + + assertEquals(1, encounterTypes.size()); + assertEquals("759799ab-c9a5-435e-b671-77773ada74e4", encounterTypes.get(0).getUuid()); + } + + @Test + public void shouldGetZeroEncounterTypesForUnmappedLocation() throws Exception { + executeDataSet("locationEncounterTypeMapData.xml"); + + List encounterTypes = locationEncounterTypeMapDao.getEncounterTypes("e36006e5-9fbb-4f20-866b-0ece245615a1"); + + assertEquals(0, encounterTypes.size()); + } + + @Test + public void shouldGetZeroEncounterTypesForNonExistingLocation() throws Exception { + executeDataSet("locationEncounterTypeMapData.xml"); + + List encounterTypes = locationEncounterTypeMapDao.getEncounterTypes("11111111-9fbb-4f20-866b-0ece245615a1"); + + assertEquals(0, encounterTypes.size()); + } +} \ No newline at end of file diff --git a/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/services/impl/BahmniLocationServiceImplTest.java b/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/services/impl/BahmniLocationServiceImplTest.java new file mode 100644 index 0000000000..e4c3d3de82 --- /dev/null +++ b/bahmni-mapping/src/test/java/org/openmrs/module/bahmnimapping/services/impl/BahmniLocationServiceImplTest.java @@ -0,0 +1,41 @@ +package org.openmrs.module.bahmnimapping.services.impl; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.openmrs.EncounterType; +import org.openmrs.api.APIException; +import org.openmrs.module.bahmnimapping.dao.LocationEncounterTypeMapDao; + +import java.util.Arrays; +import java.util.UUID; + +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniLocationServiceImplTest { + @Mock + private LocationEncounterTypeMapDao locationEncounterTypeMapDao; + private BahmniLocationServiceImpl bahmniLocationService; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Before + public void setUp() { + initMocks(this); + bahmniLocationService = new BahmniLocationServiceImpl(locationEncounterTypeMapDao); + } + + @Test + public void getEncounterTypeShouldRaiseErrorWhenLocationIsMappedToMultipleEncounterTypes() throws Exception { + String locationUuid = UUID.randomUUID().toString(); + when(locationEncounterTypeMapDao.getEncounterTypes(locationUuid)).thenReturn(Arrays.asList(new EncounterType(), new EncounterType())); + + expectedException.expect(APIException.class); + expectedException.expectMessage("The location is mapped to multiple encounter types. Please specify a encounter type for encounter"); + bahmniLocationService.getEncounterType(locationUuid); + } +} \ No newline at end of file diff --git a/bahmni-mapping/src/test/resources/TestingApplicationContext.xml b/bahmni-mapping/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..35ac0d71a7 --- /dev/null +++ b/bahmni-mapping/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,28 @@ + + + + + + + + classpath:hibernate.cfg.xml + classpath:test-hibernate.cfg.xml + + + + + + + + org.openmrs + + + + + diff --git a/bahmni-mapping/src/test/resources/entityMappingData.xml b/bahmni-mapping/src/test/resources/entityMappingData.xml new file mode 100644 index 0000000000..20fec53b13 --- /dev/null +++ b/bahmni-mapping/src/test/resources/entityMappingData.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/bahmni-mapping/src/test/resources/locationEncounterTypeMapData.xml b/bahmni-mapping/src/test/resources/locationEncounterTypeMapData.xml new file mode 100644 index 0000000000..9df25283c5 --- /dev/null +++ b/bahmni-mapping/src/test/resources/locationEncounterTypeMapData.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bahmni-mapping/src/test/resources/test-hibernate.cfg.xml b/bahmni-mapping/src/test/resources/test-hibernate.cfg.xml new file mode 100644 index 0000000000..6cd552272a --- /dev/null +++ b/bahmni-mapping/src/test/resources/test-hibernate.cfg.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/bahmni-test-commons/pom.xml b/bahmni-test-commons/pom.xml new file mode 100644 index 0000000000..a65be4f4ae --- /dev/null +++ b/bahmni-test-commons/pom.xml @@ -0,0 +1,67 @@ + + + + Bahmni Test Commons + org.bahmni.test + bahmni-test-commons + jar + 4.0.0 + ${project.parent.version} + Test setup for Bahmni + + + bahmni + org.bahmni.module + 1.2.0-SNAPSHOT + + + + + javax.servlet + javax.servlet-api + + + junit + junit + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + jar + + + org.openmrs.web + openmrs-web + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + test-jar + test + + + javax.servlet + servlet-api + + + + + org.openmrs.test + openmrs-test + ${openMRSVersion} + pom + test + + + diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ConceptBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ConceptBuilder.java new file mode 100644 index 0000000000..9733dbb958 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ConceptBuilder.java @@ -0,0 +1,166 @@ +package org.bahmni.test.builder; + +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptName; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; + +import java.util.Date; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +public class ConceptBuilder { + private final org.openmrs.Concept concept; + + public ConceptBuilder() { + concept = new Concept(); + } + + public Concept build() { + return concept; + } + + public ConceptBuilder withName(String conceptName) { + ConceptName name = new ConceptName(conceptName, LocaleUtility.getDefaultLocale()); + return withName(name); + } + + public ConceptBuilder withName(String conceptName, Locale locale) { + ConceptName name = new ConceptName(conceptName, locale); + return withName(name); + } + + public ConceptBuilder withName(ConceptName name) { + name.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + concept.setPreferredName(name); + return this; + } + + public ConceptBuilder forSample() { + return withUUID("Sample UUID") + .withDateCreated(new Date()) + .withDateChanged(new Date()) + .withName("SampleName"); + } + + public ConceptBuilder forTest(){ + return new ConceptBuilder().withClass("LabTest").withName("TestName").withDataType("Text"); + } + + public ConceptBuilder forPanel(){ + return new ConceptBuilder().withClass("LabSet").withClassUUID(ConceptClass.LABSET_UUID).withName("PanelName"); + } + + public ConceptBuilder forDepartment() { + return withUUID("Department UUID") + .withDateCreated(new Date()) + .withDateChanged(new Date()) + .withDescription("Some Description") + .withName("SampleName"); + } + + public ConceptBuilder withDataType(String name) { + withDataType(name, "hl7Abbreviation", null); + return this; + } + + public ConceptBuilder withDataType(String name, String hl7Abbreviation) { + withDataType(name, hl7Abbreviation, null); + return this; + } + + public ConceptBuilder withUUID(String uuid) { + concept.setUuid(uuid); + return this; + } + + public ConceptBuilder withClass(String conceptClassName) { + ConceptClass conceptClass = concept.getConceptClass(); + if (conceptClass == null) { + conceptClass = new ConceptClass(); + } + conceptClass.setName(conceptClassName); + concept.setConceptClass(conceptClass); + return this; + } + + public ConceptBuilder withClassUUID(String uuid) { + ConceptClass conceptClass = concept.getConceptClass(); + if (conceptClass == null) { + conceptClass = new ConceptClass(); + } + conceptClass.setUuid(uuid); + concept.setConceptClass(conceptClass); + return this; + } + + + public ConceptBuilder withSetMember(Concept setMember) { + concept.addSetMember(setMember); + return this; + } + + public ConceptBuilder withDataTypeNumeric() { + withDataType("Numeric", ConceptDatatype.NUMERIC, ConceptDatatype.NUMERIC_UUID); + return this; + } + + public ConceptBuilder withCodedDataType() { + withDataType("Coded", ConceptDatatype.CODED, ConceptDatatype.CODED_UUID); + return this; + } + + public ConceptBuilder withDateCreated(Date dateCreated) { + concept.setDateCreated(dateCreated); + return this; + } + + public ConceptBuilder withDateChanged(Date dateChanged) { + concept.setDateChanged(dateChanged); + return this; + } + + public ConceptBuilder withRetired(Boolean retired) { + concept.setRetired(retired); + return this; + } + + public ConceptBuilder withShortName(String name) { + concept.setShortName(name != null ? new ConceptName(name, Context.getLocale()) : null); + return this; + } + + private ConceptBuilder withDataType(String name, String hl7Abbreviation, String uuid) { + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setHl7Abbreviation(hl7Abbreviation); + conceptDatatype.setName(name); + conceptDatatype.setUuid(uuid); + concept.setDatatype(conceptDatatype); + return this; + } + + public ConceptBuilder withDescription(String description) { + ConceptDescription conceptDescription = new ConceptDescription(description, Context.getLocale()); + Set descriptions = new HashSet<>(); + descriptions.add(conceptDescription); + concept.setDescriptions(descriptions); + return this; + } + + public ConceptBuilder withAnswer(Concept answerConcept) { + ConceptAnswer conceptAnswer = new ConceptAnswer(answerConcept); + concept.addAnswer(conceptAnswer); + return this; + } + + public ConceptBuilder withSet(boolean b) { + concept.setSet(b); + return this; + } +} \ No newline at end of file diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ConceptNumericBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ConceptNumericBuilder.java new file mode 100644 index 0000000000..965166c02c --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ConceptNumericBuilder.java @@ -0,0 +1,86 @@ +package org.bahmni.test.builder; + +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; + +public class ConceptNumericBuilder { + private final org.openmrs.ConceptNumeric concept; + + public ConceptNumericBuilder() { + concept = new ConceptNumeric(); + withDataType("Numeric", "Abb", "dataTypeUuid"); + } + + public Concept build() { + return concept; + } + + public ConceptNumericBuilder withName(String conceptName) { + ConceptName name = new ConceptName(conceptName, LocaleUtility.getDefaultLocale()); + name.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + concept.setPreferredName(name); + return this; + } + + public ConceptNumericBuilder withLowNormal(Double lowNormal){ + concept.setLowNormal(lowNormal); + return this; + } + + + public ConceptNumericBuilder withHiNormal(Double hiNormal){ + concept.setHiNormal(hiNormal); + return this; + } + + public ConceptNumericBuilder withClass(String className) { + ConceptClass conceptClass = concept.getConceptClass(); + if (conceptClass == null) { + conceptClass = new ConceptClass(); + } + conceptClass.setName(className); + concept.setConceptClass(conceptClass); + return this; + } + + public ConceptNumericBuilder withSetMember(Concept childConcept) { + concept.addSetMember(childConcept); + return this; + } + + public ConceptNumericBuilder withUnit(String unit) { + concept.setUnits(unit); + return this; + } + + private ConceptNumericBuilder withDataType(String name, String hl7Abbreviation, String uuid) { + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setHl7Abbreviation(hl7Abbreviation); + conceptDatatype.setName(name); + conceptDatatype.setUuid(uuid); + concept.setDatatype(conceptDatatype); + return this; + } + + public ConceptNumericBuilder withId(Integer id) { + concept.setId(id); + return this; + } + + public ConceptNumericBuilder withShortName(String name) { + concept.setShortName(name != null ? new ConceptName(name, Context.getLocale()) : null); + return this; + } + + public ConceptNumericBuilder withRetired(boolean retired) { + concept.setRetired(retired); + return this; + } + +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DiagnosisBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DiagnosisBuilder.java new file mode 100644 index 0000000000..431a0a1310 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DiagnosisBuilder.java @@ -0,0 +1,74 @@ +package org.bahmni.test.builder; + +import org.openmrs.Concept; +import org.openmrs.Obs; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.UUID; + +public class DiagnosisBuilder { + public static final String VISIT_DIAGNOSES = "Visit Diagnoses"; + public static final String BAHMNI_INITIAL_DIAGNOSIS = "Bahmni Initial Diagnosis"; + public static final String BAHMNI_DIAGNOSIS_REVISED = "Bahmni Diagnosis Revised"; + + private Concept confirmedConcept = new ConceptBuilder().withName("Confirmed", Locale.getDefault()).withClass("Misc").withDataType("N/A").build(); + + private Concept codedDiagnosisConcept = new ConceptBuilder().withName("Coded Diagnosis", Locale.getDefault()).withClass("Question").withDataType("Coded").build(); + private Concept certaintyConcept = new ConceptBuilder().withName("Diagnosis Certainty", Locale.getDefault()).withClass("Question").withDataType("Coded").build(); + private Concept visitDiagnosesConcept = new ConceptBuilder().withName(VISIT_DIAGNOSES, Locale.getDefault()).withDataType("N/A").build(); + + private String diagnosisObsUUID = UUID.randomUUID().toString(); + protected Obs visitDiagnosesObs; + + + public DiagnosisBuilder() { + visitDiagnosesObs = new Obs(); + } + + public DiagnosisBuilder withUuid(String uuid) { + this.diagnosisObsUUID = uuid; + return this; + } + + public DiagnosisBuilder withDefaults() { + Concept malariaConcept = new ConceptBuilder().withName("Malaria", Locale.getDefault()).withClass("Diagnosis").build(); + + Obs codedDiagnosisObs = new ObsBuilder().withConcept(codedDiagnosisConcept).withValue(malariaConcept).build(); + Obs certaintyObs = new ObsBuilder().withConcept(certaintyConcept).withValue(confirmedConcept).build(); + + visitDiagnosesObs = new ObsBuilder().withValue("").withUUID(diagnosisObsUUID).withConcept(visitDiagnosesConcept).withGroupMembers(codedDiagnosisObs, certaintyObs).build(); + + return this; + } + + + public DiagnosisBuilder withFirstObs(String firstVisitDiagnosisObsUuid) { + Obs bahmniInitialObs = new ObsBuilder().withConcept(BAHMNI_INITIAL_DIAGNOSIS, Locale.getDefault()).withValue(firstVisitDiagnosisObsUuid).build(); + + addChildObs(bahmniInitialObs, visitDiagnosesObs); + return this; + } + + public DiagnosisBuilder withChildObs(Obs childObs){ + addChildObs(childObs,visitDiagnosesObs); + return this; + } + + private Obs addChildObs(Obs childObs, Obs parentObs) { + Set groupMembers = parentObs.getGroupMembers(true); + if (groupMembers == null) + groupMembers = new HashSet<>(); + + groupMembers.add(childObs); + + parentObs.setGroupMembers(groupMembers); + return parentObs; + } + + public Obs build() { + return visitDiagnosesObs; + } + +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DrugBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DrugBuilder.java new file mode 100644 index 0000000000..e8c6838818 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DrugBuilder.java @@ -0,0 +1,59 @@ +package org.bahmni.test.builder; + +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.Drug; + +public class DrugBuilder { + private final Drug drug; + + public DrugBuilder() { + drug = new Drug(); + } + + public Drug build() { + return drug; + } + + public DrugBuilder withName(String drugName) { + drug.setName(drugName); + return this; + } + + public DrugBuilder withConcept(Concept concept) { + drug.setConcept(concept); + return this; + } + + public DrugBuilder withConcept(String conceptName) { + Concept concept = new ConceptBuilder().withName(conceptName).withClassUUID(ConceptClass.DRUG_UUID).build(); + drug.setConcept(concept); + return this; + } + + public DrugBuilder withDosageForm(String dosageForm) { + Concept dosage = new ConceptBuilder().withName(dosageForm).build(); + drug.setDosageForm(dosage); + return this; + } + + public DrugBuilder withDosageForm(Concept dosageForm) { + drug.setDosageForm(dosageForm); + return this; + } + + public DrugBuilder withStrength(String strength) { + drug.setStrength(strength); + return this; + } + + public DrugBuilder withMaximumDosage(Double maximumDosage) { + drug.setMaximumDailyDose(maximumDosage); + return this; + } + + public DrugBuilder withMinimumDosage(Double minimumDosage) { + drug.setMinimumDailyDose(minimumDosage); + return this; + } +} \ No newline at end of file diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DrugOrderBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DrugOrderBuilder.java new file mode 100644 index 0000000000..39124568b4 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/DrugOrderBuilder.java @@ -0,0 +1,177 @@ +/** + * 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.bahmni.test.builder; + +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Drug; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.OrderFrequency; +import org.openmrs.OrderType; +import org.openmrs.Person; +import org.openmrs.PersonName; +import org.openmrs.User; +import org.openmrs.Visit; +import org.springframework.util.ReflectionUtils; + +import java.util.Date; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.UUID; + +public class DrugOrderBuilder { + private DrugOrder order; + + public DrugOrderBuilder() { + this.order = new DrugOrder(); + this.order.setUuid(UUID.randomUUID().toString()); + this.order.setDateCreated(null); + this.order.setDrug(new Drug(123)); + this.order.setOrderType(new OrderType()); + } + + public DrugOrderBuilder withUuid(UUID uuid) { + order.setUuid(String.valueOf(uuid)); + return this; + } + + public DrugOrderBuilder withId(Integer id) { + order.setId(id); + return this; + } + public DrugOrderBuilder withDrugName(String drugName) { + order.getDrug().setName(drugName); + return this; + } + + public DrugOrderBuilder withDosingType(java.lang.Class dosingType){ + order.setDosingType(dosingType); + return this; + } + + public DrugOrderBuilder withDose(Double dose){ + order.setDose(dose); + return this; + } + + public DrugOrderBuilder withDrugForm(String form){ + Concept dosageForm = new Concept(); + dosageForm.setFullySpecifiedName(new ConceptName(form, Locale.getDefault())); + order.getDrug().setDosageForm(dosageForm); + return this; + } + + public DrugOrderBuilder withDosingInstructions(String dosingInstructions){ + order.setDosingInstructions(dosingInstructions); + return this; + } + + public DrugOrderBuilder withDateActivated(Date date){ + order.setDateActivated(date); + return this; + } + + public DrugOrderBuilder withScheduledDate(Date date){ + order.setUrgency(Order.Urgency.ON_SCHEDULED_DATE); + order.setScheduledDate(date); + return this; + } + + public DrugOrder build() { + return order; + } + + public DrugOrderBuilder withDoseUnits(String doseUnitsString) { + Concept doseUnits = new Concept(); + doseUnits.setFullySpecifiedName(new ConceptName(doseUnitsString, Locale.getDefault())); + order.setDoseUnits(doseUnits); + return this; + } + + public DrugOrderBuilder withDuration(int duration) { + order.setDuration(duration); + return this; + } + + public DrugOrderBuilder withDurationUnits(String unit) { + Concept durationUnit = new Concept(); + durationUnit.setFullySpecifiedName(new ConceptName(unit, Locale.getDefault())); + order.setDurationUnits(durationUnit); + return this; + } + + public DrugOrderBuilder withAutoExpireDate(Date date) { + order.setAutoExpireDate(date); + return this; + } + + public DrugOrderBuilder withFrequency(String frequency) { + final Concept frequencyConcept = new Concept(); + frequencyConcept.setFullySpecifiedName(new ConceptName(frequency, Locale.getDefault())); + order.setFrequency(new OrderFrequency() {{ + setConcept(frequencyConcept); + }}); + return this; + } + + public DrugOrderBuilder withRoute(String route) { + final Concept routeConcept = new Concept(); + routeConcept.setFullySpecifiedName(new ConceptName(route, Locale.getDefault())); + order.setRoute(routeConcept); + return this; + } + + + public DrugOrderBuilder withVisit(Visit visit) { + order.setEncounter(visit.getEncounters().iterator().next()); + order.getEncounter().setVisit(visit); + return this; + } + + public DrugOrderBuilder withCreator(String personNameValue){ + Person personObj = new Person(); + PersonName personName = new PersonName(); + personName.setGivenName(personNameValue); + Set personNames = new HashSet<>(); + personNames.add(personName); + personObj.setNames(personNames); + User user = new User(personObj); + order.setCreator(user); + return this; + } + + public DrugOrderBuilder withPreviousOrder(DrugOrder previousOrder){ + order.setPreviousOrder(previousOrder); + return this; + } + + public DrugOrderBuilder withConcept(Concept concept) { + order.setConcept(concept); + return this; + } + + public DrugOrderBuilder withOrderAction(Order.Action action) { + order.setAction(action); + return this; + } + + public DrugOrderBuilder withOrderNumber(String orderNum) { + java.lang.reflect.Field orderNumberField = ReflectionUtils.findField(DrugOrder.class, "orderNumber"); + orderNumberField.setAccessible(true); + ReflectionUtils.setField(orderNumberField,order,orderNum); + return this; + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/EncounterBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/EncounterBuilder.java new file mode 100644 index 0000000000..db0f422f99 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/EncounterBuilder.java @@ -0,0 +1,92 @@ +package org.bahmni.test.builder; + +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.EncounterType; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.PersonName; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.VisitType; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public class EncounterBuilder { + private final Encounter encounter; + + public EncounterBuilder() { + encounter = new Encounter(); + } + + private Set createEncounterProviders() { + EncounterProvider encounterprovider = new EncounterProvider(); + Provider provider = new Provider(1234); + + Person person = new Person(2345); + Set personNames = new HashSet(); + PersonName name = new PersonName("Yogesh", "", "Jain"); + name.setPreferred(true); + personNames.add(name); + person.setNames(personNames); + + provider.setPerson(person); + encounterprovider.setProvider(provider); + Set encounterProviders = new HashSet(); + encounterProviders.add(encounterprovider); + return encounterProviders; + } + + public Encounter build() { + return encounter; + } + + public EncounterBuilder withDefaults() { + Visit visit = new Visit(); + VisitType visitType = new VisitType(); + visitType.setUuid(UUID.randomUUID().toString()); + visit.setVisitType(visitType); + visit.setUuid(UUID.randomUUID().toString()); + encounter.setVisit(visit); + encounter.setUuid(UUID.randomUUID().toString()); + + Patient patient = new Patient(); + patient.setUuid(UUID.randomUUID().toString()); + encounter.setPatient(patient); + + EncounterType encounterType = new EncounterType(); + encounterType.setUuid(UUID.randomUUID().toString()); + encounter.setEncounterType(encounterType); + + Location location = new Location(); + location.setUuid(UUID.randomUUID().toString()); + encounter.setLocation(location); + + encounter.setEncounterProviders(createEncounterProviders()); + return this; + } + + public EncounterBuilder withVisit(Visit visit) { + encounter.setVisit(visit); + return this; + } + + public EncounterBuilder withPerson(Person person) { + encounter.setPatient(new Patient(person)); + return this; + } + + public EncounterBuilder withUUID(String uuid) { + encounter.setUuid(uuid); + return this; + } + + public EncounterBuilder withDatetime(Date dateTime) { + encounter.setEncounterDatetime(dateTime); + return this; + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ObsBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ObsBuilder.java new file mode 100644 index 0000000000..28fab20dff --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/ObsBuilder.java @@ -0,0 +1,95 @@ +package org.bahmni.test.builder; + +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Person; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.Locale; + +public class ObsBuilder { + + private final Obs obs; + + public ObsBuilder() { + obs = new Obs(); + } + + public ObsBuilder withPerson(Person person) { + obs.setPerson(person); + return this; + } + + public ObsBuilder withEncounter(Encounter encounter) { + obs.setEncounter(encounter); + return this; + } + + public ObsBuilder withConcept(Concept concept) { + obs.setConcept(concept); + return this; + } + + public ObsBuilder withConcept(String conceptName) { + Concept concept = new ConceptBuilder().withName(conceptName).build(); + obs.setConcept(concept); + return this; + } + + public ObsBuilder withConcept(ConceptName conceptName) { + Concept concept = new ConceptBuilder().withName(conceptName).build(); + obs.setConcept(concept); + return this; + } + + public ObsBuilder withConcept(String conceptName, Locale locale) { + Concept concept = new ConceptBuilder().withName(conceptName, locale).build(); + obs.setConcept(concept); + return this; + } + + public ObsBuilder withValue(String value) { + obs.setValueText(value); + return this; + } + + public ObsBuilder withValue(Double value) { + obs.setValueNumeric(value); + return this; + } + + public ObsBuilder withValue(Concept value) { + obs.setValueCoded(value); + setValueCodedName(obs); + return this; + } + + public ObsBuilder withUUID(String obsUuid) { + obs.setUuid(obsUuid); + return this; + } + + private void setValueCodedName(Obs anObs) { + Concept concept = anObs.getConcept(); + if (concept != null) + anObs.setValueCodedName(concept.getName()); + } + + public ObsBuilder withDatetime(Date datetime) { + obs.setObsDatetime(datetime); + return this; + } + + public ObsBuilder withGroupMembers(Obs... groupMember) { + obs.setGroupMembers(new HashSet<>(Arrays.asList(groupMember))); + return this; + } + + public Obs build() { + return obs; + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/PersonBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/PersonBuilder.java new file mode 100644 index 0000000000..48b87bcb77 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/PersonBuilder.java @@ -0,0 +1,21 @@ +package org.bahmni.test.builder; + +import org.openmrs.Person; + +public class PersonBuilder { + + private final Person person; + + public PersonBuilder() { + person = new Person(); + } + + public PersonBuilder withUUID(String patientUuid) { + person.setUuid(patientUuid); + return this; + } + + public Person build() { + return person; + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/TestOrderBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/TestOrderBuilder.java new file mode 100644 index 0000000000..1e198876ba --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/TestOrderBuilder.java @@ -0,0 +1,44 @@ +/** + * 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.bahmni.test.builder; + +import org.openmrs.TestOrder; + +import java.util.Date; +import java.util.UUID; + +public class TestOrderBuilder { + private TestOrder order; + + public TestOrderBuilder() { + this.order = new TestOrder(); + this.order.setDateCreated(new Date()); + this.order.setUuid(UUID.randomUUID().toString()); + this.order.setDateCreated(new Date()); + } + + public TestOrderBuilder withUuid(UUID uuid) { + order.setUuid(String.valueOf(uuid)); + return this; + } + + public TestOrderBuilder withId(Integer id) { + order.setId(id); + return this; + } + + public TestOrder build() { + return order; + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/builder/VisitBuilder.java b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/VisitBuilder.java new file mode 100644 index 0000000000..5a877ba82c --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/builder/VisitBuilder.java @@ -0,0 +1,50 @@ +package org.bahmni.test.builder; + +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Visit; +import org.openmrs.VisitType; + +import java.util.Date; +import java.util.HashSet; + +public class VisitBuilder { + + private final Visit visit; + + public VisitBuilder() { + visit = new Visit(); + } + + public VisitBuilder withPerson(Person person) { + visit.setPatient(new Patient(person)); + return this; + } + + public VisitBuilder withUUID(String uuid) { + visit.setUuid(uuid); + return this; + } + + public VisitBuilder withStartDatetime(Date startDatetime) { + visit.setStartDatetime(startDatetime); + return this; + } + + public VisitBuilder withVisitType(VisitType visitType){ + visit.setVisitType(visitType); + return this; + } + + public Visit build() { + return visit; + } + + public VisitBuilder withEncounter(Encounter encounter) { + HashSet encounters = new HashSet<>(); + encounters.add(encounter); + visit.setEncounters(encounters); + return this; + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/properties/PropertiesReader.java b/bahmni-test-commons/src/test/java/org/bahmni/test/properties/PropertiesReader.java new file mode 100644 index 0000000000..d7ea0c47d9 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/properties/PropertiesReader.java @@ -0,0 +1,5 @@ +package org.bahmni.test.properties; + +public interface PropertiesReader { + String getProperty(String key); +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/properties/PropertiesReaderImpl.java b/bahmni-test-commons/src/test/java/org/bahmni/test/properties/PropertiesReaderImpl.java new file mode 100644 index 0000000000..a7eca6ddae --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/properties/PropertiesReaderImpl.java @@ -0,0 +1,37 @@ +package org.bahmni.test.properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.util.OpenmrsUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +public class PropertiesReaderImpl implements PropertiesReader { + private Properties properties; + private static Log log = LogFactory.getLog(PropertiesReaderImpl.class); + + private PropertiesReaderImpl(Properties properties) { + this.properties = properties; + } + + public static PropertiesReaderImpl load() { + String propertyFile = new File(OpenmrsUtil.getApplicationDataDirectory(), "bahmnicore.properties").getAbsolutePath(); + log.info(String.format("Reading bahmni properties from : %s", propertyFile)); + Properties properties; + try { + properties = new Properties(System.getProperties()); + properties.load(new FileInputStream(propertyFile)); + } catch (IOException e) { + throw new RuntimeException(e); + } + return new PropertiesReaderImpl(properties); + } + + @Override + public String getProperty(String key){ + return properties.getProperty(key); + } +} diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/properties/SystemPropertiesReader.java b/bahmni-test-commons/src/test/java/org/bahmni/test/properties/SystemPropertiesReader.java new file mode 100644 index 0000000000..f9af33881d --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/properties/SystemPropertiesReader.java @@ -0,0 +1,9 @@ +package org.bahmni.test.properties; + +public class SystemPropertiesReader implements PropertiesReader { + @Override + public String getProperty(String key) { + return System.getProperty(key); + } +} + diff --git a/bahmni-test-commons/src/test/java/org/bahmni/test/web/controller/BaseWebControllerTest.java b/bahmni-test-commons/src/test/java/org/bahmni/test/web/controller/BaseWebControllerTest.java new file mode 100644 index 0000000000..f031beb552 --- /dev/null +++ b/bahmni-test-commons/src/test/java/org/bahmni/test/web/controller/BaseWebControllerTest.java @@ -0,0 +1,164 @@ +package org.bahmni.test.web.controller; + +import junit.framework.Assert; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.type.TypeReference; +import org.junit.Ignore; +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +@Ignore +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BaseWebControllerTest extends BaseModuleWebContextSensitiveTest { + + @Autowired + private RequestMappingHandlerAdapter handlerAdapter; + + @Autowired + private List handlerMappings; + + private ObjectMapper objectMapper = new ObjectMapper(); + + /** + * Creates a request from the given parameters. + *

+ * The requestURI is automatically preceded with "/rest/" + RestConstants.VERSION_1. + * + * @param method + * @param requestURI + * @return + */ + public MockHttpServletRequest request(RequestMethod method, String requestURI) { + MockHttpServletRequest request = new MockHttpServletRequest(method.toString(), requestURI); + request.addHeader("content-type", "application/json"); + return request; + } + + public static class Parameter { + + public String name; + + public String value; + + public Parameter(String name, String value) { + this.name = name; + this.value = value; + } + } + + public MockHttpServletRequest newRequest(RequestMethod method, String requestURI, Parameter... parameters) { + MockHttpServletRequest request = request(method, requestURI); + for (Parameter parameter : parameters) { + request.addParameter(parameter.name, parameter.value); + } + return request; + } + + public MockHttpServletRequest newRequest(RequestMethod method, String requestURI, Map headers, Parameter... parameters) { + MockHttpServletRequest request = newRequest(method, requestURI, parameters); + for (String key : headers.keySet()) { + request.addHeader(key, headers.get(key)); + } + return request; + } + + public MockHttpServletRequest newDeleteRequest(String requestURI, Parameter... parameters) { + return newRequest(RequestMethod.DELETE, requestURI, parameters); + } + + public MockHttpServletRequest newGetRequest(String requestURI, Parameter... parameters) { + return newRequest(RequestMethod.GET, requestURI, parameters); + } + + public MockHttpServletRequest newGetRequest(String requestURI, Map headers, Parameter... parameters) { + return newRequest(RequestMethod.GET, requestURI, headers, parameters); + } + + public MockHttpServletRequest newPostRequest(String requestURI, Object content) { + return newWriteRequest(requestURI, content, RequestMethod.POST); + } + + public MockHttpServletRequest newPutRequest(String requestURI, Object content) { + return newWriteRequest(requestURI, content, RequestMethod.PUT); + } + + private MockHttpServletRequest newWriteRequest(String requestURI, Object content, RequestMethod requestMethod) { + MockHttpServletRequest request = request(requestMethod, requestURI); + try { + String json = new ObjectMapper().writeValueAsString(content); + request.setContent(json.getBytes("UTF-8")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return request; + } + + public MockHttpServletRequest newPostRequest(String requestURI, String content) { + MockHttpServletRequest request = request(RequestMethod.POST, requestURI); + try { + request.setContent(content.getBytes("UTF-8")); + } catch (Exception e) { + throw new RuntimeException(e); + } + return request; + } + + /** + * Passes the given request to a proper controller. + * + * @param request + * @return + * @throws Exception + */ + public MockHttpServletResponse handle(HttpServletRequest request) throws Exception { + MockHttpServletResponse response = new MockHttpServletResponse(); + + HandlerExecutionChain handlerExecutionChain = null; + for (RequestMappingHandlerMapping handlerMapping : handlerMappings) { + handlerExecutionChain = handlerMapping.getHandler(request); + if (handlerExecutionChain != null) { + break; + } + } + Assert.assertNotNull("The request URI does not exist", handlerExecutionChain); + + handlerAdapter.handle(request, response, handlerExecutionChain.getHandler()); + + return response; + } + + /** + * Deserializes the JSON response. + * + * @param response + * @param type + * @return + * @throws Exception + */ + public T deserialize(MockHttpServletResponse response, Class type) throws Exception { + return objectMapper.readValue(response.getContentAsString(), type); + } + + /** + * Deserializes the JSON response. + * + * @param response + * @param typeReference + * @return + * @throws Exception + */ + public T deserialize(MockHttpServletResponse response, final TypeReference typeReference) throws Exception { + return objectMapper.readValue(response.getContentAsString(), typeReference); + } +} + diff --git a/bahmni-test-commons/src/test/resources/TestingApplicationContext.xml b/bahmni-test-commons/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..9a5726e55d --- /dev/null +++ b/bahmni-test-commons/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/bahmni-test-commons/src/test/resources/configDataSetup.xml b/bahmni-test-commons/src/test/resources/configDataSetup.xml new file mode 100644 index 0000000000..5d927ff22b --- /dev/null +++ b/bahmni-test-commons/src/test/resources/configDataSetup.xml @@ -0,0 +1,134 @@ + + + + + + \ No newline at end of file diff --git a/bahmni-test-commons/src/test/resources/diseaseTemplate.xml b/bahmni-test-commons/src/test/resources/diseaseTemplate.xml new file mode 100644 index 0000000000..5febe930b4 --- /dev/null +++ b/bahmni-test-commons/src/test/resources/diseaseTemplate.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmni-test-commons/src/test/resources/drugsWithConcepts.xml b/bahmni-test-commons/src/test/resources/drugsWithConcepts.xml new file mode 100644 index 0000000000..ddbb96eeea --- /dev/null +++ b/bahmni-test-commons/src/test/resources/drugsWithConcepts.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-api/pom.xml b/bahmnicore-api/pom.xml new file mode 100644 index 0000000000..4aaf0cf22a --- /dev/null +++ b/bahmnicore-api/pom.xml @@ -0,0 +1,277 @@ + + 4.0.0 + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + bahmnicore-api + jar + Bahmni EMR Core API + + + + org.openmrs.test + openmrs-test + pom + test + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + provided + + + org.openmrs.module + idgen-api + provided + + + org.openmrs.api + openmrs-api + jar + + + org.openmrs.web + openmrs-web + jar + + + org.openmrs.api + openmrs-api + test-jar + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + javax.servlet + javax.servlet-api + + + org.openmrs.module + webservices.rest-omod + + + org.openmrs.module + webservices.rest-omod-common + + + org.bahmni.module + bahmni-commons-api + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + tests + test + + + + org.openmrs.module + providermanagement-api + + + joda-time + joda-time + 2.0 + + + org.bahmni.module + communication-api + + + org.bahmni.module + bahmni-emr-api + ${project.version} + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + + + org.openmrs.module + appframework-api + + + org.openmrs.module + reporting-api + + + org.openmrs.module + calculation-api + + + org.openmrs.module + serialization.xstream-api-2.0 + + + org.ict4h + atomfeed-client + ${atomfeed.version} + + + rome + rome + + + + + rome + rome + 1.0 + test + + + org.bahmni.module + web-clients + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + episodes-api + ${episodes.version} + provided + + + org.ict4h.openmrs + openmrs-atomfeed-common + ${openmrsAtomfeedVersion} + + + org.ict4h.openmrs + openmrs-atomfeed-api + ${openmrsAtomfeedVersion} + test + + + org.imgscalr + imgscalr-lib + 4.2 + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test + test-jar + + + org.openmrs.module + addresshierarchy-api + ${addressHierarchyVersion} + provided + jar + + + org.openmrs.module + addresshierarchy-omod + ${addressHierarchyVersion} + provided + jar + + + org.openmrs.module + legacyui-omod + + + org.jcodec + jcodec + + + + org.jcodec + jcodec-javase + + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + org.openmrs.module + emrapi-api-1.12 + + + + + + + src/main/resources + true + + + + + + src/test/resources + true + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.19 + + + BRANCH + COVEREDRATIO + 0.13 + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + test-jar + + + + + + + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/Activator.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/Activator.java new file mode 100644 index 0000000000..f2aef64693 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/Activator.java @@ -0,0 +1,23 @@ +package org.bahmni.module.bahmnicore; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.openmrs.api.context.Context; +import org.openmrs.module.BaseModuleActivator; + +public class Activator extends BaseModuleActivator { + + private Log log = LogFactory.getLog(this.getClass()); + + @Override + public void started() { + log.info("Started the Bahmni Core module"); + BahmniCoreProperties.load(); + } + + @Override + public void stopped() { + log.info("Stopped the Bahmni Core module"); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/ApplicationError.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/ApplicationError.java new file mode 100644 index 0000000000..303377e2bd --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/ApplicationError.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore; + +public class ApplicationError extends RuntimeException { + private int errorCode; + + public ApplicationError(String message, Throwable throwable) { + super(message, throwable); + } + + public ApplicationError(String message) { + super(message); + } + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/BahmniCoreException.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/BahmniCoreException.java new file mode 100644 index 0000000000..6c7ad4d95c --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/BahmniCoreException.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore; + + +public class BahmniCoreException extends ApplicationError { + public BahmniCoreException(String message, Throwable cause) { + super(message, cause); + } + + public BahmniCoreException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/BillingSystemException.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/BillingSystemException.java new file mode 100644 index 0000000000..f044865da1 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/BillingSystemException.java @@ -0,0 +1,16 @@ +package org.bahmni.module.bahmnicore; + +import org.openmrs.Patient; + +public class BillingSystemException extends ApplicationError { + private Patient patient; + + public BillingSystemException(String message, Throwable throwable, Patient patient) { + super(message, throwable); + this.patient = patient; + } + + public Patient getPatient() { + return patient; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/CIELDictionary.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/CIELDictionary.java new file mode 100644 index 0000000000..8cef814a60 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/CIELDictionary.java @@ -0,0 +1,6 @@ +package org.bahmni.module.bahmnicore; + +public class CIELDictionary { + public final static String WEIGHT_UUID = "5089AAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + public final static String HEIGHT_UUID = "5090AAAAAAAAAAAAAAAAAAAAAAAAAAAA"; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/bahmniexceptions/FileTypeNotSupportedException.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/bahmniexceptions/FileTypeNotSupportedException.java new file mode 100644 index 0000000000..fcd6d14ee5 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/bahmniexceptions/FileTypeNotSupportedException.java @@ -0,0 +1,9 @@ +package org.bahmni.module.bahmnicore.bahmniexceptions; + +import org.openmrs.api.APIException; + +public class FileTypeNotSupportedException extends APIException { + public FileTypeNotSupportedException(String message) { + super(message); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/bahmniexceptions/VideoFormatNotSupportedException.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/bahmniexceptions/VideoFormatNotSupportedException.java new file mode 100644 index 0000000000..a4a8deeb87 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/bahmniexceptions/VideoFormatNotSupportedException.java @@ -0,0 +1,9 @@ +package org.bahmni.module.bahmnicore.bahmniexceptions; + +import org.openmrs.api.APIException; + +public class VideoFormatNotSupportedException extends APIException{ + public VideoFormatNotSupportedException(String message) { + super(message); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java new file mode 100644 index 0000000000..be92dddd13 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/NoteRequestResponse.java @@ -0,0 +1,78 @@ +package org.bahmni.module.bahmnicore.contract; + +import java.util.Date; + +public class NoteRequestResponse { + + private String uuid; + + private Integer noteId; + + private String noteText; + + private String noteTypeName; + + private Date noteDate; + + private String LocationName; + + private String providerUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Integer getNoteId() { + return noteId; + } + + public void setNoteId(Integer noteId) { + this.noteId = noteId; + } + + public String getNoteText() { + return noteText; + } + + public void setNoteText(String noteText) { + this.noteText = noteText; + } + + public Date getNoteDate() { + return noteDate; + } + + public void setNoteDate(Date noteDate) { + this.noteDate = noteDate; + } + + public String getNoteTypeName() { + return noteTypeName; + } + + public void setNoteTypeName(String noteTypeName) { + this.noteTypeName = noteTypeName; + } + + public String getLocationName() { + return LocationName; + } + + public void setLocationName(String locationName) { + LocationName = locationName; + } + + public String getProviderUuid() { + return providerUuid; + } + + public void setProviderUuid(String providerUuid) { + this.providerUuid = providerUuid; + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplate.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplate.java new file mode 100644 index 0000000000..4982d76df8 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplate.java @@ -0,0 +1,49 @@ +package org.bahmni.module.bahmnicore.contract.diseasetemplate; + + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.List; + +public class DiseaseTemplate { + + public static final String ALL_DISEASE_TEMPLATES = "All Disease Templates"; + private List observationTemplates = new ArrayList<>(); + private EncounterTransaction.Concept concept; + + public DiseaseTemplate() { + } + + public DiseaseTemplate(EncounterTransaction.Concept concept) { + this.concept = concept; + } + + public List getObservationTemplates() { + return observationTemplates; + } + + public void setObservationTemplates(List observationTemplates) { + this.observationTemplates = observationTemplates; + } + + public void addObservationTemplate(ObservationTemplate observationTemplate) { + this.observationTemplates.add(observationTemplate); + } + + public void addObservationTemplates(List observationTemplates) { + this.observationTemplates.addAll(observationTemplates); + } + + public void removeObservationTemplate(ObservationTemplate observationTemplate) { + this.observationTemplates.remove(observationTemplate); + } + + public EncounterTransaction.Concept getConcept() { + return concept; + } + + public void setConcept(EncounterTransaction.Concept concept) { + this.concept = concept; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplateConfig.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplateConfig.java new file mode 100644 index 0000000000..9577621df7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplateConfig.java @@ -0,0 +1,36 @@ +package org.bahmni.module.bahmnicore.contract.diseasetemplate; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class DiseaseTemplateConfig { + private String templateName; + private List showOnly; + + public DiseaseTemplateConfig(String templateName, List showOnly) { + this.templateName = templateName; + this.showOnly = showOnly; + } + + + public DiseaseTemplateConfig() { + } + + public String getTemplateName() { + return templateName; + } + + public void setTemplateName(String templateName) { + this.templateName = templateName; + } + + public List getShowOnly() { + return showOnly; + } + + public void setShowOnly(List showOnly) { + this.showOnly = showOnly; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplatesConfig.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplatesConfig.java new file mode 100644 index 0000000000..1186782b6b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/DiseaseTemplatesConfig.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.contract.diseasetemplate; + +import org.codehaus.jackson.annotate.JsonProperty; + +import java.util.Date; +import java.util.List; + +public class DiseaseTemplatesConfig { + private List diseaseTemplateConfigList; + private String patientUuid; + private Date startDate; + private Date endDate; + + public List getDiseaseTemplateConfigList() { + return diseaseTemplateConfigList; + } + + public void setDiseaseTemplateConfigList(List diseaseTemplateConfigList) { + this.diseaseTemplateConfigList = diseaseTemplateConfigList; + } + + public String getPatientUuid() { + return patientUuid; + } + + public void setPatientUuid(String patientUuid) { + this.patientUuid = patientUuid; + } + + @JsonProperty("endDate") + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + @JsonProperty("startDate") + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/ObservationTemplate.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/ObservationTemplate.java new file mode 100644 index 0000000000..2cae25d1f3 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/diseasetemplate/ObservationTemplate.java @@ -0,0 +1,60 @@ +package org.bahmni.module.bahmnicore.contract.diseasetemplate; + +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.TreeSet; + +public class ObservationTemplate { + + private EncounterTransaction.Concept concept; + + private Date visitStartDate; + + private Collection bahmniObservations; + + public EncounterTransaction.Concept getConcept() { + return concept; + } + + public void setConcept(EncounterTransaction.Concept concept) { + this.concept = concept; + } + + public Collection getBahmniObservations() { + return bahmniObservations == null ? new TreeSet() : new TreeSet<>(bahmniObservations); + } + + public void setBahmniObservations(Collection bahmniObservations) { + this.bahmniObservations = bahmniObservations; + } + + public void removeBahmniObservation(BahmniObservation bahmniObservation) { + this.bahmniObservations.remove(bahmniObservation); + } + + public void removeBahmniObservations(Collection bahmniObservations) { + this.bahmniObservations.removeAll(bahmniObservations); + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getVisitStartDate() { + return visitStartDate; + } + + public void setVisitStartDate(Date visitStartDate) { + this.visitStartDate = visitStartDate; + } + + public void addBahmniObservation(BahmniObservation bahmniObservation){ + if(bahmniObservations == null){ + bahmniObservations = new ArrayList<>(); + } + bahmniObservations.add(bahmniObservation); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/ConceptData.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/ConceptData.java new file mode 100644 index 0000000000..6b1d1be9da --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/ConceptData.java @@ -0,0 +1,35 @@ +package org.bahmni.module.bahmnicore.contract.drugorder; + + +import org.openmrs.Concept; +import org.openmrs.api.context.Context; + +public class ConceptData { + private String name; + private String rootConcept; + + public ConceptData() { + } + + public ConceptData(Concept concept) { + if(concept != null){ + this.name = concept.getName(Context.getLocale()).getName(); + } + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRootConcept() { + return rootConcept; + } + + public void setRootConcept(String rootConcept) { + this.rootConcept = rootConcept; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/DrugOrderConfigResponse.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/DrugOrderConfigResponse.java new file mode 100644 index 0000000000..2ef2bde48d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/DrugOrderConfigResponse.java @@ -0,0 +1,83 @@ +package org.bahmni.module.bahmnicore.contract.drugorder; + + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.List; + +public class DrugOrderConfigResponse { + private List doseUnits; + private List routes; + private List durationUnits; + private List dispensingUnits; + private String[] dosingRules; + private List dosingInstructions; + private List orderAttributes; + private List frequencies = new ArrayList<>(); + + public List getFrequencies() { + return frequencies; + } + + public void setFrequencies(List frequencies) { + this.frequencies = frequencies; + } + + public void setDoseUnits(List doseUnits) { + this.doseUnits = doseUnits; + } + + public List getDoseUnits() { + return doseUnits; + } + + public void setRoutes(List routes) { + this.routes = routes; + } + + public List getRoutes() { + return routes; + } + + public void setDurationUnits(List durationUnits) { + this.durationUnits = durationUnits; + } + + public List getDurationUnits() { + return durationUnits; + } + + public void setDispensingUnits(List quantityUnits) { + this.dispensingUnits = quantityUnits; + } + + public List getDispensingUnits() { + return dispensingUnits; + } + + public void setDosingInstructions(List dosingInstructions) { + this.dosingInstructions = dosingInstructions; + } + + public List getDosingInstructions() { + return dosingInstructions; + } + + public String[] getDosingRules() { + return dosingRules; + } + + public void setDosingRules(String[] dosingRules) { + this.dosingRules = dosingRules; + } + + + public List getOrderAttributes() { + return orderAttributes; + } + + public void setOrderAttributes(List orderAttributes) { + this.orderAttributes = orderAttributes; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/OrderFrequencyData.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/OrderFrequencyData.java new file mode 100644 index 0000000000..8840b3b363 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/drugorder/OrderFrequencyData.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.contract.drugorder; + +import org.openmrs.OrderFrequency; + +public class OrderFrequencyData { + + private String uuid; + private Double frequencyPerDay; + private String name; + + public OrderFrequencyData(OrderFrequency orderFrequency) { + this.setUuid(orderFrequency.getUuid()); + this.setFrequencyPerDay(orderFrequency.getFrequencyPerDay()); + this.setName(orderFrequency.getName()); + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setFrequencyPerDay(Double frequencyPerDay) { + this.frequencyPerDay = frequencyPerDay; + } + + public Double getFrequencyPerDay() { + return frequencyPerDay; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/ConceptData.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/ConceptData.java new file mode 100644 index 0000000000..1d0b4a4f4a --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/ConceptData.java @@ -0,0 +1,30 @@ +package org.bahmni.module.bahmnicore.contract.encounter.data; + +public class ConceptData { + private String uuid; + private String name; + + public ConceptData(String uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public ConceptData() { + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/EncounterModifierData.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/EncounterModifierData.java new file mode 100644 index 0000000000..7961cf832e --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/EncounterModifierData.java @@ -0,0 +1,70 @@ +package org.bahmni.module.bahmnicore.contract.encounter.data; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.util.Date; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EncounterModifierData { + private List encounterModifierObservations; + private List drugOrders; + private ConceptData conceptSetData; + private String patientUuid; + private Date encounterDateTime; + + public EncounterModifierData(ConceptData conceptSetData, List drugOrders, Date encounterDateTime, List encounterModifierObservations, String patientUuid) { + this.conceptSetData = conceptSetData; + this.drugOrders = drugOrders; + this.encounterDateTime = encounterDateTime; + this.encounterModifierObservations = encounterModifierObservations; + this.patientUuid = patientUuid; + } + + public EncounterModifierData() { + } + + public ConceptData getConceptSetData() { + return conceptSetData; + } + + public void setConceptSetData(ConceptData conceptSetData) { + this.conceptSetData = conceptSetData; + } + + public List getDrugOrders() { + return drugOrders; + } + + public void setDrugOrders(List drugOrders) { + this.drugOrders = drugOrders; + } + + public List getEncounterModifierObservations() { + return encounterModifierObservations; + } + + public void setEncounterModifierObservations(List encounterModifierObservations) { + this.encounterModifierObservations = encounterModifierObservations; + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getEncounterDateTime() { + return encounterDateTime; + } + + public void setEncounterDateTime(Date encounterDateTime) { + this.encounterDateTime = encounterDateTime; + } + + public String getPatientUuid() { + return patientUuid; + } + + public void setPatientUuid(String patientUuid) { + this.patientUuid = patientUuid; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/EncounterModifierObservation.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/EncounterModifierObservation.java new file mode 100644 index 0000000000..57b245cc36 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/EncounterModifierObservation.java @@ -0,0 +1,243 @@ +package org.bahmni.module.bahmnicore.contract.encounter.data; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openmrs.Obs; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.obsrelation.contract.ObsRelationship; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Set; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EncounterModifierObservation { + private BahmniObservation bahmniObservation = new BahmniObservation(); + private Collection groupMembers = new ArrayList<>(); + + public EncounterModifierObservation(BahmniObservation bahmniObservation) { + this.bahmniObservation = bahmniObservation; + } + + public EncounterModifierObservation() { + } + + public void addGroupMember(BahmniObservation observation) { + bahmniObservation.addGroupMember(observation); + } + + public void addProvider(EncounterTransaction.Provider provider) { + bahmniObservation.addProvider(provider); + } + + public String getComment() { + return bahmniObservation.getComment(); + } + + public EncounterTransaction.Concept getConcept() { + return bahmniObservation.getConcept(); + } + + public String getConceptNameToDisplay() { + return bahmniObservation.getConceptNameToDisplay(); + } + + public Integer getConceptSortWeight() { + return bahmniObservation.getConceptSortWeight(); + } + + public String getConceptUuid() { + return bahmniObservation.getConceptUuid(); + } + + public Long getDuration() { + return bahmniObservation.getDuration(); + } + + public Date getEncounterDateTime() { + return bahmniObservation.getEncounterDateTime(); + } + + public String getEncounterUuid() { + return bahmniObservation.getEncounterUuid(); + } + + public Boolean getIsAbnormal() { + return bahmniObservation.getIsAbnormal(); + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getObservationDateTime() { + return bahmniObservation.getObservationDateTime(); + } + + public String getObsGroupUuid() { + return bahmniObservation.getObsGroupUuid(); + } + + public String getOrderUuid() { + return bahmniObservation.getOrderUuid(); + } + + public Set getProviders() { + return bahmniObservation.getProviders(); + } + + public ObsRelationship getTargetObsRelation() { + return bahmniObservation.getTargetObsRelation(); + } + + public String getType() { + return bahmniObservation.getType(); + } + + public String getUuid() { + return bahmniObservation.getUuid(); + } + + public Object getValue() { + return bahmniObservation.getValue(); + } + + public String getValueAsString() { + return bahmniObservation.getValueAsString(); + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getVisitStartDateTime() { + return bahmniObservation.getVisitStartDateTime(); + } + + public boolean getVoided() { + return bahmniObservation.getVoided(); + } + + public String getVoidReason() { + return bahmniObservation.getVoidReason(); + } + + public boolean hasTargetObsRelation() { + return bahmniObservation.hasTargetObsRelation(); + } + + public Boolean isAbnormal() { + return bahmniObservation.isAbnormal(); + } + + public boolean isSameAs(EncounterTransaction.Observation encounterTransactionObservation) { + return bahmniObservation.isSameAs(encounterTransactionObservation); + } + + public boolean isSameAs(Obs obs) { + return bahmniObservation.isSameAs(obs); + } + + public void removeGroupMembers(Collection observations) { + bahmniObservation.removeGroupMembers(observations); + } + + public void setAbnormal(Boolean abnormal) { + bahmniObservation.setAbnormal(abnormal); + } + + public BahmniObservation setComment(String comment) { + return bahmniObservation.setComment(comment); + } + + public BahmniObservation setConcept(EncounterTransaction.Concept concept) { + return bahmniObservation.setConcept(concept); + } + + public void setConceptSortWeight(Integer conceptSortWeight) { + bahmniObservation.setConceptSortWeight(conceptSortWeight); + } + + public void setDuration(Long duration) { + bahmniObservation.setDuration(duration); + } + + public void setEncounterDateTime(Date encounterDateTime) { + bahmniObservation.setEncounterDateTime(encounterDateTime); + } + + public void setEncounterTransactionObservation(EncounterTransaction.Observation encounterTransactionObservation) { + bahmniObservation.setEncounterTransactionObservation(encounterTransactionObservation); + } + + public void setEncounterUuid(String encounterUuid) { + bahmniObservation.setEncounterUuid(encounterUuid); + } + + public BahmniObservation setObservationDateTime(Date observationDateTime) { + return bahmniObservation.setObservationDateTime(observationDateTime); + } + + public void setObsGroupUuid(String obsGroupUuid) { + bahmniObservation.setObsGroupUuid(obsGroupUuid); + } + + public BahmniObservation setOrderUuid(String orderUuid) { + return bahmniObservation.setOrderUuid(orderUuid); + } + + public void setProviders(Set providers) { + bahmniObservation.setProviders(providers); + } + + public void setTargetObsRelation(ObsRelationship targetObsRelation) { + bahmniObservation.setTargetObsRelation(targetObsRelation); + } + + public void setType(String type) { + bahmniObservation.setType(type); + } + + public BahmniObservation setUuid(String uuid) { + return bahmniObservation.setUuid(uuid); + } + + public BahmniObservation setValue(Object value) { + return bahmniObservation.setValue(value); + } + + public void setVisitStartDateTime(Date visitStartDateTime) { + bahmniObservation.setVisitStartDateTime(visitStartDateTime); + } + + public BahmniObservation setVoided(boolean voided) { + return bahmniObservation.setVoided(voided); + } + + public BahmniObservation setVoidReason(String voidReason) { + return bahmniObservation.setVoidReason(voidReason); + } + + public EncounterTransaction.Observation toETObservation() { + return bahmniObservation.toETObservation(); + } + + public static List toETObsFromBahmniObs(Collection bahmniObservations) { + return BahmniObservation.toETObsFromBahmniObs(bahmniObservations); + } + + public Collection getGroupMembers() { + return groupMembers; + } + + public void setGroupMembers(Collection groupMembers) { + this.groupMembers = groupMembers; + } + + public Boolean isUnknown() { + return bahmniObservation.isUnknown(); + } + + public void setUnknown(Boolean unknown) { + bahmniObservation.setUnknown(unknown); + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/ObservationData.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/ObservationData.java new file mode 100644 index 0000000000..e503d7775e --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/ObservationData.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.contract.encounter.data; + +public class ObservationData { + private String conceptUUID; + private String conceptName; + private Object value; + + public ObservationData(String conceptUUID, String conceptName, Object value) { + this.conceptUUID = conceptUUID; + this.conceptName = conceptName; + this.value = value; + } + + public ObservationData() { + } + + public String getConceptUUID() { + return conceptUUID; + } + + public Object getValue() { + return value; + } + + public void setConceptUUID(String conceptUUID) { + this.conceptUUID = conceptUUID; + } + + public void setValue(Object value) { + this.value = value; + } + + public String getConceptName() { + return conceptName; + } + + public void setConceptName(String conceptName) { + this.conceptName = conceptName; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/PersonObservationData.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/PersonObservationData.java new file mode 100644 index 0000000000..43ae57b995 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/data/PersonObservationData.java @@ -0,0 +1,62 @@ +package org.bahmni.module.bahmnicore.contract.encounter.data; + +import java.util.Date; + +public class PersonObservationData { + private String conceptName; + private Double value; + private Date observationDate; + private boolean numeric; + private String units; + + public PersonObservationData(String conceptName, Double value, Date observationDate, boolean numeric, String units) { + this.conceptName = conceptName; + this.value = value; + this.observationDate = observationDate; + this.numeric = numeric; + this.units = units; + } + + public boolean isNumeric() { + return numeric; + } + + public void setNumeric(boolean numeric) { + this.numeric = numeric; + } + + public String getUnits() { + return units; + } + + public void setUnits(String units) { + this.units = units; + } + + public PersonObservationData() { + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + public String getConceptName() { + return conceptName; + } + + public void setConceptName(String conceptName) { + this.conceptName = conceptName; + } + + public Date getObservationDate() { + return observationDate; + } + + public void setObservationDate(Date observationDate) { + this.observationDate = observationDate; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/response/EncounterConfigResponse.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/response/EncounterConfigResponse.java new file mode 100644 index 0000000000..7a76930aa0 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/encounter/response/EncounterConfigResponse.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.contract.encounter.response; + +import org.bahmni.module.bahmnicore.contract.encounter.data.ConceptData; + +import java.util.HashMap; +import java.util.Map; + +public class EncounterConfigResponse { + private Map visitTypes = new HashMap(); + private Map encounterTypes = new HashMap(); + private Map orderTypes = new HashMap(); + private Map conceptData = new HashMap(); + + public Map getVisitTypes() { + return visitTypes; + } + + public void setVisitTypes(Map visitTypes) { + this.visitTypes = visitTypes; + } + + public Map getEncounterTypes() { + return encounterTypes; + } + + public void setEncounterTypes(Map encounterTypes) { + this.encounterTypes = encounterTypes; + } + + public void addVisitType(String name, String guid) { + visitTypes.put(name, guid); + } + + public void addEncounterType(String name, String guid) { + encounterTypes.put(name, guid); + } + + public void addConcept(String name, ConceptData conceptData) { + this.conceptData.put(name, conceptData); + } + + public Map getConceptData() { + return conceptData; + } + + public void setConceptData(Map conceptData) { + this.conceptData = conceptData; + } + + public void addOrderType(String name, String uuid) { + orderTypes.put(name, uuid); + } + + public Map getOrderTypes() { + return orderTypes; + } + + public void setOrderTypes(Map orderTypes) { + this.orderTypes = orderTypes; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/entityMapping/Entity.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/entityMapping/Entity.java new file mode 100644 index 0000000000..63cb8e0d54 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/entityMapping/Entity.java @@ -0,0 +1,37 @@ +package org.bahmni.module.bahmnicore.contract.entityMapping; + +import java.util.List; + +public class Entity { + public T1 entity; + + public List mappings; + + public Entity () { + } + + public Entity(T1 entity, List mappings) { + this.entity = entity; + this.mappings = mappings; + } + + public T1 getEntity() { + return entity; + } + + public void setEntity(T1 entity) { + this.entity = entity; + } + + public List getMappings() { + return mappings; + } + + public void setMappings(List mappings) { + this.mappings = mappings; + } + + public void addMapping(Object mappedEntity) { + mappings.add((T2) mappedEntity); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/monitoring/response/TasksMonitoringResponse.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/monitoring/response/TasksMonitoringResponse.java new file mode 100644 index 0000000000..b7f025a222 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/monitoring/response/TasksMonitoringResponse.java @@ -0,0 +1,34 @@ +package org.bahmni.module.bahmnicore.contract.monitoring.response; + + +import java.util.Date; + +public class TasksMonitoringResponse { + private final Boolean started; + private final String taskClass; + private final Date lastExecutionTime; + private final Date nextExecutionTime; + + public TasksMonitoringResponse(Boolean started, String taskClass, Date lastExecutionTime, Date nextExecutionTime) { + this.started = started; + this.taskClass = taskClass; + this.lastExecutionTime = lastExecutionTime; + this.nextExecutionTime = nextExecutionTime; + } + + public Boolean getStarted() { + return started; + } + + public String getTaskClass() { + return taskClass; + } + + public Date getLastExecutionTime() { + return lastExecutionTime; + } + + public Date getNextExecutionTime() { + return nextExecutionTime; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/orderTemplate/OrderTemplateJson.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/orderTemplate/OrderTemplateJson.java new file mode 100644 index 0000000000..957dee2f13 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/orderTemplate/OrderTemplateJson.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.contract.orderTemplate; + +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.List; + +public class OrderTemplateJson { + private List orderTemplates; + + public List getOrderTemplates() { + return orderTemplates; + } + + public void setOrderTemplates(List orderTemplates) { + this.orderTemplates = orderTemplates; + } + + public static class OrderTemplate { + private String name; + private List drugOrders; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getDrugOrders() { + return drugOrders; + } + + public void setDrugOrders(List drugOrders) { + this.drugOrders = drugOrders; + } + } + } diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/visit/EncounterType.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/visit/EncounterType.java new file mode 100644 index 0000000000..aab51002f7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/visit/EncounterType.java @@ -0,0 +1,16 @@ +package org.bahmni.module.bahmnicore.contract.visit; + +public enum EncounterType { + ADMISSION ("ADMISSION"), + DISHCARGE ("DISCHARGE"); + + private final String name; + + EncounterType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/visit/VisitSummary.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/visit/VisitSummary.java new file mode 100644 index 0000000000..4924009ca6 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/contract/visit/VisitSummary.java @@ -0,0 +1,100 @@ +package org.bahmni.module.bahmnicore.contract.visit; + +import java.util.Date; + +public class VisitSummary { + private String uuid; + private Date startDateTime; + private Date stopDateTime; + private String visitType; + private IPDDetails admissionDetails; + private IPDDetails dischargeDetails; + + + public Date getStartDateTime() { + return startDateTime; + } + + public void setStartDateTime(Date startDateTime) { + this.startDateTime = startDateTime; + } + + public Date getStopDateTime() { + return stopDateTime; + } + + public void setStopDateTime(Date stopDateTime) { + this.stopDateTime = stopDateTime; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVisitType() { + return visitType; + } + + public void setVisitType(String visitType) { + this.visitType = visitType; + } + + public IPDDetails getAdmissionDetails() { + return admissionDetails; + } + + public void setAdmissionDetails(IPDDetails admissionDetails) { + this.admissionDetails = admissionDetails; + } + + public IPDDetails getDischargeDetails() { + return dischargeDetails; + } + + public void setDischargeDetails(IPDDetails dischargeDetails) { + this.dischargeDetails = dischargeDetails; + } + + public static class IPDDetails { + private String uuid; + private Date date; + private String provider; + private String notes; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/customdatatype/datatype/CodedConceptDatatype.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/customdatatype/datatype/CodedConceptDatatype.java new file mode 100644 index 0000000000..90aee4cd0e --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/customdatatype/datatype/CodedConceptDatatype.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.customdatatype.datatype; + +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.api.context.Context; +import org.openmrs.customdatatype.InvalidCustomValueException; +import org.openmrs.customdatatype.SerializingCustomDatatype; + +import java.util.Collection; + +public class CodedConceptDatatype extends SerializingCustomDatatype { + private Concept codedConcept; + + @Override + public void setConfiguration(String id) { + this.codedConcept = Context.getConceptService().getConcept(Integer.valueOf(id)); + } + + @Override + public String serialize(Concept concept) { + return concept.getId().toString(); + } + + @Override + public Concept deserialize(String value) { + try { + return Context.getConceptService().getConcept(Integer.valueOf(value)); + } catch (NumberFormatException e) { + return Context.getConceptService().getConceptByUuid(value); + } + } + + @Override + public void validate(Concept concept) throws InvalidCustomValueException { + Collection answers = codedConcept.getAnswers(); + for (ConceptAnswer existingAnswer : answers) { + if (existingAnswer.getAnswerConcept().equals(concept)) + return; + } + throw new InvalidCustomValueException("Doesn't match the Coded Concept Answers"); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/ApplicationDataDirectory.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/ApplicationDataDirectory.java new file mode 100644 index 0000000000..fc1518326e --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/ApplicationDataDirectory.java @@ -0,0 +1,9 @@ +package org.bahmni.module.bahmnicore.dao; + +import java.io.File; + +public interface ApplicationDataDirectory { + File getFile(String relativePath); + + File getFileFromConfig(String relativePath); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniAddressHierarchyDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniAddressHierarchyDao.java new file mode 100644 index 0000000000..155172f646 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniAddressHierarchyDao.java @@ -0,0 +1,9 @@ +package org.bahmni.module.bahmnicore.dao; + +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; + +import java.util.List; + +public interface BahmniAddressHierarchyDao { + List getAddressHierarchyEntriesByUuid(List uuids); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniConceptDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniConceptDao.java new file mode 100644 index 0000000000..c1178de6f9 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniConceptDao.java @@ -0,0 +1,18 @@ +package org.bahmni.module.bahmnicore.dao; + + +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; + +import java.util.Collection; +import java.util.List; + +public interface BahmniConceptDao { + Collection searchByQuestion(Concept questionConcept, String searchQuery); + Concept getConceptByFullySpecifiedName(String fullySpecifiedConceptName); + Collection getDrugByListOfConcepts(Collection conceptSet); + List searchDrugsByDrugName(Integer conceptSetId, String searchTerm); + + List getConceptsByFullySpecifiedName(List conceptNames); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniOrderSetDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniOrderSetDao.java new file mode 100644 index 0000000000..4ac1ff88f7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/BahmniOrderSetDao.java @@ -0,0 +1,10 @@ +package org.bahmni.module.bahmnicore.dao; + + +import org.openmrs.OrderSet; + +import java.util.List; + +public interface BahmniOrderSetDao { + List getOrderSetByQuery(String searchTerm); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/EntityDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/EntityDao.java new file mode 100644 index 0000000000..a54e48d934 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/EntityDao.java @@ -0,0 +1,6 @@ +package org.bahmni.module.bahmnicore.dao; + +public interface EntityDao { + + public T getByUuid(String uuid, Class className); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java new file mode 100644 index 0000000000..3cc137c4ff --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/NoteDao.java @@ -0,0 +1,29 @@ +package org.bahmni.module.bahmnicore.dao; + +import java.util.Date; +import java.util.List; + +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.openmrs.api.db.DAOException; + +public interface NoteDao { + + Note createNote(Note note); + + Note getNoteById(Integer noteId); + + Note updateNote(Note note); + + void deleteNote(Note note); + + Note voidNote(Note note); + + Note getNote(Date noteDate, String noteType); + + NoteType getNoteType(String name); + + List getNotes(Date startDate, Date endDate, String noteType); + + Note getNoteByUuid(String uuid); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/ObsDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/ObsDao.java new file mode 100644 index 0000000000..b1683cc4e8 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/ObsDao.java @@ -0,0 +1,39 @@ +package org.bahmni.module.bahmnicore.dao; + +import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Person; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +public interface ObsDao { + List getNumericObsByPerson(String personUUID); + + List getNumericConceptsForPerson(String personUUID); + + List getObsFor(String patientUuid, Concept rootConcept, Concept childConcept, List visitIdsFor, Collection encounters, Date startDate, Date endDate); + + List getObsForFormBuilderForms(String patientUuid, List formNames, List visitIdsFor, Collection encounters, Date startDate, Date endDate); + + List getLatestObsFor(String patientUuid, String conceptName, Integer limit); + + List getLatestObsForConceptSetByVisit(String patientUuid, String conceptNames, Integer visitId); + + List getObsForOrder(String orderUuid); + + List getObsForVisits(List persons, ArrayList visit, List conceptsForNames, Collection obsIgnoreList, Boolean filterOutOrders, Order order); + + List getObsByPatientAndVisit(String patientUuid, List conceptNames, List listOfVisitIds, Integer limit, ObsDaoImpl.OrderBy sortOrder, List obsIgnoreList, Boolean filterOutOrderObs, Order order, Date startDate, Date endDate); + + List getObsForConceptsByEncounter(String encounterUuid, List conceptNames); + + Obs getChildObsFromParent(String parentObsUuid, Concept childConcept); + + List getObsByPatientProgramUuidAndConceptNames(String patientProgramUuid, List conceptNames, Integer limit, ObsDaoImpl.OrderBy sortOrder, Date startDate, Date endDate); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/OrderDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/OrderDao.java new file mode 100644 index 0000000000..142b64849c --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/OrderDao.java @@ -0,0 +1,60 @@ +package org.bahmni.module.bahmnicore.dao; + +import org.openmrs.CareSetting; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public interface OrderDao { + List getCompletedOrdersFrom(List orders); + + List getPrescribedDrugOrders(Patient patient, Boolean includeActiveVisit, Integer numberOfVisits, Date startDate, Date endDate, Boolean getEffectiveOrdersOnly); + + List getVisitsWithActiveOrders(Patient patient, String orderType, Boolean includeActiveVisit, Integer numberOfVisits); + + List getVisitsWithAllOrders(Patient patient, String orderType, Boolean includeActiveVisit, Integer numberOfVisits); + + List getPrescribedDrugOrders(List visitUuids); + + List getPrescribedDrugOrdersForConcepts(Patient patient, Boolean includeActiveVisit, List visits, + List conceptIds, Date startDate, Date endDate); + + Collection getDrugOrderForRegimen(String regimenName); + + List getVisitsForUUids(String[] visitUuids); + + List getAllOrders(Patient patient, List orderTypes, Integer offset, Integer limit); + + List getAllOrdersForVisits(OrderType orderType, List visits); + + Order getOrderByUuid(String orderUuid); + + List getOrdersForVisitUuid(String visitUuid, String orderTypeUuid); + + List getAllOrders(Patient patientByUuid, OrderType drugOrderTypeUuid, Set conceptsForDrugs, Set drugConceptsToBeExcluded, Collection encounters); + + Map getDiscontinuedDrugOrders(List drugOrders); + + List getActiveOrders(Patient patient, OrderType orderType, CareSetting careSetting, Date asOfDate, Set conceptsToFilter, + Set conceptsToExclude, Date startDate, Date endDate, Collection encounters); + + List getInactiveOrders(Patient patient, OrderType orderTypeByName, CareSetting careSettingByName, Date asOfDate, + Set concepts, Set drugConceptsToBeExcluded, Collection encounters); + + Order getChildOrder(Order order); + + List getOrdersByPatientProgram(String patientProgramUuid, OrderType orderTypeByUuid, Set conceptsForDrugs); + + List getAllOrders(Patient patientByUuid, OrderType drugOrderTypeUuid, Integer offset, Integer limit, List locationUuids); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/PersonAttributeDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/PersonAttributeDao.java new file mode 100644 index 0000000000..e3d23a810b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/PersonAttributeDao.java @@ -0,0 +1,8 @@ +package org.bahmni.module.bahmnicore.dao; + +import org.bahmni.module.bahmnicore.model.ResultList; + +public interface PersonAttributeDao { + + public ResultList getUnique(String personAttribute, String query); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/PersonNameDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/PersonNameDao.java new file mode 100644 index 0000000000..8b86e5d013 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/PersonNameDao.java @@ -0,0 +1,8 @@ +package org.bahmni.module.bahmnicore.dao; + +import org.bahmni.module.bahmnicore.model.ResultList; + +public interface PersonNameDao { + + public ResultList getUnique(String key, String query); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/VisitDao.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/VisitDao.java new file mode 100644 index 0000000000..073bb6505c --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/VisitDao.java @@ -0,0 +1,20 @@ +package org.bahmni.module.bahmnicore.dao; + +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.List; + +public interface VisitDao { + public Visit getLatestVisit(String patientUuid, String conceptName); + + Visit getVisitSummary(String visitUuid); + + List getAdmitAndDischargeEncounters(Integer visitId); + + List getVisitsByPatient(Patient patient, int numberOfVisits); + + List getVisitIdsFor(String patientUuid, Integer numberOfVisits); + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java new file mode 100644 index 0000000000..2cfa4627e7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ApplicationDataDirectoryImpl.java @@ -0,0 +1,23 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.ApplicationDataDirectory; +import org.openmrs.util.OpenmrsUtil; + +import java.io.File; + +public class ApplicationDataDirectoryImpl implements ApplicationDataDirectory { + + @Override + public File getFile(String relativePath) { + String applicationDataDirectory = OpenmrsUtil.getApplicationDataDirectory(); + if (!applicationDataDirectory.endsWith(File.separator) && !relativePath.startsWith(File.separator)) { + applicationDataDirectory += File.separator; + } + return new File(applicationDataDirectory + relativePath); + } + + @Override + public File getFileFromConfig(String relativePath) { + return new File(OpenmrsUtil.getApplicationDataDirectory(),"bahmni_config"+ File.separator+relativePath); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniAddressHierarchyDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniAddressHierarchyDaoImpl.java new file mode 100644 index 0000000000..c6c94ddf09 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniAddressHierarchyDaoImpl.java @@ -0,0 +1,70 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniAddressHierarchyDao; +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyLevel; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.transform.Transformers; +import org.hibernate.type.StandardBasicTypes; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class BahmniAddressHierarchyDaoImpl implements BahmniAddressHierarchyDao { + @Autowired + private SessionFactory sessionFactory; + + @Override + public List getAddressHierarchyEntriesByUuid(List uuids) { + Session currentSession = sessionFactory.getCurrentSession(); + List bahmniAddressHierarchyEntries; + StringBuilder queryString = new StringBuilder("select ahe.address_hierarchy_entry_id as addressHierarchyEntryId, ahe.parent_id as parentId, ahe.uuid as uuid, ahe.level_id as levelId, " + + " ahe.user_generated_id as userGeneratedId, ahe.name as name from address_hierarchy_entry ahe " + + "where ahe.uuid in (:uuids) "); + + SQLQuery sqlQuery = currentSession + .createSQLQuery(queryString.toString()) + .addScalar("uuid", StandardBasicTypes.STRING) + .addScalar("addressHierarchyEntryId", StandardBasicTypes.INTEGER) + .addScalar("parentId", StandardBasicTypes.INTEGER) + .addScalar("levelId", StandardBasicTypes.INTEGER) + .addScalar("userGeneratedId", StandardBasicTypes.STRING) + .addScalar("name", StandardBasicTypes.STRING); + + sqlQuery.setParameterList("uuids", uuids); + sqlQuery.setResultTransformer(Transformers.aliasToBean(BahmniAddressHierarchyEntry.class)); + + bahmniAddressHierarchyEntries = (List) sqlQuery.list(); + for(BahmniAddressHierarchyEntry bahmniAddressHierarchyEntry: bahmniAddressHierarchyEntries){ + bahmniAddressHierarchyEntry.setAddressHierarchyLevel(getAddressHierarchyLevelById(bahmniAddressHierarchyEntry.getLevelId())); + } + + return bahmniAddressHierarchyEntries; + } + + private BahmniAddressHierarchyLevel getAddressHierarchyLevelById(Integer levelId) { + + Session currentSession = sessionFactory.getCurrentSession(); + StringBuilder queryString = new StringBuilder("select ahl.address_hierarchy_level_id as levelId, ahl.parent_level_id as parentLevelId, ahl.uuid as uuid, ahl.required as required, " + + " ahl.address_field as addressField, ahl.name as name from address_hierarchy_level ahl " + + "where ahl.address_hierarchy_level_id = (:levelId) "); + + SQLQuery sqlQuery = currentSession + .createSQLQuery(queryString.toString()) + .addScalar("uuid", StandardBasicTypes.STRING) + .addScalar("parentLevelId", StandardBasicTypes.INTEGER) + .addScalar("required", StandardBasicTypes.BOOLEAN) + .addScalar("levelId", StandardBasicTypes.INTEGER) + .addScalar("addressField", StandardBasicTypes.STRING) + .addScalar("name", StandardBasicTypes.STRING); + + sqlQuery.setParameter("levelId", levelId); + sqlQuery.setResultTransformer(Transformers.aliasToBean(BahmniAddressHierarchyLevel.class)); + + return (BahmniAddressHierarchyLevel) sqlQuery.uniqueResult(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java new file mode 100644 index 0000000000..b119448b85 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImpl.java @@ -0,0 +1,147 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniConceptDao; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.hibernate.type.StandardBasicTypes; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +@Repository +public class BahmniConceptDaoImpl implements BahmniConceptDao { + + private static final String WHITE_SPACE = "\\s+"; + private static final String WILD_CARD = "%"; + private static final String BASE_SEARCH_QUERY = "select answer " + + "from ConceptAnswer as answer " + + "join answer.answerConcept.names as answerConceptNames " + + "where answer.concept = :questionConcept " + + " and answerConceptNames.voided = false "; + @Autowired + private SessionFactory sessionFactory; + private String drugsWithConceptNamesForConceptSet = "concept_set csmembers " + + "INNER JOIN concept c ON c.concept_id = csmembers.concept_id and csmembers.concept_set= (:conceptSetId) " + + "RIGHT JOIN concept_name cn ON csmembers.concept_id = cn.concept_id and cn.voided = 0 " + + "INNER JOIN drug d ON csmembers.concept_id = d.concept_id and d.retired = 0 "; + + @Override + public Collection searchByQuestion(Concept questionConcept, String searchQuery) { + String[] queryArray = (searchQuery==null? "":searchQuery).split(WHITE_SPACE); + StringBuffer queryStringBuffer = new StringBuffer(BASE_SEARCH_QUERY); + appendSearchQueriesToBase(queryArray, queryStringBuffer); + + Query query = sessionFactory.getCurrentSession().createQuery( + queryStringBuffer.toString()); + + query.setEntity("questionConcept", questionConcept); + for (int i = 0; i < queryArray.length; i++) { + query.setString("query"+ i, searchBothSidesOf(queryArray[i])); + } + + return new HashSet<>(query.list()); + } + + @Override + public Concept getConceptByFullySpecifiedName(String fullySpecifiedConceptName) { + List concepts = sessionFactory.getCurrentSession() + .createQuery("select concept " + + "from ConceptName as conceptName " + + "where conceptName.conceptNameType ='FULLY_SPECIFIED' " + + " and lower(conceptName.name)= lower(:fullySpecifiedName)") + .setString("fullySpecifiedName", fullySpecifiedConceptName) + .list(); + + return concepts.size() > 0 ? concepts.get(0) : null; + } + + @Override + public Collection getDrugByListOfConcepts(Collection concepts) { + return sessionFactory.getCurrentSession() + .createQuery("select drug from Drug as drug, ConceptSet as conceptSet " + + "where drug.concept in (:conceptIds) and conceptSet.concept = drug.concept order by conceptSet.sortWeight") + .setParameterList("conceptIds", concepts) + .list(); + } + + @Override + public List searchDrugsByDrugName(Integer conceptSetId, String searchTerm) { + List drugIds; + if (null != searchTerm) { + drugIds = sessionFactory.getCurrentSession() + .createSQLQuery(getSqlForDrugsMatchingEitherConceptOrDrugName()) + .addScalar("drugId", StandardBasicTypes.INTEGER) + .setParameter("conceptSetId", conceptSetId) + .setString("searchPattern", searchBothSidesOf(searchTerm)) + .list(); + } else { + drugIds = sessionFactory.getCurrentSession() + .createSQLQuery(getSqlForAllDrugIds()) + .setParameter("conceptSetId", conceptSetId) + .list(); + } + return getDrugsByDrugIds(drugIds); + } + + @Override + public List getConceptsByFullySpecifiedName(List conceptNames) { + List lowerCaseConceptNames = getLowerCaseFor(conceptNames); + List concepts = sessionFactory.getCurrentSession() + .createQuery("select concept " + + "from ConceptName as conceptName " + + "where conceptName.conceptNameType ='FULLY_SPECIFIED' and conceptName.voided = false" + + " and lower(conceptName.name) in (:conceptNames)").setParameterList("conceptNames", lowerCaseConceptNames).list(); + return concepts; + } + + private String getSqlForDrugsMatchingEitherConceptOrDrugName() { + return getDrugIdsFrom("(SELECT DISTINCT csmembers.sort_weight as sortWeight,d.drug_id as drugId " + + "FROM " + drugsWithConceptNamesForConceptSet + + "WHERE lower(cn.name) like (:searchPattern) or lower(d.name) LIKE (:searchPattern))"); + } + + private String getSqlForAllDrugIds() { + return getDrugIdsFrom("SELECT DISTINCT csmembers.sort_weight as sortWeight,d.drug_id as drugId " + + "FROM " + + drugsWithConceptNamesForConceptSet); + } + + private String getDrugIdsFrom(String drugs) { + return "SELECT drugs.drugId as drugId FROM (" + drugs + ") as drugs ORDER BY drugs.sortWeight"; + } + + private List getDrugsByDrugIds(List drugsIdsInSortedOrder) { + List drugsInSortedOrder; + drugsInSortedOrder = new ArrayList<>(); + for (Integer drugId : drugsIdsInSortedOrder) { + drugsInSortedOrder.add(Context.getConceptService().getDrug(drugId)); + } + return drugsInSortedOrder; + } + + private void appendSearchQueriesToBase(String[] queryArray, StringBuffer queryStringBuffer) { + for (int i = 0; i < queryArray.length; i++) { + queryStringBuffer.append(" and lower(answerConceptNames.name) like :query" + i); + } + } + + private String searchBothSidesOf(String searchString) { + return WILD_CARD + searchString.trim().toLowerCase() + WILD_CARD; + } + + private List getLowerCaseFor(List conceptNames){ + List lowerCaseConceptNames = new ArrayList<>(); + for (String concept : conceptNames) { + lowerCaseConceptNames.add(concept.toLowerCase()); + } + return lowerCaseConceptNames; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniOrderSetDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniOrderSetDaoImpl.java new file mode 100644 index 0000000000..eeda9f1d0b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/BahmniOrderSetDaoImpl.java @@ -0,0 +1,28 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniOrderSetDao; +import org.hibernate.Criteria; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.MatchMode; +import org.hibernate.criterion.Restrictions; +import org.openmrs.OrderSet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class BahmniOrderSetDaoImpl implements BahmniOrderSetDao { + + @Autowired + private SessionFactory sessionFactory; + + @Override + public List getOrderSetByQuery(String searchTerm) { + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(OrderSet.class); + criteria.add(Restrictions.or(Restrictions.like("name", searchTerm, MatchMode.ANYWHERE), + Restrictions.like("description", searchTerm, MatchMode.ANYWHERE))); + criteria.add(Restrictions.eq("retired", Boolean.FALSE)); + return criteria.list(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/EntityDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/EntityDaoImpl.java new file mode 100644 index 0000000000..5730127501 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/EntityDaoImpl.java @@ -0,0 +1,26 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.EntityDao; +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class EntityDaoImpl implements EntityDao { + @Autowired + private SessionFactory sessionFactory; + + @Override + public T getByUuid(String uuid, Class className) { + Session currentSession = sessionFactory.getCurrentSession(); + Criteria criteria = currentSession.createCriteria(className); + criteria.add(Restrictions.eq("uuid", uuid)); + List list = criteria.list(); + return list.size() > 0? (T) list.get(0) : null; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java new file mode 100644 index 0000000000..793f05a61d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/NoteDaoImpl.java @@ -0,0 +1,106 @@ +package org.bahmni.module.bahmnicore.dao.impl; + + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.hibernate.query.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.openmrs.api.APIException; + +public class NoteDaoImpl implements NoteDao { + + protected final static Log log = LogFactory.getLog(NoteDaoImpl.class); + + private SessionFactory sessionFactory; + + public NoteDaoImpl() { + } + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Note getNoteById(Integer id) { + log.info("Get note " + id); + return (Note) sessionFactory.getCurrentSession().get(Note.class, id); + } + + public Note createNote(Note note) { + log.debug("Creating new note"); + sessionFactory.getCurrentSession().save(note); + return note; + } + + public NoteType getNoteType(String name){ + List noteType = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery("select noteType from NoteType noteType " + + "where noteType.name = :name"); + query.setParameter("name", name); + noteType.addAll(query.list()); + return CollectionUtils.isEmpty(noteType) ? null : noteType.get(0); + + } + + public Note updateNote(Note note) { + log.debug("Updating existing note"); + sessionFactory.getCurrentSession().save(note); + return note; + } + + public void deleteNote(Note note) { + log.debug("Deleting existing note"); + sessionFactory.getCurrentSession().delete(note); + } + + public Note voidNote(Note note) throws APIException { + sessionFactory.getCurrentSession().save(note); + return note; + } + + @Override + public Note getNote(Date noteDate, String noteType) { + List notes = new ArrayList<>(); + StringBuilder query = new StringBuilder("select note from Note note " + + "where note.noteDate = :noteDate " + + "and note.noteType.name = :noteType " + + "and note.voided = false"); + + Query queryToGetNotes = sessionFactory.getCurrentSession().createQuery(query.toString()); + queryToGetNotes.setParameter("noteDate", noteDate); + queryToGetNotes.setParameter("noteType", noteType); + + notes.addAll(queryToGetNotes.list()); + return CollectionUtils.isEmpty(notes) ? null : notes.get(0); + } + + @Override + public List getNotes(Date startDate, Date endDate, String noteType) { + List notes = new ArrayList<>(); + Session currentSession = sessionFactory.getCurrentSession(); + Query query = currentSession.createQuery( + "select note from Note note " + + "where note.noteDate between :startDate and :endDate " + + "and note.noteType.name = :noteType" + + " and note.voided = false"); + query.setParameter("startDate", startDate); + query.setParameter("endDate", endDate); + query.setParameter("noteType", noteType); + notes.addAll(query.list()); + return notes; + + } + @Override + public Note getNoteByUuid(String uuid) { + return (Note)this.sessionFactory.getCurrentSession().createQuery("from Note note where note.uuid = :uuid").setParameter("uuid", uuid).uniqueResult(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java new file mode 100644 index 0000000000..15a276bee0 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImpl.java @@ -0,0 +1,392 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.hibernate.Criteria; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Person; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static java.util.Objects.nonNull; + +@Repository +public class ObsDaoImpl implements ObsDao { + + public static final String COMMA = ","; + private static final String OR = "|"; + @Autowired + private SessionFactory sessionFactory; + + public enum OrderBy {ASC, DESC} + + @Override + public List getNumericObsByPerson(String personUUID) { + Query query = sessionFactory.getCurrentSession().createQuery( + "select obs from Obs as obs inner join fetch " + + "obs.concept as concept inner join fetch " + + "concept.datatype as datatype inner join " + + "obs.person as person " + + "where datatype.hl7Abbreviation = :hl7abrv " + + "and person.uuid= :personUUID " + + "and obs.voided = false "); + query.setString("hl7abrv", ConceptDatatype.NUMERIC); + query.setString("personUUID", personUUID); + return query.list(); + + } + + @Override + public List getNumericConceptsForPerson(String personUUID) { + Query query = sessionFactory.getCurrentSession().createQuery( + "select concept " + + "from Obs as obs " + + "inner join obs.concept as concept " + + "inner join concept.datatype as datatype " + + "inner join obs.person as person " + + "where datatype.hl7Abbreviation = :hl7abrv " + + "and person.uuid = :personUUID " + + "and obs.voided = false "); + query.setString("hl7abrv", ConceptDatatype.NUMERIC); + query.setString("personUUID", personUUID); + return query.list(); + + } + + public List getObsByPatientAndVisit(String patientUuid, List conceptNames, List listOfVisitIds, + Integer limit, OrderBy sortOrder, List obsIgnoreList, Boolean filterOutOrderObs, Order order, Date startDate, Date endDate) { + + StringBuilder query = new StringBuilder("select obs from Obs as obs, ConceptName as cn " + + " where obs.person.uuid = :patientUuid " + + " and cn.concept = obs.concept.conceptId " + + " and cn.name in (:conceptNames) " + + " and cn.locale in (:locale) " + + " and cn.conceptNameType = :conceptNameType " + + " and cn.voided = false and obs.voided = false "); + + if (CollectionUtils.isNotEmpty(listOfVisitIds)) { + query.append(" and obs.encounter.visit.visitId in (:listOfVisitIds) "); + } + if (startDate != null) { + query.append(" and obs.obsDatetime >= :startDate "); + } + if (endDate != null) { + query.append(" and obs.obsDatetime <= :endDate "); + } + + if (CollectionUtils.isNotEmpty(obsIgnoreList)) { + query.append(" and cn.name not in (:obsIgnoreList) "); + } + if (filterOutOrderObs) { + query.append(" and obs.order.orderId is null "); + } + if (null != order) { + query.append(" and obs.order = (:order) "); + } + if (sortOrder == OrderBy.ASC) { + query.append(" order by obs.obsDatetime asc "); + } else { + query.append(" order by obs.obsDatetime desc "); + } + + List localeList = new ArrayList<>(); + localeList.add(Context.getLocale()); + if (!LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + localeList.add(LocaleUtility.getDefaultLocale()); + } + + Query queryToGetObservations = sessionFactory.getCurrentSession().createQuery(query.toString()); + queryToGetObservations.setMaxResults(limit); + queryToGetObservations.setString("patientUuid", patientUuid); + queryToGetObservations.setParameterList("conceptNames", conceptNames); + queryToGetObservations.setParameter("conceptNameType", ConceptNameType.FULLY_SPECIFIED); + queryToGetObservations.setParameterList("locale", localeList); + if (null != obsIgnoreList && obsIgnoreList.size() > 0) { + queryToGetObservations.setParameterList("obsIgnoreList", obsIgnoreList); + } + if (null != listOfVisitIds && listOfVisitIds.size() > 0) { + queryToGetObservations.setParameterList("listOfVisitIds", listOfVisitIds); + } + if (null != order) { + queryToGetObservations.setParameter("order", order); + } + if (startDate != null) { + queryToGetObservations.setParameter("startDate", startDate); + } + if (endDate != null) { + queryToGetObservations.setParameter("endDate", endDate); + } + return queryToGetObservations.list(); + } + + @Override + public List getLatestObsFor(String patientUuid, String conceptName, Integer limit) { + Query queryToGetObservations = sessionFactory.getCurrentSession().createQuery( + "select obs " + + " from Obs as obs, ConceptName as cn " + + " where obs.person.uuid = :patientUuid " + + " and cn.concept = obs.concept.conceptId " + + " and cn.name = (:conceptName) " + + " and cn.locale = :locale " + + " and cn.conceptNameType = :conceptNameType " + + " and cn.voided = false " + + " and obs.voided = false" + + " order by obs.obsDatetime desc "); + + queryToGetObservations.setMaxResults(limit); + queryToGetObservations.setString("patientUuid", patientUuid); + queryToGetObservations.setParameter("conceptName", conceptName); + queryToGetObservations.setParameter("conceptNameType", ConceptNameType.FULLY_SPECIFIED); + queryToGetObservations.setString("locale", Context.getLocale().getLanguage()); + + return queryToGetObservations.list(); + } + + @Override + public List getLatestObsForConceptSetByVisit(String patientUuid, String conceptName, Integer visitId) { + if (visitId == null) return new ArrayList<>(); + + String queryString = + "select obs\n" + + "from Obs obs join obs.encounter enc join enc.visit v \n" + + "where obs.voided = false and obs.concept.conceptId in " + + " ( select cs.concept.conceptId\n" + + " from ConceptName cn, ConceptSet cs\n" + + " where cs.conceptSet.conceptId = cn.concept.conceptId and cn.conceptNameType='FULLY_SPECIFIED' " + + " and cn.locale = :locale and cn.name=:conceptName)\n" + + " and obs.person.uuid=:patientUuid and v.visitId =:visitId order by enc.encounterId desc"; + Query queryToGetObs = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetObs.setString("conceptName", conceptName); + queryToGetObs.setString("patientUuid", patientUuid); + queryToGetObs.setInteger("visitId", visitId); + queryToGetObs.setString("locale", Context.getLocale().getLanguage()); + + return queryToGetObs.list(); + } + + @Override + public List getObsForConceptsByEncounter(String encounterUuid, List conceptNames) { + if (encounterUuid == null) return new ArrayList<>(); + + String queryString = + "select obs\n" + + "from Obs obs, ConceptName cn \n" + + "where obs.voided = false and obs.encounter.uuid =:encounterUuid " + + "and obs.concept.conceptId = cn.concept.conceptId " + + "and cn.name in (:conceptNames) " + + "and cn.locale = :locale " + + "and cn.conceptNameType='FULLY_SPECIFIED'"; + Query queryToGetObs = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetObs.setParameterList("conceptNames", conceptNames); + queryToGetObs.setString("encounterUuid", encounterUuid); + queryToGetObs.setString("locale", Context.getLocale().getLanguage()); + + return queryToGetObs.list(); + } + + @Override + public List getObsForOrder(String orderUuid) { + String queryString = "from Obs obs where obs.voided = false and obs.order.uuid = :orderUuid order by obs.obsDatetime desc"; + Query queryToGetObs = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetObs.setString("orderUuid", orderUuid); + + return queryToGetObs.list(); + } + + @Override + public List getObsForVisits(List persons, ArrayList encounters, List conceptsForNames, Collection obsIgnoreList, Boolean filterOutOrders, Order order) { + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Obs.class, "obs"); + if (CollectionUtils.isEmpty(encounters)) { + return new ArrayList<>(); + } else { + criteria.add(Restrictions.in("encounter", encounters)); + } + if (CollectionUtils.isNotEmpty(persons)) { + criteria.add(Restrictions.in("person", persons)); + } + if (CollectionUtils.isNotEmpty(conceptsForNames)) { + criteria.add(Restrictions.in("concept", conceptsForNames)); + } + if (CollectionUtils.isNotEmpty(obsIgnoreList)) { + criteria.add(Restrictions.not(Restrictions.in("concept", obsIgnoreList))); + } + if (filterOutOrders) { + criteria.add(Restrictions.isNull("order")); + } + if (order != null) { + criteria.add(Restrictions.eq("order", order)); + } + criteria.add(Restrictions.eq("voided", Boolean.FALSE)); + + criteria.addOrder(org.hibernate.criterion.Order.desc("obsDatetime")); + + return criteria.list(); + } + + @Override + public List getObsFor(String patientUuid, Concept rootConcept, Concept childConcept, List listOfVisitIds, Collection encounters, Date startDate, Date endDate) { + if (listOfVisitIds == null || listOfVisitIds.isEmpty()) + return new ArrayList<>(); + + String encounterFilter = ""; + if (encounters != null && encounters.size() > 0) { + encounterFilter = "AND encounter.encounter_id in (" + commaSeparatedEncounterIds(encounters) + ")"; + } + StringBuilder queryString = new StringBuilder("SELECT rootObs.* " + + "FROM obs rootObs " + + "JOIN concept_name rootConceptName " + + "ON rootObs.concept_id = rootConceptName.concept_id AND rootConceptName.name = :rootConceptName AND " + + "rootConceptName.concept_name_type = 'FULLY_SPECIFIED' " + + "JOIN person ON person.person_id = rootObs.person_id AND person.uuid = :patientUuid AND " + + "rootObs.voided = 0 AND person.voided = 0 " + + "JOIN encounter ON encounter.encounter_id = rootObs.encounter_id AND encounter.voided = 0 " + + encounterFilter + + "JOIN visit ON visit.visit_id = encounter.visit_id AND visit.visit_id IN :visitIds " + + "JOIN obs groupByObs ON groupByObs.obs_group_id = rootObs.obs_id AND groupByObs.voided = 0 " + + "JOIN concept_name groupByConceptName " + + "ON groupByConceptName.concept_id = groupByObs.concept_id AND groupByConceptName.name = :childConceptName AND " + + "groupByConceptName.concept_name_type = 'FULLY_SPECIFIED' "); + + if (startDate != null) queryString.append("where groupByObs.obs_datetime >= :startDate "); + if (startDate != null && endDate != null) queryString.append("and groupByObs.obs_datetime <= :endDate "); + queryString.append("group by groupByObs.obs_group_id order by obs_datetime asc "); + + Query queryToGetObs = sessionFactory.getCurrentSession() + .createSQLQuery(queryString.toString()).addEntity(Obs.class); + queryToGetObs.setParameter("rootConceptName", rootConcept.getName().getName()); + queryToGetObs.setParameter("patientUuid", patientUuid); + queryToGetObs.setParameterList("visitIds", listOfVisitIds); + queryToGetObs.setParameter("childConceptName", childConcept.getName().getName()); + if (startDate != null) + queryToGetObs.setParameter("startDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startDate)); + if (endDate != null) + queryToGetObs.setParameter("endDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endDate)); + + + return queryToGetObs.list(); + } + + @Override + public List getObsForFormBuilderForms(String patientUuid, List formNames, List listOfVisitIds, + Collection encounters, Date startDate, Date endDate) { + if (listOfVisitIds == null || listOfVisitIds.isEmpty()) + return new ArrayList<>(); + String encounterFilter = ""; + if (encounters != null && encounters.size() > 0) { + encounterFilter = "AND encounter.encounter_id in (" + commaSeparatedEncounterIds(encounters) + ")"; + } + StringBuilder queryString = new StringBuilder("SELECT obs.* " + + "FROM obs " + + "JOIN person ON person.person_id = obs.person_id AND person.uuid = :patientUuid AND " + + "obs.voided = 0 AND person.voided = 0 " + + "JOIN encounter ON encounter.encounter_id = obs.encounter_id AND encounter.voided = 0 " + + encounterFilter + + "JOIN visit ON visit.visit_id = encounter.visit_id AND visit.visit_id IN :visitIds "); + queryString.append(String.format("where obs.form_namespace_and_path REGEXP '%s' ", commaSeparatedFormNamesPattern(formNames))); + if (startDate != null) queryString.append("and obs.obs_datetime >= :startDate "); + if (startDate != null && endDate != null) queryString.append("and obs.obs_datetime <= :endDate "); + queryString.append("order by obs_datetime asc "); + Query queryToGetObs = sessionFactory.getCurrentSession() + .createSQLQuery(queryString.toString()).addEntity(Obs.class); + queryToGetObs.setParameter("patientUuid", patientUuid); + queryToGetObs.setParameterList("visitIds", listOfVisitIds); + if (nonNull(startDate)) + queryToGetObs.setParameter("startDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startDate)); + if (nonNull(endDate)) + queryToGetObs.setParameter("endDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endDate)); + + return queryToGetObs.list(); + } + + private String commaSeparatedFormNamesPattern(List formNames) { + ArrayList formPatterns = new ArrayList<>(); + formNames.forEach(form -> formPatterns.add("\\\\^" + form + "\\\\.")); + return StringUtils.join(formPatterns, OR); + } + + private String commaSeparatedEncounterIds(Collection encounters) { + ArrayList encounterIds = new ArrayList<>(); + for (Encounter encounter : encounters) { + encounterIds.add(encounter.getEncounterId().toString()); + } + return StringUtils.join(encounterIds, COMMA); + } + + @Override + public Obs getChildObsFromParent(String parentObsUuid, Concept childConcept) { + String queryString = "from Obs obs where obs.obsGroup.uuid = :parentObsUuid and obs.concept = :concept and obs.voided = false order by obs.obsDatetime desc"; + Query queryToGetObs = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetObs.setParameter("parentObsUuid", parentObsUuid); + queryToGetObs.setParameter("concept", childConcept); + List obsList = queryToGetObs.list(); + if (obsList.size() > 0) { + return (Obs) queryToGetObs.list().get(0); + } + return null; + + } + + @Override + public List getObsByPatientProgramUuidAndConceptNames(String patientProgramUuid, List conceptNames, Integer limit, OrderBy sortOrder, Date startDate, Date endDate) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + StringBuilder queryString = new StringBuilder("SELECT o.* " + + "FROM patient_program pp " + + "INNER JOIN episode_patient_program epp " + + "ON pp.patient_program_id = epp.patient_program_id\n " + + "INNER JOIN episode_encounter ee " + + "ON epp.episode_id = ee.episode_id\n " + + "INNER JOIN obs o " + + "ON o.encounter_id = ee.encounter_id\n " + + "INNER JOIN concept_name cn on o.concept_id = cn.concept_id\n " + + "WHERE pp.uuid = (:patientProgramUuid) " + + "AND o.voided = false " + + "AND cn.concept_name_type='FULLY_SPECIFIED' " + + "AND cn.name IN (:conceptNames) " + + "AND cn.locale = :locale"); + if(null != startDate) { + queryString.append(" AND o.obs_datetime >= STR_TO_DATE(:startDate, '%Y-%m-%d')"); + } + if(null != endDate) { + queryString.append(" AND o.obs_datetime <= STR_TO_DATE(:endDate, '%Y-%m-%d')"); + } + if (sortOrder == OrderBy.ASC) { + queryString.append(" ORDER by o.obs_datetime asc"); + } else { + queryString.append(" ORDER by o.obs_datetime desc"); + } + if (limit != null) { + queryString.append(" limit " + limit); + } + Query queryToGetObs = sessionFactory.getCurrentSession().createSQLQuery(queryString.toString()).addEntity(Obs.class); + queryToGetObs.setParameterList("conceptNames", conceptNames); + queryToGetObs.setString("patientProgramUuid", patientProgramUuid); + queryToGetObs.setString("locale", Context.getLocale().getLanguage()); + if(null != startDate) { + queryToGetObs.setString("startDate", dateFormat.format(startDate)); + } + if(null != endDate) { + queryToGetObs.setString("endDate", dateFormat.format(endDate)); + } + + return queryToGetObs.list(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImpl.java new file mode 100644 index 0000000000..0cf6b04ac9 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImpl.java @@ -0,0 +1,494 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.contract.orderTemplate.OrderTemplateJson; +import org.bahmni.module.bahmnicore.dao.ApplicationDataDirectory; +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.codehaus.jackson.map.ObjectMapper; +import org.hibernate.Criteria; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Disjunction; +import org.hibernate.criterion.Projections; +import org.hibernate.criterion.Restrictions; +import org.openmrs.CareSetting; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.emrapi.CareSettingType; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Component +public class OrderDaoImpl implements OrderDao { + private static final String ORDER_TEMPLATES_DIRECTORY = "ordertemplates"; + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final Logger log = LogManager.getLogger(OrderDaoImpl.class); + + private SessionFactory sessionFactory; + private ApplicationDataDirectory applicationDataDirectory; + private String TEMPLATES_JSON_FILE = "templates.json"; + private String FILE_SEPARATOR = "/"; + + + @Autowired + public OrderDaoImpl(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + this.applicationDataDirectory = new ApplicationDataDirectoryImpl(); + } + + @Override + public List getCompletedOrdersFrom(List allOrders) { + Criteria criteria = getCurrentSession().createCriteria(Obs.class); + criteria.setProjection(Projections.groupProperty("order")); + + criteria.add(Restrictions.in("order", allOrders)); + return criteria.list(); + } + + @Override + public List getPrescribedDrugOrders(Patient patient, Boolean includeActiveVisit, Integer numberOfVisits, Date startDate, Date endDate, Boolean getEffectiveOrdersOnly) { + Session currentSession = getCurrentSession(); + List visitWithDrugOrderIds = getVisitIds(getVisitsWithAllOrders(patient, "DrugOrder", includeActiveVisit, numberOfVisits)); + if (visitWithDrugOrderIds.isEmpty()) { + return new ArrayList<>(); + } + StringBuilder queryString = new StringBuilder("select d1 " + + "from DrugOrder d1, Encounter e, Visit v " + + "where d1.encounter = e and e.visit = v and v.visitId in (:visitIds) " + + "and d1.voided = false and d1.action != :discontinued " + + "and not exists " + + "(select d2 from DrugOrder d2 where d2.voided = false and d2.action = :revised and d2.encounter = d1.encounter and d2.previousOrder = d1)"); + + if (getEffectiveOrdersOnly) { + if (startDate != null) { + queryString.append(" and (d1.scheduledDate >= :startDate or d1.autoExpireDate >= :startDate or d1.autoExpireDate = null)"); + } + if (endDate != null || getEffectiveOrdersOnly) { + queryString.append(" and d1.scheduledDate <= :endDate "); + } + queryString.append(" order by d1.scheduledDate desc"); + + } else { + if (startDate != null) { + queryString.append(" and (d1.dateActivated >= :startDate or d1.autoExpireDate >= :startDate or d1.autoExpireDate = null)"); + } + if (endDate != null || getEffectiveOrdersOnly) { + queryString.append(" and d1.dateActivated <= :endDate "); + } + queryString.append(" order by d1.dateActivated desc"); + } + Query query = currentSession.createQuery(queryString.toString()); + query.setParameterList("visitIds", visitWithDrugOrderIds); + query.setParameter("discontinued", Order.Action.DISCONTINUE); + query.setParameter("revised", Order.Action.REVISE); + if (startDate != null) query.setParameter("startDate", startDate); + if (endDate != null) + query.setParameter("endDate", endDate); + else if (getEffectiveOrdersOnly) + query.setParameter("endDate", new Date()); + return query.list(); + } + + @Override + public List getPrescribedDrugOrders(List visitUuids) { + if (visitUuids != null && visitUuids.size() != 0) { + Session currentSession = getCurrentSession(); + Query query = currentSession.createQuery("select d1 from DrugOrder d1, Encounter e, Visit v where d1.encounter = e and e.visit = v and v.uuid in (:visitUuids) " + + "and d1.voided = false and d1.action != :discontinued and " + + "not exists (select d2 from DrugOrder d2 where d2.voided = false and d2.action = :revised and d2.encounter = d1.encounter and d2.previousOrder = d1)" + + "order by d1.dateActivated desc"); + query.setParameterList("visitUuids", visitUuids); + query.setParameter("discontinued", Order.Action.DISCONTINUE); + query.setParameter("revised", Order.Action.REVISE); + return (List) query.list(); + } + return new ArrayList<>(); + } + + @Override + public List getPrescribedDrugOrdersForConcepts(Patient patient, Boolean includeActiveVisit, List visits, List concepts, Date startDate, Date endDate) { + Session currentSession = getCurrentSession(); + List visitWithDrugOrderIds = getVisitIds(visits); + if (!visitWithDrugOrderIds.isEmpty()) { + StringBuilder queryBuilder = new StringBuilder("select d1 from DrugOrder d1, Encounter e, Visit v where d1.encounter = e and e.visit = v and v.visitId in (:visitIds) and d1.drug.concept in (:concepts)" + + "and d1.voided = false and d1.action != :discontinued and " + + "not exists (select d2 from DrugOrder d2 where d2.voided = false and d2.action = :revised and d2.encounter = d1.encounter and d2.previousOrder = d1)"); + if (startDate != null) { + queryBuilder.append(" and d1.dateActivated >= :startDate"); + } + if (endDate != null) { + queryBuilder.append(" and d1.dateActivated <= :endDate "); + } + queryBuilder.append(" order by d1.dateActivated desc"); + Query query = currentSession.createQuery(queryBuilder.toString()); + + query.setParameterList("visitIds", visitWithDrugOrderIds); + query.setParameterList("concepts", concepts); + query.setParameter("discontinued", Order.Action.DISCONTINUE); + query.setParameter("revised", Order.Action.REVISE); + if (startDate != null) { + query.setParameter("startDate", startDate); + } + if (endDate != null) { + query.setParameter("endDate", endDate); + } + return (List) query.list(); + } + return new ArrayList<>(); + } + + @Override + public Collection getDrugOrderForRegimen(String regimenName) { + File file = getTemplates(); + OrderTemplateJson orderTemplates = null; + try { + orderTemplates = OBJECT_MAPPER.readValue(file, OrderTemplateJson.class); + setDefaultFields(orderTemplates); + } catch (IOException e) { + log.error("Could not deserialize file " + file.getAbsolutePath()); + throw new RuntimeException(e); + } + for (OrderTemplateJson.OrderTemplate orderTemplate : orderTemplates.getOrderTemplates()) { + if (orderTemplate.getName().equals(regimenName)) { + return orderTemplate.getDrugOrders(); + } + } + return new ArrayList<>(); + } + + private void setDefaultFields(OrderTemplateJson orderTemplateJson) { + for (OrderTemplateJson.OrderTemplate orderTemplate : orderTemplateJson.getOrderTemplates()) { + for (EncounterTransaction.DrugOrder drugOrder : orderTemplate.getDrugOrders()) { + drugOrder.setCareSetting(CareSettingType.OUTPATIENT); + drugOrder.setOrderType("Drug Order"); + drugOrder.setDosingInstructionType("org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions.FlexibleDosingInstructions"); + drugOrder.getDosingInstructions().setAsNeeded(false); + } + } + } + + private File getTemplates() { + return applicationDataDirectory.getFile(ORDER_TEMPLATES_DIRECTORY + FILE_SEPARATOR + TEMPLATES_JSON_FILE); + } + + public List getVisitsWithActiveOrders(Patient patient, String orderType, Boolean includeActiveVisit, Integer numberOfVisits) { + Session currentSession = getCurrentSession(); + String includevisit = includeActiveVisit == null || !includeActiveVisit ? "and v.stopDatetime is not null and v.stopDatetime < :now" : ""; + Query queryVisitsWithDrugOrders = currentSession.createQuery("select v from " + orderType + " o, Encounter e, Visit v where o.encounter = e.encounterId and e.visit = v.visitId and v.patient = (:patientId) " + + "and o.voided = false and o.dateStopped = null and o.action != :discontinued " + includevisit + " group by v.visitId order by v.startDatetime desc"); + queryVisitsWithDrugOrders.setParameter("patientId", patient); + queryVisitsWithDrugOrders.setParameter("discontinued", Order.Action.DISCONTINUE); + if (includeActiveVisit == null || !includeActiveVisit) { + queryVisitsWithDrugOrders.setParameter("now", new Date()); + } + if (numberOfVisits != null) { + queryVisitsWithDrugOrders.setMaxResults(numberOfVisits); + } + return (List) queryVisitsWithDrugOrders.list(); + } + + public List getVisitsWithAllOrders(Patient patient, String orderType, Boolean includeActiveVisit, Integer numberOfVisits) { + Session currentSession = getCurrentSession(); + String includevisit = includeActiveVisit == null || !includeActiveVisit ? "and v.stopDatetime is not null and v.stopDatetime < :now" : ""; + Query queryVisitsWithDrugOrders = currentSession.createQuery("select v from " + orderType + " o, Encounter e, Visit v where o.encounter = e.encounterId and e.visit = v.visitId and v.patient = (:patientId) " + + "and o.voided = false " + includevisit + " group by v.visitId order by v.startDatetime desc"); + queryVisitsWithDrugOrders.setParameter("patientId", patient); + if (includeActiveVisit == null || !includeActiveVisit) { + queryVisitsWithDrugOrders.setParameter("now", new Date()); + } + if (numberOfVisits != null) { + queryVisitsWithDrugOrders.setMaxResults(numberOfVisits); + } + return (List) queryVisitsWithDrugOrders.list(); + } + + void setApplicationDataDirectory(ApplicationDataDirectory applicationDataDirectory) { + this.applicationDataDirectory = applicationDataDirectory; + } + + @Override + public List getVisitsForUUids(String[] visitUuids) { + return getCurrentSession() + .createQuery("from Visit v where v.uuid in (:visitUuids)") + .setParameterList("visitUuids", visitUuids) + .list(); + } + + private Session getCurrentSession() { + return sessionFactory.getCurrentSession(); + } + + private List getVisitIds(List visits) { + List visitIds = new ArrayList<>(); + for (Visit visit : visits) { + visitIds.add(visit.getId()); + } + return visitIds; + } + + @Override + public List getAllOrders(Patient patient, List orderTypes, Integer offset, Integer limit) { + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Order.class); + criteria.add(Restrictions.eq("patient", patient)); + + if (orderTypes != null && orderTypes.size() > 0) { + criteria.add(Restrictions.in("orderType", orderTypes)); + } + + criteria.add(Restrictions.eq("voided", false)); + criteria.add(Restrictions.isNull("dateStopped")); + criteria.add(Restrictions.ne("action", Order.Action.DISCONTINUE)); + criteria.addOrder(org.hibernate.criterion.Order.desc("dateCreated")); + if (offset != null) { + criteria.setFirstResult(offset); + } + + if (limit != null && limit > 0) { + criteria.setMaxResults(limit); + } + + return criteria.list(); + } + + @Override + public List getAllOrdersForVisits(OrderType orderType, List visits) { + if (visits == null || visits.isEmpty()) { + return new ArrayList<>(); + } + Session currentSession = getCurrentSession(); + Query queryVisitsWithDrugOrders = currentSession.createQuery(" select o from Order o where o.encounter.encounterId in\n" + + "(select e.encounterId from Encounter e where e.visit in (:visits) group by e.visit.visitId )\n" + + "and o.dateStopped = null and o.voided = false and o.orderType = (:orderTypeId) " + + "and o.action != :discontinued order by o.dateActivated desc"); + queryVisitsWithDrugOrders.setParameter("discontinued", Order.Action.DISCONTINUE); + queryVisitsWithDrugOrders.setParameter("orderTypeId", orderType); + queryVisitsWithDrugOrders.setParameterList("visits", visits); + return (List) queryVisitsWithDrugOrders.list(); + } + + @Override + public Order getOrderByUuid(String uuid) { + String queryString = "select o from Order o where o.uuid = (:uuid)"; + Query queryToGetVisitId = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetVisitId.setString("uuid", uuid); + queryToGetVisitId.setMaxResults(1); + return (Order) queryToGetVisitId.uniqueResult(); + } + + @Override + public List getOrdersForVisitUuid(String visitUuid, String orderTypeUuid) { + Session currentSession = getCurrentSession(); + Query queryVisitsWithDrugOrders = currentSession.createQuery(" select o from Order o where o.encounter.encounterId in\n" + + "(select e.encounterId from Encounter e where e.visit.uuid =:visitUuid)\n" + + "and o.voided = false and o.dateStopped = null and o.orderType.uuid = (:orderTypeUuid) and o.action != :discontinued order by o.dateActivated desc"); + queryVisitsWithDrugOrders.setParameter("orderTypeUuid", orderTypeUuid); + queryVisitsWithDrugOrders.setParameter("discontinued", Order.Action.DISCONTINUE); + queryVisitsWithDrugOrders.setParameter("visitUuid", visitUuid); + return (List) queryVisitsWithDrugOrders.list(); + } + + @Override + public List getAllOrders(Patient patientByUuid, OrderType orderType, Set conceptsForOrders, Set orderConceptsToBeExcluded, Collection encounters) { + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Order.class); + criteria.add(Restrictions.eq("patient", patientByUuid)); + if (CollectionUtils.isNotEmpty(conceptsForOrders)) { + criteria.add(Restrictions.in("concept", conceptsForOrders)); + } + if (CollectionUtils.isNotEmpty(orderConceptsToBeExcluded)) { + criteria.add(Restrictions.not(Restrictions.in("concept", orderConceptsToBeExcluded))); + } + if (CollectionUtils.isNotEmpty(encounters)) { + criteria.add(Restrictions.in("encounter", encounters)); + } + criteria.add(Restrictions.eq("orderType", orderType)); + criteria.add(Restrictions.eq("voided", false)); + criteria.add(Restrictions.ne("action", Order.Action.DISCONTINUE)); + criteria.addOrder(org.hibernate.criterion.Order.asc("orderId")); + + return criteria.list(); + + } + + public List getOrdersByPatientProgram(String patientProgramUuid, OrderType drugOrderType, Set conceptsForDrugs){ + StringBuilder queryString = new StringBuilder("select order\n" + + "from Episode as episode\n" + + " join episode.encounters as encounter\n" + + " join encounter.orders as order\n" + + " join episode.patientPrograms as patientProgram\n" + + "where patientProgram.uuid = :patientProgramUuid and order.voided = false and order.orderType= :drugOrderType and order.action != :orderAction"); + if (CollectionUtils.isNotEmpty(conceptsForDrugs)) { + queryString.append(" and order.concept in :conceptsForDrugs "); + } + Query query = sessionFactory.getCurrentSession().createQuery(queryString.toString()) + .setParameter("patientProgramUuid", patientProgramUuid) + .setParameter("drugOrderType", drugOrderType) + .setParameter("orderAction", Order.Action.DISCONTINUE); + if (CollectionUtils.isNotEmpty(conceptsForDrugs)) { + query.setParameterList("conceptsForDrugs", conceptsForDrugs); + } + return query.list(); + } + + @Override + public List getAllOrders(Patient patientByUuid, OrderType drugOrderTypeUuid, Integer offset, Integer limit, List locationUuids) { + if (CollectionUtils.isNotEmpty(locationUuids)) { + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Encounter.class, "encounter"); + criteria.createAlias("encounter.location", "location"); + criteria.add(Restrictions.in("location.uuid", locationUuids)); + criteria.add(Restrictions.eq("encounter.patient", patientByUuid)); + List encounters = criteria.list(); + if (CollectionUtils.isEmpty(encounters)) { + return new ArrayList<>(); + } + + return getAllOrders(patientByUuid, drugOrderTypeUuid, null, null, encounters); + } + return getAllOrders(patientByUuid, Arrays.asList(drugOrderTypeUuid), offset, limit); + } + + @Override + public Map getDiscontinuedDrugOrders(List drugOrders) { + + if (drugOrders == null || drugOrders.size() == 0) + return new HashMap<>(); + + Session currentSession = getCurrentSession(); + + Query query = currentSession.createQuery("select d1 from DrugOrder d1 where d1.action = :discontinued and d1.previousOrder in :drugOrderList"); + query.setParameter("discontinued", Order.Action.DISCONTINUE); + query.setParameterList("drugOrderList", drugOrders); + List discontinuedDrugOrders = query.list(); + + Map discontinuedDrugOrderMap = new HashMap<>(); + for (DrugOrder discontinuedDrugOrder : discontinuedDrugOrders) { + discontinuedDrugOrderMap.put(discontinuedDrugOrder.getPreviousOrder().getOrderNumber(), discontinuedDrugOrder); + } + + return discontinuedDrugOrderMap; + } + + @Override + public List getActiveOrders(Patient patient, OrderType orderType, CareSetting careSetting, Date asOfDate, + Set conceptsToFilter, Set conceptsToExclude, Date startDate, Date endDate, Collection encounters) { + if (patient == null) { + throw new IllegalArgumentException("Patient is required when fetching active orders"); + } + if (asOfDate == null) { + asOfDate = new Date(); + } + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Order.class); + criteria.add(Restrictions.eq("patient", patient)); + if (CollectionUtils.isNotEmpty(encounters)) { + criteria.add(Restrictions.in("encounter", encounters)); + } + if (careSetting != null) { + criteria.add(Restrictions.eq("careSetting", careSetting)); + } + + if (CollectionUtils.isNotEmpty(conceptsToFilter)) { + criteria.add(Restrictions.in("concept", conceptsToFilter)); + } + if (CollectionUtils.isNotEmpty(conceptsToExclude)) { + criteria.add(Restrictions.not(Restrictions.in("concept", conceptsToExclude))); + } + criteria.add(Restrictions.eq("orderType", orderType)); + criteria.add(Restrictions.le("dateActivated", asOfDate)); + criteria.add(Restrictions.eq("voided", false)); + criteria.add(Restrictions.ne("action", Order.Action.DISCONTINUE)); + if (startDate != null) { + criteria.add(Restrictions.or(Restrictions.ge("scheduledDate", startDate), Restrictions.ge("autoExpireDate", startDate))); + if (endDate == null) { + endDate = new Date(); + } + criteria.add(Restrictions.le("scheduledDate", endDate)); + } + + Disjunction dateStoppedAndAutoExpDateDisjunction = Restrictions.disjunction(); + Criterion stopAndAutoExpDateAreBothNull = Restrictions.and(Restrictions.isNull("dateStopped"), Restrictions + .isNull("autoExpireDate")); + dateStoppedAndAutoExpDateDisjunction.add(stopAndAutoExpDateAreBothNull); + Criterion autoExpireDateEqualToOrAfterAsOfDate = Restrictions.and(Restrictions.isNull("dateStopped"), Restrictions.ge("autoExpireDate", asOfDate)); + + dateStoppedAndAutoExpDateDisjunction.add(autoExpireDateEqualToOrAfterAsOfDate); + + dateStoppedAndAutoExpDateDisjunction.add(Restrictions.ge("dateStopped", asOfDate)); + + criteria.add(dateStoppedAndAutoExpDateDisjunction); + + return criteria.list(); + } + + @Override + public List getInactiveOrders(Patient patient, OrderType orderType, CareSetting careSetting, Date asOfDate, + Set concepts, Set conceptsToExclude, Collection encounters) { + if (patient == null) { + throw new IllegalArgumentException("Patient is required when fetching active orders"); + } + if (asOfDate == null) { + asOfDate = new Date(); + } + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Order.class); + criteria.add(Restrictions.eq("patient", patient)); + if (CollectionUtils.isNotEmpty(encounters)) { + criteria.add(Restrictions.in("encounter", encounters)); + } + + if (careSetting != null) { + criteria.add(Restrictions.eq("careSetting", careSetting)); + } + + if (concepts != null || CollectionUtils.isNotEmpty(concepts)) { + criteria.add(Restrictions.in("concept", concepts)); + } + if (CollectionUtils.isNotEmpty(conceptsToExclude)) { + criteria.add(Restrictions.not(Restrictions.in("concept", conceptsToExclude))); + } + criteria.add(Restrictions.eq("orderType", orderType)); + criteria.add(Restrictions.eq("voided", false)); + criteria.add(Restrictions.ne("action", Order.Action.DISCONTINUE)); + + Disjunction dateStoppedAndAutoExpDateDisjunction = Restrictions.disjunction(); + Criterion isStopped = Restrictions.and(Restrictions.isNotNull("dateStopped"), + Restrictions.le("dateStopped", asOfDate)); + dateStoppedAndAutoExpDateDisjunction.add(isStopped); + + Criterion isAutoExpired = Restrictions.and(Restrictions.isNull("dateStopped"), Restrictions + .le("autoExpireDate", asOfDate)); + dateStoppedAndAutoExpDateDisjunction.add(isAutoExpired); + + + criteria.add(dateStoppedAndAutoExpDateDisjunction); + + return criteria.list(); + } + + @Override + public Order getChildOrder(Order order) { + Session currentSession = getCurrentSession(); + Query query = currentSession.createQuery("select o from Order o where o.previousOrder = :order and o.voided = false"); + query.setParameter("order", order); + return (Order) query.uniqueResult(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/PersonAttributeDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/PersonAttributeDaoImpl.java new file mode 100644 index 0000000000..29eba03c65 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/PersonAttributeDaoImpl.java @@ -0,0 +1,29 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.PersonAttributeDao; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.hibernate.SQLQuery; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class PersonAttributeDaoImpl implements PersonAttributeDao { + + @Autowired + private SessionFactory sessionFactory; + + @Override + public ResultList getUnique(String personAttribute, String query) { + SQLQuery sqlQuery = sessionFactory + .getCurrentSession() + .createSQLQuery( + "Select distinct value from person_attribute, person_attribute_type " + + "where person_attribute.person_attribute_type_id = person_attribute_type.person_attribute_type_id " + + "and person_attribute_type.name = :name and lower(person_attribute.value) like :value order by value asc"); + sqlQuery.setParameter("name", personAttribute); + sqlQuery.setParameter("value", query.toLowerCase() + "%"); + sqlQuery.setMaxResults(20); + return new ResultList(sqlQuery.list()); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/PersonNameDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/PersonNameDaoImpl.java new file mode 100644 index 0000000000..4de218eacc --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/PersonNameDaoImpl.java @@ -0,0 +1,28 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.PersonNameDao; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.hibernate.Criteria; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Projections; +import org.hibernate.criterion.Restrictions; +import org.openmrs.PersonName; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class PersonNameDaoImpl implements PersonNameDao { + + @Autowired + private SessionFactory sessionFactory; + + @SuppressWarnings("unchecked") + @Override + public ResultList getUnique(String key, String query) { + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PersonName.class); + criteria.add(Restrictions.ilike(key, query + "%")); + criteria.setProjection(Projections.distinct(Projections.property(key))); + criteria.setMaxResults(20); + return new ResultList(criteria.list()); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/VisitDaoImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/VisitDaoImpl.java new file mode 100644 index 0000000000..2ccb984524 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/dao/impl/VisitDaoImpl.java @@ -0,0 +1,85 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.hibernate.Criteria; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; + +@Repository +public class VisitDaoImpl implements VisitDao { + + @Autowired + private SessionFactory sessionFactory; + + @Override + public Visit getLatestVisit(String patientUuid, String conceptName) { + String queryString = "select v\n" + + "from Obs obs join obs.encounter enc join enc.visit v, ConceptName cn \n" + + "where cn.concept.conceptId = obs.concept.conceptId and cn.name=:conceptName and cn.conceptNameType='FULLY_SPECIFIED' and obs.person.uuid=:patientUuid\n" + + "order by v.startDatetime desc"; + Query queryToGetVisitId = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetVisitId.setString("conceptName", conceptName); + queryToGetVisitId.setString("patientUuid", patientUuid); + queryToGetVisitId.setMaxResults(1); + + return (Visit) queryToGetVisitId.uniqueResult(); + } + + @Override + public Visit getVisitSummary(String visitUuid) { + String queryString = "select v from Visit v where v.uuid=:visitUuid and v.voided=false"; + Query queryToGetVisitInfo = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetVisitInfo.setString("visitUuid", visitUuid); + return (Visit) queryToGetVisitInfo.uniqueResult(); + } + + + @Override + public List getAdmitAndDischargeEncounters(Integer visitId) { + String queryString = "select e from Encounter e where e.visit.id = :visitId and e.voided=false and e.encounterType.name in ('ADMISSION', 'DISCHARGE')"; + Query queryToGetVisitInfo = sessionFactory.getCurrentSession().createQuery(queryString); + queryToGetVisitInfo.setInteger("visitId", visitId); + return (List) queryToGetVisitInfo.list(); + } + + @Override + public List getVisitsByPatient(Patient patient, int numberOfVisits) { + if (patient == null || numberOfVisits <= 0) { + return new ArrayList<>(); + } + + Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Visit.class); + criteria.add(Restrictions.eq("patient", patient)); + criteria.add(Restrictions.eq("voided", false)); + criteria.addOrder(Order.desc("startDatetime")); + criteria.addOrder(Order.desc("visitId")); + criteria.setMaxResults(numberOfVisits); + List visits = criteria.list(); + + return visits; + } + + public List getVisitIdsFor(String patientUuid, Integer numberOfVisits) { + Query queryToGetVisitIds = sessionFactory.getCurrentSession().createQuery( + "select v.visitId " + + " from Visit as v " + + " where v.patient.uuid = :patientUuid " + + " and v.voided = false " + + "order by v.startDatetime desc"); + queryToGetVisitIds.setString("patientUuid", patientUuid); + if (numberOfVisits != null) { + queryToGetVisitIds.setMaxResults(numberOfVisits); + } + return queryToGetVisitIds.list(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/datamigration/ExecutionMode.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/datamigration/ExecutionMode.java new file mode 100644 index 0000000000..54e963b662 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/datamigration/ExecutionMode.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.datamigration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.ApplicationError; +import org.bahmni.module.bahmnicore.BahmniCoreException; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.model.error.ErrorCode; +import org.bahmni.module.bahmnicore.model.error.ErrorMessage; + +public class ExecutionMode { + private final boolean dataMigrationMode; + private static Logger logger = LogManager.getLogger(ExecutionMode.class); + + public ExecutionMode(String dataMigrationProperty) { + dataMigrationMode = !(dataMigrationProperty == null || !Boolean.parseBoolean(dataMigrationProperty)); + } + + private void handleFailure(BahmniPatient bahmniPatient, ApplicationError applicationError) { + if (!dataMigrationMode) { + throw applicationError; + } + + if (ErrorCode.duplicationError(applicationError.getErrorCode())) + logger.warn(applicationError.getMessage(), bahmniPatient.getIdentifier()); + else + throw applicationError; + } + + public void handleSavePatientFailure(RuntimeException e, BahmniPatient bahmniPatient) { + if(e.getMessage() != null){ + int errorCode = e.getMessage().contains(ErrorMessage.ExistingPatientMessagePart) ? ErrorCode.DuplicatePatient : ErrorCode.OpenMRSError; + BahmniCoreException bahmniCoreException = new BahmniCoreException("Create patient failed", e); + bahmniCoreException.setErrorCode(errorCode); + handleFailure(bahmniPatient, bahmniCoreException); + } + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterModifier/EncounterModifier.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterModifier/EncounterModifier.java new file mode 100644 index 0000000000..30be803af0 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterModifier/EncounterModifier.java @@ -0,0 +1,8 @@ +package org.bahmni.module.bahmnicore.encounterModifier; + +import org.bahmni.module.bahmnicore.contract.encounter.data.EncounterModifierData; +import org.bahmni.module.bahmnicore.encounterModifier.exception.CannotModifyEncounterException; + +public abstract class EncounterModifier { + public abstract EncounterModifierData run(EncounterModifierData encounterModifierData) throws CannotModifyEncounterException; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterModifier/exception/CannotModifyEncounterException.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterModifier/exception/CannotModifyEncounterException.java new file mode 100644 index 0000000000..41178c2819 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterModifier/exception/CannotModifyEncounterException.java @@ -0,0 +1,4 @@ +package org.bahmni.module.bahmnicore.encounterModifier.exception; + +public class CannotModifyEncounterException extends Exception { +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommand.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommand.java new file mode 100644 index 0000000000..f455f9a1c9 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommand.java @@ -0,0 +1,48 @@ +package org.bahmni.module.bahmnicore.encounterTransaction.command; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.openmrs.Encounter; +import org.openmrs.PatientProgram; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.EncounterDataPostSaveCommand; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class EpisodeEncounterCreateCommand implements EncounterDataPostSaveCommand { + + private EpisodeService episodeService; + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + + @Autowired + public EpisodeEncounterCreateCommand(EpisodeService episodeService, BahmniProgramWorkflowService bahmniProgramWorkflowService) { + this.episodeService = episodeService; + this.bahmniProgramWorkflowService = bahmniProgramWorkflowService; + } + + @Override + public EncounterTransaction save(BahmniEncounterTransaction bahmniEncounterTransaction, Encounter currentEncounter, EncounterTransaction updatedEncounterTransaction) { + if (!bahmniEncounterTransaction.isAssociatedToPatientProgram()) return updatedEncounterTransaction; + + PatientProgram patientProgram = bahmniProgramWorkflowService.getPatientProgramByUuid(bahmniEncounterTransaction.getPatientProgramUuid()); + Episode episode = getOrCreateEpisodeForPatientProgram(patientProgram); + episode.addEncounter(currentEncounter); + episodeService.save(episode); + return updatedEncounterTransaction; + } + + private Episode getOrCreateEpisodeForPatientProgram(PatientProgram patientProgram) { + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + return episode != null ? episode : createEpisode(patientProgram); + } + + private Episode createEpisode(PatientProgram patientProgram) { + Episode episode; + episode = new Episode(); + episode.addPatientProgram(patientProgram); + return episode; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java new file mode 100644 index 0000000000..1681c1e017 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEvent.java @@ -0,0 +1,26 @@ +package org.bahmni.module.bahmnicore.events; + +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class BahmniEvent { + + private static final long version = 1L; + public UserContext userContext; + public String eventId; + public BahmniEventType eventType; + public String payloadId; + public LocalDateTime publishedDateTime; + + public BahmniEvent(BahmniEventType bahmniEventType) { + this.eventType = bahmniEventType; + this.eventId = UUID.randomUUID().toString(); + this.publishedDateTime = LocalDateTime.now(); + this.userContext= Context.getUserContext(); + this.payloadId=""; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java new file mode 100644 index 0000000000..0f2dd642ce --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/BahmniEventType.java @@ -0,0 +1,16 @@ +package org.bahmni.module.bahmnicore.events; + +public enum BahmniEventType { + BAHMNI_PATIENT_CREATED("bahmni-patient"), + BAHMNI_PATIENT_UPDATED("bahmni-patient"), + BAHMNI_ENCOUNTER_CREATED("bahmni-encounter"), + BAHMNI_ENCOUNTER_UPDATED("bahmni-encounter"); + + private final String topic; + BahmniEventType(String topic) { + this.topic = topic; + } + public String topic() { + return topic; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java new file mode 100644 index 0000000000..a3b0107902 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/EncounterEvent.java @@ -0,0 +1,19 @@ +package org.bahmni.module.bahmnicore.events; + +import org.openmrs.Encounter; + +public class EncounterEvent extends BahmniEvent { + + private Encounter encounter; + + public EncounterEvent(BahmniEventType bahmniEventType, Encounter encounter) { + super(bahmniEventType); + this.encounter = encounter; + this.payloadId=encounter.getUuid(); + } + + public Encounter getEncounter() { + return encounter; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java new file mode 100644 index 0000000000..dba79af640 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/PatientEvent.java @@ -0,0 +1,24 @@ +package org.bahmni.module.bahmnicore.events; + +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class PatientEvent extends BahmniEvent { + + private Patient patient; + + public PatientEvent(BahmniEventType bahmniEventType, Patient patient) { + super(bahmniEventType); + this.patient = patient; + this.payloadId=patient.getUuid(); + } + + public Patient getPatient() { + return patient; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java new file mode 100644 index 0000000000..649a21f563 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/EncounterAdvice.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.events.advice; + +import com.google.common.collect.Sets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.events.BahmniEventType; +import org.bahmni.module.bahmnicore.events.EncounterEvent; +import org.bahmni.module.bahmnicore.events.eventPublisher.BahmniEventPublisher; +import org.openmrs.Encounter; +import org.openmrs.api.context.Context; +import org.springframework.aop.AfterReturningAdvice; +import org.springframework.aop.MethodBeforeAdvice; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_ENCOUNTER_CREATED; +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_ENCOUNTER_UPDATED; + + +public class EncounterAdvice implements AfterReturningAdvice, MethodBeforeAdvice { + + private final Logger log = LogManager.getLogger(this.getClass()); + private final BahmniEventPublisher eventPublisher; + private final ThreadLocal> threadLocal = new ThreadLocal<>(); + private final String ENCOUNTER_ID_KEY = "encounterId"; + private final Set adviceMethodNames = Sets.newHashSet("saveEncounter"); + + public EncounterAdvice() { + this.eventPublisher = Context.getRegisteredComponent("bahmniEventPublisher", BahmniEventPublisher.class); + } + + @Override + public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) { + if (adviceMethodNames.contains(method.getName())) { + Map encounterInfo = threadLocal.get(); + if (encounterInfo != null) { + BahmniEventType eventType = encounterInfo.get(ENCOUNTER_ID_KEY) == null ? BAHMNI_ENCOUNTER_CREATED : BAHMNI_ENCOUNTER_UPDATED; + threadLocal.remove(); + + Encounter encounter = (Encounter) returnValue; + EncounterEvent encounterEvent = new EncounterEvent(eventType, encounter); + eventPublisher.publishEvent(encounterEvent); + + log.info("Successfully published event with uuid : " + encounter.getUuid()); + } + } + } + + @Override + public void before(Method method, Object[] objects, Object o) { + if (adviceMethodNames.contains(method.getName())) { + Encounter encounter = (Encounter) objects[0]; + Map encounterInfo = new HashMap<>(1); + encounterInfo.put(ENCOUNTER_ID_KEY, encounter.getId()); + threadLocal.set(encounterInfo); + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java new file mode 100644 index 0000000000..50bbd77e02 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/advice/PatientAdvice.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.events.advice; + +import com.google.common.collect.Sets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.events.BahmniEventType; +import org.bahmni.module.bahmnicore.events.PatientEvent; +import org.bahmni.module.bahmnicore.events.eventPublisher.BahmniEventPublisher; +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.springframework.aop.AfterReturningAdvice; +import org.springframework.aop.MethodBeforeAdvice; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_PATIENT_CREATED; +import static org.bahmni.module.bahmnicore.events.BahmniEventType.BAHMNI_PATIENT_UPDATED; + + +public class PatientAdvice implements AfterReturningAdvice, MethodBeforeAdvice { + + private final Logger log = LogManager.getLogger(PatientAdvice.class); + private final BahmniEventPublisher eventPublisher; + private final ThreadLocal> threadLocal = new ThreadLocal<>(); + private final String PATIENT_ID_KEY = "patientId"; + private final Set adviceMethodNames = Sets.newHashSet("savePatient"); + + public PatientAdvice() { + this.eventPublisher = Context.getRegisteredComponent("bahmniEventPublisher", BahmniEventPublisher.class); + } + + @Override + public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) { + if (adviceMethodNames.contains(method.getName())) { + Map patientInfo = threadLocal.get(); + if (patientInfo != null) { + BahmniEventType eventType = patientInfo.get(PATIENT_ID_KEY) == null ? BAHMNI_PATIENT_CREATED : BAHMNI_PATIENT_UPDATED; + threadLocal.remove(); + + Patient patient = (Patient) returnValue; + PatientEvent patientEvent =new PatientEvent(eventType,patient); + eventPublisher.publishEvent(patientEvent); + + log.info("Successfully published event with uuid : " + patient.getUuid()); + } + } + } + @Override + public void before(Method method, Object[] objects, Object o) { + if (adviceMethodNames.contains(method.getName())) { + Patient patient = (Patient) objects[0]; + + Map patientInfo = new HashMap<>(1); + patientInfo.put(PATIENT_ID_KEY, patient.getId()); + threadLocal.set(patientInfo); + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java new file mode 100644 index 0000000000..0a527134a8 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventListener/PatientSmsEventListener.java @@ -0,0 +1,78 @@ +package org.bahmni.module.bahmnicore.events.eventListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.events.BahmniEventType; +import org.bahmni.module.bahmnicore.events.PatientEvent; +import org.bahmni.module.communication.service.CommunicationService; +import org.bahmni.module.communication.service.MessageBuilderService; +import org.openmrs.Patient; +import org.openmrs.PersonAttribute; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class PatientSmsEventListener { + + private final Log log = LogFactory.getLog(this.getClass()); + + + @Async("BahmniAsyncThreadExecutor") + @EventListener + public void onApplicationEvent(PatientEvent event) { + try { + Context.openSession(); + Context.setUserContext(event.userContext); + if (event.eventType == BahmniEventType.BAHMNI_PATIENT_CREATED) { + handlePatientCreatedEvent(event.getPatient()); + } + } catch(Exception e){ + log.error("Exception occurred during event processing", e); + } finally{ + Context.closeSession(); + } + } + + private void handlePatientCreatedEvent(Patient patient) { + AdministrationService administrationService = Context.getService(AdministrationService.class); + boolean patientRegistrationSMSProperty = Boolean.parseBoolean(administrationService.getGlobalProperty("sms.enableRegistrationSMSAlert","false")); + if (!patientRegistrationSMSProperty) + return; + String phoneNumber = getPhoneNumber(patient); + if (phoneNumber != null) { + MessageBuilderService messageBuilderService = Context.getRegisteredComponent("messageBuilderService", MessageBuilderService.class); + CommunicationService communicationService = Context.getRegisteredComponent("communicationService", CommunicationService.class); + String message=messageBuilderService.getRegistrationMessage(createArgumentsMapForPatientRegistration(patient)); + communicationService.sendSMS(phoneNumber, message); + } + } + + public Map createArgumentsMapForPatientRegistration(Patient patient) { + String helpdeskNumber = Context.getAdministrationService().getGlobalPropertyObject("clinic.helpDeskNumber").getPropertyValue(); + Map arguments = new HashMap<>(); + arguments.put("location", Context.getUserContext().getLocation().getName()); + arguments.put("identifier", patient.getPatientIdentifier().getIdentifier()); + arguments.put("patientname", patient.getGivenName() + " " + patient.getFamilyName()); + arguments.put("gender", patient.getGender()); + arguments.put("age", patient.getAge().toString()); + arguments.put("helpdesknumber", helpdeskNumber); + return arguments; + } + + private String getPhoneNumber(Patient patient) { + PersonAttribute phoneNumber = patient.getAttribute("phoneNumber"); + if (phoneNumber == null) { + log.info("No mobile number found for the patient. SMS not sent."); + return null; + } + return phoneNumber.getValue(); + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java new file mode 100644 index 0000000000..0ff4b9bdbb --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/events/eventPublisher/BahmniEventPublisher.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.events.eventPublisher; + +import org.bahmni.module.bahmnicore.events.BahmniEvent; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; + +@Component +public class BahmniEventPublisher implements ApplicationEventPublisherAware { + + private ApplicationEventPublisher eventPublisher; + + @Override + public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) { + this.eventPublisher = applicationEventPublisher; + } + public void publishEvent(BahmniEvent event) { + this.eventPublisher.publishEvent(event); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/extensions/BahmniExtensions.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/extensions/BahmniExtensions.java new file mode 100644 index 0000000000..dd6e2f1d9b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/extensions/BahmniExtensions.java @@ -0,0 +1,45 @@ +package org.bahmni.module.bahmnicore.extensions; + +import groovy.lang.GroovyClassLoader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.dao.ApplicationDataDirectory; +import org.bahmni.module.bahmnicore.dao.impl.ApplicationDataDirectoryImpl; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; + +@Component +public class BahmniExtensions { + + private static final Logger log = LogManager.getLogger(BahmniExtensions.class); + public static final String GROOVY_EXTENSION = ".groovy"; + + private GroovyClassLoader groovyClassLoader; + + private ApplicationDataDirectory applicationDataDirectory; + + public BahmniExtensions() { + groovyClassLoader = new GroovyClassLoader(); + applicationDataDirectory = new ApplicationDataDirectoryImpl(); + } + + public Object getExtension(String directory, String fileName) { + File groovyFile = applicationDataDirectory + .getFileFromConfig("openmrs" + File.separator + directory + File.separator + fileName); + if (!groovyFile.exists()) { + log.error("File not found " + groovyFile.getAbsolutePath()); + } else { + try { + Class clazz = groovyClassLoader.parseClass(groovyFile); + return clazz.newInstance(); + } catch (IOException | IllegalAccessException e) { + log.error("Problem with the groovy class " + groovyFile, e); + } catch (InstantiationException e) { + log.error("The groovy class " + groovyFile + " cannot be instantiated", e); + } + } + return null; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/extensions/MonthCalculationExtension.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/extensions/MonthCalculationExtension.java new file mode 100644 index 0000000000..50ca86b063 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/extensions/MonthCalculationExtension.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.extensions; + +import org.openmrs.module.bahmniemrapi.drugogram.contract.BaseTableExtension; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; + +public class MonthCalculationExtension extends BaseTableExtension { + + @Override + public void update(TreatmentRegimen treatmentRegimen, String patientUuid, String patientProgramUuid) { + // Do nothing + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/contract/FormDetails.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/contract/FormDetails.java new file mode 100644 index 0000000000..a56718fe77 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/contract/FormDetails.java @@ -0,0 +1,116 @@ +package org.bahmni.module.bahmnicore.forms2.contract; + +import org.bahmni.module.bahmnicore.model.Provider; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +public class FormDetails { + + private String formType; + private String formName; + private int formVersion; + private String visitUuid; + private Date visitStartDateTime; + private String encounterUuid; + private Date encounterDateTime; + private Set providers; + + public String getFormType() { + return formType; + } + + public void setFormType(String formType) { + this.formType = formType; + } + + public String getFormName() { + return formName; + } + + public void setFormName(String formName) { + this.formName = formName; + } + + public int getFormVersion() { + return formVersion; + } + + public void setFormVersion(int formVersion) { + this.formVersion = formVersion; + } + + public String getVisitUuid() { + return visitUuid; + } + + public void setVisitUuid(String visitUuid) { + this.visitUuid = visitUuid; + } + + public Date getVisitStartDateTime() { + return visitStartDateTime; + } + + public void setVisitStartDateTime(Date visitStartDateTime) { + this.visitStartDateTime = visitStartDateTime; + } + + public String getEncounterUuid() { + return encounterUuid; + } + + public void setEncounterUuid(String encounterUuid) { + this.encounterUuid = encounterUuid; + } + + public Date getEncounterDateTime() { + return encounterDateTime; + } + + public void setEncounterDateTime(Date encounterDateTime) { + this.encounterDateTime = encounterDateTime; + } + + public Set getProviders() { + return providers; + } + + public void setProviders(Set providers) { + this.providers = providers; + } + + public void addProvider(String providerName, String providerUuid) { + if (providers == null) { + this.providers = new HashSet<>(); + } + Provider provider = new Provider(); + provider.setProviderName(providerName); + provider.setUuid(providerUuid); + + this.providers.add(provider); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof FormDetails)) { + return false; + } + FormDetails formDetails = (FormDetails) obj; + return this.formName.equals(formDetails.getFormName()) + && this.formVersion == formDetails.formVersion + && this.encounterUuid.equals(formDetails.encounterUuid); + } + + @Override + public int hashCode() { + int result = this.formName != null ? this.formName.hashCode() : 0; + result += 31 * result + this.formVersion; + result += 31 * result + (this.encounterUuid != null ? this.encounterUuid.hashCode() : 0); + return result; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/contract/FormType.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/contract/FormType.java new file mode 100644 index 0000000000..4df6135f58 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/contract/FormType.java @@ -0,0 +1,26 @@ +package org.bahmni.module.bahmnicore.forms2.contract; + +public enum FormType { + + FORMS1("v1"), FORMS2("v2"); + + private final String type; + + FormType(String type) { + this.type = type; + } + + + public static FormType valueOfType(String value) { + for(FormType v : values()) { + if (v.type.equalsIgnoreCase(value)) return v; + } + throw new IllegalArgumentException(); + } + + public String getType() { + return this.type; + } + + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/mapper/FormDetailsMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/mapper/FormDetailsMapper.java new file mode 100644 index 0000000000..528e611f77 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/mapper/FormDetailsMapper.java @@ -0,0 +1,58 @@ +package org.bahmni.module.bahmnicore.forms2.mapper; + +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.util.FormUtil; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.User; +import org.openmrs.Visit; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +public class FormDetailsMapper { + + public static Collection createFormDetails(List observations, FormType formType) { + HashMap formDetailsMap = new HashMap<>(); + observations.forEach(obs -> { + FormDetails formDetails = FormDetailsMapper.map(obs, formType); + addMultipleProvidersOfAForm(formDetailsMap, formDetails); + }); + return formDetailsMap.keySet(); + } + + private static FormDetails map(Obs obs, FormType formType) { + + Encounter encounter = obs.getEncounter(); + Visit visit = encounter.getVisit(); + User creator = obs.getCreator(); + + FormDetails formDetails = new FormDetails(); + + formDetails.setFormType(formType.getType()); + if (formType.equals(FormType.FORMS2)) { + formDetails.setFormName(FormUtil.getFormNameFromFieldPath(obs.getFormFieldPath())); + formDetails.setFormVersion(FormUtil.getFormVersionFromFieldPath(obs.getFormFieldPath())); + } else if (formType.equals(FormType.FORMS1)) { + formDetails.setFormName(obs.getConcept().getName().getName()); + } + formDetails.setEncounterUuid(encounter.getUuid()); + formDetails.setEncounterDateTime(encounter.getEncounterDatetime()); + formDetails.setVisitUuid(visit.getUuid()); + formDetails.setVisitStartDateTime(visit.getStartDatetime()); + formDetails.addProvider(creator.getPersonName().getFullName(), creator.getUuid()); + return formDetails; + } + + private static void addMultipleProvidersOfAForm(HashMap formDetailsMap, FormDetails formDetails) { + if (formDetailsMap.containsKey(formDetails)) { + formDetails.getProviders().forEach(provider -> + formDetailsMap.get(formDetails).addProvider(provider.getProviderName(), provider.getUuid())); + } else { + formDetailsMap.put(formDetails, formDetails); + } + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/BahmniFormDetailsService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/BahmniFormDetailsService.java new file mode 100644 index 0000000000..f6913a8a4e --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/BahmniFormDetailsService.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.forms2.service; + +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.contract.FormType; + +import java.util.Collection; + +public interface BahmniFormDetailsService { + Collection getFormDetails(String patientUuid, FormType formType, int numberOfVisits); + + Collection getFormDetails(String patientUuid, FormType formType, String visitUuid, String patientProgramUuid); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java new file mode 100644 index 0000000000..cb09203f9c --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImpl.java @@ -0,0 +1,130 @@ +package org.bahmni.module.bahmnicore.forms2.service.impl; + +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.service.BahmniFormDetailsService; +import org.bahmni.module.bahmnicore.forms2.util.FormUtil; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.service.BahmniVisitService; +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.ObsService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.parameter.EncounterSearchCriteria; +import org.openmrs.parameter.EncounterSearchCriteriaBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.Collections.singletonList; +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; +import static org.bahmni.module.bahmnicore.forms2.mapper.FormDetailsMapper.createFormDetails; + +@Service +public class BahmniFormDetailsServiceImpl implements BahmniFormDetailsService { + + private final VisitService visitService; + private final PatientService patientService; + private final EncounterService encounterService; + private final ObsService obsService; + private BahmniVisitService bahmniVisitService; + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + + @Autowired + public BahmniFormDetailsServiceImpl(PatientService patientService, VisitService visitService, + EncounterService encounterService, ObsService obsService, + BahmniVisitService bahmniVisitService, + BahmniProgramWorkflowService bahmniProgramWorkflowService) { + this.visitService = visitService; + this.patientService = patientService; + this.encounterService = encounterService; + this.obsService = obsService; + this.bahmniVisitService = bahmniVisitService; + this.bahmniProgramWorkflowService = bahmniProgramWorkflowService; + } + + @Override + public Collection getFormDetails(String patientUuid, FormType formType, int numberOfVisits) { + Patient patient = getPatient(patientUuid); + List visits = visitService.getVisitsByPatient(patient); + + //Warning: This check is needed to avoid getEncounters returning ALL non-voided encounters of all patients leading to OutOfMemoryError:Java Heap + //Refer: https://bahmni.atlassian.net/browse/BAH-3513 + if(visits.isEmpty()) + return Collections.emptyList(); + + List limitedVisits = limitVisits(visits, numberOfVisits); + + List encounters = getEncounters(limitedVisits); + + if (isNotEmpty(encounters) && isNotEmpty(limitedVisits)) { + return getFormDetails(patient, encounters, formType); + } + return Collections.emptyList(); + } + + private Patient getPatient(String patientUuid) { + Patient patient = patientService.getPatientByUuid(patientUuid); + if (patient == null) { + throw new InvalidParameterException("Patient does not exist"); + } + return patient; + } + + private List getEncounters(List visits) { + EncounterSearchCriteria encounterSearchCriteria = new EncounterSearchCriteriaBuilder() + .setVisits(visits).createEncounterSearchCriteria(); + return encounterService.getEncounters(encounterSearchCriteria); + } + + private Collection getFormDetails(Patient patient, List encounters, FormType formType) { + Collection formDetails = new ArrayList<>(); + List observations = obsService.getObservations(singletonList(patient.getPerson()), encounters, + null, null, null, null, null, null, null, null, null, false); + if (FormType.FORMS2.equals(formType) || (formType == null)) { + formDetails = createFormDetails(FormUtil.filterFormBuilderObs(observations), FormType.FORMS2); + } + return formDetails; + } + + @Override + public Collection getFormDetails(String patientUuid, FormType formType, String visitUuid, + String patientProgramUuid) { + Patient patient = getPatient(patientUuid); + Visit visit = bahmniVisitService.getVisitSummary(visitUuid); + List encountersByVisitUuid = getEncounters(singletonList(visit)); + + Collection encountersByPatientProgramUuid = bahmniProgramWorkflowService + .getEncountersByPatientProgramUuid(patientProgramUuid); + + if (isNotEmpty(encountersByVisitUuid) && isNotEmpty(encountersByPatientProgramUuid)) { + List encountersByPatientProgramUuidAndVisitUuid = encountersByPatientProgramUuid.stream() + .filter(encounter -> encounter.getVisit().equals(visit)).collect(Collectors.toList()); + return getFormDetails(patient, encountersByPatientProgramUuidAndVisitUuid, formType); + } else if (isNotEmpty(encountersByVisitUuid)) { + return getFormDetails(patient, encountersByVisitUuid, formType); + } else if (isNotEmpty(encountersByPatientProgramUuid)) { + return getFormDetails(patient, new ArrayList<>(encountersByPatientProgramUuid), formType); + } + return Collections.emptyList(); + } + + private List limitVisits(List visits, int numberOfVisits) { + if (numberOfVisits <= -1) { + return visits; + } + return visits.size() > numberOfVisits ? visits.subList(0, numberOfVisits) : visits; + } + + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/util/FormUtil.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/util/FormUtil.java new file mode 100644 index 0000000000..a88220057e --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/forms2/util/FormUtil.java @@ -0,0 +1,36 @@ +package org.bahmni.module.bahmnicore.forms2.util; + +import org.openmrs.Obs; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +public class FormUtil { + + public static String getFormNameFromFieldPath(String formFieldPath) { + return isNotBlank(formFieldPath) && formFieldPath.contains(".") ? + formFieldPath.substring(0, formFieldPath.indexOf(".")) : ""; + } + + public static int getFormVersionFromFieldPath(String formFieldPath) { + String formVersion = ""; + if (isNotBlank(formFieldPath) && formFieldPath.contains(".") && formFieldPath.contains("/")) { + formVersion = formFieldPath.substring(formFieldPath.indexOf(".") + 1, formFieldPath.indexOf("/")); + } + return isNotBlank(formVersion) ? Integer.parseInt(formVersion) : 0; + } + + public static List filterFormBuilderObs(List observations) { + return observations != null ? observations.stream().filter(obs -> isNotBlank(obs.getFormFieldPath())) + .collect(Collectors.toList()) : Collections.emptyList(); + } + + public static String getParentFormFieldPath(String formFieldPath) { + return isNotBlank(formFieldPath) && formFieldPath.contains("/") + ? formFieldPath.substring(0, formFieldPath.lastIndexOf("/")) : ""; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/AddressMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/AddressMapper.java new file mode 100644 index 0000000000..e7bd827445 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/AddressMapper.java @@ -0,0 +1,83 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniAddress; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.openmrs.Patient; +import org.openmrs.PersonAddress; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; + +@Component +public class AddressMapper { + + public Patient map(Patient patient, List addresses) { + PersonAddress personAddress = getNonVoidedAddress(patient); + + if (personAddress == null) { + personAddress = new PersonAddress(); + populateAddress(personAddress, addresses); + patient.addAddress(personAddress); + } else { + populateAddress(personAddress, addresses); + } + + return patient; + } + + private PersonAddress getNonVoidedAddress(Patient patient) { + PersonAddress personAddress = null; + Set patientAddresses = patient.getAddresses(); + for (PersonAddress address : patientAddresses) { + if (!address.isVoided()) personAddress = address; + } + return personAddress; + } + + private void populateAddress(PersonAddress personAddress1, List addresses) { + PersonAddress personAddress = personAddress1; + + for (BahmniAddress address : addresses) { + personAddress.setAddress1(address.getAddress1()); + personAddress.setAddress2(address.getAddress2()); + personAddress.setAddress3(address.getAddress3()); + personAddress.setAddress4(address.getAddress4()); + personAddress.setAddress5(address.getAddress5()); + personAddress.setAddress6(address.getAddress6()); + personAddress.setCityVillage(address.getCityVillage()); + personAddress.setCountyDistrict(address.getCountyDistrict()); + personAddress.setStateProvince(address.getStateProvince()); + personAddress.setPostalCode(address.getPostalCode()); + personAddress.setCountry(address.getCountry()); + personAddress.setLatitude(address.getLatitude()); + personAddress.setLongitude(address.getLongitude()); + personAddress.setPreferred(true); + } + } + + public BahmniPatient mapFromPatient(BahmniPatient bahmniPatient, Patient patient) { + if(bahmniPatient == null){ + bahmniPatient = new BahmniPatient(); + } + PersonAddress personAddress = patient.getPersonAddress(); + if(personAddress != null){ + BahmniAddress bahmniAddress = new BahmniAddress(); + bahmniAddress.setAddress1(personAddress.getAddress1()); + bahmniAddress.setAddress2(personAddress.getAddress2()); + bahmniAddress.setAddress3(personAddress.getAddress3()); + bahmniAddress.setAddress4(personAddress.getAddress4()); + bahmniAddress.setAddress5(personAddress.getAddress5()); + bahmniAddress.setAddress6(personAddress.getAddress6()); + bahmniAddress.setCityVillage(personAddress.getCityVillage()); + bahmniAddress.setCountyDistrict(personAddress.getCountyDistrict()); + bahmniAddress.setStateProvince(personAddress.getStateProvince()); + bahmniAddress.setPostalCode(personAddress.getPostalCode()); + bahmniAddress.setCountry(personAddress.getCountry()); + bahmniAddress.setLatitude(personAddress.getLatitude()); + bahmniAddress.setLongitude(personAddress.getLongitude()); + bahmniPatient.addAddress(bahmniAddress); + } + return bahmniPatient; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/BahmniVisitSummaryMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/BahmniVisitSummaryMapper.java new file mode 100644 index 0000000000..cf0649b7da --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/BahmniVisitSummaryMapper.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicore.contract.visit.VisitSummary; +import org.openmrs.Encounter; +import org.openmrs.Visit; + +import java.util.List; + +public class BahmniVisitSummaryMapper { + public VisitSummary map(Visit visit, List admissionAndDischargeEncounters) { + VisitSummary visitSummary = new VisitSummary(); + visitSummary.setUuid(visit.getUuid()); + visitSummary.setStartDateTime(visit.getStartDatetime()); + visitSummary.setStopDateTime(visit.getStopDatetime()); + visitSummary.setVisitType(visit.getVisitType().getName()); + mapAdmissionAndDischargeDetails(admissionAndDischargeEncounters, visitSummary); + + return visitSummary; + } + + private void mapAdmissionAndDischargeDetails(List admissionAndDischargeEncounters, VisitSummary visitSummary) { + if (CollectionUtils.isNotEmpty(admissionAndDischargeEncounters)) { + for (Encounter encounter : admissionAndDischargeEncounters) { + VisitSummary.IPDDetails details = new VisitSummary.IPDDetails(); + details.setUuid(encounter.getUuid()); + details.setDate(encounter.getEncounterDatetime()); + details.setProvider(encounter.getEncounterProviders().iterator().next().getProvider().getName()); + if (CollectionUtils.isNotEmpty(encounter.getAllObs())){ + details.setNotes(encounter.getAllObs().iterator().next().getValueText()); + } + if (encounter.getEncounterType().getName().equalsIgnoreCase("ADMISSION")) { + visitSummary.setAdmissionDetails(details); + } else { + visitSummary.setDischargeDetails(details); + } + } + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/BirthDateMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/BirthDateMapper.java new file mode 100644 index 0000000000..22eaf2d490 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/BirthDateMapper.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.Age; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.openmrs.Patient; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +public class BirthDateMapper { + + public Patient map(Patient patient, BahmniPatient bahmniPatient) { + Date birthDate = bahmniPatient.getBirthdate(); + Age age = bahmniPatient.getAge(); + if (birthDate != null) { + patient.setBirthdate(birthDate); + patient.setBirthdateEstimated(false); + + } else if (age != null) { + patient.setBirthdate(age.getDateOfBirth()); + patient.setBirthdateEstimated(true); + } + return patient; + } + + public BahmniPatient mapFromPatient(BahmniPatient bahmniPatient, Patient patient) { + if(bahmniPatient == null){ + bahmniPatient = new BahmniPatient(); + } + + if(patient.getBirthdateEstimated()){ + bahmniPatient.setAge(Age.fromBirthDate(patient.getBirthdate())); + return bahmniPatient; + } + bahmniPatient.setBirthDate(patient.getBirthdate()); + bahmniPatient.setAge(Age.fromBirthDate(patient.getBirthdate())); + return bahmniPatient; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java new file mode 100644 index 0000000000..52a59afc41 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/NoteMapper.java @@ -0,0 +1,34 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class NoteMapper { + + @Autowired + private NoteService noteService; + + public NoteRequestResponse mapResponse(Note note){ + NoteRequestResponse noteResponse = new NoteRequestResponse(); + noteResponse.setNoteId(note.getNoteId()); + noteResponse.setNoteDate(note.getNoteDate()); + noteResponse.setNoteText(note.getNoteText()); + noteResponse.setUuid(note.getUuid()); + noteResponse.setNoteTypeName(note.getNoteType().getName()); + return noteResponse; + } + + public Note mapRequest(NoteRequestResponse noteRequest){ + Note note = new Note(); + note.setNoteId(noteRequest.getNoteId()); + note.setNoteDate(noteRequest.getNoteDate()); + note.setNoteText(noteRequest.getNoteText()); + note.setUuid(noteRequest.getUuid()); + note.setNoteType(noteService.getNoteType(noteRequest.getNoteTypeName())); + return note; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/ObservationTemplateMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/ObservationTemplateMapper.java new file mode 100644 index 0000000000..be034a4a17 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/ObservationTemplateMapper.java @@ -0,0 +1,52 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.apache.commons.lang3.ObjectUtils; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.ObservationTemplate; +import org.openmrs.Concept; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ObservationTemplateMapper { + + private final ConceptMapper conceptMapper; + + public ObservationTemplateMapper(ConceptMapper conceptMapper) { + this.conceptMapper = conceptMapper; + } + + public List map(Collection observations, Concept concept) { + List observationTemplates = new ArrayList<>(); + for (BahmniObservation observation : observations) { + ObservationTemplate matchingObservationTemplate = getMatchingObservationTemplate(observation, observationTemplates); + if(matchingObservationTemplate == null){ + observationTemplates.add(createObservationTemplate(observation, concept)); + } else { + matchingObservationTemplate.addBahmniObservation(observation); + } + } + return observationTemplates; + } + + private ObservationTemplate createObservationTemplate(BahmniObservation observation, Concept concept) { + ObservationTemplate observationTemplate = new ObservationTemplate(); + observationTemplate.addBahmniObservation(observation); + EncounterTransaction.Concept conceptData = conceptMapper.map(concept); + observationTemplate.setConcept(conceptData); + observationTemplate.setVisitStartDate(observation.getVisitStartDateTime()); + return observationTemplate; + } + + private ObservationTemplate getMatchingObservationTemplate(BahmniObservation observation, List observationTemplates) { + for (ObservationTemplate observationTemplate : observationTemplates) { + if(ObjectUtils.equals(observationTemplate.getVisitStartDate(), observation.getVisitStartDateTime())){ + return observationTemplate; + } + } + return null; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PatientIdentifierMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PatientIdentifierMapper.java new file mode 100644 index 0000000000..11c5dc5497 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PatientIdentifierMapper.java @@ -0,0 +1,74 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.idgen.IdentifierSource; +import org.openmrs.module.idgen.service.IdentifierSourceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class PatientIdentifierMapper { + + public static final String BAHMNI_PRIMARY_IDENTIFIER_TYPE = "bahmni.primaryIdentifierType"; + private PatientService patientService; + private AdministrationService administrationService; + + @Autowired + public PatientIdentifierMapper(PatientService patientService, + @Qualifier("adminService") AdministrationService administrationService) { + this.patientService = patientService; + this.administrationService = administrationService; + } + + public Patient map(BahmniPatient bahmniPatient, Patient patient) { + PatientIdentifier patientIdentifier; + String existingIdentifierValue = bahmniPatient.getIdentifier(); + + if (existingIdentifierValue == null || existingIdentifierValue.trim().isEmpty()) { + patientIdentifier = generateIdentifier(bahmniPatient.getCenterName()); + } else { + PatientIdentifierType identifierType = getPatientIdentifierType(); + patientIdentifier = new PatientIdentifier(existingIdentifierValue, identifierType, null); + } + + patientIdentifier.setPreferred(true); + patient.addIdentifier(patientIdentifier); + return patient; + } + + public BahmniPatient mapFromPatient(BahmniPatient bahmniPatient, Patient patient) { + if(bahmniPatient == null){ + bahmniPatient = new BahmniPatient(); + } + bahmniPatient.setIdentifier(patient.getPatientIdentifier().getIdentifier()); + return bahmniPatient; + } + + private PatientIdentifier generateIdentifier(String centerName) { + IdentifierSourceService identifierSourceService = Context.getService(IdentifierSourceService.class); + List allIdentifierSources = identifierSourceService.getAllIdentifierSources(false); + for (IdentifierSource identifierSource : allIdentifierSources) { + if (identifierSource.getName().equals(centerName)) { + String identifier = identifierSourceService.generateIdentifier(identifierSource, "Bahmni Registration App"); + PatientIdentifierType identifierType = getPatientIdentifierType(); + return new PatientIdentifier(identifier, identifierType, null); + } + } + return null; + } + + private PatientIdentifierType getPatientIdentifierType() { + String globalProperty = administrationService.getGlobalProperty(BAHMNI_PRIMARY_IDENTIFIER_TYPE); + PatientIdentifierType patientIdentifierByUuid = patientService.getPatientIdentifierTypeByUuid(globalProperty); + return patientIdentifierByUuid; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PatientMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PatientMapper.java new file mode 100644 index 0000000000..d2b7e78e96 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PatientMapper.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.openmrs.Patient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class PatientMapper { + + private PersonNameMapper personNameMapper; + + private BirthDateMapper birthDateMapper; + + private PersonAttributeMapper personAttributeMapper; + + private AddressMapper addressMapper; + + private final PatientIdentifierMapper patientIdentifierMapper; + + @Autowired + public PatientMapper(PersonNameMapper personNameMapper, BirthDateMapper birthDateMapper, + PersonAttributeMapper personAttributeMapper, AddressMapper addressMapper, + PatientIdentifierMapper patientIdentifierMapper) { + this.personNameMapper = personNameMapper; + this.birthDateMapper = birthDateMapper; + this.personAttributeMapper = personAttributeMapper; + this.addressMapper = addressMapper; + this.patientIdentifierMapper = patientIdentifierMapper; + } + + public Patient map(Patient patient, BahmniPatient bahmniPatient) { + if (patient == null) { + patient = new Patient(); + patient.setPersonDateCreated(bahmniPatient.getPersonDateCreated()); + patient.setUuid(bahmniPatient.getUuid()); + } + patient.setGender(bahmniPatient.getGender()); + patient = personNameMapper.map(patient, bahmniPatient.getNames()); + patient = birthDateMapper.map(patient, bahmniPatient); + patient = personAttributeMapper.map(patient, bahmniPatient.getAttributes()); + patient = addressMapper.map(patient, bahmniPatient.getAddresses()); + patient = patientIdentifierMapper.map(bahmniPatient, patient); + return patient; + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PersonAttributeMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PersonAttributeMapper.java new file mode 100644 index 0000000000..56bca3a37a --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PersonAttributeMapper.java @@ -0,0 +1,49 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.model.BahmniPersonAttribute; +import org.openmrs.Patient; +import org.openmrs.PersonAttribute; +import org.openmrs.api.PersonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; + +@Component +public class PersonAttributeMapper { + + private PersonService personService; + + @Autowired + public PersonAttributeMapper(PersonService personService) { + this.personService = personService; + } + + public Patient map(Patient patient, List attributes) { + for (BahmniPersonAttribute attribute : attributes) { + if (attribute.getPersonAttributeUuid() == null || attribute.getValue() == null) + continue; + + PersonAttribute personAttribute = new PersonAttribute(); + personAttribute.setAttributeType(personService.getPersonAttributeTypeByUuid( + attribute.getPersonAttributeUuid().toString())); + personAttribute.setValue(attribute.getValue().toString()); + patient.addAttribute(personAttribute); + } + return patient; + } + + public BahmniPatient mapFromPatient(BahmniPatient bahmniPatient, Patient patient) { + if(bahmniPatient == null){ + bahmniPatient = new BahmniPatient(); + } + Set attributes = patient.getAttributes(); + for (PersonAttribute attribute : attributes) { + bahmniPatient.addAttribute(new BahmniPersonAttribute(attribute.getAttributeType().getUuid(), attribute.getValue())); + } + return bahmniPatient; + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PersonNameMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PersonNameMapper.java new file mode 100644 index 0000000000..469f8354b9 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/mapper/PersonNameMapper.java @@ -0,0 +1,51 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniName; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.openmrs.Patient; +import org.openmrs.PersonName; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class PersonNameMapper { + + public Patient map(Patient patient, List names) { + + int oldNumberOfNames = patient.getNames().size(); + addName(patient, names); + int newNumberOfNames = patient.getNames().size(); + + voidEarlierNames(patient, oldNumberOfNames, newNumberOfNames); + + return patient; + } + + public BahmniPatient mapFromPatient(BahmniPatient bahmniPatient, Patient patient) { + if (bahmniPatient == null){ + bahmniPatient = new BahmniPatient(); + } + bahmniPatient.addName(new BahmniName(patient.getGivenName(), patient.getFamilyName())); + + return bahmniPatient; + } + + private void voidEarlierNames(Patient patient, int oldNumberOfNames, int newNumberOfNames) { + if (newNumberOfNames > oldNumberOfNames) { + for (PersonName name : patient.getNames()) { + if (name.getId() != null) { + name.setVoided(true); + } + } + } + } + + private void addName(Patient patient, List names) { + for (BahmniName name : names) { + PersonName personName = new PersonName(name.getGivenName(), null, name.getFamilyName()); + personName.setPreferred(true); + patient.addName(personName); + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/matcher/EncounterSessionMatcher.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/matcher/EncounterSessionMatcher.java new file mode 100644 index 0000000000..58f0915bba --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/matcher/EncounterSessionMatcher.java @@ -0,0 +1,181 @@ +package org.bahmni.module.bahmnicore.matcher; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.openmrs.Encounter; +import org.openmrs.EncounterType; +import org.openmrs.Form; +import org.openmrs.Location; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.EncounterTypeIdentifier; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.openmrs.module.emrapi.encounter.matcher.BaseEncounterMatcher; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Component +public class EncounterSessionMatcher implements BaseEncounterMatcher { + + public static final int DEFAULT_SESSION_DURATION_IN_MINUTES = 60; + public static final String PATIENT_PROGAM_UUID = "patientProgramUuid"; + + private AdministrationService adminService; + private EncounterTypeIdentifier encounterTypeIdentifier; + private EncounterService encounterService; + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + private EpisodeService episodeService; + private BahmniVisitLocationService bahmniVisitLocationService; + + @Autowired + public EncounterSessionMatcher(@Qualifier("adminService") AdministrationService administrationService, + EncounterTypeIdentifier encounterTypeIdentifier, + EncounterService encounterService, + BahmniProgramWorkflowService bahmniProgramWorkflowService, EpisodeService episodeService, BahmniVisitLocationService bahmniVisitLocationService) { + this.adminService = administrationService; + this.encounterTypeIdentifier = encounterTypeIdentifier; + this.encounterService = encounterService; + this.bahmniProgramWorkflowService = bahmniProgramWorkflowService; + this.episodeService = episodeService; + this.bahmniVisitLocationService = bahmniVisitLocationService; + } + + @Override + public Encounter findEncounter(Visit visit, EncounterParameters encounterParameters) { + if (encounterParameters.getEncounterUuid() != null) { + return findEncounterByUuid(visit, encounterParameters.getEncounterUuid()); + } + return findMatchingEncounter(visit, encounterParameters); + } + + private Encounter findEncounterByUuid(Visit visit, String encounterUuid) { + for (Encounter encounter : visit.getEncounters()) { + if (encounter.getUuid().equals(encounterUuid)) { + return encounter; + } + } + return null; + } + + private Encounter findMatchingEncounter(Visit visit, EncounterParameters encounterParameters) { + Collection visits = null; + List matchingEncounters = new ArrayList<>(); + if (visit != null) { + if (visit.getId() == null) { // To handle new Visit scenario where visit will not be persisted in DB and we toString a visit obj (Called from emr-api). + return null; + } + visits = Arrays.asList(visit); + } + + if (null == encounterParameters.getEncounterDateTime()) { + encounterParameters.setEncounterDateTime(new Date()); + } + encounterParameters.setEncounterType(getEncounterType(encounterParameters)); + + Collection encounters = this.encounterService.getEncounters(encounterParameters.getPatient(), null, + getSearchStartDate(encounterParameters.getEncounterDateTime()), + encounterParameters.getEncounterDateTime(), new ArrayList(), + Arrays.asList(encounterParameters.getEncounterType()), + encounterParameters.getProviders(), null, visits, false); + + Map context = encounterParameters.getContext(); + if (context != null) { + encounters = filterByPatientProgram(encounters, (String) context.get(PATIENT_PROGAM_UUID)); + } + + if (CollectionUtils.isNotEmpty(encounters)) { + for (Encounter encounter : encounters) { + if (CollectionUtils.isNotEmpty(encounterParameters.getProviders())) { + matchingEncounters.add(encounter); + } else if (CollectionUtils.isEmpty(encounter.getEncounterProviders()) && isSameUser(encounter)) { + matchingEncounters.add(encounter); + } + } + } + + matchingEncounters = encounterParameters.getLocation() != null ? checkEncounterIsInCurrentVisitLocation(matchingEncounters, encounterParameters.getLocation()) : new ArrayList(); + + if (matchingEncounters.size() > 1) { + throw new RuntimeException("More than one encounter matches the criteria"); + } + + if (!matchingEncounters.isEmpty()) { + return matchingEncounters.get(0); + } + return null; + } + + private List checkEncounterIsInCurrentVisitLocation(List encounters, Location loginLocation) { + List matchingEncounters = new ArrayList<>(); + Location encountersVisitLocation; + Location visitLocation = bahmniVisitLocationService.getVisitLocation(loginLocation.getUuid()); + for (Encounter encounter : encounters) { + if (encounter.getLocation() != null) { + encountersVisitLocation = bahmniVisitLocationService.getVisitLocation(encounter.getLocation().getUuid()); + if (visitLocation.equals(encountersVisitLocation)) { + matchingEncounters.add(encounter); + } + } + } + return matchingEncounters; + } + + private Collection filterByPatientProgram(Collection encounters, String patientProgramUuid) { + if (StringUtils.isBlank(patientProgramUuid)) { + Collection episodeEncounters = new ArrayList<>(); + for (Encounter encounter : encounters) { + if (episodeService.getEpisodeForEncounter(encounter) != null) { + episodeEncounters.add(encounter); + } + } + encounters.removeAll(episodeEncounters); + return encounters; + } + return CollectionUtils.intersection(encounters, + bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)); + } + + private Date getSearchStartDate(Date endDate) { + Date startDate = DateUtils.addMinutes(endDate, getSessionDuration() * -1); + if (!DateUtils.isSameDay(startDate, endDate)) { + return DateUtils.truncate(endDate, Calendar.DATE); + } + return startDate; + } + + private EncounterType getEncounterType(EncounterParameters encounterParameters) { + EncounterType encounterType = encounterParameters.getEncounterType(); + if (encounterType == null) { + encounterType = encounterTypeIdentifier.getDefaultEncounterType(); + } + return encounterType; + } + + private boolean isSameUser(Encounter encounter) { + return encounter.getCreator().getId().intValue() == Context.getUserContext().getAuthenticatedUser().getId().intValue(); + } + + private int getSessionDuration() { + String configuredSessionDuration = adminService.getGlobalProperty("bahmni.encountersession.duration"); + int sessionDurationInMinutes = DEFAULT_SESSION_DURATION_IN_MINUTES; + if (configuredSessionDuration != null) { + sessionDurationInMinutes = Integer.parseInt(configuredSessionDuration); + } + return sessionDurationInMinutes; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Age.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Age.java new file mode 100644 index 0000000000..391aa138ef --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Age.java @@ -0,0 +1,75 @@ +package org.bahmni.module.bahmnicore.model; + +import org.joda.time.LocalDate; +import org.joda.time.Period; +import org.joda.time.PeriodType; + +import java.util.Date; +import java.util.LinkedHashMap; + +public class Age { + private final int years; + private final int months; + private final int days; + + public Age(int years, int months, int days) { + this.years = years; + this.months = months; + this.days = days; + } + + public Date getDateOfBirth(Date forDate) { + Period ageAsPeriod = new Period(years, months, 0, days, 0, 0, 0, 0, PeriodType.yearMonthDay()); + LocalDate dateOfBirth = new LocalDate(forDate).minus(ageAsPeriod); + return dateOfBirth.toDate(); + } + + public Date getDateOfBirth() { + return getDateOfBirth(new Date()); + } + + public static Age fromDateOfBirth(Date birthDate, Date today) { + Period ageAsPeriod = new Period(new LocalDate(birthDate), new LocalDate(today), PeriodType.yearMonthDay()); + return new Age(ageAsPeriod.getYears(), ageAsPeriod.getMonths(), ageAsPeriod.getDays()); + } + + public static Age fromBirthDate(Date birthDate) { + return fromDateOfBirth(birthDate, new Date()); + } + + public static Age fromHash(LinkedHashMap simpleObject) { + SimpleObjectExtractor simpleObjectExtractor = new SimpleObjectExtractor(simpleObject); + int years = simpleObjectExtractor.getValueOrDefault("years", int.class); + int months = simpleObjectExtractor.getValueOrDefault("months", int.class); + int days = simpleObjectExtractor.getValueOrDefault("days", int.class); + return new Age(years, months, days); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Age age = (Age) o; + + return days == age.days && months == age.months && years == age.years; + + } + + @Override + public int hashCode() { + int result = years; + result = 31 * result + months; + result = 31 * result + days; + return result; + } + + @Override + public String toString() { + return "Age{" + + "years=" + years + + ", months=" + months + + ", days=" + days + + '}'; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddress.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddress.java new file mode 100644 index 0000000000..05e9533209 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddress.java @@ -0,0 +1,145 @@ +package org.bahmni.module.bahmnicore.model; + +import java.util.LinkedHashMap; + +public class BahmniAddress { + + private String address1; + private String address2; + private String address3; + private String address4; + private String address5; + private String address6; + private String cityVillage; + private String countyDistrict; + private String stateProvince; + private String postalCode; + private String country; + private String latitude; + private String longitude; + + public BahmniAddress() { + } + + public BahmniAddress(LinkedHashMap post) { + SimpleObjectExtractor extractor = new SimpleObjectExtractor(post); + address1 = extractor.extract("address1"); + address2 = extractor.extract("address2"); + address3 = extractor.extract("address3"); + address4 = extractor.extract("address4"); + address5 = extractor.extract("address5"); + address6 = extractor.extract("address6"); + cityVillage = extractor.extract("cityVillage"); + countyDistrict = extractor.extract("countyDistrict"); + stateProvince = extractor.extract("stateProvince"); + postalCode = extractor.extract("postalCode"); + country = extractor.extract("country"); + latitude = extractor.extract("latitude"); + longitude = extractor.extract("longitude"); + } + + public String getAddress1() { + return address1; + } + + public String getAddress2() { + return address2; + } + + public String getAddress3() { + return address3; + } + + public String getCityVillage() { + return cityVillage; + } + + public String getCountyDistrict() { + return countyDistrict; + } + + public String getStateProvince() { + return stateProvince; + } + + public void setAddress1(String address1) { + this.address1 = address1; + } + + public void setAddress2(String address2) { + this.address2 = address2; + } + + public void setAddress3(String address3) { + this.address3 = address3; + } + + public void setCityVillage(String cityVillage) { + this.cityVillage = cityVillage; + } + + public void setCountyDistrict(String countyDistrict) { + this.countyDistrict = countyDistrict; + } + + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + + public String getAddress4() { + return address4; + } + + public void setAddress4(String address4) { + this.address4 = address4; + } + + public String getAddress5() { + return address5; + } + + public void setAddress5(String address5) { + this.address5 = address5; + } + + + public String getAddress6() { + return address6; + } + + public void setAddress6(String address6) { + this.address6 = address6; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddressHierarchyEntry.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddressHierarchyEntry.java new file mode 100644 index 0000000000..5b5bee14af --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddressHierarchyEntry.java @@ -0,0 +1,75 @@ +package org.bahmni.module.bahmnicore.model; + + +public class BahmniAddressHierarchyEntry { + + private Integer addressHierarchyEntryId; + + private String name; + + private Integer levelId; + + private BahmniAddressHierarchyLevel addressHierarchyLevel; + + private Integer parentId; + + private String userGeneratedId; + + private String uuid; + + public Integer getAddressHierarchyEntryId() { + return addressHierarchyEntryId; + } + + public void setAddressHierarchyEntryId(Integer addressHierarchyEntryId) { + this.addressHierarchyEntryId = addressHierarchyEntryId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getParentId() { + return parentId; + } + + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + + public String getUserGeneratedId() { + return userGeneratedId; + } + + public void setUserGeneratedId(String userGeneratedId) { + this.userGeneratedId = userGeneratedId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Integer getLevelId() { + return levelId; + } + + public void setLevelId(Integer levelId) { + this.levelId = levelId; + } + + public BahmniAddressHierarchyLevel getAddressHierarchyLevel() { + return addressHierarchyLevel; + } + + public void setAddressHierarchyLevel(BahmniAddressHierarchyLevel addressHierarchyLevel) { + this.addressHierarchyLevel = addressHierarchyLevel; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddressHierarchyLevel.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddressHierarchyLevel.java new file mode 100644 index 0000000000..03f1ade4ea --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniAddressHierarchyLevel.java @@ -0,0 +1,72 @@ +package org.bahmni.module.bahmnicore.model; + +public class BahmniAddressHierarchyLevel { + + private Integer levelId; + + private String name; + + private Integer parentLevelId; + + private String addressField; + + private Boolean required = false; + + private String uuid; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setLevelId(Integer levelId) { + this.levelId = levelId; + } + + public Integer getLevelId() { + return this.levelId; + } + + public void setAddressField(String addressField) { + this.addressField = addressField; + } + + public String getAddressField() { + return addressField; + } + + public Integer getId() { + return this.levelId; + } + + public void setId(Integer id) { + this.levelId = id; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public Boolean getRequired() { + return required; + } + + public Integer getParentLevelId() { + return parentLevelId; + } + + public void setParentLevelId(Integer parentLevelId) { + this.parentLevelId = parentLevelId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrder.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrder.java new file mode 100644 index 0000000000..cd5053102b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrder.java @@ -0,0 +1,70 @@ +package org.bahmni.module.bahmnicore.model; + +public class BahmniFeedDrugOrder { + private int numberOfDays; + private String productUuid; + private Double quantity; + private Double dosage; + private String unit; + private String orderUuid; + + public BahmniFeedDrugOrder() { + } + + public BahmniFeedDrugOrder(String productUuid, Double dosage, int numberOfDays, Double quantity, String unit, String orderUuid) { + this.numberOfDays = numberOfDays; + this.productUuid = productUuid; + this.quantity = quantity; + this.dosage = dosage; + this.unit = unit; + this.orderUuid = orderUuid; + } + + public int getNumberOfDays() { + return numberOfDays; + } + + public String getProductUuid() { + return productUuid; + } + + public Double getQuantity() { + return quantity; + } + + public Double getDosage() { + return dosage; + } + + public String getUnit() { + return unit; + } + + public void setNumberOfDays(int numberOfDays) { + this.numberOfDays = numberOfDays; + } + + public void setProductUuid(String productUuid) { + this.productUuid = productUuid; + } + + public void setQuantity(Double quantity) { + this.quantity = quantity; + } + + public void setDosage(Double dosage) { + this.dosage = dosage; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public String getOrderUuid() { + return orderUuid; + } + + public void setOrderUuid(String orderUuid) { + this.orderUuid = orderUuid; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrders.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrders.java new file mode 100644 index 0000000000..74d88c0651 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrders.java @@ -0,0 +1,57 @@ +/** + * 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.bahmni.module.bahmnicore.model; + +import org.apache.commons.lang3.ObjectUtils; + +import java.util.ArrayList; +import java.util.List; + +public class BahmniFeedDrugOrders extends ArrayList { + + public BahmniFeedDrugOrders(List bahmniDrugOrders) { + super(bahmniDrugOrders); + } + + public BahmniFeedDrugOrders() { + super(); + } + + public BahmniFeedDrugOrders getUniqueOrders() { + BahmniFeedDrugOrders uniqueDrugOrders = new BahmniFeedDrugOrders(); + for (BahmniFeedDrugOrder drugOrder: this) { + BahmniFeedDrugOrder existingDrugOrder = uniqueDrugOrders.findOrderByUuid(drugOrder.getProductUuid()); + if(existingDrugOrder == null) { + uniqueDrugOrders.add(drugOrder); + } else { + double averageDosage = (existingDrugOrder.getDosage() + drugOrder.getDosage()) / 2; + int totalNumberOfDays = existingDrugOrder.getNumberOfDays() + drugOrder.getNumberOfDays(); + double totalQuantity = existingDrugOrder.getQuantity() + drugOrder.getQuantity(); + existingDrugOrder.setDosage(averageDosage); + existingDrugOrder.setNumberOfDays(totalNumberOfDays); + existingDrugOrder.setQuantity(totalQuantity); + } + } + return uniqueDrugOrders; + } + + public BahmniFeedDrugOrder findOrderByUuid(String productUuid) { + for (BahmniFeedDrugOrder bahmniDrugOrder: this) { + if(ObjectUtils.equals(bahmniDrugOrder.getProductUuid(), productUuid)) { + return bahmniDrugOrder; + } + } + return null; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniName.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniName.java new file mode 100644 index 0000000000..3b6d9e4168 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniName.java @@ -0,0 +1,32 @@ +package org.bahmni.module.bahmnicore.model; + +import java.util.LinkedHashMap; + +public class BahmniName { + private String givenName; + + private String familyName; + + public BahmniName(LinkedHashMap post) { + SimpleObjectExtractor extractor = new SimpleObjectExtractor(post); + givenName = extractor.extract("givenName"); + familyName = extractor.extract("familyName"); + } + + public BahmniName(String givenName, String familyName) { + this.givenName = givenName; + this.familyName = familyName; + } + + public String getGivenName() { + return givenName; + } + + public String getFamilyName() { + return familyName; + } + + public String getFullName() { + return String.format("%s %s", givenName, familyName); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniPatient.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniPatient.java new file mode 100644 index 0000000000..a0c449e4b8 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniPatient.java @@ -0,0 +1,185 @@ +package org.bahmni.module.bahmnicore.model; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; + +public class BahmniPatient { + private Date birthdate; + private Age age; + private String centerName; + private String identifier; + private List attributes = new ArrayList(); + private List addresses = new ArrayList(); + private List names = new ArrayList(); + private String gender; + private String image; + private String uuid; + private String balance; + private Date personDateCreated; + private static Logger logger = LogManager.getLogger(BahmniPatient.class); + + public BahmniPatient() { + } + + public BahmniPatient(SimpleObject post) throws ParseException { + SimpleObjectExtractor extractor = new SimpleObjectExtractor(post); + balance = extractor.extract("balance"); + age = Age.fromHash(extractor.extract("age")); + identifier = extractor.extract("identifier"); + image = extractor.extract("image"); + gender = extractor.extract("gender"); + centerName = extractor.extract("centerID"); + + extractRegistrationDate(extractor); + extractBirthdate(extractor); + + List nameList = extractor.extract("names"); + for (LinkedHashMap name : nameList) { + names.add(new BahmniName(name)); + } + + List addressList = extractor.extract("addresses"); + for (LinkedHashMap address : addressList) { + addresses.add(new BahmniAddress(address)); + } + + List attributeList = extractor.extract("attributes"); + for (LinkedHashMap attribute : attributeList) { + attributes.add(new BahmniPersonAttribute(attribute)); + } + } + + private void extractBirthdate(SimpleObjectExtractor extractor) { + try { + birthdate = new SimpleDateFormat("dd-MM-yyyy").parse(extractor. extract("birthdate")); + } + catch (Exception e) { + logger.warn(e); + } + } + + private void extractRegistrationDate(SimpleObjectExtractor extractor) { + try { + personDateCreated = new SimpleDateFormat("dd-MM-yyyy").parse(extractor.extract("dateOfRegistration")); + } + catch (Exception e) { + logger.warn(e); + } + } + + public Date getBirthdate() { + return birthdate; + } + + public Age getAge() { + return age; + } + + public List getAddresses() { + return addresses; + } + + public List getNames() { + return names; + } + + public String getIdentifier() { + return identifier; + } + + public String getCenterName() { + return centerName; + } + + public List getAttributes() { + return attributes; + } + + public String getGender() { + return gender; + } + + public String getImage() { + return image; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public double getBalance() { + return (balance == null || StringUtils.isEmpty(balance)) ? Double.NaN : Double.parseDouble(balance); + } + + public String getFullName() { + return names.get(0).getFullName(); + } + + public String getPatientName() { + BahmniName patientName = getNames().get(0); + return patientName.getGivenName() + " " + patientName.getFamilyName(); + } + + public boolean hasBalance() { + return !Double.isNaN(getBalance()) && getBalance() > 0; + } + + public void setBalance(String balance) { + this.balance = balance; + } + + public Date getPersonDateCreated() { + return personDateCreated; + } + + public void setPersonDateCreated(Date personDateCreated) { + this.personDateCreated = personDateCreated; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public void addName(BahmniName bahmniName) { + names.add(bahmniName); + } + + public void addAttribute(BahmniPersonAttribute bahmniPersonAttribute) { + attributes.add(bahmniPersonAttribute); + } + + public void addAddress(BahmniAddress bahmniAddress) { + addresses.add(bahmniAddress); + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public void setCenter(String center) { + this.centerName = center; + } + + public void setAge(Age age) { + this.age = age; + } + + public void setBirthDate(Date birthDate) { + this.birthdate = birthDate; + } + + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniPersonAttribute.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniPersonAttribute.java new file mode 100644 index 0000000000..aef3bd0b2c --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/BahmniPersonAttribute.java @@ -0,0 +1,36 @@ +package org.bahmni.module.bahmnicore.model; + +import java.util.LinkedHashMap; + +public class BahmniPersonAttribute { + + private String personAttributeUuid; + + private String value; + + public BahmniPersonAttribute(String personAttributeUuid, String value) { + this.personAttributeUuid = personAttributeUuid; + this.value = value; + } + + public BahmniPersonAttribute(LinkedHashMap post) { + SimpleObjectExtractor extractor = new SimpleObjectExtractor(post); + personAttributeUuid = extractor.extract("attributeType"); + Object extractValue = extractor.extract("value"); + + if (extractValue instanceof String) { + value = (String) extractValue; + } else { + LinkedHashMap extractValue1 = (LinkedHashMap) extractValue; + value = (String) extractValue1.get("display"); + } + } + + public String getPersonAttributeUuid() { + return personAttributeUuid; + } + + public String getValue() { + return value; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Document.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Document.java new file mode 100644 index 0000000000..ce69d3ddf9 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Document.java @@ -0,0 +1,71 @@ +package org.bahmni.module.bahmnicore.model; + +public class Document { + private String content; + private String format; + private String encounterTypeName; + private String patientUuid; + private String fileType; + private String fileName; + + public Document() { + } + + public Document(String content, String format, String encounterTypeName, String patientUuid, String fileType, String fileName) { + this.content = content; + this.format = format; + this.encounterTypeName = encounterTypeName; + this.patientUuid = patientUuid; + this.fileType = fileType; + this.fileName = fileName; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getEncounterTypeName() { + return encounterTypeName; + } + + public void setEncounterTypeName(String encounterTypeName) { + this.encounterTypeName = encounterTypeName; + } + + public String getPatientUuid() { + return patientUuid; + } + + public void setPatientUuid(String patientUuid) { + this.patientUuid = patientUuid; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java new file mode 100644 index 0000000000..82ec99c8e2 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Note.java @@ -0,0 +1,127 @@ +package org.bahmni.module.bahmnicore.model; + + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.openmrs.Auditable; +import org.openmrs.BaseOpenmrsData; +import org.openmrs.Patient; +import org.openmrs.User; + +public class Note extends BaseOpenmrsData implements Auditable, Serializable { + + private Integer noteId; + + private String noteText; + + private Date dateChanged; + + private Date dateCreated; + + private NoteType noteType; + + private Date noteDate; + + private Integer locationId; + + private User creator; + + private User changedBy; + + + public Note() { + } + + @Override + public void setId(Integer id) { + setNoteId(id); + } + + @Override + public Integer getId() { + return getNoteId(); + } + + public Date getDateChanged() { + return dateChanged; + } + + public void setDateChanged(Date dateChanged) { + this.dateChanged = dateChanged; + } + + @Override + public Date getDateCreated() { + return dateCreated; + } + + @Override + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + public Integer getNoteId() { + return noteId; + } + + public void setNoteId(Integer noteId) { + this.noteId = noteId; + } + + public Integer getLocationId() { + return locationId; + } + + public void setLocationId(Integer locationId) { + this.locationId = locationId; + } + + public Date getNoteDate() { + return noteDate; + } + + public void setNoteDate(Date noteDate) { + this.noteDate = noteDate; + } + + public NoteType getNoteType() { + return noteType; + } + + public void setNoteType(NoteType noteType) { + this.noteType = noteType; + } + + public String getNoteText() { + return noteText; + } + + public void setNoteText(String noteText) { + this.noteText = noteText; + } + + @Override + @JsonIgnore + public User getCreator() { + return creator; + } + + @Override + public void setCreator(User creator) { + this.creator = creator; + } + + @Override + @JsonIgnore + public User getChangedBy() { + return changedBy; + } + + @Override + public void setChangedBy(User changedBy) { + this.changedBy = changedBy; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java new file mode 100644 index 0000000000..ab4bfad380 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/NoteType.java @@ -0,0 +1,43 @@ +package org.bahmni.module.bahmnicore.model; + +import org.openmrs.BaseOpenmrsData; + +import java.io.Serializable; + +public class NoteType extends BaseOpenmrsData implements Serializable { + + private Integer noteTypeId; + + private String name; + + private String description; + public NoteType() { + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Integer getNoteTypeId() { + return noteTypeId; + } + public void setNoteTypeId(Integer noteTypeId) { + this.noteTypeId = noteTypeId; + } + public Integer getId() { + return getNoteTypeId(); + } + + public void setId(Integer id) { + setNoteTypeId(id); + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Provider.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Provider.java new file mode 100644 index 0000000000..39de9761f6 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/Provider.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.model; + +import java.util.Objects; + +public class Provider { + private String providerName; + private String uuid; + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Provider provider = (Provider) o; + return Objects.equals(providerName, provider.providerName) && + Objects.equals(uuid, provider.uuid); + } + + @Override + public int hashCode() { + + return Objects.hash(providerName, uuid); + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/ResultList.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/ResultList.java new file mode 100644 index 0000000000..a74d247b2a --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/ResultList.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.model; + +import java.util.ArrayList; +import java.util.List; + +public class ResultList { + + private List results; + + public ResultList(List results) { + this.results = results == null ? new ArrayList() : results; + } + + public List getResults() { + return results; + } + + public int size() { + return results.size(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/SimpleObjectExtractor.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/SimpleObjectExtractor.java new file mode 100644 index 0000000000..68063db943 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/SimpleObjectExtractor.java @@ -0,0 +1,55 @@ +package org.bahmni.module.bahmnicore.model; +import java.util.LinkedHashMap; + +public class SimpleObjectExtractor { + + private LinkedHashMap post; + + public SimpleObjectExtractor(LinkedHashMap post) { + this.post = post; + } + + public T extract(String key) { + return post == null || key == null ? null : (T) post.get(key); + } + + public T getValueOrDefault(String key, Class clazz) { + if(post == null || key == null) + return (T)defaultValue(clazz); + Object value = post.get(key); + return value == null ? (T)defaultValue(clazz) : (T)value; + } + + //TODO: Remove this when openmrs start using jackson-mapper-asl > 1.7.1 + //http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.jackson/jackson-mapper-asl/1.8.5/org/codehaus/jackson/map/util/ClassUtil.java#ClassUtil.defaultValue%28java.lang.Class%29 + public static Object defaultValue(Class cls) + { + if (cls == Integer.TYPE) { + return Integer.valueOf(0); + } + if (cls == Long.TYPE) { + return Long.valueOf(0L); + } + if (cls == Boolean.TYPE) { + return Boolean.FALSE; + } + if (cls == Double.TYPE) { + return Double.valueOf(0.0); + } + if (cls == Float.TYPE) { + return Float.valueOf(0.0f); + } + if (cls == Byte.TYPE) { + return Byte.valueOf((byte) 0); + } + if (cls == Short.TYPE) { + return Short.valueOf((short) 0); + } + if (cls == Character.TYPE) { + return '\0'; + } + throw new IllegalArgumentException("Class "+cls.getName()+" is not a primitive type"); + } + +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/VideoFormats.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/VideoFormats.java new file mode 100644 index 0000000000..9ed51faceb --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/VideoFormats.java @@ -0,0 +1,26 @@ +package org.bahmni.module.bahmnicore.model; + +public enum VideoFormats { + + OGG("OGG"), _3GP("3GPP"), MP4("MP4"), MPEG("MPEG"), WMV("WMV"), AVI("AVI"), MOV("MOV"), FLV("FLV"), WEBM("WEBM"), MKV("MKV"); + + private final String value; + + VideoFormats(String value) { + this.value = value; + } + + public static boolean isFormatSupported(String givenFormat) { + for (VideoFormats format : VideoFormats.values()) { + if (givenFormat.toUpperCase().contains(format.value)) + return true; + } + return false; + } + + @Override + public String toString() { + return value.toLowerCase(); + } +} + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/VideoFormatsForThumbnailGeneration.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/VideoFormatsForThumbnailGeneration.java new file mode 100644 index 0000000000..fccf66ea24 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/VideoFormatsForThumbnailGeneration.java @@ -0,0 +1,24 @@ +package org.bahmni.module.bahmnicore.model; + +public enum VideoFormatsForThumbnailGeneration { + _3GP("3GPP"), MP4("MP4"), MOV("MOV"); + + private final String value; + + VideoFormatsForThumbnailGeneration(String value) { + this.value = value; + } + + public static boolean isFormatSupported(String givenFormat) { + for (VideoFormatsForThumbnailGeneration format : VideoFormatsForThumbnailGeneration.values()) { + if (givenFormat.toUpperCase().contains(format.value)) + return true; + } + return false; + } + + @Override + public String toString() { + return value.toLowerCase(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/error/ErrorCode.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/error/ErrorCode.java new file mode 100644 index 0000000000..9c08470547 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/error/ErrorCode.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.model.error; + +public class ErrorCode { + public static int DuplicatePatient = 1; + public static int DuplicateCustomer = 2; + public static int OpenERPError = 3; + public static int OpenMRSError = 4; + + public static boolean duplicationError(int errorCode) { + return errorCode == DuplicateCustomer || errorCode == DuplicatePatient; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/error/ErrorMessage.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/error/ErrorMessage.java new file mode 100644 index 0000000000..3677b44fbf --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/error/ErrorMessage.java @@ -0,0 +1,6 @@ +package org.bahmni.module.bahmnicore.model.error; + +public class ErrorMessage { + public static String ExistingPatientMessagePart = "already in use by another patient"; + public static String ExistingCustomerMessagePart = "Customer with id, name already exists"; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/searchParams/AdditionalSearchParam.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/searchParams/AdditionalSearchParam.java new file mode 100644 index 0000000000..f546555a1a --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/model/searchParams/AdditionalSearchParam.java @@ -0,0 +1,33 @@ +package org.bahmni.module.bahmnicore.model.searchParams; + +public class AdditionalSearchParam { + + private String additionalSearchHandler; + private String tests; + + public AdditionalSearchParam(String additionalSearchHandler, String tests) { + this.additionalSearchHandler = additionalSearchHandler; + this.tests = tests; + } + + public AdditionalSearchParam() { + } + + public String getAdditionalSearchHandler() { + return additionalSearchHandler; + } + + public void setAdditionalSearchHandler(String additionalSearchHandler) { + this.additionalSearchHandler = additionalSearchHandler; + } + + public String getTests(){ + return tests; + } + + public void setTests(String tests){ + this.tests = tests; + } +} + + diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/ObservationsAdder.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/ObservationsAdder.java new file mode 100644 index 0000000000..79a42a3b4a --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/ObservationsAdder.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.obs; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; + +import java.text.ParseException; +import java.util.Collection; +import java.util.List; + +public interface ObservationsAdder { + + void addObservations(Collection observations, List conceptNames) throws ParseException; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/ImageUrlHandler.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/ImageUrlHandler.java new file mode 100644 index 0000000000..a8f0062484 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/ImageUrlHandler.java @@ -0,0 +1,33 @@ +package org.bahmni.module.bahmnicore.obs.handler; + +import org.openmrs.Obs; +import org.openmrs.api.APIException; +import org.openmrs.obs.ComplexData; +import org.openmrs.obs.ComplexObsHandler; +import org.openmrs.obs.handler.AbstractHandler; +import org.openmrs.obs.handler.BinaryDataHandler; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; + +@Component +public class ImageUrlHandler extends AbstractHandler implements ComplexObsHandler { + + @Override + public Obs getObs(Obs obs, String view) { + File file = BinaryDataHandler.getComplexDataFile(obs); + ComplexData complexData = null; + complexData = new ComplexData(file.getName(), null); + String mimeType = OpenmrsUtil.getFileMimeType(file); + complexData.setMimeType(mimeType); + obs.setComplexData(complexData); + return obs; + } + + @Override + public Obs saveObs(Obs obs) throws APIException { + return obs; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/LocationObsHandler.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/LocationObsHandler.java new file mode 100644 index 0000000000..9ed8397f81 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/LocationObsHandler.java @@ -0,0 +1,70 @@ +package org.bahmni.module.bahmnicore.obs.handler; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.api.APIException; +import org.openmrs.api.LocationService; +import org.openmrs.api.context.Context; +import org.openmrs.obs.ComplexData; +import org.openmrs.obs.ComplexObsHandler; +import org.openmrs.obs.handler.AbstractHandler; +import org.springframework.stereotype.Component; + +@Component +public class LocationObsHandler extends AbstractHandler implements ComplexObsHandler { + + public static final Log log = LogFactory.getLog(LocationObsHandler.class); + private static final String[] supportedViews = new String[] { ComplexObsHandler.RAW_VIEW, + ComplexObsHandler.URI_VIEW, ComplexObsHandler.HTML_VIEW, ComplexObsHandler.TEXT_VIEW}; + + @Override + public Obs saveObs(Obs obs) throws APIException { + LocationService ls = Context.getLocationService(); + Object complexObsData = obs.getValueComplex(); + + try { + int locationId = Integer.parseInt(complexObsData.toString()); + Integer conceptId = obs.getConcept().getId(); + Location location = ls.getLocation(locationId); + if (location == null) { + throw new APIException(String.format("Cannot save complex obs [concept:%d] with desired location [%d] information. Can not find location.", conceptId, locationId)); + } + obs.setComplexData(null); + obs.setValueComplex(String.valueOf(locationId)); + return obs; + } catch (NumberFormatException e) { + log.error("Error occurred while trying to parse Location info from obs. "); + throw new APIException(String.format("Cannot save complex obs [concept:%d] with desired location [%s] information.", obs.getConcept().getId(), complexObsData.toString())); + } + + } + + @Override + public Obs getObs(Obs obs, String view) { + LocationService ls = Context.getLocationService(); + try { + String valueComplex = obs.getValueComplex(); + if (valueComplex != null && !valueComplex.isEmpty()) { + String[] parts = valueComplex.split("\\|"); + Location location = ls.getLocation(Integer.parseInt(parts[0])); + if (location != null) { + ComplexData cd = new ComplexData(location.getName(), location); + obs.setComplexData(cd); + } + } + } catch (Exception e) { + log.error(String.format("Error occurred while retreving location obs data for obs [concept:%d].", obs.getConcept().getId()), e); + //TODO: should we be throwing error, how do the apis handle exception? + } + return obs; + } + + @Override + public String[] getSupportedViews() { + return supportedViews; + } + + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/ProviderObsHandler.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/ProviderObsHandler.java new file mode 100644 index 0000000000..ca3967bf8d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/ProviderObsHandler.java @@ -0,0 +1,70 @@ +package org.bahmni.module.bahmnicore.obs.handler; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.Obs; +import org.openmrs.Provider; +import org.openmrs.api.APIException; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.obs.ComplexData; +import org.openmrs.obs.ComplexObsHandler; +import org.openmrs.obs.handler.AbstractHandler; +import org.springframework.stereotype.Component; + +@Component +public class ProviderObsHandler extends AbstractHandler implements ComplexObsHandler { + + public static final Log log = LogFactory.getLog(LocationObsHandler.class); + private static final String[] supportedViews = new String[] { ComplexObsHandler.RAW_VIEW, + ComplexObsHandler.URI_VIEW, ComplexObsHandler.HTML_VIEW, ComplexObsHandler.TEXT_VIEW}; + + @Override + public Obs saveObs(Obs obs) throws APIException { + ProviderService ps = Context.getProviderService(); + Object complexObsData = obs.getValueComplex(); + + try { + int providerId = Integer.parseInt(complexObsData.toString()); + Integer conceptId = obs.getConcept().getId(); + Provider provider = ps.getProvider(providerId); + if (provider == null) { + throw new APIException(String.format("Cannot save complex obs [concept:%d] with desired provider [%d] information. Can not find provider.", conceptId, providerId)); + } + obs.setComplexData(null); + obs.setValueComplex(String.valueOf(providerId)); + return obs; + } catch (NumberFormatException e) { + log.error("Error occurred while trying to parse Provider info from obs. "); + throw new APIException(String.format("Cannot save complex obs [concept:%d] with desired provider [%s] information.", obs.getConcept().getId(), complexObsData.toString())); + } + + } + + @Override + public Obs getObs(Obs obs, String view) { + ProviderService ps = Context.getProviderService(); + try { + String valueComplex = obs.getValueComplex(); + if (valueComplex != null && !valueComplex.isEmpty()) { + String[] parts = valueComplex.split("\\|"); + Provider provider = ps.getProvider(Integer.parseInt(parts[0])); + if (provider != null) { + ComplexData cd = new ComplexData(provider.getName(), provider); + obs.setComplexData(cd); + } + } + } catch (Exception e) { + log.error(String.format("Error occurred while retreving provider obs data for obs [concept:%d].", obs.getConcept().getId()), e); + //TODO: should we be throwing error, how do the apis handle exception? + } + return obs; + } + + @Override + public String[] getSupportedViews() { + return supportedViews; + } + + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/VideoUrlHandler.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/VideoUrlHandler.java new file mode 100644 index 0000000000..6612d08763 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/VideoUrlHandler.java @@ -0,0 +1,33 @@ +package org.bahmni.module.bahmnicore.obs.handler; + +import org.openmrs.Obs; +import org.openmrs.api.APIException; +import org.openmrs.obs.ComplexData; +import org.openmrs.obs.ComplexObsHandler; +import org.openmrs.obs.handler.AbstractHandler; +import org.openmrs.obs.handler.BinaryDataHandler; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.stereotype.Component; + +import java.io.File; + +@Component +public class VideoUrlHandler extends AbstractHandler implements ComplexObsHandler { + + @Override + public Obs saveObs(Obs obs) throws APIException { + return obs; + } + + @Override + public Obs getObs(Obs obs, String view) { + File file = BinaryDataHandler.getComplexDataFile(obs); + ComplexData complexData = null; + complexData = new ComplexData(file.getName(), null); + String mimeType = OpenmrsUtil.getFileMimeType(file); + complexData.setMimeType(mimeType); + obs.setComplexData(complexData); + return obs; + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/properties/BahmniCoreProperties.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/properties/BahmniCoreProperties.java new file mode 100644 index 0000000000..c537333a90 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/properties/BahmniCoreProperties.java @@ -0,0 +1,37 @@ +package org.bahmni.module.bahmnicore.properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.util.OpenmrsUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +public class BahmniCoreProperties { + private static Properties properties; + private static Log log = LogFactory.getLog(BahmniCoreProperties.class); + + public static void load() { + String propertyFile = new File(OpenmrsUtil.getApplicationDataDirectory(), "bahmnicore.properties").getAbsolutePath(); + log.info(String.format("Reading bahmni properties from : %s", propertyFile)); + try { + properties = new Properties(System.getProperties()); + properties.load(new FileInputStream(propertyFile)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static String getProperty(String key){ + if(properties == null){ + load(); + } + return properties.getProperty(key); + } + + public static void initalize(Properties props) { + properties = props; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/resource/BahmniVisitResource.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/resource/BahmniVisitResource.java new file mode 100644 index 0000000000..42269f88fd --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/resource/BahmniVisitResource.java @@ -0,0 +1,151 @@ +package org.bahmni.module.bahmnicore.resource; + +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.VisitAttribute; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertySetter; +import org.openmrs.module.webservices.rest.web.api.RestService; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DataDelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PatientResource1_8; + +import java.util.Set; + +//Copied over from VisitResource since OpenMRS does not publish Rest 1.9 extensions anymore +public class BahmniVisitResource extends DataDelegatingCrudResource { + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + if (rep instanceof DefaultRepresentation) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("display", findMethod("getDisplayString")); + description.addProperty("patient", Representation.REF); + description.addProperty("visitType", Representation.REF); + description.addProperty("indication", Representation.REF); + description.addProperty("location", Representation.REF); + description.addProperty("startDatetime"); + description.addProperty("stopDatetime"); + description.addProperty("encounters", Representation.REF); + description.addProperty("attributes", "activeAttributes", Representation.REF); + description.addProperty("voided"); + description.addSelfLink(); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + return description; + } else if (rep instanceof FullRepresentation) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("display", findMethod("getDisplayString")); + description.addProperty("patient", Representation.REF); + description.addProperty("visitType", Representation.REF); + description.addProperty("indication", Representation.REF); + description.addProperty("location", Representation.REF); + description.addProperty("startDatetime"); + description.addProperty("stopDatetime"); + description.addProperty("encounters", Representation.DEFAULT); + description.addProperty("attributes", "activeAttributes", Representation.DEFAULT); + description.addProperty("voided"); + description.addProperty("auditInfo", findMethod("getAuditInfo")); + description.addSelfLink(); + return description; + } + return null; + } + + public String getDisplayString(Visit visit) { + String ret = visit.getVisitType().getName(); + ret += " "; + ret += visit.getLocation() == null ? "?" : "@ " + visit.getLocation().getName(); + ret += " - "; + ret += Context.getDateTimeFormat().format(visit.getStartDatetime()); + return ret; + } + + @Override + public DelegatingResourceDescription getCreatableProperties() { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addRequiredProperty("patient"); + description.addRequiredProperty("visitType"); + description.addRequiredProperty("startDatetime"); + + description.addProperty("location"); + description.addProperty("indication"); + description.addProperty("stopDatetime"); + description.addProperty("encounters"); + description.addProperty("attributes"); + + return description; + } + + @Override + public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { + DelegatingResourceDescription description = super.getUpdatableProperties(); + description.removeProperty("patient"); + return description; + } + + @Override + public Visit newDelegate() { + return new Visit(); + } + + @Override + public Visit save(Visit visit) { + return Context.getVisitService().saveVisit(visit); + } + + @Override + public Visit getByUniqueId(String uuid) { + return Context.getVisitService().getVisitByUuid(uuid); + } + + @Override + public void delete(Visit visit, String reason, RequestContext context) throws ResponseException { + if (visit.isVoided()) { + // Makes no sense, so we return success here + return; + } + Context.getVisitService().voidVisit(visit, reason); + } + + @Override + public void purge(Visit visit, RequestContext context) throws ResponseException { + if (visit == null) + return; + Context.getVisitService().purgeVisit(visit); + } + + public SimpleObject getVisitsByPatient(String patientUniqueId, RequestContext context) throws ResponseException { + DelegatingCrudResource resource = (DelegatingCrudResource) Context.getService(RestService.class).getResourceBySupportedClass(PatientResource1_8.class); + Patient patient = resource.getByUniqueId(patientUniqueId); + if (patient == null) + throw new ObjectNotFoundException(); + return new NeedsPaging(Context.getVisitService().getVisitsByPatient(patient, true, false), context) + .toSimpleObject(this); + } + + @Override + public String getResourceVersion() { + return "1.9"; + } + + @PropertySetter("attributes") + public static void setAttributes(Visit visit, Set attributes) { + for (VisitAttribute attribute : attributes) { + attribute.setOwner(visit); + } + visit.setAttributes(attributes); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/security/PrivilegeConstants.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/security/PrivilegeConstants.java new file mode 100644 index 0000000000..8fa4d1e6e4 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/security/PrivilegeConstants.java @@ -0,0 +1,5 @@ +package org.bahmni.module.bahmnicore.security; + +public class PrivilegeConstants { + public static final String DELETE_PATIENT_DOCUMENT_PRIVILEGE = "Delete Patient Document"; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniAddressHierarchyService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniAddressHierarchyService.java new file mode 100644 index 0000000000..3e438ee461 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniAddressHierarchyService.java @@ -0,0 +1,9 @@ +package org.bahmni.module.bahmnicore.service; + +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; + +import java.util.List; + +public interface BahmniAddressHierarchyService { + List getAddressHierarchyEntriesByUuid(List uuids); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniConceptService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniConceptService.java new file mode 100644 index 0000000000..20196922bc --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniConceptService.java @@ -0,0 +1,20 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.Collection; +import java.util.List; + +public interface BahmniConceptService { + EncounterTransaction.Concept getConceptByName(String conceptName); + + Collection searchByQuestion(String questionConcept, String query); + Collection getDrugsByConceptSetName(String conceptSetName, String searchTerm); + + Concept getConceptByFullySpecifiedName(String drug); + + List getConceptsByFullySpecifiedName(List conceptNames); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java new file mode 100644 index 0000000000..3a2497ccfb --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDiagnosisService.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Concept; +import org.openmrs.ConceptSource; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; + +import java.text.ParseException; +import java.util.Collection; +import java.util.List; + +public interface BahmniDiagnosisService { + void delete(String diagnosisObservationUuid); + List getBahmniDiagnosisByPatientAndVisit(String patientUuid,String visitUuid); + List getBahmniDiagnosisByPatientAndDate(String patientUuid, String date) throws ParseException; + + boolean isExternalTerminologyServerLookupNeeded(); + + Collection getDiagnosisSets(); + + List getConceptSourcesForDiagnosisSearch(); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java new file mode 100644 index 0000000000..f483c45b88 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniDrugOrderService.java @@ -0,0 +1,43 @@ +package org.bahmni.module.bahmnicore.service; + +import org.bahmni.module.bahmnicore.contract.drugorder.DrugOrderConfigResponse; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; + +import java.text.ParseException; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public interface BahmniDrugOrderService { + List getActiveDrugOrders(String patientUuid, Date startDate, Date endDate); + + List getActiveDrugOrders(String patientUuid); + + List getPrescribedDrugOrders(List visitUuids, String patientUuid, Boolean includeActiveVisit, + Integer numberOfVisit, Date startDate, Date endDate, Boolean getEffectiveOrdersOnly); + + List getPrescribedDrugOrdersForConcepts(Patient patient, Boolean includeActiveVisit, List visits, List concepts, Date startDate, Date endDate); + + DrugOrderConfigResponse getConfig(); + + List getAllDrugOrders(String patientUuid, String patientProgramUuid, Set conceptsForDrugs, + Set drugConceptsToBeExcluded, Collection encounters) throws ParseException; + + Map getDiscontinuedDrugOrders(List drugOrders); + + List getInactiveDrugOrders(String patientUuid, Set concepts, Set drugConceptsToBeExcluded, + Collection encountersByPatientProgramUuid); + + List getDrugOrders(String patientUuid, Boolean isActive, Set conceptsToFilter, Set conceptsToExclude, + String patientProgramUuid) throws ParseException; + + DrugOrder getDrugOrderByOrderId(String orderId); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniEncounterModifierService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniEncounterModifierService.java new file mode 100644 index 0000000000..6137bb0d28 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniEncounterModifierService.java @@ -0,0 +1,10 @@ +package org.bahmni.module.bahmnicore.service; + +import org.bahmni.module.bahmnicore.contract.encounter.data.EncounterModifierData; +import org.bahmni.module.bahmnicore.encounterModifier.exception.CannotModifyEncounterException; + +import java.io.IOException; + +public interface BahmniEncounterModifierService { + public EncounterModifierData getModifiedEncounter(EncounterModifierData encounterModifierData) throws IllegalAccessException, IOException, InstantiationException, CannotModifyEncounterException; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniObsService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniObsService.java new file mode 100644 index 0000000000..c04fec85b3 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniObsService.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Concept; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +public interface BahmniObsService { + public List getNumericConceptsForPerson(String personUUID); + public List getObsForPerson(String identifier); + + public Collection getInitial(String patientUuid, Collection conceptNames, Integer numberOfVisits, List obsIgnoreList, Boolean filterOutOrderObs, Order order); + public Collection getInitialObsByVisit(Visit visit, List rootConcepts, List obsIgnoreList, Boolean filterObsWithOrders); + public Collection getLatest(String patientUuid, Collection conceptNames, Integer numberOfVisits, List obsIgnoreList, Boolean filterOutOrderObs, Order order); + public Collection getLatestObsForConceptSetByVisit(String patientUuid, String conceptName, Integer visitId); + public Collection getLatestObsByVisit(Visit visit, Collection concepts, List obsIgnoreList, Boolean filterObsWithOrders); + + public Collection getObservationsForOrder(String orderUuid); + + public Collection observationsFor(String patientUuid, Collection concepts, Integer numberOfVisits, List obsIgnoreList, Boolean filterOutOrderObs, Order order, Date startDate, Date endDate); + public Collection observationsFor(String patientUuid, Concept rootConcept, Concept childConcept, Integer numberOfVisits, Date startDate, Date endDate, String patientProgramUuid); + + public Collection getObservationForVisit(String visitUuid, List conceptNames, Collection obsIgnoreList, Boolean filterOutOrders, Order order); + public Collection getObservationsForEncounter(String encounterUuid, List conceptNames); + public Collection getObservationsForPatientProgram(String patientProgramUuid, List conceptNames, List obsIgnoreList); + public Collection getLatestObservationsForPatientProgram(String patientProgramUuid, List conceptNames, List obsIgnoreList); + public Collection getInitialObservationsForPatientProgram(String patientProgramUuid, List conceptNames, List obsIgnoreList); + + BahmniObservation getBahmniObservationByUuid(String observationUuid); + BahmniObservation getRevisedBahmniObservationByUuid(String observationUuid); + + Collection getObsForFormBuilderForms(String patientUuid, List formNames, Integer numberOfVisits, Date startDate, Date endDate, String patientProgramUuid); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniOrderService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniOrderService.java new file mode 100644 index 0000000000..54ca9bf681 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniOrderService.java @@ -0,0 +1,17 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Concept; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.order.contract.BahmniOrder; + +import java.util.List; + +public interface BahmniOrderService{ + List ordersForOrderType(String patientUuid, List concepts, Integer numberOfVisits, List obsIgnoreList, String orderTypeUuid, Boolean includeObs, List locationUuids); + + List ordersForOrderUuid(String patientUuid, List concepts, List obsIgnoreList, String orderUuid); + + List ordersForVisit(String visitUuid, String orderTypeUuid, List conceptNames, List obsIgnoreList); + + Order getChildOrder(Order order); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniOrderSetService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniOrderSetService.java new file mode 100644 index 0000000000..e2dc76088f --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniOrderSetService.java @@ -0,0 +1,10 @@ +package org.bahmni.module.bahmnicore.service; + + +import org.openmrs.OrderSet; + +import java.util.List; + +public interface BahmniOrderSetService { + List getOrderSetByQuery(String searchTerm); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniProgramServiceValidator.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniProgramServiceValidator.java new file mode 100644 index 0000000000..ff21b8d896 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniProgramServiceValidator.java @@ -0,0 +1,8 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.PatientProgram; +import org.openmrs.api.APIException; + +public interface BahmniProgramServiceValidator { + void validate(PatientProgram patientProgram) throws APIException; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniProgramWorkflowService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniProgramWorkflowService.java new file mode 100644 index 0000000000..c7452e8b76 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniProgramWorkflowService.java @@ -0,0 +1,16 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Encounter; +import org.openmrs.annotation.Authorized; +import org.openmrs.api.ProgramWorkflowService; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; + +public interface BahmniProgramWorkflowService extends ProgramWorkflowService { + + @Transactional(readOnly = true) + @Authorized({"View Patient Programs"}) + Collection getEncountersByPatientProgramUuid(String patientProgramUuid); + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniVisitService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniVisitService.java new file mode 100644 index 0000000000..65f5618e3d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/BahmniVisitService.java @@ -0,0 +1,14 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Encounter; +import org.openmrs.Visit; + +import java.util.List; + +public interface BahmniVisitService { + public Visit getLatestVisit(String patientUuid, String conceptName); + + Visit getVisitSummary(String visitUuid); + + List getAdmitAndDischargeEncounters(Integer visitId); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/DiseaseTemplateService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/DiseaseTemplateService.java new file mode 100644 index 0000000000..09745a5939 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/DiseaseTemplateService.java @@ -0,0 +1,13 @@ +package org.bahmni.module.bahmnicore.service; + +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplate; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplatesConfig; + +import java.util.List; + +public interface DiseaseTemplateService { + + List allDiseaseTemplatesFor(DiseaseTemplatesConfig diseaseTemplatesConfig); + + DiseaseTemplate diseaseTemplateFor(DiseaseTemplatesConfig diseaseTemplatesConfig); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java new file mode 100644 index 0000000000..b58d24cb5d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/NoteService.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.service; + + +import java.util.Date; +import java.util.List; + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.openmrs.annotation.Authorized; +import org.openmrs.api.APIException; +import org.openmrs.util.PrivilegeConstants; +import org.springframework.transaction.annotation.Transactional; + + +public interface NoteService { + + @Transactional + @Authorized(PrivilegeConstants.GET_NOTE) + List getNotes(Date noteStartDate, Date noteEndDate, String noteType) throws Exception; + + @Transactional + Note createNote(Note note); + + @Transactional + Note updateNote(Integer id, NoteRequestResponse noteRequestResponse); + + @Transactional + @Authorized(PrivilegeConstants.DELETE_NOTE) + Note voidNote(Integer id, String reason); + + @Transactional + List createNotes(List notes); + + @Transactional + NoteType getNoteType(String name); + + @Transactional + @Authorized(PrivilegeConstants.GET_NOTE) + Note getNote(Date noteDate, String noteType); + + @Transactional + Note getNoteById(Integer id); + + @Transactional + Note getNoteByUuid(String uuid); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/OrderService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/OrderService.java new file mode 100644 index 0000000000..6800c02204 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/OrderService.java @@ -0,0 +1,23 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; + +import java.util.List; + +public interface OrderService { + List getPendingOrders(String patientUuid, String orderTypeUuid); + + List getAllOrders(String patientUuid, String orderTypeUuid, Integer offset, Integer limit, List locationUuids); + + List getVisitsWithOrders(Patient patient, String orderType, Boolean includeActiveVisit, Integer numberOfVisits); + + List getAllOrdersForVisits(String patientUuid, String orderType, Integer numberOfVisits); + + Order getOrderByUuid(String orderUuid); + + List getAllOrdersForVisitUuid(String visitUuid, String orderTypeUuid); + + Order getChildOrder(Order order); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/PatientDocumentService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/PatientDocumentService.java new file mode 100644 index 0000000000..ad55e69877 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/PatientDocumentService.java @@ -0,0 +1,11 @@ +package org.bahmni.module.bahmnicore.service; + +import org.springframework.http.ResponseEntity; + +public interface PatientDocumentService { + public void saveImage(String patientIdentifier, String image); + public String saveDocument(Integer patientId, String encounterTypeName, String content, String format, String fileType, String fileName); + public ResponseEntity retriveImage(String patientUuid); + + void delete(String fileName); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/RowMapper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/RowMapper.java new file mode 100644 index 0000000000..88da015ef0 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/RowMapper.java @@ -0,0 +1,28 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.module.webservices.rest.SimpleObject; +import org.springframework.jdbc.support.JdbcUtils; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +public class RowMapper { + + public SimpleObject mapRow(ResultSet rs) throws SQLException { + SimpleObject row = new SimpleObject(); + ResultSetMetaData rsmd = rs.getMetaData(); + int columnCount = rsmd.getColumnCount(); + for (int index = 1; index <= columnCount; index++) { + String column = JdbcUtils.lookupColumnName(rsmd, index); + Object value = rs.getObject(column); + if (value == null) { + row.put(column, ""); + } else { + row.put(column, value); + } + } + return row; + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchService.java new file mode 100644 index 0000000000..0ee1c97a7f --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchService.java @@ -0,0 +1,14 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.annotation.Authorized; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.util.List; +import java.util.Map; + +public interface SqlSearchService { + + @Authorized + public List search(String sqlQuery, Map params); + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/ThumbnailGenerator.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/ThumbnailGenerator.java new file mode 100644 index 0000000000..0e89641812 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/ThumbnailGenerator.java @@ -0,0 +1,10 @@ +package org.bahmni.module.bahmnicore.service; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public interface ThumbnailGenerator { + boolean isFormatSupported(String format); + BufferedImage generateThumbnail(File video) throws IOException; +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java new file mode 100644 index 0000000000..085da4c723 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/TsConceptSearchService.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.service; + +import org.openmrs.annotation.Authorized; +import org.openmrs.api.OpenmrsService; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.util.List; + +public interface TsConceptSearchService extends OpenmrsService { + @Authorized(value = {"Get Concepts"}) + List getConcepts(String query, Integer limit, String locale); +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniAddressHierarchyServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniAddressHierarchyServiceImpl.java new file mode 100644 index 0000000000..4f7017f839 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniAddressHierarchyServiceImpl.java @@ -0,0 +1,26 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniAddressHierarchyDao; +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; +import org.bahmni.module.bahmnicore.service.BahmniAddressHierarchyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Component +@Transactional +public class BahmniAddressHierarchyServiceImpl implements BahmniAddressHierarchyService { + private BahmniAddressHierarchyDao bahmniAddressHierarchyDao; + + @Autowired + public BahmniAddressHierarchyServiceImpl(BahmniAddressHierarchyDao bahmniAddressHierarchyDao) { + this.bahmniAddressHierarchyDao = bahmniAddressHierarchyDao; + } + + @Override + public List getAddressHierarchyEntriesByUuid(List uuids) { + return bahmniAddressHierarchyDao.getAddressHierarchyEntriesByUuid(uuids); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java new file mode 100644 index 0000000000..a875997c7b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridge.java @@ -0,0 +1,252 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.joda.time.LocalDate; +import org.joda.time.Years; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.PersonAttributeType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.mapper.OrderMapper1_12; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +/** + * Bridge between extension scripts of Bahmni and Bahmni core as well as OpenMRS core. + */ +@Component +@Scope("prototype") +public class BahmniBridge { + + private String patientUuid; + private String patientProgramUuid; + private String visitUUid; + + private ObsDao obsDao; + private PatientService patientService; + private PersonService personService; + private ConceptService conceptService; + private OrderDao orderDao; + private BahmniDrugOrderService bahmniDrugOrderService; + private OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper; + private BahmniConceptService bahmniConceptService; + + private OrderMapper1_12 drugOrderMapper = new OrderMapper1_12(); + /** + * Factory method to construct objects of BahmniBridge. + * This is provided so that BahmniBridge can be called by extensions without having to use the + * Spring application context. Prefer using this as opposed to the constructor. + * + * @return instance of BahmniBridge registered with OpenMRS Context + */ + public static BahmniBridge create() { + return Context.getRegisteredComponents(BahmniBridge.class).iterator().next(); + } + + @Autowired + public BahmniBridge(ObsDao obsDao, PatientService patientService, PersonService personService, ConceptService conceptService, OrderDao orderDao, BahmniDrugOrderService bahmniDrugOrderService, OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper, BahmniConceptService bahmniConceptService) { + this.obsDao = obsDao; + this.patientService = patientService; + this.personService = personService; + this.conceptService = conceptService; + this.orderDao = orderDao; + this.bahmniDrugOrderService = bahmniDrugOrderService; + this.omrsObsToBahmniObsMapper = omrsObsToBahmniObsMapper; + this.bahmniConceptService = bahmniConceptService; + } + + /** + * Set patient uuid. This will be used by methods that require the patient to perform its operations. + * Setting patient uuid might be mandatory depending on the operation you intend to perform using the bridge. + * + * @param patientUuid uuid of the patient + * @return reference to the instance + */ + public BahmniBridge forPatient(String patientUuid) { + this.patientUuid = patientUuid; + return this; + } + + /** + * Set patient program uuid. This will be used by methods that require the patient to perform its operations associated with a specific program. + * Setting patient program uuid might be mandatory depending on the operation you intend to perform using the bridge. + * + * @param patientProgramUuid patient's program uuid + * @return reference to the instance + */ + public BahmniBridge forPatientProgram(String patientProgramUuid) { + this.patientProgramUuid = patientProgramUuid; + return this; + } + + /** + * Set visit uuid. This will be used by methods that require a visit to perform its operations. + * Setting visit uuid might be mandatory depending on the operation you intend to perform using the bridge. + * + * @param visitUuid visit uuid + * @return reference to the instance + */ + public BahmniBridge forVisit(String visitUuid) { + this.visitUUid = visitUuid; + return this; + } + + /** + * Retrieve last observation for patientUuid set using {@link org.bahmni.module.bahmnicore.service.impl.BahmniBridge#forPatient(String)} + * for the given conceptName. + * + * @param conceptName concept name FSN in preferred language + * @return latest obs captured for the concept + */ + public Obs latestObs(String conceptName) { + List obsList; + List conceptNames = new ArrayList<>(); + conceptNames.add(conceptName); + if (patientProgramUuid != null) { + obsList = obsDao.getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, conceptNames, 1, ObsDaoImpl.OrderBy.DESC, null, null); + } else { + obsList = obsDao.getLatestObsFor(patientUuid, conceptName, 1); + } + if (obsList.size() > 0) { + return obsList.get(0); + } + return null; + } + + /** + * Retrieve age in years for patientUuid set using {@link org.bahmni.module.bahmnicore.service.impl.BahmniBridge#forPatient(String)} + * + * @param asOfDate date as of today + * @return age in years + */ + public Integer ageInYears(Date asOfDate) { + Date birthdate = patientService.getPatientByUuid(patientUuid).getBirthdate(); + return Years.yearsBetween(new LocalDate(birthdate), new LocalDate(asOfDate)).getYears(); + + } + + /** + * Retrieve drug orders set for regimenName + * + * @param regimenName drug regimen name + * @return list of DrugOrder + */ + public Collection drugOrdersForRegimen(String regimenName) { + return orderDao.getDrugOrderForRegimen(regimenName); + } + + /** + * Retrieve active Drug orders for patientUuid + * + * @return List of Drug Order + */ + public List activeDrugOrdersForPatient() { + List activeOpenMRSDrugOrders = bahmniDrugOrderService.getActiveDrugOrders(patientUuid); + List drugOrders = new ArrayList<>(); + for (DrugOrder activeOpenMRSDrugOrder : activeOpenMRSDrugOrders) { + EncounterTransaction.DrugOrder drugOrder = drugOrderMapper.mapDrugOrder(activeOpenMRSDrugOrder); + if ((isNotScheduled(drugOrder) || hasScheduledOrderBecameActive(drugOrder)) && isNotStopped(drugOrder)) { + drugOrders.add(drugOrder); + } + } + return drugOrders; + } + + /** + * Retrieve person attribute type for attributeType + * @param attributeType name of the attribute + * @return patient attribute def + */ + public PersonAttributeType getPersonAttributeType(String attributeType) { + return personService.getPersonAttributeTypeByName(attributeType); + } + + /** + * Retrieve concept for conceptName + * + * @return concept identified by name + */ + public Concept getConcept(String conceptName) { + return conceptService.getConceptByName(conceptName); + } + private boolean isNotScheduled(EncounterTransaction.DrugOrder drugOrder) { + return drugOrder.getScheduledDate() == null; + } + + private boolean isNotStopped(EncounterTransaction.DrugOrder drugOrder) { + return drugOrder.getEffectiveStopDate() == null || drugOrder.getEffectiveStopDate().after(new Date()); + } + + private boolean hasScheduledOrderBecameActive(EncounterTransaction.DrugOrder drugOrder) { + + return drugOrder.getScheduledDate().before(new Date()); + } + + /** + * Retrieve concept by FullySpecifiedName + */ + + public Concept getConceptByFullySpecifiedName(String conceptName) { + return bahmniConceptService.getConceptByFullySpecifiedName(conceptName); + } + + /** + * Retrieve concept for conceptName + * + * @return start date of treatment + */ + public Date getStartDateOfTreatment() throws ParseException { + List allDrugOrders = bahmniDrugOrderService.getAllDrugOrders(patientUuid, null, null, null, null); + + sortOders(allDrugOrders); + return allDrugOrders.get(0).getScheduledDate() !=null ? allDrugOrders.get(0).getScheduledDate() : allDrugOrders.get(0).getDateActivated(); + } + + private void sortOders(List drugOrders) { + Collections.sort(drugOrders, new Comparator() { + @Override + public int compare(Order o1, Order o2) { + if (o1.getDateActivated().before(o2.getDateActivated())) + return -1; + else if (o1.getDateActivated().after(o2.getDateActivated())) + return 1; + else + return 0; + } + }); + } + + public BahmniObservation getChildObsFromParentObs(String parentObsGroupUuid, String childConceptName){ + Concept childConcept = conceptService.getConceptByName(childConceptName); + return omrsObsToBahmniObsMapper.map(obsDao.getChildObsFromParent(parentObsGroupUuid, childConcept), null); + } + + public BahmniObservation getLatestBahmniObservationFor(String conceptName){ + Obs obs = latestObs(conceptName); + if(obs != null) { + return omrsObsToBahmniObsMapper.map(obs, null); + } + return null; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniConceptServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniConceptServiceImpl.java new file mode 100644 index 0000000000..8a0d405dc9 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniConceptServiceImpl.java @@ -0,0 +1,86 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniConceptDao; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Component +@Transactional +public class BahmniConceptServiceImpl implements BahmniConceptService{ + + private ConceptService conceptService; + private ConceptMapper conceptMapper; + private BahmniConceptDao bahmniConceptDao; + + @Autowired + public BahmniConceptServiceImpl(ConceptService conceptService, BahmniConceptDao bahmniConceptDao) { + this.conceptService = conceptService; + this.bahmniConceptDao = bahmniConceptDao; + this.conceptMapper = new ConceptMapper(); + } + + @Override + @Transactional(readOnly = true) + public EncounterTransaction.Concept getConceptByName(String conceptName) { + Concept concept = conceptByName(conceptName); + if (concept == null) { + return new EncounterTransaction.Concept(null, conceptName, false, null, null, null, null,null); + } + return convertToContract(concept); + } + + @Override + @Transactional(readOnly = true) + public Collection searchByQuestion(String questionConceptName, String query) { + return bahmniConceptDao.searchByQuestion(getConcept(questionConceptName), query); + } + + @Override + @Transactional(readOnly = true) + public List getDrugsByConceptSetName(String conceptSetName, String searchTerm) { + return bahmniConceptDao.searchDrugsByDrugName(getConcept(conceptSetName).getId(), searchTerm); + } + + @Override + @Transactional(readOnly = true) + public Concept getConceptByFullySpecifiedName(String drug) { + return bahmniConceptDao.getConceptByFullySpecifiedName(drug); + } + + @Override + public List getConceptsByFullySpecifiedName(List conceptNames) { + if(conceptNames == null || conceptNames.isEmpty()){ + return Collections.EMPTY_LIST; + } + return bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + } + + private Concept getConcept(String conceptSetName) { + Concept conceptSet = bahmniConceptDao.getConceptByFullySpecifiedName(conceptSetName); + if (conceptSet == null) { + throw new ConceptNotFoundException("Concept '" + conceptSetName + "' not found"); + } + return conceptSet; + } + + private EncounterTransaction.Concept convertToContract(Concept concept) { + return conceptMapper.map(concept); + } + + private Concept conceptByName(String conceptName) { + return conceptService.getConceptByName(conceptName); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java new file mode 100644 index 0000000000..d5c19eb7ce --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImpl.java @@ -0,0 +1,229 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.openmrs.Concept; +import org.openmrs.ConceptSource; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ObsService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.diagnosis.helper.BahmniDiagnosisMetadata; +import org.openmrs.module.emrapi.EmrApiProperties; +import org.openmrs.module.emrapi.diagnosis.Diagnosis; +import org.openmrs.module.emrapi.diagnosis.DiagnosisService; +import org.openmrs.module.emrapi.encounter.DiagnosisMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +public class BahmniDiagnosisServiceImpl implements BahmniDiagnosisService { + + private static final String BAHMNI_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED = "bahmni.lookupExternalTerminologyServer"; + private static final boolean DEFAULT_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED = false; + + private EncounterService encounterService; + private ObsService obsService; + private VisitService visitService; + private PatientService patientService; + private DiagnosisMapper diagnosisMapper; + private BahmniDiagnosisMetadata bahmniDiagnosisMetadata; + private ConceptService conceptService; + private EmrApiProperties emrApiProperties; + private AdministrationService administrationService; + + @Autowired + public BahmniDiagnosisServiceImpl(EncounterService encounterService, ObsService obsService, VisitService visitService, PatientService patientService, DiagnosisMapper diagnosisMapper, BahmniDiagnosisMetadata bahmniDiagnosisMetadata, ConceptService conceptService, EmrApiProperties emrApiProperties, @Qualifier("adminService") AdministrationService administrationService) { + this.encounterService = encounterService; + this.obsService = obsService; + this.visitService = visitService; + this.patientService = patientService; + this.diagnosisMapper = diagnosisMapper; + this.bahmniDiagnosisMetadata = bahmniDiagnosisMetadata; + this.conceptService = conceptService; + this.emrApiProperties = emrApiProperties; + this.administrationService = administrationService; + } + + @Override + public void delete(String visitDiagnosesObservationUuid) { + Obs visitDiagnosisObs = obsService.getObsByUuid(visitDiagnosesObservationUuid); + String initialVisitDiagnosisUuid = bahmniDiagnosisMetadata.findInitialDiagnosisUuid(visitDiagnosisObs); + voidAllDiagnosisWithSameInitialDiagnosis(initialVisitDiagnosisUuid, visitDiagnosisObs); + } + + private void voidAllDiagnosisWithSameInitialDiagnosis(String initialVisitDiagnosisUuid, Obs visitDiagnosisObs) { + //find observations for this patient and concept + List observations = obsService.getObservationsByPersonAndConcept(visitDiagnosisObs.getPerson(), visitDiagnosisObs.getConcept()); + for (Obs observation : observations) { + for (Obs obs : observation.getGroupMembers()) { + if (initialVisitDiagnosisUuid.equals(obs.getValueText())) { + voidDiagnosis(observation); + break; + } + } + } + } + + + private List getDiagnosisByPatient(Patient patient, Visit visit) { + List diagnoses = new ArrayList(); + + List observations = obsService.getObservations(Arrays.asList((Person) patient), new ArrayList<>(visit.getEncounters()), + Arrays.asList(bahmniDiagnosisMetadata.getDiagnosisSetConcept()), null, null, null, Arrays.asList("obsDatetime"), + null, null, null, null, false); + + Collection nonDiagnosisConcepts = emrApiProperties.getSuppressedDiagnosisConcepts(); + Collection nonDiagnosisConceptSets = emrApiProperties.getNonDiagnosisConceptSets(); + + for (Obs obs : observations) { + Diagnosis diagnosis = bahmniDiagnosisMetadata.buildDiagnosisFromObsGroup(obs, nonDiagnosisConcepts, nonDiagnosisConceptSets); + if (diagnosis != null) { + diagnoses.add(diagnosis); + } + } + return diagnoses; + } + + private void addDiagnosisToCollectionIfRecent(List bahmniDiagnosisRequests, BahmniDiagnosisRequest bahmniDiagnosisRequestNew) { + String existingObsForNewDiag = bahmniDiagnosisRequestNew.getFirstDiagnosis().getExistingObs(); + Iterator bahmniIterator = bahmniDiagnosisRequests.iterator(); + boolean addFlag = true; + while (bahmniIterator.hasNext()) { + BahmniDiagnosisRequest bahmniDiagnosisRequestFromList = bahmniIterator.next(); + String existingObsOfDiagFromList = bahmniDiagnosisRequestFromList.getFirstDiagnosis().getExistingObs(); + if (existingObsOfDiagFromList.equals(existingObsForNewDiag)) { + if (bahmniDiagnosisRequestFromList.getDiagnosisDateTime().getTime() > bahmniDiagnosisRequestFromList.getDiagnosisDateTime().getTime()) { + bahmniIterator.remove(); + break; + } else { + addFlag = false; + break; + } + } + } + if (addFlag) { + bahmniDiagnosisRequests.add(bahmniDiagnosisRequestNew); + } + } + + public List getBahmniDiagnosisByPatientAndVisit(String patientUuid, String visitUuid) { + Patient patient = patientService.getPatientByUuid(patientUuid); + Visit visit = visitService.getVisitByUuid(visitUuid); + + if (visit == null || CollectionUtils.isEmpty(visit.getEncounters())) { + return new ArrayList<>(); + } + List diagnosisByVisit = getDiagnosisByPatient(patient, visit); + + List bahmniDiagnosisRequests = new ArrayList<>(); + boolean diagnosisSchemaContainsStatus = bahmniDiagnosisMetadata.diagnosisSchemaContainsStatus(); + Concept bahmniDiagnosisRevised = bahmniDiagnosisMetadata.getBahmniDiagnosisRevisedConcept(); + Collection nonDiagnosisConcepts = emrApiProperties.getSuppressedDiagnosisConcepts(); + Collection nonDiagnosisConceptSets = emrApiProperties.getNonDiagnosisConceptSets(); + + for (Diagnosis diagnosis : diagnosisByVisit) { + + EncounterTransaction.Diagnosis etDiagnosis = diagnosisMapper.convert(diagnosis); + Obs latestObsGroup = getLatestObsGroupBasedOnAnyDiagnosis(diagnosis, bahmniDiagnosisRevised); + Diagnosis latestDiagnosis = bahmniDiagnosisMetadata.buildDiagnosisFromObsGroup(latestObsGroup, nonDiagnosisConcepts, nonDiagnosisConceptSets); //buildDiagnosisFromObsGroup(getBahmniDiagnosisHelper().getLatestBasedOnAnyDiagnosis(diagnosis)); + EncounterTransaction.Diagnosis etLatestDiagnosis = diagnosisMapper.convert(latestDiagnosis); + BahmniDiagnosisRequest bahmniDiagnosisRequestNew = bahmniDiagnosisMetadata.mapBahmniDiagnosis(etDiagnosis, + etLatestDiagnosis, true, false, diagnosisSchemaContainsStatus, true); + addDiagnosisToCollectionIfRecent(bahmniDiagnosisRequests, bahmniDiagnosisRequestNew); + } + + return bahmniDiagnosisRequests; + } + + private Obs getLatestObsGroupBasedOnAnyDiagnosis(Diagnosis diagnosis, Concept bahmniDiagnosisRevised) { + String initialDiagnosisUuid = bahmniDiagnosisMetadata.findInitialDiagnosisUuid(diagnosis.getExistingObs()); + + List observations = obsService.getObservations(Arrays.asList(diagnosis.getExistingObs().getPerson()), null, + Arrays.asList(bahmniDiagnosisRevised), + Arrays.asList(conceptService.getFalseConcept()), null, null, null, + null, null, null, null, false); + + for (Obs obs : observations) { + Obs diagnosisObsGroup = obs.getObsGroup(); + //This is main diagosis group. Now, find the initialDiagnosis. Also ensure that this is visitDiagnosis?? + Obs bahmniInitialDiagnosis = bahmniDiagnosisMetadata.findInitialDiagnosis(diagnosisObsGroup); + if (initialDiagnosisUuid.equals(bahmniInitialDiagnosis.getValueText())) { + return diagnosisObsGroup; + } + } + + return null; + } + + public List getBahmniDiagnosisByPatientAndDate(String patientUuid, String date) throws ParseException { + Patient patient = patientService.getPatientByUuid(patientUuid); + + Date fromDate = date != null ? new SimpleDateFormat("yyyy-MM-dd").parse(date) : null; + List diagnosisByPatientAndDate = Context.getService(DiagnosisService.class).getDiagnoses(patient, fromDate); + + List bahmniDiagnosisRequests = new ArrayList<>(); + boolean diagnosisSchemaContainsStatus = bahmniDiagnosisMetadata.diagnosisSchemaContainsStatus(); + + for (Diagnosis diagnosis : diagnosisByPatientAndDate) { + EncounterTransaction.Diagnosis etDiagnosis = diagnosisMapper.convert(diagnosis); + BahmniDiagnosisRequest bahmniDiagnosisRequest = bahmniDiagnosisMetadata.mapBahmniDiagnosis(etDiagnosis, + null, true, false, diagnosisSchemaContainsStatus,false); + + if (bahmniDiagnosisRequest != null) { + bahmniDiagnosisRequests.add(bahmniDiagnosisRequest); + } + } + + return bahmniDiagnosisRequests; + } + + private void voidDiagnosis(Obs observation) { + voidObsAndItsChildren(observation); + encounterService.saveEncounter(observation.getEncounter()); + } + + private void voidObsAndItsChildren(Obs obs) { + obs.setVoided(true); + if (obs.getGroupMembers() == null) + return; + for (Obs childObs : obs.getGroupMembers()) { + voidObsAndItsChildren(childObs); + } + } + + @Override + public boolean isExternalTerminologyServerLookupNeeded() { + String externalTSLookupNeeded = administrationService.getGlobalProperty(BAHMNI_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED); + return StringUtils.isNotBlank(externalTSLookupNeeded) ? Boolean.valueOf(externalTSLookupNeeded) : DEFAULT_EXTERNAL_TERMINOLOGY_SERVER_LOOKUP_NEEDED; + } + + @Override + public Collection getDiagnosisSets() { + return emrApiProperties.getDiagnosisSets(); + } + + @Override + public List getConceptSourcesForDiagnosisSearch() { + return emrApiProperties.getConceptSourcesForDiagnosisSearch(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java new file mode 100644 index 0000000000..e7631f8f1b --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImpl.java @@ -0,0 +1,244 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.contract.drugorder.ConceptData; +import org.bahmni.module.bahmnicore.contract.drugorder.DrugOrderConfigResponse; +import org.bahmni.module.bahmnicore.contract.drugorder.OrderFrequencyData; +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.openmrs.CareSetting; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.OrderFrequency; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniOrderAttribute; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniDrugOrderMapper; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.utils.HibernateLazyLoader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class BahmniDrugOrderServiceImpl implements BahmniDrugOrderService { + private ConceptService conceptService; + private OrderService orderService; + private PatientService openmrsPatientService; + private OrderDao orderDao; + private ConceptMapper conceptMapper = new ConceptMapper(); + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + private BahmniDrugOrderMapper bahmniDrugOrderMapper; + + + private static final String GP_DOSING_INSTRUCTIONS_CONCEPT_UUID = "order.dosingInstructionsConceptUuid"; + private static Logger logger = LogManager.getLogger(BahmniDrugOrderService.class); + + + @Autowired + public BahmniDrugOrderServiceImpl(ConceptService conceptService, OrderService orderService, + PatientService patientService, OrderDao orderDao, BahmniProgramWorkflowService bahmniProgramWorkflowService) { + this.conceptService = conceptService; + this.orderService = orderService; + this.openmrsPatientService = patientService; + this.orderDao = orderDao; + this.bahmniProgramWorkflowService = bahmniProgramWorkflowService; + this.bahmniDrugOrderMapper = new BahmniDrugOrderMapper(); + } + + + @Override + public List getActiveDrugOrders(String patientUuid) { + return getActiveDrugOrders(patientUuid, new Date(), null, null, null, null, null); + } + + @Override + public List getActiveDrugOrders(String patientUuid, Date startDate, Date endDate) { + return getActiveDrugOrders(patientUuid, new Date(), null, null, startDate, endDate, null); + } + + @Override + public List getPrescribedDrugOrders(List visitUuids, String patientUuid, Boolean includeActiveVisit, Integer numberOfVisits, Date startDate, Date endDate, Boolean getEffectiveOrdersOnly) { + if(CollectionUtils.isNotEmpty(visitUuids)) { + return orderDao.getPrescribedDrugOrders(visitUuids); + } else { + Patient patient = openmrsPatientService.getPatientByUuid(patientUuid); + return orderDao.getPrescribedDrugOrders(patient, includeActiveVisit, numberOfVisits, startDate, endDate, getEffectiveOrdersOnly); + } + } + + public Map getDiscontinuedDrugOrders(List drugOrders){ + return orderDao.getDiscontinuedDrugOrders(drugOrders); + } + + @Override + public List getInactiveDrugOrders(String patientUuid, Set concepts, Set drugConceptsToBeExcluded, + Collection encounters) { + Patient patient = openmrsPatientService.getPatientByUuid(patientUuid); + CareSetting outPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); + CareSetting inPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.INPATIENT.toString()); + Date asOfDate = new Date(); + List outPatientOrders = orderDao.getInactiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + outPatientCareSetting, asOfDate, concepts, drugConceptsToBeExcluded, encounters); + List inPatientOrders = orderDao.getInactiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + inPatientCareSetting, asOfDate, concepts, drugConceptsToBeExcluded, encounters); + List allActiveDrugOrders = new ArrayList<>(); + allActiveDrugOrders.addAll(outPatientOrders); + allActiveDrugOrders.addAll(inPatientOrders); + return mapOrderToDrugOrder(allActiveDrugOrders); + } + + @Override + public List getDrugOrders(String patientUuid, Boolean isActive, Set drugConceptsToBeFiltered, + Set drugConceptsToBeExcluded, String patientProgramUuid) throws ParseException { + Collection programEncounters = null; + if (patientProgramUuid != null) { + programEncounters = bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); + if(programEncounters.isEmpty()){ + return new ArrayList<>(); + } + } + List drugOrders; + + if (isActive == null) { + List orders = getAllDrugOrders(patientUuid, null, drugConceptsToBeFiltered, drugConceptsToBeExcluded, programEncounters); + drugOrders = mapOrderToDrugOrder(orders); + } else if (isActive) { + drugOrders = getActiveDrugOrders(patientUuid, new Date(), drugConceptsToBeFiltered, drugConceptsToBeExcluded, null, null, programEncounters); + } else { + drugOrders = getInactiveDrugOrders(patientUuid, drugConceptsToBeFiltered, drugConceptsToBeExcluded, programEncounters); + } + + Map discontinuedDrugOrderMap = getDiscontinuedDrugOrders(drugOrders); + try { + return bahmniDrugOrderMapper.mapToResponse(drugOrders, null, discontinuedDrugOrderMap, null); + } catch (IOException e) { + logger.error("Could not parse dosing instructions", e); + throw new RuntimeException("Could not parse dosing instructions", e); + + } + } + + @Override + public DrugOrder getDrugOrderByOrderId(String orderId) { + Order order = orderDao.getOrderByUuid(orderId); + List drugOrders = mapOrderToDrugOrder(Collections.singletonList(order)); + return drugOrders.get(0); + } + + @Override + public List getPrescribedDrugOrdersForConcepts(Patient patient, Boolean includeActiveVisit, List visits, List concepts, Date startDate, Date endDate) { + if( concepts == null || concepts.isEmpty()){ + return new ArrayList<>(); + } + return orderDao.getPrescribedDrugOrdersForConcepts(patient, includeActiveVisit, visits, concepts, startDate, endDate); + } + + @Override + public DrugOrderConfigResponse getConfig() { + DrugOrderConfigResponse response = new DrugOrderConfigResponse(); + response.setFrequencies(getFrequencies()); + response.setRoutes(mapConcepts(orderService.getDrugRoutes())); + response.setDoseUnits(mapConcepts(orderService.getDrugDosingUnits())); + response.setDurationUnits(mapConcepts(orderService.getDurationUnits())); + response.setDispensingUnits(mapConcepts(orderService.getDrugDispensingUnits())); + response.setDosingInstructions(mapConcepts(getSetMembersOfConceptSetFromGP(GP_DOSING_INSTRUCTIONS_CONCEPT_UUID))); + response.setOrderAttributes(fetchOrderAttributeConcepts()); + return response; + } + + @Override + public List getAllDrugOrders(String patientUuid, String patientProgramUuid, Set conceptsForDrugs, + Set drugConceptsToBeExcluded, Collection encounters) throws ParseException { + Patient patientByUuid = openmrsPatientService.getPatientByUuid(patientUuid); + OrderType orderTypeByUuid = orderService.getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID); + if (patientProgramUuid != null) { + return orderDao.getOrdersByPatientProgram(patientProgramUuid, orderTypeByUuid, conceptsForDrugs); + } + return orderDao.getAllOrders(patientByUuid, orderTypeByUuid, conceptsForDrugs, drugConceptsToBeExcluded, encounters); + } + + private List fetchOrderAttributeConcepts() { + Concept orderAttributesConceptSet = conceptService.getConceptByName(BahmniOrderAttribute.ORDER_ATTRIBUTES_CONCEPT_SET_NAME); + if(orderAttributesConceptSet != null){ + List etOrderAttributeConcepts = new ArrayList<>(); + List orderAttributes = orderAttributesConceptSet.getSetMembers(); + for (Concept orderAttribute : orderAttributes) { + etOrderAttributeConcepts.add(conceptMapper.map(orderAttribute)); + } + return etOrderAttributeConcepts; + } + return Collections.EMPTY_LIST; + } + + private List getSetMembersOfConceptSetFromGP(String globalProperty) { + String conceptUuid = Context.getAdministrationService().getGlobalProperty(globalProperty); + Concept concept = Context.getConceptService().getConceptByUuid(conceptUuid); + if (concept != null && concept.isSet()) { + return concept.getSetMembers(); + } + return Collections.emptyList(); + } + + private List mapConcepts(List drugDosingUnits) { + return drugDosingUnits.stream().map((concept) -> new ConceptData(concept)) + .collect(Collectors.toList()); + } + + private List getFrequencies() { + List orderFrequencies = orderService.getOrderFrequencies(false); + return orderFrequencies.stream().map((orderFrequency) -> new OrderFrequencyData(orderFrequency)) + .collect(Collectors.toList()); + } + + + private List getActiveDrugOrders(String patientUuid, Date asOfDate, Set conceptsToFilter, + Set conceptsToExclude, Date startDate, Date endDate, Collection encounters) { + Patient patient = openmrsPatientService.getPatientByUuid(patientUuid); + CareSetting outPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); + CareSetting inPatientCareSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.INPATIENT.toString()); + List outPatientOrders = orderDao.getActiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + outPatientCareSetting, asOfDate, conceptsToFilter, conceptsToExclude, startDate, endDate, encounters); + List inPatientOrders = orderDao.getActiveOrders(patient, orderService.getOrderTypeByName("Drug order"), + inPatientCareSetting, asOfDate, conceptsToFilter, conceptsToExclude, startDate, endDate, encounters); + List allActiveDrugOrders = new ArrayList<>(); + allActiveDrugOrders.addAll(outPatientOrders); + allActiveDrugOrders.addAll(inPatientOrders); + return mapOrderToDrugOrder(allActiveDrugOrders); + } + + private List mapOrderToDrugOrder(List orders){ + HibernateLazyLoader hibernateLazyLoader = new HibernateLazyLoader(); + List drugOrders = new ArrayList<>(); + for(Order order: orders){ + order = hibernateLazyLoader.load(order); + if(order instanceof DrugOrder) { + drugOrders.add((DrugOrder) order); + } + } + return drugOrders; + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniEncounterModifierServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniEncounterModifierServiceImpl.java new file mode 100644 index 0000000000..30ccaa0cb1 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniEncounterModifierServiceImpl.java @@ -0,0 +1,68 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import groovy.lang.GroovyClassLoader; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.contract.encounter.data.EncounterModifierData; +import org.bahmni.module.bahmnicore.encounterModifier.EncounterModifier; +import org.bahmni.module.bahmnicore.encounterModifier.exception.CannotModifyEncounterException; +import org.bahmni.module.bahmnicore.service.BahmniEncounterModifierService; +import org.openmrs.api.context.Context; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +@Service +public class BahmniEncounterModifierServiceImpl implements BahmniEncounterModifierService { + + public static final String ENCOUNTER_MODIFIER_ALGORITHM_DIRECTORY = "/encounterModifier/"; + public static final String ENCOUNTER_MODIFIER_GROOVY_ALLOW_CACHING = "encounterModifier.groovy.allowCaching"; + protected Map encounterModifiers = new HashMap<>(); + + private static final Logger log = LogManager.getLogger(BahmniEncounterModifierServiceImpl.class); + + @Override + public EncounterModifierData getModifiedEncounter(EncounterModifierData encounterModifierData) throws IllegalAccessException, IOException, InstantiationException, CannotModifyEncounterException { + String encounterModifierClassName = encounterModifierData.getConceptSetData().getName().replaceAll(" ", "").concat(".groovy"); + return modifyEncounter(encounterModifierData, encounterModifierClassName); + } + + private EncounterModifierData modifyEncounter(EncounterModifierData encounterModifierData, String encounterModifierClassName) throws IllegalAccessException, IOException, InstantiationException, CannotModifyEncounterException { + if (StringUtils.isEmpty(encounterModifierData.getConceptSetData().getName())) { + return encounterModifierData; + } + EncounterModifier encounterModifier = getEncounterModifierAlgorithm(encounterModifierClassName); + log.debug("EncounterModifier : Using Algorithm in " + encounterModifier.getClass().getName()); + return encounterModifier.run(encounterModifierData); + } + + private EncounterModifier getEncounterModifierAlgorithm(String encounterModifierClassName) throws IOException, InstantiationException, IllegalAccessException { + if(isGroovyCachingAllowed()){ + EncounterModifier encounterModifier = encounterModifiers.get(encounterModifierClassName); + if (encounterModifier == null) { + encounterModifiers.put(encounterModifierClassName, loadGroovyClass(encounterModifierClassName)); + } + return encounterModifiers.get(encounterModifierClassName); + } + return loadGroovyClass(encounterModifierClassName); + } + + private EncounterModifier loadGroovyClass(String encounterModifierClassName) throws IOException, InstantiationException, IllegalAccessException { + Class clazz = new GroovyClassLoader().parseClass(new File(getEncounterModifierClassPath(encounterModifierClassName))); + return (EncounterModifier) clazz.newInstance(); + } + + private String getEncounterModifierClassPath(String encounterModifierClassName) { + return OpenmrsUtil.getApplicationDataDirectory() + ENCOUNTER_MODIFIER_ALGORITHM_DIRECTORY + encounterModifierClassName ; + } + + private boolean isGroovyCachingAllowed(){ + String globalProperty = Context.getAdministrationService().getGlobalProperty(ENCOUNTER_MODIFIER_GROOVY_ALLOW_CACHING); + return Boolean.valueOf(globalProperty); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java new file mode 100644 index 0000000000..5c9087d468 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImpl.java @@ -0,0 +1,416 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; +import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl.OrderBy; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.util.MiscUtils; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Person; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class BahmniObsServiceImpl implements BahmniObsService { + + private ObsDao obsDao; + private VisitDao visitDao; + private OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper; + private VisitService visitService; + private ConceptService conceptService; + private BahmniProgramWorkflowService programWorkflowService; + private ObsService obsService; + + @Autowired + public BahmniObsServiceImpl(ObsDao obsDao, OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper, VisitService visitService, ConceptService conceptService, VisitDao visitDao, BahmniProgramWorkflowService programWorkflowService, ObsService obsService) { + this.obsDao = obsDao; + this.omrsObsToBahmniObsMapper = omrsObsToBahmniObsMapper; + this.visitService = visitService; + this.conceptService = conceptService; + this.visitDao = visitDao; + this.programWorkflowService = programWorkflowService; + this.obsService = obsService; + } + + @Override + public List getObsForPerson(String identifier) { + return obsDao.getNumericObsByPerson(identifier); + } + + @Override + public Collection observationsFor(String patientUuid, Collection concepts, Integer numberOfVisits, + List obsIgnoreList, Boolean filterOutOrderObs, Order order, Date startDate, Date endDate) { + if (CollectionUtils.isNotEmpty(concepts)) { + List conceptNames = getConceptNames(concepts); + + List observations = obsDao.getObsByPatientAndVisit(patientUuid, conceptNames, + visitDao.getVisitIdsFor(patientUuid, numberOfVisits), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.DESC, obsIgnoreList, filterOutOrderObs, order, startDate, endDate); + + return omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList,observations), concepts); + } + return Collections.EMPTY_LIST; + } + + private List getConceptNames(Collection concepts) { + List conceptNames = new ArrayList<>(); + for (Concept concept : concepts) { + if(concept != null) { + conceptNames.add(getConceptName(concept, Context.getLocale())); + } + } + return conceptNames; + } + + private String getConceptName(Concept concept, Locale searchLocale) { + if (concept.getName(searchLocale) != null) + return concept.getName(searchLocale).getName(); + else + return concept.getName(LocaleUtility.getDefaultLocale()).getName(); + } + + @Override + public Collection observationsFor(String patientUuid, Concept rootConcept, Concept childConcept, Integer numberOfVisits, Date startDate, Date endDate, String patientProgramUuid) { + Collection encounters = programWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); + if (programDoesNotHaveEncounters(patientProgramUuid, encounters)) return Collections.EMPTY_LIST; + + List observations = obsDao.getObsFor(patientUuid, rootConcept, childConcept, visitDao.getVisitIdsFor(patientUuid, numberOfVisits), encounters, startDate, endDate); + + return convertToBahmniObservation(observations); + } + + private boolean programDoesNotHaveEncounters(String patientProgramUuid, Collection encounters) { + return StringUtils.isNotEmpty(patientProgramUuid) && encounters.size() == 0; + } + + private List convertToBahmniObservation(List observations) { + List bahmniObservations = new ArrayList<>(); + for (Obs observation : observations) { + BahmniObservation bahmniObservation = omrsObsToBahmniObsMapper.map(observation, null); + bahmniObservation.setObservationDateTime(observation.getObsDatetime()); + bahmniObservations.add(bahmniObservation); + } + return bahmniObservations; + } + + + private List filterIgnoredObs(List obsIgnoreList, List observations) { + return null != obsIgnoreList && obsIgnoreList.size() > 0 ? filterObs(obsIgnoreList, observations) : observations; + } + + private List filterObs(List obsIgnoreList, List observations) { + ArrayList filteredObs = new ArrayList<>(); + for (Obs observation : observations) { + if(!isContains(obsIgnoreList, observation)) { + if(hasGroupMembers(observation)) { + Obs filteredGroupMembers = filterGroupMembers(observation, obsIgnoreList); + if (hasGroupMembers(filteredGroupMembers)) + filteredObs.add(filteredGroupMembers); + } else { + filteredObs.add(observation); + } + } + } + return filteredObs; + } + + private boolean hasGroupMembers(Obs observation) { + return observation.getGroupMembers().size() > 0; + } + + private Obs filterGroupMembers(Obs observation, List obsIgnoreList) { + HashSet filteredGroup = new HashSet<>(); + for (Obs groupMember : observation.getGroupMembers()) { + if (!isContains(obsIgnoreList, groupMember)) { + if (hasGroupMembers(groupMember)) + groupMember = filterGroupMembers(groupMember, obsIgnoreList); + filteredGroup.add(groupMember); + } + } + observation.setGroupMembers(filteredGroup); + return observation; + } + + private boolean isContains(List obsIgnoreList, Obs obs) { + return obsIgnoreList.contains(obs.getConcept().getName().toString()); + } + + @Override + public Collection getLatest(String patientUuid, Collection concepts, Integer numberOfVisits, List obsIgnoreList, + Boolean filterOutOrderObs, Order order) { + List latestObs = new ArrayList<>(); + if (concepts == null) + return new ArrayList<>(); + for (Concept concept : concepts) { + List observations = obsDao.getObsByPatientAndVisit(patientUuid, Arrays.asList(concept.getName().getName()), + visitDao.getVisitIdsFor(patientUuid, numberOfVisits), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.DESC, obsIgnoreList, filterOutOrderObs, order, null, null); + if (CollectionUtils.isNotEmpty(observations)) { + latestObs.addAll(filterIgnoredObs(obsIgnoreList, getAllLatestObsForAConcept(observations))); + } + } + + return omrsObsToBahmniObsMapper.map(latestObs, concepts); + } + + @Override + public Collection getLatestObsByVisit(Visit visit, Collection concepts, List obsIgnoreList, Boolean filterOutOrderObs) { + List latestObs = new ArrayList<>(); + for (Concept concept : concepts) { + latestObs.addAll(obsDao.getObsByPatientAndVisit(visit.getPatient().getUuid(), Arrays.asList(concept.getName().getName()), + Arrays.asList(visit.getVisitId()), 1, ObsDaoImpl.OrderBy.DESC, obsIgnoreList, filterOutOrderObs, null, null, null)); + } + + return omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList,latestObs), concepts); + } + + @Override + public Collection getInitial(String patientUuid, Collection conceptNames, + Integer numberOfVisits, List obsIgnoreList, Boolean filterOutOrderObs, Order order) { + List latestObs = new ArrayList<>(); + for (Concept concept : conceptNames) { + latestObs.addAll(obsDao.getObsByPatientAndVisit(patientUuid, Arrays.asList(concept.getName().getName()), + visitDao.getVisitIdsFor(patientUuid, numberOfVisits), 1, ObsDaoImpl.OrderBy.ASC, obsIgnoreList, filterOutOrderObs, order, null, null)); + } + + return omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList, latestObs), conceptNames); + } + + @Override + public Collection getInitialObsByVisit(Visit visit, List concepts, List obsIgnoreList, Boolean filterObsWithOrders) { + List latestObs = new ArrayList<>(); + for (Concept concept : concepts) { + latestObs.addAll(obsDao.getObsByPatientAndVisit(visit.getPatient().getUuid(), Arrays.asList(concept.getName().getName()), + Arrays.asList(visit.getVisitId()), 1, ObsDaoImpl.OrderBy.ASC, obsIgnoreList, filterObsWithOrders, null, null, null)); + } + + Collection map = omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList,latestObs), concepts); + return map; + } + + @Override + public List getNumericConceptsForPerson(String personUUID) { + return obsDao.getNumericConceptsForPerson(personUUID); + } + + @Override + public Collection getLatestObsForConceptSetByVisit(String patientUuid, String conceptName, Integer visitId) { + List obs = withUniqueConcepts(filterByRootConcept(obsDao.getLatestObsForConceptSetByVisit(patientUuid, conceptName, visitId), conceptName)); + return omrsObsToBahmniObsMapper.map(obs, Arrays.asList(getConceptByName(conceptName))); + } + + @Override + public Collection getObservationForVisit(String visitUuid, List conceptNames, Collection obsIgnoreList, Boolean filterOutOrders, Order order) { + Visit visit = visitService.getVisitByUuid(visitUuid); + List persons = new ArrayList<>(); + persons.add(visit.getPatient()); + List observations = obsDao.getObsForVisits(persons, new ArrayList<>(visit.getEncounters()), + MiscUtils.getConceptsForNames(conceptNames, conceptService), obsIgnoreList, filterOutOrders, order); + observations = new ArrayList<>(getObsAtTopLevelAndApplyIgnoreList(observations, conceptNames, obsIgnoreList)); + return omrsObsToBahmniObsMapper.map(observations, null); + } + + @Override + public Collection getObservationsForEncounter(String encounterUuid, List conceptNames) { + List observations = obsDao.getObsForConceptsByEncounter(encounterUuid, conceptNames); + return omrsObsToBahmniObsMapper.map(observations, getConceptsByName(conceptNames)); + } + + @Override + public Collection getObservationsForPatientProgram(String patientProgramUuid, List conceptNames, List obsIgnoreList) { + List observations = new ArrayList<>(); + if (conceptNames == null) + return new ArrayList<>(); + for (String conceptName : conceptNames) { + observations.addAll(obsDao.getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, Arrays.asList(conceptName), null, ObsDaoImpl.OrderBy.DESC, null, null)); + } + + return omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList,observations), getConceptsByName(conceptNames)); + } + + @Override + public Collection getLatestObservationsForPatientProgram(String patientProgramUuid, List conceptNames, List obsIgnoreList) { + List observations = new ArrayList<>(); + if (conceptNames == null) + return new ArrayList<>(); + for (String conceptName : conceptNames) { + List obsByPatientProgramUuidAndConceptName = obsDao.getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, Arrays.asList(conceptName), null, OrderBy.DESC, null, null); + List obsList = getAllLatestObsForAConcept(obsByPatientProgramUuidAndConceptName); + if (CollectionUtils.isNotEmpty(obsList)) { + observations.addAll(obsList); + } + } + + return omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList,observations), getConceptsByName(conceptNames)); + } + + @Override + public Collection getInitialObservationsForPatientProgram(String patientProgramUuid, List conceptNames, List obsIgnoreList) { + List observations = new ArrayList<>(); + if (conceptNames == null) + return new ArrayList<>(); + for (String conceptName : conceptNames) { + observations.addAll(obsDao.getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, Arrays.asList(conceptName), 1, ObsDaoImpl.OrderBy.ASC, null, null)); + } + + return omrsObsToBahmniObsMapper.map(filterIgnoredObs(obsIgnoreList,observations), getConceptsByName(conceptNames)); + } + + @Override + public BahmniObservation getBahmniObservationByUuid(String observationUuid) { + Obs obs = obsService.getObsByUuid(observationUuid); + return omrsObsToBahmniObsMapper.map(obs, null); + } + + @Override + public BahmniObservation getRevisedBahmniObservationByUuid(String observationUuid) { + Obs obs = obsService.getObsByUuid(observationUuid); + if (obs.getVoided()) { + obs = getRevisionObs(obs); + } + return omrsObsToBahmniObsMapper.map(obs, null); + } + + @Override + public Collection getObsForFormBuilderForms(String patientUuid, List formNames, + Integer numberOfVisits, Date startDate, Date endDate, String patientProgramUuid) { + Collection encounters = programWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); + if (programDoesNotHaveEncounters(patientProgramUuid, encounters)) { + return Collections.EMPTY_LIST; + } + List obsList = obsDao.getObsForFormBuilderForms(patientUuid, formNames, + visitDao.getVisitIdsFor(patientUuid, numberOfVisits), encounters, startDate, endDate); + return convertToBahmniObservation(obsList); + } + + private Obs getRevisionObs(Obs initialObs) { + Obs revisedObs = obsService.getRevisionObs(initialObs); + if (revisedObs != null && revisedObs.getVoided()) { + revisedObs = getRevisionObs(revisedObs); + } + return revisedObs; + } + + @Override + public Collection getObservationsForOrder(String orderUuid) { + List observations = obsDao.getObsForOrder(orderUuid); + return omrsObsToBahmniObsMapper.map(observations, null); + } + + private Concept getConceptByName(String conceptName) { + return conceptService.getConceptByName(conceptName); + } + + private Collection getConceptsByName(List conceptNames) { + List concepts = new ArrayList<>(); + for (String conceptName : conceptNames) { + concepts.add(getConceptByName(conceptName)); + } + return concepts; + } + + private List getObsAtTopLevelAndApplyIgnoreList(List observations, List topLevelConceptNames, Collection obsIgnoreList) { + List topLevelObservations = new ArrayList<>(); + if (topLevelConceptNames == null) topLevelConceptNames = new ArrayList<>(); + + Set topLevelConceptNamesWithoutCase = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + topLevelConceptNamesWithoutCase.addAll(topLevelConceptNames); + for (Obs o : observations) { + if (o.getObsGroup() == null || topLevelConceptNamesWithoutCase.contains(o.getConcept().getName().getName().toLowerCase())) { + if (!(removeIgnoredObsOrIgnoreParentItself(o, obsIgnoreList) || topLevelObservations.contains(o))) { + topLevelObservations.add(o); + } + } + } + + return topLevelObservations; + } + + //Removes groupmembers who are ignored, and ignore a parent if all children are in ignore list + private boolean removeIgnoredObsOrIgnoreParentItself(Obs o, Collection obsIgnoreList) { + if (CollectionUtils.isNotEmpty(o.getGroupMembers()) && CollectionUtils.isNotEmpty(obsIgnoreList)) { + int size = o.getGroupMembers().size(); + int matchCount = 0; + Iterator itr = o.getGroupMembers().iterator(); + while (itr.hasNext()) { + Obs temp = itr.next(); + for (Concept concept : obsIgnoreList) { + if (temp.getConcept().getConceptId() == concept.getConceptId()) { + itr.remove(); + matchCount++; + } + } + } + if (matchCount == size) { + return true; + } + } + return false; + } + + private List filterByRootConcept(List obs, String parentConceptName) { + List filteredList = new ArrayList<>(); + for (Obs ob : obs) { + if (partOfParent(ob, parentConceptName)) { + filteredList.add(ob); + } + } + return filteredList; + } + + private boolean partOfParent(Obs ob, String parentConceptName) { + if (ob == null) return false; + if (ob.getConcept().getName().getName().equals(parentConceptName)) return true; + return partOfParent(ob.getObsGroup(), parentConceptName); + } + + + private List withUniqueConcepts(List observations) { + Map conceptToEncounterMap = new HashMap<>(); + List filteredObservations = new ArrayList<>(); + for (Obs obs : observations) { + Integer encounterId = conceptToEncounterMap.get(obs.getConcept().getId()); + if (encounterId == null) { + conceptToEncounterMap.put(obs.getConcept().getId(), obs.getEncounter().getId()); + filteredObservations.add(obs); + } else if (obs.getEncounter().getId().intValue() == encounterId.intValue()) { + filteredObservations.add(obs); + } + } + return filteredObservations; + } + + private List getAllLatestObsForAConcept(List observations) { + Map> obsToEncounterDateTimeMap = new TreeMap<>(Collections.reverseOrder()); + for (Obs obs : observations) { + if (obsToEncounterDateTimeMap.get(obs.getEncounter().getEncounterDatetime()) != null) { + obsToEncounterDateTimeMap.get(obs.getEncounter().getEncounterDatetime()).add(obs); + } else { + List obsList = new ArrayList<>(); + obsList.add(obs); + obsToEncounterDateTimeMap.put(obs.getEncounter().getEncounterDatetime(), obsList); + } + } + if (CollectionUtils.isNotEmpty(obsToEncounterDateTimeMap.entrySet())) { + return obsToEncounterDateTimeMap.entrySet().iterator().next().getValue(); + } else { + return null; + } + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderServiceImpl.java new file mode 100644 index 0000000000..04b4688652 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderServiceImpl.java @@ -0,0 +1,102 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.service.BahmniOrderService; +import org.bahmni.module.bahmnicore.service.OrderService; +import org.openmrs.Concept; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.order.contract.BahmniOrder; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + + +@Service +public class BahmniOrderServiceImpl implements BahmniOrderService { + + private ConceptMapper conceptMapper; + private OrderService orderService; + private BahmniObsService bahmniObsService; + + @Autowired + public BahmniOrderServiceImpl(OrderService orderService, BahmniObsService bahmniObsService, ConceptMapper conceptMapper) { + this.orderService = orderService; + this.bahmniObsService = bahmniObsService; + this.conceptMapper = conceptMapper; + + } + + @Override + public List ordersForOrderType(String patientUuid, List concepts, Integer numberOfVisits, List obsIgnoreList, String orderTypeUuid, Boolean includeObs, List locationUuids) { + List bahmniOrders = new ArrayList<>(); + List orders; + if(numberOfVisits == null || numberOfVisits ==0){ + orders = orderService.getAllOrders(patientUuid, orderTypeUuid, null, null, locationUuids); + }else { + orders = orderService.getAllOrdersForVisits(patientUuid, orderTypeUuid, numberOfVisits); + } + + for (Order order : orders) { + Collection obs = bahmniObsService.observationsFor(patientUuid, concepts, null, obsIgnoreList, false, order, null, null); + BahmniOrder bahmniOrder = createBahmniOrder(order, obs, includeObs); + + bahmniOrders.add(bahmniOrder); + } + return bahmniOrders; + } + + @Override + public List ordersForOrderUuid(String patientUuid, List concepts, List obsIgnoreList, String orderUuid) { + List bahmniOrders = new ArrayList<>(); + Order order = orderService.getOrderByUuid(orderUuid); + Collection obs = bahmniObsService.observationsFor(patientUuid, concepts, null, obsIgnoreList, false, order, null, null); + BahmniOrder bahmniOrder = createBahmniOrder(order, obs, true); + bahmniOrders.add(bahmniOrder); + return bahmniOrders; + } + + @Override + public List ordersForVisit(String visitUuid, String orderTypeUuid, List conceptNames, List obsIgnoreList) { + List orders = orderService.getAllOrdersForVisitUuid(visitUuid, orderTypeUuid); + List bahmniOrders = new ArrayList<>(); + for (Order order : orders) { + Collection observations = bahmniObsService.getObservationForVisit(visitUuid, conceptNames, obsIgnoreList, false, order); + BahmniOrder bahmniOrder = createBahmniOrder(order, observations, true); + bahmniOrders.add(bahmniOrder); + } + return bahmniOrders; + } + + @Override + public Order getChildOrder(Order order) { + return orderService.getChildOrder(order); + } + + private BahmniOrder createBahmniOrder(Order order, Collection bahmniObservations, boolean includeObs){ + BahmniOrder bahmniOrder = new BahmniOrder(); + + bahmniOrder.setOrderDateTime(order.getDateActivated()); + bahmniOrder.setOrderNumber(order.getOrderNumber()); + bahmniOrder.setOrderTypeUuid(order.getOrderType().getUuid()); + bahmniOrder.setOrderUuid(order.getUuid()); + bahmniOrder.setProvider(order.getOrderer().getName()); + bahmniOrder.setProviderUuid(order.getOrderer().getUuid()); + bahmniOrder.setConcept(conceptMapper.map(order.getConcept())); + bahmniOrder.setHasObservations(CollectionUtils.isNotEmpty(bahmniObservations)); + bahmniOrder.setCommentToFulfiller(order.getCommentToFulfiller()); + + if(order.getFulfillerStatus() != null) + bahmniOrder.setFulfillerStatus(order.getFulfillerStatus()); + + if(includeObs) { + bahmniOrder.setBahmniObservations(bahmniObservations); + } + return bahmniOrder; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderSetServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderSetServiceImpl.java new file mode 100644 index 0000000000..8a6afe1187 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderSetServiceImpl.java @@ -0,0 +1,28 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniOrderSetDao; +import org.bahmni.module.bahmnicore.service.BahmniOrderSetService; +import org.openmrs.OrderSet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Component +@Transactional +public class BahmniOrderSetServiceImpl implements BahmniOrderSetService { + + private BahmniOrderSetDao bahmniOrderSetDao; + + @Autowired + public BahmniOrderSetServiceImpl(BahmniOrderSetDao bahmniOrderSetDao) { + this.bahmniOrderSetDao = bahmniOrderSetDao; + } + + @Override + @Transactional(readOnly = true) + public List getOrderSetByQuery(String searchTerm) { + return bahmniOrderSetDao.getOrderSetByQuery(searchTerm); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramServiceValidatorImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramServiceValidatorImpl.java new file mode 100644 index 0000000000..962a70d9c7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramServiceValidatorImpl.java @@ -0,0 +1,11 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.service.BahmniProgramServiceValidator; +import org.openmrs.PatientProgram; +import org.openmrs.api.APIException; +import org.springframework.stereotype.Component; + +@Component +public class BahmniProgramServiceValidatorImpl implements BahmniProgramServiceValidator { + public void validate(PatientProgram patientProgram) throws APIException {} +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramWorkflowServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramWorkflowServiceImpl.java new file mode 100644 index 0000000000..1b96ea8bef --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramWorkflowServiceImpl.java @@ -0,0 +1,71 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.openmrs.ProgramAttributeType; +import org.bahmni.module.bahmnicore.service.BahmniProgramServiceValidator; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.openmrs.Encounter; +import org.openmrs.PatientProgram; +import org.openmrs.api.APIException; +import org.openmrs.api.db.ProgramWorkflowDAO; +import org.openmrs.api.impl.ProgramWorkflowServiceImpl; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +@Transactional +public class BahmniProgramWorkflowServiceImpl extends ProgramWorkflowServiceImpl implements BahmniProgramWorkflowService { + + @Autowired + private EpisodeService episodeService; + @Autowired + private List bahmniProgramServiceValidators; + + public BahmniProgramWorkflowServiceImpl(ProgramWorkflowDAO programWorkflowDAO, EpisodeService episodeService) { + this.episodeService = episodeService; + this.dao = programWorkflowDAO; + } + + //Default constructor to satisfy Spring + public BahmniProgramWorkflowServiceImpl() { + } + + @Override + public Collection getEncountersByPatientProgramUuid(String patientProgramUuid) { + PatientProgram patientProgram = dao.getPatientProgramByUuid(patientProgramUuid); + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + return episode == null ? Collections.EMPTY_LIST : episode.getEncounters(); + } + + @Override + public PatientProgram savePatientProgram(PatientProgram patientProgram) throws APIException { + preSaveValidation(patientProgram); + if (patientProgram.getOutcome() != null && patientProgram.getDateCompleted() == null) { + patientProgram.setDateCompleted(new Date()); + } + PatientProgram bahmniPatientProgram = super.savePatientProgram(patientProgram); + createEpisodeIfRequired(bahmniPatientProgram); + return bahmniPatientProgram; + } + + private void preSaveValidation(PatientProgram patientProgram) { + if(CollectionUtils.isNotEmpty(bahmniProgramServiceValidators)) { + for (BahmniProgramServiceValidator bahmniProgramServiceValidator : bahmniProgramServiceValidators) { + bahmniProgramServiceValidator.validate(patientProgram); + } + } + } + + private void createEpisodeIfRequired(PatientProgram bahmniPatientProgram) { + if (episodeService.getEpisodeForPatientProgram(bahmniPatientProgram) != null) return; + Episode episode = new Episode(); + episode.addPatientProgram(bahmniPatientProgram); + episodeService.save(episode); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniVisitServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniVisitServiceImpl.java new file mode 100644 index 0000000000..0b5cc86631 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/BahmniVisitServiceImpl.java @@ -0,0 +1,36 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.bahmni.module.bahmnicore.service.BahmniVisitService; +import org.openmrs.Encounter; +import org.openmrs.Visit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BahmniVisitServiceImpl implements BahmniVisitService { + + private VisitDao visitDao; + + @Autowired + public BahmniVisitServiceImpl(VisitDao visitDao) { + this.visitDao = visitDao; + } + + @Override + public Visit getLatestVisit(String patientUuid, String conceptName) { + return visitDao.getLatestVisit(patientUuid, conceptName); + } + + @Override + public Visit getVisitSummary(String visitUuid) { + return visitDao.getVisitSummary(visitUuid); + } + + @Override + public List getAdmitAndDischargeEncounters(Integer visitId) { + return visitDao.getAdmitAndDischargeEncounters(visitId); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/DiseaseTemplateServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/DiseaseTemplateServiceImpl.java new file mode 100644 index 0000000000..4343cf51b8 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/DiseaseTemplateServiceImpl.java @@ -0,0 +1,218 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.BahmniCoreException; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplate; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplateConfig; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplatesConfig; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.ObservationTemplate; +import org.bahmni.module.bahmnicore.mapper.ObservationTemplateMapper; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.service.BahmniVisitService; +import org.bahmni.module.bahmnicore.service.DiseaseTemplateService; +import org.openmrs.Concept; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +@Service +public class DiseaseTemplateServiceImpl implements DiseaseTemplateService { + + private BahmniObsService bahmniObsService; + private BahmniVisitService bahmniVisitService; + private ConceptService conceptService; + private VisitService visitService; + private PatientService patientService; + private ConceptMapper conceptMapper; + private ObservationTemplateMapper observationTemplateMapper; + private BahmniConceptService bahmniConceptService; + private final String CASE_INTAKE_CONCEPT_CLASS = "Case Intake"; + private static final Logger log = LogManager.getLogger(DiseaseTemplateServiceImpl.class); + + @Autowired + public DiseaseTemplateServiceImpl(BahmniObsService bahmniObsService, BahmniVisitService bahmniVisitService, + ConceptService conceptService, + PatientService patientService, VisitService visitService, + BahmniConceptService bahmniConceptService) { + this.bahmniObsService = bahmniObsService; + this.bahmniVisitService = bahmniVisitService; + this.conceptService = conceptService; + this.bahmniConceptService = bahmniConceptService; + this.conceptMapper = new ConceptMapper(); + this.observationTemplateMapper = new ObservationTemplateMapper(conceptMapper); + this.patientService = patientService; + this.visitService = visitService; + } + + @Override + @Transactional(readOnly = true) + public List allDiseaseTemplatesFor(DiseaseTemplatesConfig diseaseTemplatesConfig) { + List diseaseTemplates = new ArrayList<>(); + + for (DiseaseTemplateConfig diseaseTemplateConfig : diseaseTemplatesConfig.getDiseaseTemplateConfigList()) { + String templateName = diseaseTemplateConfig.getTemplateName(); + Concept diseaseTemplateConcept = conceptService.getConceptByName(templateName); + DiseaseTemplate diseaseTemplate = new DiseaseTemplate(mapToETConcept(diseaseTemplateConcept, templateName)); + diseaseTemplate.addObservationTemplates(createObservationTemplates(diseaseTemplatesConfig.getPatientUuid(), + diseaseTemplateConcept, diseaseTemplatesConfig.getStartDate(), diseaseTemplatesConfig.getEndDate())); + List showOnlyConceptsForTheDisease = getShowOnlyConceptsForTheDisease(diseaseTemplate, diseaseTemplatesConfig); + if (CollectionUtils.isNotEmpty(showOnlyConceptsForTheDisease)) { + filterObs(diseaseTemplate, showOnlyConceptsForTheDisease); + } + diseaseTemplates.add(diseaseTemplate); + } + return diseaseTemplates; + } + + @Override + @Transactional(readOnly = true) + public DiseaseTemplate diseaseTemplateFor(DiseaseTemplatesConfig diseaseTemplatesConfig) { + if(CollectionUtils.isEmpty(diseaseTemplatesConfig.getDiseaseTemplateConfigList())){ + throw new BahmniCoreException("Disease template not found"); + } + String templateName = diseaseTemplatesConfig.getDiseaseTemplateConfigList().get(0).getTemplateName(); + Concept diseaseTemplateConcept = conceptService.getConceptByName(templateName); + DiseaseTemplate diseaseTemplate = new DiseaseTemplate(mapToETConcept(diseaseTemplateConcept, templateName)); + if (diseaseTemplateConcept == null) { + log.warn("Disease template concept " + templateName + " not found. Please check your configuration"); + return diseaseTemplate; + } + List observationTemplateConcepts = diseaseTemplateConcept.getSetMembers(); + for (Concept concept : observationTemplateConcepts) { + Collection observations = bahmniObsService.observationsFor(diseaseTemplatesConfig.getPatientUuid(), + Arrays.asList(concept), null, null, false, null, diseaseTemplatesConfig.getStartDate(), diseaseTemplatesConfig.getEndDate()); + List observationTemplates = observationTemplateMapper.map(observations, concept); + diseaseTemplate.addObservationTemplates(observationTemplates); + } + + return diseaseTemplate; + } + + private EncounterTransaction.Concept mapToETConcept(Concept concept, String conceptName) { + if (concept == null) { + return new EncounterTransaction.Concept(null, conceptName, false, null, null, null, null,null); + } + return conceptMapper.map(concept); + } + + private List getShowOnlyConceptsForTheDisease(DiseaseTemplate diseaseTemplate, DiseaseTemplatesConfig diseaseTemplatesConfig) { + if (diseaseTemplate.getConcept().getName() == null) return new ArrayList<>(); + + for (DiseaseTemplateConfig diseaseTemplateConfig : diseaseTemplatesConfig.getDiseaseTemplateConfigList()) { + if (diseaseTemplateConfig.getTemplateName().equals(diseaseTemplate.getConcept().getName())) { + return diseaseTemplateConfig.getShowOnly(); + } + } + return new ArrayList<>(); + } + + private void filterObs(DiseaseTemplate diseaseTemplate, List showOnly) { + List removableObservationTemplate = new ArrayList<>(); + for (ObservationTemplate observationTemplate : diseaseTemplate.getObservationTemplates()) { + if (!isExists(observationTemplate.getConcept(), showOnly)) { + filterObs(observationTemplate, showOnly); + if (observationTemplate.getBahmniObservations().size() == 0) { + removableObservationTemplate.add(observationTemplate); + } + } + } + diseaseTemplate.getObservationTemplates().removeAll(removableObservationTemplate); + } + + private void filterObs(ObservationTemplate observationTemplate, List conceptNames) { + Collection removableObservation = new ArrayList<>(); + for (BahmniObservation bahmniObservation : observationTemplate.getBahmniObservations()) { + if (!isExists(bahmniObservation.getConcept(), conceptNames)) { + if (bahmniObservation.getGroupMembers().size() > 0) { + filterObsGroupMembers(bahmniObservation, conceptNames); + } + if (bahmniObservation.getGroupMembers().size() == 0) { + removableObservation.add(bahmniObservation); + } + } + } + observationTemplate.removeBahmniObservations(removableObservation); + } + + private void filterObsGroupMembers(BahmniObservation parent, List conceptNames) { + Collection removableObservation = new ArrayList<>(); + for (BahmniObservation bahmniObservation : parent.getGroupMembers()) { + if (!isExists(bahmniObservation.getConcept(), conceptNames)) { + if (bahmniObservation.getGroupMembers().size() > 0) { + filterObsGroupMembers(bahmniObservation, conceptNames); + } + if (bahmniObservation.getGroupMembers().size() == 0) { + removableObservation.add(bahmniObservation); + } + } + } + + parent.removeGroupMembers(removableObservation); + } + + private boolean isExists(EncounterTransaction.Concept concept, List conceptNames) { + return conceptNames.contains(concept.getName()); + } + + private List createObservationTemplates(String patientUuid, Concept diseaseTemplateConcept, Date startDate, Date endDate) { + List observationTemplates = new ArrayList<>(); + Patient patient = patientService.getPatientByUuid(patientUuid); + List visits = visitService.getVisitsByPatient(patient); + if (null != diseaseTemplateConcept && CollectionUtils.isNotEmpty(diseaseTemplateConcept.getSetMembers())) { + for (Concept concept : diseaseTemplateConcept.getSetMembers()) { + if (concept.getConceptClass().getName().equals(CASE_INTAKE_CONCEPT_CLASS) && CollectionUtils.isNotEmpty(visits)) { + Collection observations = bahmniObsService.observationsFor(patientUuid, Arrays.asList(concept), null, null, false, null, startDate, endDate); + observationTemplates.addAll(observationTemplateMapper.map(observations, concept)); + } else { + Visit latestVisit = bahmniVisitService.getLatestVisit(patientUuid, concept.getName().getName()); + if (latestVisit != null) { + getObservationTemplate(observationTemplates, patientUuid, concept, latestVisit, startDate, endDate); + } + } + } + } + return observationTemplates; + } + + private void getObservationTemplate(List observationTemplates, String patientUuid, Concept concept, Visit latestVisit, Date startDate, Date endDate) { + Collection observations = + bahmniObsService.getLatestObsForConceptSetByVisit(patientUuid, concept.getName(Context.getLocale()).getName(), latestVisit.getVisitId()); + for (Iterator iterator = observations.iterator(); iterator.hasNext();) { + BahmniObservation observation = iterator.next(); + if((startDate != null && observation.getObservationDateTime().before(startDate)) || (endDate != null && observation.getObservationDateTime().after(endDate))) { + iterator.remove(); + } + } + if (CollectionUtils.isNotEmpty(observations)) { + observationTemplates.add(createObservationTemplate(concept, latestVisit, observations)); + } + } + + private ObservationTemplate createObservationTemplate(Concept concept, Visit visit, Collection observations) { + ObservationTemplate observationTemplate = new ObservationTemplate(); + observationTemplate.setVisitStartDate(visit.getStartDatetime()); + observationTemplate.setConcept(conceptMapper.map(concept)); + observationTemplate.setBahmniObservations(observations); + return observationTemplate; + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java new file mode 100644 index 0000000000..d96f89114d --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImpl.java @@ -0,0 +1,109 @@ +package org.bahmni.module.bahmnicore.service.impl; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.api.ProviderService; +import org.openmrs.api.UserService; +import org.openmrs.api.context.Context; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Transactional +public class NoteServiceImpl implements NoteService, Serializable { + + private NoteDao noteDao; + + public void setNoteDao(NoteDao noteDao) { + this.noteDao = noteDao; + } + + private NoteDao getNoteDAO() { + return noteDao; + } + + private Log log = LogFactory.getLog(this.getClass()); + + public NoteServiceImpl() { + } + + public Note createNote(Note note) { + log.info("Create a note " + note); + noteDao.createNote(note); + return note; + } + + public Note getNote(Integer noteId) { + log.info("Get note " + noteId); + return noteDao.getNoteById(noteId); + } + + public Note updateNote(Integer id, NoteRequestResponse noteRequestResponse) { + Note note = noteDao.getNoteById(id); + Provider provider = Context.getService(ProviderService.class).getProviderByUuid(noteRequestResponse.getProviderUuid()); + User user = Context.getService(UserService.class).getUsersByPerson(provider.getPerson(), false).get(0); + if (note.getCreator().getUserId() == user.getUserId()) { + note.setNoteText(noteRequestResponse.getNoteText()); + log.info("Update note " + note); + return noteDao.updateNote(note); + } else { + Note newNote = new Note(); + newNote.setNoteDate(note.getNoteDate()); + newNote.setNoteText(noteRequestResponse.getNoteText()); + newNote.setNoteType(note.getNoteType()); + newNote = noteDao.createNote(newNote); + voidNote(id, "Updated to #" + newNote.getNoteId()); + log.info("Voided old note and created note " + newNote); + return newNote; + } + } + + public List getNotes(Date noteStartDate, Date noteEndDate, String noteType) { + return noteDao.getNotes(noteStartDate, noteEndDate, noteType); + } + + + public Note voidNote(Integer id, String reason) { + Note note = noteDao.getNoteById(id); + note.setVoided(true); + note.setVoidReason(reason); + log.debug("voiding note because " + reason); + return noteDao.voidNote(note); + } + + @Override + public List createNotes(List notes) { + return notes.stream().map(note -> noteDao.createNote(note)).collect(Collectors.toList()); + } + + @Override + public NoteType getNoteType(String name) { + return noteDao.getNoteType(name); + } + + @Override + public Note getNote(Date noteDate, String noteType) { + return noteDao.getNote(noteDate, noteType); + } + + @Override + public Note getNoteById(Integer noteId) { + return noteDao.getNoteById(noteId); + } + + @Override + public Note getNoteByUuid(String uuid) { + return noteDao.getNoteByUuid(uuid); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/OrderServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000000..cf05a70cd3 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/OrderServiceImpl.java @@ -0,0 +1,75 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.bahmni.module.bahmnicore.service.OrderService; +import org.openmrs.Order; +import org.openmrs.OrderType; +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.Collections; +import java.util.List; + +@Service +public class OrderServiceImpl implements OrderService { + + private org.openmrs.api.OrderService orderService; + private PatientService patientService; + private VisitDao visitDao; + private OrderDao orderDao; + + @Autowired + public OrderServiceImpl(org.openmrs.api.OrderService orderService, PatientService patientService, VisitDao visitDao, OrderDao orderDao) { + this.orderService = orderService; + this.patientService = patientService; + this.visitDao = visitDao; + this.orderDao = orderDao; + } + + @Override + public List getPendingOrders(String patientUuid, String orderTypeUuid) { + Patient patient = patientService.getPatientByUuid(patientUuid); + List allOrders = orderService.getAllOrdersByPatient(patient); + List completedOrders = orderDao.getCompletedOrdersFrom(Collections.unmodifiableList(allOrders)); + allOrders.removeAll(completedOrders); + return allOrders; + } + + @Override + public List getAllOrders(String patientUuid, String orderTypeUuid, Integer offset, Integer limit, List locationUuids) { + Patient patient = patientService.getPatientByUuid(patientUuid); + OrderType orderType = orderService.getOrderTypeByUuid(orderTypeUuid); + return orderDao.getAllOrders(patient, orderType, offset, limit, locationUuids); + } + + @Override + public List getVisitsWithOrders(Patient patient, String orderType, Boolean includeActiveVisit, Integer numberOfVisits){ + return orderDao.getVisitsWithActiveOrders(patient, orderType, includeActiveVisit, numberOfVisits); + } + + @Override + public List getAllOrdersForVisits(String patientUuid, String orderTypeUuid, Integer numberOfVisits) { + Patient patient = patientService.getPatientByUuid(patientUuid); + OrderType orderType = orderService.getOrderTypeByUuid(orderTypeUuid); + List visits = visitDao.getVisitsByPatient(patient, numberOfVisits); + return orderDao.getAllOrdersForVisits(orderType, visits); + } + @Override + public Order getOrderByUuid(String orderUuid){ + return orderDao.getOrderByUuid(orderUuid); + } + + @Override + public List getAllOrdersForVisitUuid(String visitUuid, String orderTypeUuid) { + return orderDao.getOrdersForVisitUuid(visitUuid, orderTypeUuid); + } + + @Override + public Order getChildOrder(Order order) { + return orderDao.getChildOrder(order); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java new file mode 100644 index 0000000000..4f2bd60025 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImpl.java @@ -0,0 +1,260 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import liquibase.util.file.FilenameUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.BahmniCoreException; +import org.bahmni.module.bahmnicore.bahmniexceptions.FileTypeNotSupportedException; +import org.bahmni.module.bahmnicore.bahmniexceptions.VideoFormatNotSupportedException; +import org.bahmni.module.bahmnicore.model.VideoFormats; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.bahmni.module.bahmnicore.service.PatientDocumentService; +import org.bahmni.module.bahmnicore.service.ThumbnailGenerator; +import org.imgscalr.Scalr; +import org.openmrs.module.webservices.rest.web.RestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import javax.imageio.ImageIO; +import javax.xml.bind.DatatypeConverter; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +@Service +@Lazy +public class PatientDocumentServiceImpl implements PatientDocumentService { + private static final String PDF = "pdf"; + private static final String INVALID_FILE_SPECIFIED = "Invalid file specified"; + private static final String FILE_NAME_PARAM_REQUIRED = "[Required String parameter 'filename' is empty]"; + private Log log = LogFactory.getLog(PatientDocumentServiceImpl.class); + private static final String patientImagesFormat = "jpeg"; + private final Integer NO_OF_PATIENT_FILE_IN_A_DIRECTORY = 100; + private final String VIDEO_FILE_TYPE = "video"; + private final String IMAGE_FILE_TYPE = "image"; + private static final String LAB_RESULT_ENCOUNTER_TYPE = "LAB_RESULT"; + + protected void setThumbnailGenerators(List thumbnailGenerators) { + this.thumbnailGenerators = thumbnailGenerators; + } + + @Autowired + List thumbnailGenerators; + + + + @Override + public void saveImage(String patientIdentifier, String image) { + try { + if (image == null || image.isEmpty()) return; + + File outputFile = new File(String.format("%s/%s.%s", BahmniCoreProperties.getProperty("bahmnicore.images.directory"), patientIdentifier, patientImagesFormat)); + saveDocumentInFile(image, patientImagesFormat, outputFile, "image"); + } catch (IOException e) { + throw new BahmniCoreException("[%s] : Could not save patient image", e); + } + } + + @Override + public String saveDocument(Integer patientId, String encounterTypeName, String content, String format, String fileType, String fileName) { + String basePath; + try { + if (content == null || content.isEmpty()) return null; + basePath = getBasePathByEncounterType(encounterTypeName); + + String relativeFilePath = createFilePath(basePath, patientId, encounterTypeName, format, fileName); + + File outputFile = new File(String.format("%s/%s", basePath, relativeFilePath)); + saveDocumentInFile(content, format, outputFile, fileType); + + return relativeFilePath; + + } catch (IOException e) { + throw new BahmniCoreException("[%s] : Could not save patient Document ", e); + } + } + + private String getBasePathByEncounterType(String encounterTypeName) { + String basePath; + if(encounterTypeName.equalsIgnoreCase(LAB_RESULT_ENCOUNTER_TYPE)){ + basePath = BahmniCoreProperties.getProperty("bahmnicore.documents.lablitebaseDirectory"); + } else{ + basePath = getBasePath(); + } + return basePath; + } + + private String getBasePath() { + return BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory"); + } + + private String createFileName(Integer patientId, String encounterTypeName, Object format, String originalFileName) { + String uuid = UUID.randomUUID().toString(); + if (StringUtils.isNotBlank(originalFileName)) { + originalFileName = "__" + originalFileName; + } + return String.format("%s-%s-%s%s.%s", patientId, encounterTypeName, uuid, originalFileName, format); + } + + protected String createFilePath(String basePath, Integer patientId, String encounterTypeName, String format, String originalFileName) { + String fileName = createFileName(patientId, encounterTypeName, format, originalFileName); + String documentDirectory = findDirectoryForDocumentsByPatientId(patientId); + String absoluteFilePath = String.format("%s/%s", basePath, documentDirectory); + File absoluteFileDirectory = new File(absoluteFilePath); + if (!absoluteFileDirectory.exists()) { + absoluteFileDirectory.mkdirs(); + } + return String.format("%s/%s", documentDirectory, fileName); + } + + private String findDirectoryForDocumentsByPatientId(Integer patientId) { + Integer directory = (patientId / NO_OF_PATIENT_FILE_IN_A_DIRECTORY + 1) * NO_OF_PATIENT_FILE_IN_A_DIRECTORY; + return directory.toString(); + } + + private void saveDocumentInFile(String content, String format, File outputFile, String fileType) throws IOException { + log.info(String.format("Creating patient document of format %s at %s", format, outputFile)); + byte[] decodedBytes = DatatypeConverter.parseBase64Binary(content); + if (VIDEO_FILE_TYPE.equals(fileType)) { + if (!isVideoFormatSupported(format)) { + throw new VideoFormatNotSupportedException(String.format("The video format '%s' is not supported. Supported formats are %s", format, Arrays.toString(VideoFormats.values()))); + } + + FileUtils.writeByteArrayToFile(outputFile, decodedBytes); + createAndSaveThumbnailForVideo(outputFile, format); + + } else if (PDF.equals(format)) { + FileUtils.writeByteArrayToFile(outputFile, decodedBytes); + } else if (IMAGE_FILE_TYPE.equals(fileType)){ + try { + BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(decodedBytes)); + boolean results = ImageIO.write(bufferedImage, format, outputFile); + if(!results) { + throw new FileTypeNotSupportedException(String.format("The image format '%s' is not supported. Supported formats are %s", format, Arrays.toString(new String[]{"png", "jpeg", "gif"}))); + } + saveThumbnail(bufferedImage, outputFile, null, 100); + bufferedImage.flush(); + log.info(String.format("Successfully created patient image at %s", outputFile)); + } catch (Exception exception) { + throw new FileTypeNotSupportedException(String.format("The image format '%s' is not supported. Supported formats are %s", format, Arrays.toString(new String[]{"png", "jpeg", "gif"}))); + } + } else { + throw new FileTypeNotSupportedException(String.format("The file type is not supported. Supported types are %s/%s/%s", IMAGE_FILE_TYPE, VIDEO_FILE_TYPE, PDF)); + } + } + + private boolean isVideoFormatSupported(String format) { + return VideoFormats.isFormatSupported(format); + } + + + private void createAndSaveThumbnailForVideo(File outputVideoFile, String format) throws IOException { + ThumbnailGenerator thumbnailGenerator = getSupportedThumbnailGenerator(format); + BufferedImage bufferedImage = null; + if(thumbnailGenerator != null) { + bufferedImage = thumbnailGenerator.generateThumbnail(outputVideoFile); + saveThumbnail(bufferedImage, outputVideoFile, "jpg", 300); + } + } + + private ThumbnailGenerator getSupportedThumbnailGenerator(String format) throws IOException { + for(ThumbnailGenerator thumbnailGenerator: thumbnailGenerators) { + if (thumbnailGenerator.isFormatSupported(format)) { + return thumbnailGenerator; + } + } + return null; + } + + private void saveThumbnail(BufferedImage image, File outputFile, String imageFileType, int imageSize) throws IOException { + String nameWithoutExtension = FilenameUtils.removeExtension(outputFile.getAbsolutePath()); + if(imageFileType == null){ + imageFileType = FilenameUtils.getExtension(outputFile.getAbsolutePath()); + } + File thumbnailFile = new File(String.format("%s_thumbnail.%s", nameWithoutExtension, imageFileType)); + BufferedImage reSizedImage = Scalr.resize(image, imageSize); + ImageIO.write(reSizedImage, imageFileType, thumbnailFile); + image.flush(); + reSizedImage.flush(); + } + + @Override + public ResponseEntity retriveImage(String patientUuid) { + File file = getPatientImageFile(patientUuid); + return readImage(file); + } + + @Override + public void delete(String fileName) { + validateFileToBeDeleted(fileName); + File file = new File(getBasePath() + "/" + fileName); + deleteThumbnailFile(file); + deleteFile(file); + } + + private void validateFileToBeDeleted(String fileName) { + log.debug(String.format("Patient document file to be deleted: %s", fileName)); + if (StringUtils.isBlank(fileName)) { + log.error(FILE_NAME_PARAM_REQUIRED); + throw new RuntimeException(FILE_NAME_PARAM_REQUIRED); + } + String docLocation = getBasePath(); + log.debug(String.format("Document path: %s", docLocation)); + Path docLocationPath = Paths.get(docLocation); + Path filePath = Paths.get(docLocation, fileName).normalize(); + if (!filePath.startsWith(docLocationPath) || !filePath.toFile().exists()) { + String invalidFileError = String.format(INVALID_FILE_SPECIFIED.concat(": %s"), fileName); + log.error(invalidFileError); + throw new RuntimeException(invalidFileError); + } + } + + private void deleteThumbnailFile(File file) { + String absolutePath = file.getAbsolutePath(); + String nameWithoutExtension = FilenameUtils.removeExtension(absolutePath); + String extension = FilenameUtils.getExtension(absolutePath); + FileUtils.deleteQuietly(new File(String.format("%s_thumbnail.%s", nameWithoutExtension, extension))); + } + + private void deleteFile(File file) { + boolean deleted = FileUtils.deleteQuietly(file); + if (deleted) + log.info(String.format("%s file is deleted successfully", file.getAbsolutePath())); + else + log.warn(String.format("Unable to delete %s", file.getAbsolutePath())); + } + + private File getPatientImageFile(String patientUuid) { + File file = new File(String.format("%s/%s.%s", BahmniCoreProperties.getProperty("bahmnicore.images.directory"), patientUuid, patientImagesFormat)); + if (file.exists() && file.isFile()) { + return file; + } + return new File(BahmniCoreProperties.getProperty("bahmnicore.images.directory.defaultImage")); + } + + private ResponseEntity readImage(File file) { + byte[] fileByteArray = new byte[(int) file.length()]; + try { + FileInputStream fileInputStream = new FileInputStream(file); + fileInputStream.read(fileByteArray); + return new ResponseEntity(fileByteArray, HttpStatus.OK); + } catch (FileNotFoundException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.NOT_FOUND); + } catch (IOException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java new file mode 100644 index 0000000000..5e48a729fd --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java @@ -0,0 +1,63 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.service.RowMapper; +import org.bahmni.module.bahmnicore.service.SqlSearchService; +import org.bahmni.module.bahmnicore.util.SqlQueryHelper; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationServiceImpl; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.DatabaseUpdater; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SqlSearchServiceImpl implements SqlSearchService { + private AdministrationService administrationService; + + public void setAdministrationService(AdministrationService administrationService) { + this.administrationService = administrationService; + } + + @Override + public List search(String queryId, Map params) { + Map updatedParams = conditionallyAddVisitLocation(params); + List results = new ArrayList<>(); + SqlQueryHelper sqlQueryHelper = new SqlQueryHelper(); + String query = getSql(queryId); + try( Connection conn = DatabaseUpdater.getConnection(); + PreparedStatement statement = sqlQueryHelper.constructPreparedStatement(query,updatedParams,conn); + ResultSet resultSet = statement.executeQuery()) { + + RowMapper rowMapper = new RowMapper(); + while (resultSet.next()) { + results.add(rowMapper.mapRow(resultSet)); + } + return results; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private String getSql(String queryId) { + String query = administrationService.getGlobalProperty(queryId); + if (query == null) throw new RuntimeException("No such query:" + queryId); + return query; + } + + private Map conditionallyAddVisitLocation(Map params) { + Map updatedParams = new HashMap<>(params); + if (params.containsKey("location_uuid")) { + String locationUuid = params.get("location_uuid")[0]; + String visitLocation = new BahmniVisitLocationServiceImpl(Context.getLocationService()).getVisitLocationUuid(locationUuid); + String[] visitLcoationValue = {visitLocation}; + updatedParams.put("visit_location_uuid", visitLcoationValue); + } + return updatedParams; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/ThumbnailGeneratorImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/ThumbnailGeneratorImpl.java new file mode 100644 index 0000000000..f2763d5eb5 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/ThumbnailGeneratorImpl.java @@ -0,0 +1,35 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.model.VideoFormatsForThumbnailGeneration; +import org.bahmni.module.bahmnicore.service.ThumbnailGenerator; +import org.jcodec.api.FrameGrab; +import org.jcodec.api.JCodecException; +import org.jcodec.common.model.Picture; +import org.jcodec.scale.AWTUtil; +import org.springframework.stereotype.Component; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +@Component +public class ThumbnailGeneratorImpl implements ThumbnailGenerator { + + @Override + public boolean isFormatSupported(String format) { + return VideoFormatsForThumbnailGeneration.isFormatSupported(format); + } + + @Override + public BufferedImage generateThumbnail(File video) throws IOException { + BufferedImage bufferedImage; + try{ + Picture picture = FrameGrab.getFrameFromFile(video,0); + bufferedImage = AWTUtil.toBufferedImage(picture); + } + catch (JCodecException e) { + throw new RuntimeException(e); + } + return bufferedImage; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java new file mode 100644 index 0000000000..0dca3fe209 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImpl.java @@ -0,0 +1,133 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.lang3.LocaleUtils; +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.bahmni.module.bahmnicore.service.TsConceptSearchService; +import org.openmrs.Concept; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptName; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.ConceptSearchResult; +import org.openmrs.ConceptSource; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.concept.EmrConceptService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +public class TsConceptSearchServiceImpl implements TsConceptSearchService { + private BahmniDiagnosisService bahmniDiagnosisService; + + private EmrConceptService emrConceptService; + + + @Autowired + public TsConceptSearchServiceImpl(BahmniDiagnosisService bahmniDiagnosisService, EmrConceptService emrConceptService) { + this.bahmniDiagnosisService = bahmniDiagnosisService; + this.emrConceptService = emrConceptService; + } + + @Override + public List getConcepts(String query, Integer limit, String locale) { + boolean externalTerminologyServerLookupNeeded = bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded(); + if (externalTerminologyServerLookupNeeded) { + return new ArrayList<>(); + } else { + return getDiagnosisConcepts(query, limit, locale); + } + } + + private List getDiagnosisConcepts(String query, Integer limit, String locale) { + Collection diagnosisSets = bahmniDiagnosisService.getDiagnosisSets(); + List conceptSources = bahmniDiagnosisService.getConceptSourcesForDiagnosisSearch(); + Locale searchLocale = getSearchLocale(locale); + List conceptSearchResults = + emrConceptService.conceptSearch(query, LocaleUtility.getDefaultLocale(), null, diagnosisSets, conceptSources, limit); + if(!LocaleUtility.getDefaultLocale().equals(searchLocale)) { + conceptSearchResults.addAll(emrConceptService.conceptSearch(query, searchLocale, null, diagnosisSets, conceptSources, limit)); + } + + ConceptSource conceptSource = conceptSources.isEmpty() ? null : conceptSources.get(0); + return createListResponse(conceptSearchResults, conceptSource, searchLocale); + } + + private List createListResponse(List resultList, + ConceptSource conceptSource, Locale searchLocale) { + List allDiagnoses = new ArrayList<>(); + + for (ConceptSearchResult diagnosis : resultList) { + SimpleObject diagnosisObject = new SimpleObject(); + ConceptName conceptName = diagnosis.getConcept().getName(searchLocale); + if (conceptName == null) { + conceptName = diagnosis.getConcept().getName(); + } + diagnosisObject.add("conceptName", conceptName.getName()); + diagnosisObject.add("conceptUuid", diagnosis.getConcept().getUuid()); + if (diagnosis.getConceptName() != null) { + diagnosisObject.add("matchedName", diagnosis.getConceptName().getName()); + } + ConceptReferenceTerm term = getConceptReferenceTermByConceptSource(diagnosis.getConcept(), conceptSource); + if (term != null) { + diagnosisObject.add("code", term.getCode()); + } + allDiagnoses.add(diagnosisObject); + } + return allDiagnoses; + } + + private ConceptReferenceTerm getConceptReferenceTermByConceptSource(Concept concept, ConceptSource conceptSource) { + Collection conceptMappings = concept.getConceptMappings(); + if (conceptMappings != null && conceptSource != null) { + for (ConceptMap cm : conceptMappings) { + ConceptReferenceTerm term = cm.getConceptReferenceTerm(); + if (conceptSource.equals(term.getConceptSource())) { + return term; + } + } + } + return null; + } + + private Locale getSearchLocale(String localeStr) { + if (localeStr == null) { + return Context.getLocale(); + } + Locale locale; + try { + locale = LocaleUtils.toLocale(localeStr); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(localeErrorMessage("emrapi.conceptSearch.invalidLocale", localeStr)); + } + if (allowedLocale(locale)) { + return locale; + } else { + throw new IllegalArgumentException(localeErrorMessage("emrapi.conceptSearch.unsupportedLocale", localeStr)); + } + } + + private boolean allowedLocale(Locale locale) { + Set allowedLocales = new HashSet<>(Context.getAdministrationService().getAllowedLocales()); + return allowedLocales.contains(locale); + } + + private String localeErrorMessage(String msgKey, String localeStr) { + return Context.getMessageSourceService().getMessage(msgKey, new Object[]{localeStr}, Context.getLocale()); + } + + @Override + public void onStartup() { + + } + + @Override + public void onShutdown() { + + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java new file mode 100644 index 0000000000..db49d734e7 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniAsyncThreadExecutor.java @@ -0,0 +1,28 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.bahmni.module.bahmnicore.util; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@Configuration +@EnableAsync +public class BahmniAsyncThreadExecutor { + + @Bean(name = "BahmniAsyncThreadExecutor") + public Executor threadPoolTaskExecutor() { + ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); + return threadPoolTaskExecutor; + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniDateUtil.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniDateUtil.java new file mode 100644 index 0000000000..f157433edb --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/BahmniDateUtil.java @@ -0,0 +1,50 @@ +package org.bahmni.module.bahmnicore.util; + +import org.apache.commons.lang3.StringUtils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class BahmniDateUtil { + + public enum DateFormatType { + UTC("yyyy-MM-dd'T'HH:mm:ss.SSS"); + + private final String dateFormat; + + DateFormatType(String dateFormat) { + this.dateFormat = dateFormat; + } + + public String getDateFormat() { + return dateFormat; + } + } + + public static Date convertToDate(String dateString, DateFormatType dateFormat) throws ParseException { + if (StringUtils.isEmpty(dateString) || dateFormat == null) { + return null; + } + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat.getDateFormat()); + return simpleDateFormat.parse(dateString); + } + + public static Date convertToDate(String dateString, String dateFormat) throws ParseException { + if (StringUtils.isEmpty(dateString) || StringUtils.isEmpty(dateFormat)) { + return null; + } + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); + return simpleDateFormat.parse(dateString); + } + + public static Date convertToLocalDateFromUTC(String dateString) throws ParseException { + if (StringUtils.isEmpty(dateString)) { + return null; + } + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(BahmniDateUtil.DateFormatType.UTC.dateFormat); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return simpleDateFormat.parse(dateString); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java new file mode 100644 index 0000000000..73042231b6 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/MiscUtils.java @@ -0,0 +1,62 @@ +package org.bahmni.module.bahmnicore.util; + +import org.apache.commons.collections.CollectionUtils; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.util.LocaleUtility; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.regex.Pattern; + +public class MiscUtils { + public static List getConceptsForNames(List conceptNames, ConceptService conceptService) { + //Returning null for the sake of UTs + if (CollectionUtils.isNotEmpty(conceptNames)) { + List rootConcepts = new ArrayList<>(); + for (String rootConceptName : conceptNames) { + Concept concept = conceptService.getConceptByName(rootConceptName); + if (concept == null) { + concept = getConceptInDefaultLocale(conceptService, rootConceptName); + } + if (concept != null) { + rootConcepts.add(concept); + } + } + return rootConcepts; + } + return new ArrayList<>(); + } + private static Concept getConceptInDefaultLocale(ConceptService conceptService, String rootConceptName) { + if (LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + return null; + } + List conceptsByName = conceptService.getConceptsByName(rootConceptName, LocaleUtility.getDefaultLocale(), false); + for (Concept concept : conceptsByName) { + for (ConceptName conceptname : concept.getNames()) { + if (conceptname.getName().equalsIgnoreCase(rootConceptName) && (conceptname.isPreferred() || conceptname.isFullySpecifiedName())) { + return concept; + } + } + } + return null; + } + + public static void setUuidsForObservations(Collection bahmniObservations) { + for (BahmniObservation bahmniObservation : bahmniObservations) { + if (org.apache.commons.lang3.StringUtils.isBlank(bahmniObservation.getUuid())) { + bahmniObservation.setUuid(UUID.randomUUID().toString()); + } + } + } + + public static boolean onlyDigits(String input) { + Pattern onlyDigits = Pattern.compile("\\d+"); + return onlyDigits.matcher(input).matches(); + } +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java new file mode 100644 index 0000000000..08bcbffdc6 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/SqlQueryHelper.java @@ -0,0 +1,134 @@ +package org.bahmni.module.bahmnicore.util; + +import org.apache.commons.lang3.StringUtils; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.model.searchParams.AdditionalSearchParam; +import org.codehaus.jackson.map.ObjectMapper; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class SqlQueryHelper { + private final Pattern paramPlaceHolderPattern; + private static final String PARAM_PLACE_HOLDER_REGEX = "\\$\\{[^{]*\\}"; + private static final Logger log = LogManager.getLogger(SqlQueryHelper.class); + + public SqlQueryHelper() { + this.paramPlaceHolderPattern = Pattern.compile(PARAM_PLACE_HOLDER_REGEX); + } + + List getParamNamesFromPlaceHolders(String query){ + List params = new ArrayList<>(); + Matcher matcher = paramPlaceHolderPattern.matcher(query); + while(matcher.find()){ + params.add(stripDelimiters(matcher.group())); + } + return params; + } + + private String stripDelimiters(String text) { + return text.replaceAll("[${}]", ""); + } + + public String transformIntoPreparedStatementFormat(String queryString){ + return queryString.replaceAll(PARAM_PLACE_HOLDER_REGEX,"?"); + } + + public PreparedStatement constructPreparedStatement(String queryString, Map params, Connection conn) throws SQLException { + String finalQueryString = queryString; + if (params.get("additionalParams") != null && params.get("additionalParams") != null) { + finalQueryString = parseAdditionalParams(params.get("additionalParams")[0], queryString); + } + + List paramNamesFromPlaceHolders = getParamNamesFromPlaceHolders(finalQueryString); + String statement = transformIntoPreparedStatementFormat(finalQueryString); + PreparedStatement preparedStatement = conn.prepareStatement(statement); + if(params != null ){ + int i=1; + for (String paramName : paramNamesFromPlaceHolders) { + String paramValue = params.get(paramName)[0]; + preparedStatement.setObject(i++,paramValue); + } + } + return preparedStatement; + } + + String parseAdditionalParams(String additionalParams, String queryString) { + String queryWithAdditionalParams = queryString; + try { + AdditionalSearchParam additionalSearchParams = new ObjectMapper().readValue(additionalParams, AdditionalSearchParam.class); + String test = additionalSearchParams.getTests(); + queryWithAdditionalParams = queryString.replaceAll("\\$\\{testName\\}", test); + } catch (IOException e) { + log.error("Failed to parse Additional Search Parameters."); + e.printStackTrace(); + } + return queryWithAdditionalParams; + } + + public static String escapeSQL(String str, boolean escapeDoubleQuotes, Character escapeChar) { + if (StringUtils.isBlank(str)) { + return str; + } + char escChar = '\\'; + if (escapeChar != null) { + escChar = escapeChar.charValue(); + } + String strToCheck = str.trim().replace("0x", "0X").replace("/*", "\\/*"); + StringBuilder sBuilder = new StringBuilder(); + int stringLength = strToCheck.length(); + for (int i = 0; i < stringLength; ++i) { + char c = strToCheck.charAt(i); + switch (c) { + case 0: + sBuilder.append(escChar); + sBuilder.append('0'); + break; + case ';': + sBuilder.append(escChar); + sBuilder.append(';'); + break; + case '\n': /* Must be escaped for logs */ + sBuilder.append(escChar); + sBuilder.append('n'); + break; + case '\r': + sBuilder.append(escChar); + sBuilder.append('r'); + break; + case '\\': + sBuilder.append(escChar); + sBuilder.append('\\'); + break; + case '\'': + sBuilder.append(escChar); + sBuilder.append('\''); + break; + case '"': + if (escapeDoubleQuotes) { + sBuilder.append('\\'); + } + sBuilder.append('"'); + break; + case '\032': + sBuilder.append(escChar); + sBuilder.append('Z'); + break; + default: + sBuilder.append(c); + } + } + return sBuilder.toString(); + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/WebUtils.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/WebUtils.java new file mode 100644 index 0000000000..43bb72ac61 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/util/WebUtils.java @@ -0,0 +1,20 @@ +package org.bahmni.module.bahmnicore.util; + +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.util.LinkedHashMap; + +public class WebUtils { + + public static SimpleObject wrapErrorResponse(String code, String reason) { + LinkedHashMap map = new LinkedHashMap(); + if (reason != null && !"".equals(reason)) { + map.put("message", reason); + } + if (code != null && !"".equals(code)) { + map.put("code", code); + } + return (new SimpleObject()).add("error", map); + } + +} diff --git a/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java new file mode 100644 index 0000000000..ef4a6e1e93 --- /dev/null +++ b/bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/validator/NoteValidator.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.validator; + + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +import static java.util.Objects.nonNull; + +@Component +public class NoteValidator implements Validator { + + @Autowired + private NoteDao noteDao; + + @Override + public boolean supports(Class c) { + return NoteRequestResponse.class.isAssignableFrom(c); + } + + @Override + public void validate(Object obj, Errors errors) { + NoteRequestResponse noteRequest = (NoteRequestResponse) obj; + if (noteRequest == null) { + errors.reject("error.general"); + } else { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "noteTypeName", "Note.noteType.required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "noteText", "Note.noteText.required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "noteDate", "Note.noteDate.required"); + } + + if(nonNull(noteDao.getNote(noteRequest.getNoteDate(), noteRequest.getNoteTypeName()))) { + errors.reject("Note entry exist for noteType and noteDate"); + } + } + + +} diff --git a/bahmnicore-api/src/main/resources/NoteType.hbm.xml b/bahmnicore-api/src/main/resources/NoteType.hbm.xml new file mode 100644 index 0000000000..4712b2011d --- /dev/null +++ b/bahmnicore-api/src/main/resources/NoteType.hbm.xml @@ -0,0 +1,33 @@ + + + + + + + + + note_type_id_seq + + + + + + + + diff --git a/bahmnicore-api/src/main/resources/Notes.hbm.xml b/bahmnicore-api/src/main/resources/Notes.hbm.xml new file mode 100644 index 0000000000..d512195301 --- /dev/null +++ b/bahmnicore-api/src/main/resources/Notes.hbm.xml @@ -0,0 +1,44 @@ + + + + + + + + + note_id_seq + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/main/resources/atomfeed.properties b/bahmnicore-api/src/main/resources/atomfeed.properties new file mode 100644 index 0000000000..ec8dc81227 --- /dev/null +++ b/bahmnicore-api/src/main/resources/atomfeed.properties @@ -0,0 +1 @@ +atomdb.default_schema= \ No newline at end of file diff --git a/bahmnicore-api/src/main/resources/moduleApplicationContext.xml b/bahmnicore-api/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..7129614967 --- /dev/null +++ b/bahmnicore-api/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + ImageUrlHandler + + + + VideoUrlHandler + + + + LocationObsHandler + + + + ProviderObsHandler + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService + + + + + + + + + + + + + + + + + + + + + + + + org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.BahmniOrderService + + + + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.TsConceptSearchService + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.BahmniDiagnosisService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.bahmni.module.bahmnicore.service.NoteService + + + + + diff --git a/bahmnicore-api/src/main/resources/visitAttributeDataSet.xml b/bahmnicore-api/src/main/resources/visitAttributeDataSet.xml new file mode 100644 index 0000000000..55556f4188 --- /dev/null +++ b/bahmnicore-api/src/main/resources/visitAttributeDataSet.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/BaseIntegrationTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/BaseIntegrationTest.java new file mode 100644 index 0000000000..531e706d8b --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/BaseIntegrationTest.java @@ -0,0 +1,8 @@ +package org.bahmni.module.bahmnicore; + +import org.springframework.test.context.ContextConfiguration; +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; + +@ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BaseIntegrationTest extends BaseModuleWebContextSensitiveTest { +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/customdatatype/datatype/CodedConceptDatatypeTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/customdatatype/datatype/CodedConceptDatatypeTest.java new file mode 100644 index 0000000000..6e28e1f91e --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/customdatatype/datatype/CodedConceptDatatypeTest.java @@ -0,0 +1,92 @@ +package org.bahmni.module.bahmnicore.customdatatype.datatype; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.customdatatype.InvalidCustomValueException; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Collections; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class CodedConceptDatatypeTest { + @Mock + ConceptService conceptService; + + private CodedConceptDatatype codedConceptDatatype; + private Concept concept; + + @Before + public void setUp() { + concept = new Concept(); + concept.setId(1); + + ConceptAnswer answer = new ConceptAnswer(); + answer.setId(2); + answer.setAnswerConcept(concept); + + concept.setAnswers(Collections.singletonList(answer)); + codedConceptDatatype = new CodedConceptDatatype(); + + PowerMockito.mockStatic(Context.class); + BDDMockito.when(Context.getConceptService()).thenReturn(conceptService); + + when(conceptService.getConcept(1)).thenReturn(concept); + when(conceptService.getConceptByUuid("abcd")).thenReturn(concept); + } + + @Test + public void shouldGetCorrectConceptWhenSettingConfiguration() throws Exception { + codedConceptDatatype.setConfiguration("1"); + + verify(conceptService).getConcept(1); + } + + @Test + public void shouldReturnConceptIdWhenSerialized() throws Exception { + String conceptId = codedConceptDatatype.serialize(concept); + + assertEquals("1", conceptId); + } + + @Test + public void shouldReturnConceptWhenDeserializedUsingConceptId() throws Exception { + Concept deserializedConcept = codedConceptDatatype.deserialize("1"); + + assertEquals(concept, deserializedConcept); + } + + @Test + public void shouldReturnConceptWhenDeserializedUsingConceptUuid() throws Exception { + Concept deserializedConcept = codedConceptDatatype.deserialize("abcd"); + + assertEquals(concept, deserializedConcept); + } + + @Test + public void shouldNotThrowAnyExceptionWhenAConceptIsACorrectAnswer() throws Exception { + codedConceptDatatype.setConfiguration("1"); + codedConceptDatatype.validate(concept); + } + + @Test(expected = InvalidCustomValueException.class) + public void shouldThrowExceptionWhenAConceptIsAnIncorrectAnswer() throws Exception { + codedConceptDatatype.setConfiguration("1"); + Concept concept = new Concept(); + concept.setId(2); + codedConceptDatatype.validate(concept); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/AbstractDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/AbstractDaoImplIT.java new file mode 100644 index 0000000000..d63dbf3649 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/AbstractDaoImplIT.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.EntityDao; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class AbstractDaoImplIT extends BaseIntegrationTest { + @Autowired + EntityDao entityDao; + + @Before + public void setUp() throws Exception { + executeDataSet("apiTestData.xml"); + } + + @Test + public void getByUuidShouldGetLocationByUuid() throws Exception { + String locationUuid = "8d6c993e-c2cc-11de-8d13-0010c6dfed0f"; + Location location = entityDao.getByUuid(locationUuid, Location.class); + assertNotNull(location); + assertEquals(locationUuid, location.getUuid()); + assertEquals("Semariya subcentre",location.getDescription()); + } + + @Test + public void getByUuidShouldGetConceptByUuid() throws Exception{ + String conceptUuid = "True_concept_uuid"; + Concept concept = entityDao.getByUuid(conceptUuid, Concept.class); + assertNotNull(concept); + assertEquals(conceptUuid, concept.getUuid()); + assertEquals("True",concept.getName().getName()); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImplIT.java new file mode 100644 index 0000000000..0bb1a16eaa --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/BahmniConceptDaoImplIT.java @@ -0,0 +1,287 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.BahmniConceptDao; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; +import org.openmrs.api.ConceptService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class BahmniConceptDaoImplIT extends BaseIntegrationTest{ + @Autowired + private BahmniConceptDao bahmniConceptDao; + + @Autowired + private ConceptService conceptService; + private Concept questionConcept; + + @Test + public void shouldReturnNonVoidedAnswersForAQuestion() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + Collection result = bahmniConceptDao.searchByQuestion(questionConcept, "Aneurism"); + + assertThat(result.size(), is(equalTo(1))); + + Concept resultConcept = result.iterator().next().getAnswerConcept(); + assertTrue(resultConcept.getId().equals(902)); + } + + @Test + public void shouldIgnoreCaseWhenSearching() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + Collection result = bahmniConceptDao.searchByQuestion(questionConcept, "aNeUrIsM"); + + assertThat(result.size(), is(equalTo(1))); + + Concept resultConcept = result.iterator().next().getAnswerConcept(); + assertTrue(resultConcept.getId().equals(902)); + } + + @Test + public void shouldNotReturnVoidedAnswers() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + Collection result = bahmniConceptDao.searchByQuestion(questionConcept, "Porphyria"); + assertThat(result.size(), is(equalTo(0))); + } + + @Test + public void shouldSearchEachTermByQuestion() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + + //Searching for "Abscess, Skin" + Collection result = bahmniConceptDao.searchByQuestion(questionConcept, " ab sk "); + assertThat(result.size(), is(equalTo(1))); + Concept resultConcept = result.iterator().next().getAnswerConcept(); + assertTrue(resultConcept.getId().equals(903)); + + result = bahmniConceptDao.searchByQuestion(questionConcept, "in ab"); + assertThat(result.size(), is(equalTo(2))); + + ArrayList actualConceptAnswers = new ArrayList<>(result); + ArrayList actualConcepts = new ArrayList<>(); + actualConcepts.add(actualConceptAnswers.get(0).getAnswerConcept()); + actualConcepts.add(actualConceptAnswers.get(1).getAnswerConcept()); + + assertThat(actualConcepts, containsInAnyOrder(conceptService.getConcept(902), conceptService.getConcept(903))); + + result = bahmniConceptDao.searchByQuestion(questionConcept, "in and another term that is not present"); + assertThat(result.size(), is(equalTo(0))); + } + + @Test + public void shouldReturnMultipleResultsIfAvailable() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + + Collection result = bahmniConceptDao.searchByQuestion(questionConcept, "ab"); + + assertThat(result.size(), is(equalTo(2))); + + ArrayList actualConceptAnswers = new ArrayList<>(result); + ArrayList actualConcepts = new ArrayList<>(); + actualConcepts.add(actualConceptAnswers.get(0).getAnswerConcept()); + actualConcepts.add(actualConceptAnswers.get(1).getAnswerConcept()); + + assertThat(actualConcepts, containsInAnyOrder(conceptService.getConcept(902), conceptService.getConcept(903))); + } + + @Test + public void getConceptByFullySpecifiedNameShouldGetConceptByItsFullySpecifiedName() throws Exception{ + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + + Concept result = bahmniConceptDao.getConceptByFullySpecifiedName("Acne"); + + assertNotNull(result); + assertEquals("65230431-2fe5-49fc-b535-ae42bc90979d",result.getUuid()); + } + + @Test + public void getConceptByFullySpecifiedNameShouldBeCaseInsensitive() throws Exception{ + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + + Concept result = bahmniConceptDao.getConceptByFullySpecifiedName("ACNE"); + + assertNotNull(result); + assertEquals("65230431-2fe5-49fc-b535-ae42bc90979d",result.getUuid()); + } + + @Test + public void searchByQuestionShouldGetAllConceptAnswersWhenQueryIsEmpty() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + questionConcept = conceptService.getConcept(90); + + Collection result = bahmniConceptDao.searchByQuestion(questionConcept, null); + + assertEquals(4,result.size()); + } + + @Test + public void getByConceptSetShouldRetrieveDrugsForSetMembersOfTheConceptSet() throws Exception { + executeDataSet("drugsWithConcepts.xml"); + + Collection drugs = bahmniConceptDao.getDrugByListOfConcepts( + conceptService.getConceptsByConceptSet(conceptService.getConcept(3010))); + assertEquals(3, drugs.size()); + assertThat(drugs, containsInAnyOrder(conceptService.getDrug(2001), conceptService.getDrug(4001), conceptService.getDrug(6001))); + } + + @Test + public void shouldSearchDrugsByDrugNameInTheGivenListOfConcepts() throws Exception{ + executeDataSet("drugsWithConcepts.xml"); + + List resultantDrugs = bahmniConceptDao.searchDrugsByDrugName(3010, "Isoniazid"); + + assertEquals(1,resultantDrugs.size()); + assertEquals(conceptService.getDrug(4001),resultantDrugs.get(0)); + + } + + @Test + public void shouldSearchDrugsByDrugNameInTheGivenListOfConceptsIrrespectiveOfCase() throws Exception{ + executeDataSet("drugsWithConcepts.xml"); + + List resultantDrugs = bahmniConceptDao.searchDrugsByDrugName(3010, "IsOnIazId"); + + assertEquals(1,resultantDrugs.size()); + assertEquals(conceptService.getDrug(4001),resultantDrugs.get(0)); + + } + + @Test + public void shouldGetAllDrugsInTheGivenListOfConceptsWhichMatchTheDrugConceptNameAsWell() throws Exception{ + executeDataSet("drugsWithConcepts.xml"); + + List drugs = bahmniConceptDao.searchDrugsByDrugName(3010, "t"); + + assertEquals(3,drugs.size()); + assertThat(drugs, containsInAnyOrder(conceptService.getDrug(2001), conceptService.getDrug(4001), conceptService.getDrug(6001))); + } + + @Test + public void shouldGetAllDrugsInTheGivenListOfConceptsWhenSearchTermNotGiven() throws Exception{ + executeDataSet("drugsWithConcepts.xml"); + + List drugs = bahmniConceptDao.searchDrugsByDrugName(3010, null); + + assertEquals(3,drugs.size()); + assertThat(drugs, containsInAnyOrder(conceptService.getDrug(2001), conceptService.getDrug(4001), conceptService.getDrug(6001))); + } + + @Test + public void shouldGetMatchingDrugsInSortedOrder_wrt_sortWeightWhenSearchTermIsGiven() throws Exception{ + executeDataSet("drugsWithConcepts.xml"); + + List drugs = bahmniConceptDao.searchDrugsByDrugName(3010, "t"); + + assertEquals(3,drugs.size()); + + assertEquals(conceptService.getDrug(2001),drugs.get(0)); + assertEquals(conceptService.getDrug(4001),drugs.get(1)); + assertEquals(conceptService.getDrug(6001),drugs.get(2)); + } + + @Test + public void shouldGetMatchingDrugsInSortedOrder_wrt_sortWeightWhenSearchTermIsNotGiven() throws Exception{ + executeDataSet("drugsWithConcepts.xml"); + + List drugs = bahmniConceptDao.searchDrugsByDrugName(3010, null); + + assertEquals(3,drugs.size()); + + assertEquals(conceptService.getDrug(2001),drugs.get(0)); + assertEquals(conceptService.getDrug(4001),drugs.get(1)); + assertEquals(conceptService.getDrug(6001),drugs.get(2)); + } + + @Test + public void shouldGetConceptsByFullySpecifiedName() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + List conceptNames = new ArrayList<>(); + conceptNames.add("List of Diagnoses"); + conceptNames.add("Dengue Fever"); + + List concepts = bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + + assertEquals(2, concepts.size()); + assertEquals(90,concepts.get(0).getConceptId().intValue()); + assertEquals(901,concepts.get(1).getConceptId().intValue()); + } + + @Test + public void shouldReturnEmptyConceptsListIfConceptNamesNotExist() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + List conceptNames = new ArrayList<>(); + conceptNames.add("concept1"); + conceptNames.add("concept2"); + + List concepts = bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + + assertEquals(0, concepts.size()); + } + + @Test + public void shouldReturnConceptsOnlyByFullySpecifiedName() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + List conceptNames = new ArrayList<>(); + conceptNames.add("acne"); + + List concepts = bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + + assertEquals(1, concepts.size()); + } + + @Test + public void shouldGetConceptsByUsingConceptNamesBasedOnCaseInsensitivity() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + List conceptNames = new ArrayList<>(); + conceptNames.add("List Of diagnoses"); + conceptNames.add("Dengue fever"); + + List concepts = bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + + assertEquals(2, concepts.size()); + } + + @Test + public void shouldNotGetTheConceptsByShortName() throws Exception { + executeDataSet("sampleCodedConcept.xml"); + List conceptNames = new ArrayList<>(); + conceptNames.add("Skin"); + + List concepts = bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + + assertEquals(0, concepts.size()); + } + + @Test + public void shouldNotReturnConceptIfConceptNameIsVoided() throws Exception { + + executeDataSet("sampleCodedConcept.xml"); + List conceptNames = new ArrayList<>(); + conceptNames.add("Acute Porphyria (voided)"); + + List concepts = bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames); + + assertEquals(0, concepts.size()); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/BahmniOrderSetImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/BahmniOrderSetImplIT.java new file mode 100644 index 0000000000..11576aeea5 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/BahmniOrderSetImplIT.java @@ -0,0 +1,46 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.BahmniOrderSetDao; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.OrderSet; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class BahmniOrderSetImplIT extends BaseIntegrationTest{ + @Autowired + private BahmniOrderSetDao bahmniOrderSetDao; + + @Before + public void setUp() throws Exception { + executeDataSet("orderSet.xml"); + } + + @Test + public void shouldReturnOrderSetsWhichContainsSearchTermInName() throws Exception { + List result = bahmniOrderSetDao.getOrderSetByQuery("Order"); + assertThat(result.size(), is(equalTo(3))); + } + + @Test + public void shouldReturnOrderSetsWhichContainsSearchTermInDescription() throws Exception { + List result = bahmniOrderSetDao.getOrderSetByQuery("New_Order"); + assertThat(result.size(), is(equalTo(1))); + Assert.assertEquals("222fb1d0-a666-22e3-dde2-0110211c1111", result.get(0).getUuid()); + } + + @Test + public void shouldNotAnyResultsIfBothNameAndDescriptionDoNotContainSearchTerm() throws Exception{ + List result = bahmniOrderSetDao.getOrderSetByQuery("Random"); + assertThat(result.size(), is(equalTo(0))); + } + + +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoIT.java new file mode 100644 index 0000000000..2751b89ee3 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoIT.java @@ -0,0 +1,159 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Obs; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static junit.framework.Assert.assertEquals; + +public class ObsDaoIT extends BaseIntegrationTest { + @Autowired + ObsDao obsDao; + + @Before + public void setUp() throws Exception { + executeDataSet("apiTestData.xml"); + } + + @Test + public void shouldRetrievePatientObs() throws Exception { + List obsByPerson = obsDao.getNumericObsByPerson("86526ed5-3c11-11de-a0ba-001e378eb67a"); + assertEquals(5, obsByPerson.size()); + } + + @Test + public void retrieveAllObservationsWhenNoVisitIdsAreSpecified() throws Exception { + List allObs = obsDao.getObsByPatientAndVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", Arrays.asList("Blood Pressure"), new ArrayList(), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.ASC, null, false, null, null, null); + assertEquals(1, allObs.size()); + + Obs parent_obs = allObs.get(0); + List groupMembers = new ArrayList<>(parent_obs.getGroupMembers()); + assertEquals(2, groupMembers.size()); + assertEquals("Blood Pressure", parent_obs.getConcept().getName().getName()); + + Obs childObs1 = groupMembers.get(0); + Obs childObs2 = groupMembers.get(1); + List childGroupMembers1 = new ArrayList<>(childObs1.getGroupMembers()); + List childGroupMembers2 = new ArrayList<>(childObs2.getGroupMembers()); + assertEquals("Systolic Data", childObs1.getConcept().getName().getName()); + assertEquals("Diastolic Data", childObs2.getConcept().getName().getName()); + + assertEquals("Systolic", childGroupMembers1.get(0).getConcept().getName().getName()); + assertEquals("Diastolic", childGroupMembers2.get(0).getConcept().getName().getName()); + + assertEquals(120.0, childGroupMembers1.get(0).getValueNumeric()); + assertEquals(100.0, childGroupMembers2.get(0).getValueNumeric()); + + assertEquals("Systolic Abnormal", childGroupMembers1.get(1).getConcept().getName().getName()); + assertEquals("Diastolic Abnormal", childGroupMembers2.get(1).getConcept().getName().getName()); + + assertEquals("False", childGroupMembers1.get(1).getValueCoded().getName().getName()); + assertEquals("True", childGroupMembers2.get(1).getValueCoded().getName().getName()); + } + + @Test + public void retrieveOnlyOrphanedObservation() throws Exception { + List allObs = obsDao.getObsByPatientAndVisit("341b4e41-790c-484f-b6ed-71dc8da222db", Arrays.asList("Diastolic"), new ArrayList(), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.ASC, null, false, null, null, null); + assertEquals(1, allObs.size()); + assertEquals("Diastolic", allObs.get(0).getConcept().getName().getName()); + assertEquals(125.0, allObs.get(0).getValueNumeric()); + } + + @Test + public void shouldRetrieveNumericalConceptsForPatient() throws Exception { + assertEquals(5, obsDao.getNumericConceptsForPerson("86526ed5-3c11-11de-a0ba-001e378eb67a").size()); + } + + @Test + public void doNotFetchVoidedObservations() throws Exception { + List allObs = obsDao.getObsByPatientAndVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", Arrays.asList("Blood Pressure"), new ArrayList(), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.ASC, null, false, null, null, null); + assertEquals(1, allObs.size()); + } + + @Test + public void shouldRetrieveObservationsForGivenDateRange() throws Exception { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-M-dd hh:mm:ss"); + Date startDate = dateFormat.parse("2008-08-15 15:09:05"); + Date endDate = dateFormat.parse("2008-08-17 15:09:05"); + + List allObs = obsDao.getObsByPatientAndVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", Arrays.asList("Blood Pressure"), + new ArrayList(), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.ASC, null, false, null, startDate, endDate); + + assertEquals(0, allObs.size()); + + startDate = dateFormat.parse("2008-08-17 15:09:05"); + endDate = dateFormat.parse("2008-08-20 15:09:05"); + + allObs = obsDao.getObsByPatientAndVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", Arrays.asList("Blood Pressure"), + new ArrayList(), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.ASC, null, false, null, startDate, endDate); + + Obs parent_obs = allObs.get(0); + List groupMembers = new ArrayList<>(parent_obs.getGroupMembers()); + assertEquals(2, groupMembers.size()); + assertEquals("Blood Pressure", parent_obs.getConcept().getName().getName()); + + Obs childObs1 = groupMembers.get(0); + Obs childObs2 = groupMembers.get(1); + List childGroupMembers1 = new ArrayList<>(childObs1.getGroupMembers()); + List childGroupMembers2 = new ArrayList<>(childObs2.getGroupMembers()); + assertEquals("Systolic Data", childObs1.getConcept().getName().getName()); + assertEquals("Diastolic Data", childObs2.getConcept().getName().getName()); + + assertEquals("Systolic", childGroupMembers1.get(0).getConcept().getName().getName()); + assertEquals("Diastolic", childGroupMembers2.get(0).getConcept().getName().getName()); + + assertEquals(120.0, childGroupMembers1.get(0).getValueNumeric()); + assertEquals(100.0, childGroupMembers2.get(0).getValueNumeric()); + + assertEquals("Systolic Abnormal", childGroupMembers1.get(1).getConcept().getName().getName()); + assertEquals("Diastolic Abnormal", childGroupMembers2.get(1).getConcept().getName().getName()); + + assertEquals("False", childGroupMembers1.get(1).getValueCoded().getName().getName()); + assertEquals("True", childGroupMembers2.get(1).getValueCoded().getName().getName()); + + } + + @Test + public void shouldRetrieveObservationsFromGivenStartDate() throws Exception { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-M-dd hh:mm:ss"); + Date startDate = dateFormat.parse("2008-08-17 15:09:05"); + Date endDate = null; + + List allObs = obsDao.getObsByPatientAndVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", Arrays.asList("Blood Pressure"), + new ArrayList(), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.ASC, null, false, null, startDate, endDate); + + Obs parent_obs = allObs.get(0); + List groupMembers = new ArrayList<>(parent_obs.getGroupMembers()); + assertEquals(2, groupMembers.size()); + assertEquals("Blood Pressure", parent_obs.getConcept().getName().getName()); + + Obs childObs1 = groupMembers.get(0); + Obs childObs2 = groupMembers.get(1); + List childGroupMembers1 = new ArrayList<>(childObs1.getGroupMembers()); + List childGroupMembers2 = new ArrayList<>(childObs2.getGroupMembers()); + assertEquals("Systolic Data", childObs1.getConcept().getName().getName()); + assertEquals("Diastolic Data", childObs2.getConcept().getName().getName()); + + assertEquals("Systolic", childGroupMembers1.get(0).getConcept().getName().getName()); + assertEquals("Diastolic", childGroupMembers2.get(0).getConcept().getName().getName()); + + assertEquals(120.0, childGroupMembers1.get(0).getValueNumeric()); + assertEquals(100.0, childGroupMembers2.get(0).getValueNumeric()); + + assertEquals("Systolic Abnormal", childGroupMembers1.get(1).getConcept().getName().getName()); + assertEquals("Diastolic Abnormal", childGroupMembers2.get(1).getConcept().getName().getName()); + + assertEquals("False", childGroupMembers1.get(1).getValueCoded().getName().getName()); + assertEquals("True", childGroupMembers2.get(1).getValueCoded().getName().getName()); + + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImplIT.java new file mode 100644 index 0000000000..e4edc9d6c6 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/ObsDaoImplIT.java @@ -0,0 +1,181 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.bahmni.module.bahmnicore.util.BahmniDateUtil; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.EncounterService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class ObsDaoImplIT extends BaseIntegrationTest { + + @Autowired + ObsDao obsDao; + + @Autowired + EncounterService encounterService; + + Map conceptToObsMap = new HashMap<>(); + + @Before + public void setUp() throws Exception { + executeDataSet("obsTestData.xml"); + executeDataSet("patientProgramTestData.xml"); + + conceptToObsMap.put(9012, 5); + conceptToObsMap.put(9011, 4); + } + + @Test + public void shouldGetLatestObsForConceptSetByVisit() { + List obsList = obsDao.getLatestObsForConceptSetByVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", "Breast Cancer Intake", 901); + assertEquals(2, obsList.size()); + for (Obs obs : obsList) { + assertEquals("for concept : " + obs.getConcept().getName().getName(), conceptToObsMap.get(obs.getConcept().getId()), obs.getId()); + } + } + + @Test + public void shouldNotRetrieveIfObservationMadeInADifferentTemplate() { + List obsList = obsDao.getLatestObsForConceptSetByVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", "Breast Cancer Progress", 901); + assertEquals(2, obsList.size()); + } + + @Test + public void shouldRetrieveObservationsForAnOrder() throws Exception { + assertEquals(1, obsDao.getObsForOrder("5145792e-feb5-11e4-ae7f-080027b662ec").size()); + + List obsForOrder = obsDao.getObsForOrder("129de0a3-05c4-444a-be03-e01b4c4b2419"); + assertEquals(5, obsForOrder.size()); + assertEquals((Integer)12, obsForOrder.get(0).getId()); + assertEquals((Integer)11, obsForOrder.get(1).getId()); + assertEquals((Integer)10, obsForOrder.get(2).getId()); + assertEquals((Integer)8, obsForOrder.get(3).getId()); + assertEquals((Integer)7, obsForOrder.get(4).getId()); + + assertEquals(0, obsDao.getObsForOrder("some-random-uuid").size()); + } + + @Test + public void shouldRetrieveObservationWithinProgramsDateRange() throws Exception { + String rootConceptName = "Breast Cancer Intake"; + String childConceptName = "Histopathology"; + String patientUUid = "86526ed5-3c11-11de-a0ba-001e378eb67a"; + Date startDate = BahmniDateUtil.convertToDate("2008-08-18T15:00:01.000", BahmniDateUtil.DateFormatType.UTC); + Concept rootConcept = Context.getConceptService().getConceptByName(rootConceptName); + Concept childConcept = Context.getConceptService().getConceptByName(childConceptName); + List listOfVisitIds = new ArrayList(); + listOfVisitIds.add(902); + rootConcept.getName().getName(); + + List bahmniObservations = obsDao.getObsFor(patientUUid, rootConcept, childConcept,listOfVisitIds, Collections.EMPTY_LIST, startDate, null); + + assertEquals(1, bahmniObservations.size()); + assertEquals(rootConceptName, bahmniObservations.get(0).getConcept().getName().getName()); + assertEquals(3, bahmniObservations.get(0).getGroupMembers(true).size()); + } + + + @Test + public void shouldFilterObservationsBasedOnEncounters() throws Exception { + String rootConceptName = "Breast Cancer Intake"; + String childConceptName = "Histopathology"; + String patientUUid = "86526ed5-3c11-11de-a0ba-001e378eb67a"; + Date startDate = BahmniDateUtil.convertToDate("2008-08-18T15:00:01.000", BahmniDateUtil.DateFormatType.UTC); + Concept rootConcept = Context.getConceptService().getConceptByName(rootConceptName); + Concept childConcept = Context.getConceptService().getConceptByName(childConceptName); + List listOfVisitIds = new ArrayList(); + listOfVisitIds.add(902); + rootConcept.getName().getName(); + Encounter anEncounter = encounterService.getEncounter(40); + Encounter anotherEncounter = encounterService.getEncounter(41); + Encounter unrelatedEncounter = encounterService.getEncounter(3); + + List bahmniObservations = obsDao.getObsFor(patientUUid, rootConcept, childConcept,listOfVisitIds, Arrays.asList(anEncounter, anotherEncounter), startDate, null); + + assertEquals(1, bahmniObservations.size()); + assertEquals(rootConceptName, bahmniObservations.get(0).getConcept().getName().getName()); + assertEquals(3, bahmniObservations.get(0).getGroupMembers(true).size()); + + assertEquals(0, obsDao.getObsFor(patientUUid, rootConcept, childConcept, listOfVisitIds, Arrays.asList(unrelatedEncounter), startDate, null).size()); + } + + @Test + public void shouldRetrieveObservationWithinEncounter() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("Breast Cancer Progress"); + List observations = obsDao.getObsForConceptsByEncounter("f8ee38f6-1c8e-11e4-bb80-f18addb6f9bb", conceptNames); + + assertEquals(1, observations.size()); + assertEquals("6d8f507a-fb89-11e3-bb80-f18addb6f909", observations.get(0).getUuid()); + } + + + @Test + public void shouldRetrieveChildObservationFromParentGroup() throws Exception { + Concept vitalsConcept = Context.getConceptService().getConceptByName("Histopathology"); + Obs observation = obsDao.getChildObsFromParent("7d8f507a-fb89-11e3-bb80-f18addb6f9a4", vitalsConcept); + + assertEquals((Integer)24, observation.getId()); + } + + @Test + public void shouldRetrieveObsFromPatientProgramIdAndConceptNames() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("conceptABC"); + + List observations = obsDao.getObsByPatientProgramUuidAndConceptNames("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, null, null, null, null); + + assertEquals(1, observations.size()); + } + + @Test + public void shouldRetrieveLatestObsFromPatientProgramIdAndConceptNamesOrderByObsDateTime() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("DiagnosisProgram"); + + List observations = obsDao.getObsByPatientProgramUuidAndConceptNames("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, 1, ObsDaoImpl.OrderBy.DESC, null, null); + + assertEquals(1, observations.size()); + assertEquals("2016-08-18 15:09:05.0", observations.get(0).getObsDatetime().toString()); + } + + @Test + public void shouldRetrieveObsFromPatientProgramIdAndConceptNamesInDescendingOrderByObsDateTime() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("DiagnosisProgram"); + + List observations = obsDao.getObsByPatientProgramUuidAndConceptNames("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, -1, ObsDaoImpl.OrderBy.DESC, null, null); + + assertEquals(2, observations.size()); + assertEquals("2016-08-18 15:09:05.0", observations.get(0).getObsDatetime().toString()); + assertEquals("2015-08-18 15:09:05.0", observations.get(1).getObsDatetime().toString()); + } + + @Test + public void shouldRetrieveObsFromPatientProgramIdAndConceptNamesInAscendingOrderByObsDateTime() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("DiagnosisProgram"); + + List observations = obsDao.getObsByPatientProgramUuidAndConceptNames("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, -1, ObsDaoImpl.OrderBy.ASC, null, null); + + assertEquals(2, observations.size()); + assertEquals("2015-08-18 15:09:05.0", observations.get(0).getObsDatetime().toString()); + assertEquals("2016-08-18 15:09:05.0", observations.get(1).getObsDatetime().toString()); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java new file mode 100644 index 0000000000..54fb23f79d --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/OrderDaoImplIT.java @@ -0,0 +1,487 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.ApplicationDataDirectory; +import org.bahmni.module.bahmnicore.service.OrderService; +import org.bahmni.module.bahmnicore.util.BahmniDateUtil; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.net.URISyntaxException; +import java.util.*; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class OrderDaoImplIT extends BaseIntegrationTest { + + @Autowired + private OrderDaoImpl orderDao; + @Autowired + private ConceptService conceptService; + @Autowired + private OrderService orderService; + @Autowired + private PatientService patientService; + + + @Test + public void getPrescribedDrugOrdersShouldNotGetDiscontinueOrders() throws Exception { + executeDataSet("patientWithDiscontinuedOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + List drugOrdersInLastVisit = orderDao.getPrescribedDrugOrders(patient, true, null, null, null, false); + + assertThat(drugOrdersInLastVisit.size(), is(3)); + assertThat(getOrderIds(drugOrdersInLastVisit), hasItems(15, 16, 18)); + } + + @Test + public void getPrescribedDrugOrdersShouldGetRevisedOrdersAloneIfRevisionIsInSameEncounter() throws Exception { + executeDataSet("patientWithOrderRevisedInSameEncounter.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + List drugOrdersInLastVisit = orderDao.getPrescribedDrugOrders(patient, true, null, null, null, false); + + assertThat(drugOrdersInLastVisit.size(), is(1)); + assertThat(getOrderIds(drugOrdersInLastVisit), hasItems(16)); + } + + @Test + public void getPrescribedDrugOrdersShouldGetBothRevisedOrdersAndPreviousOrderIfRevisionIsInDifferentEncounter() throws Exception { + executeDataSet("patientWithOrderRevisedInDifferentEncounter.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + List drugOrdersInLastVisit = orderDao.getPrescribedDrugOrders(patient, true, null, null, null, false); + + assertThat(drugOrdersInLastVisit.size(), is(2)); + assertThat(getOrderIds(drugOrdersInLastVisit), hasItems(15, 16)); + } + + @Test + public void getPrescribedDrugOrdersShouldFetchAllPrescribedDrugOrdersInPastVisits() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + List drugOrdersInLastVisit = orderDao.getPrescribedDrugOrders(patient, false, 1, null, null, false); + assertThat(drugOrdersInLastVisit.size(), is(equalTo(1))); + assertThat(getOrderIds(drugOrdersInLastVisit), hasItems(17)); + + List drugOrdersInLastTwoVisit = orderDao.getPrescribedDrugOrders(patient, false, 2, null, null, false); + assertThat(drugOrdersInLastTwoVisit.size(), is(equalTo(3))); + assertThat(getOrderIds(drugOrdersInLastTwoVisit), hasItems(15, 16, 17)); + + List drugOrders = orderDao.getPrescribedDrugOrders(patient, false, null, null, null, false); + assertThat(drugOrders.size(), is(equalTo(3))); + assertThat(getOrderIds(drugOrders), hasItems(15, 16, 17)); + } + + @Test + public void getPrescribedDrugOrdersShouldFetchAllPrescribedDrugOrdersIncludingActiveVisit() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + List drugOrders = orderDao.getPrescribedDrugOrders(patient, true, null, null, null, false); + assertThat(drugOrders.size(), is(equalTo(9))); + assertThat(getOrderIds(drugOrders), hasItems(15, 16, 17, 19, 21, 23, 24, 26, 27)); + + + drugOrders = orderDao.getPrescribedDrugOrders(patient, null, null, null, null, false); + assertThat(drugOrders.size(), is(equalTo(3))); + assertThat(getOrderIds(drugOrders), hasItems(15, 16, 17)); + } + + @Test + public void getPrescribedDrugOrdersShouldFetchAllPrescribedDrugOrdersWithInGivenDateRange() throws Exception{ + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + Date startDate = BahmniDateUtil.convertToDate("2003-01-01T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate("2013-09-09T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + + List drugOrders = orderDao.getPrescribedDrugOrders(patient, true, null, startDate, null, false); + assertThat(drugOrders.size(), is(equalTo(9))); + assertThat(getOrderIds(drugOrders), hasItems(16, 15,21, 23, 24, 19, 17, 26, 27)); + + drugOrders = orderDao.getPrescribedDrugOrders(patient, true, null, startDate, endDate, false); + assertThat(drugOrders.size(), is(equalTo(3))); + assertThat(getOrderIds(drugOrders), hasItems(15,16,17)); + + drugOrders = orderDao.getPrescribedDrugOrders(patient, true, null, null, endDate, false); + assertThat(drugOrders.size(), is(equalTo(3))); + assertThat(getOrderIds(drugOrders), hasItems(15, 16, 17)); + + } + + @Test + public void getPrescribedDrugOrdersShouldFetchAllPastDrugOrdersThatAreActiveInGivenDateRange() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + Date startDate = BahmniDateUtil.convertToDate("2015-01-01T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate("2015-09-09T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + + List drugOrders = orderDao.getPrescribedDrugOrders(patient, true, null, startDate, endDate, false); + assertThat(drugOrders.size(), is(equalTo(9))); + assertThat(getOrderIds(drugOrders), hasItems(21, 23, 24, 19, 17 ,16, 15, 26, 27)); + } + + @Test + public void getVisitsWithOrdersShouldFetchVisitsWithGivenOrderType() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + + List visits = orderDao.getVisitsWithActiveOrders(patient, "Order", true, 1); + + assertThat(visits.size(), is(equalTo(1))); + assertThat(visits.get(0).getId(), is(equalTo(5))); + } + + @Test + public void getPrescribedDrugOrdersForConceptsShouldFetchAllPrescribedDrugOrdersForGivenConceptsForGivenNoOfVisits() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = patientService.getPatient(2); + + List concepts = new ArrayList<>(); + concepts.add(conceptService.getConcept(3)); + concepts.add(conceptService.getConcept(25)); + + List visits = orderService.getVisitsWithOrders(patient, "DrugOrder", true, 1); + assertEquals(1, visits.size()); + + List result = orderDao.getPrescribedDrugOrdersForConcepts(patient, true, visits, concepts, null, null); + assertEquals(2, result.size()); + assertThat(getOrderIds(result), hasItems(55, 57)); + + } + + @Test + public void shouldFetchAllPrescribedDrugOrdersForGivenConceptsForGivenNoOfVisitsWithinGivenDateRange() throws Exception { + executeDataSet("patientWithOrders.xml"); + Date startDate = BahmniDateUtil.convertToDate("2013-08-07T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate("2013-08-09T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + + Patient patient = patientService.getPatient(2); + + List concepts = new ArrayList<>(); + concepts.add(conceptService.getConcept(25)); + concepts.add(conceptService.getConcept(26)); + + List visits = orderService.getVisitsWithOrders(patient, "DrugOrder", true, 1); + assertEquals(1, visits.size()); + + List result = orderDao.getPrescribedDrugOrdersForConcepts(patient, true, visits, concepts, startDate, endDate); + assertEquals(1, result.size()); + assertThat(getOrderIds(result), hasItems(57)); + + } + + @Test + public void shouldRetrieveAllVisitsRequested() throws Exception { + executeDataSet("patientWithOrders.xml"); + String visitUuid1 = "1e5d5d48-6b78-11e0-93c3-18a97ba044dc"; + String visitUuid2 = "1e5d5d48-6b78-11e0-93c3-18a97b8ca4dc"; + String[] visitUuids = {visitUuid1, visitUuid2}; + + List visits = orderDao.getVisitsForUUids(visitUuids); + + assertThat(visits.size(), is(equalTo(visitUuids.length))); + assertTrue(visitWithUuidExists(visitUuid1, visits)); + assertTrue(visitWithUuidExists(visitUuid2, visits)); + } + + @Test + public void shouldGetDrugOrdersByVisitUuid() throws Exception { + executeDataSet("patientWithOrders.xml"); + String visitUuid1 = "1e5d5d48-6b78-11e0-93c3-18a97ba044dc"; + String visitUuid2 = "1e5d5d48-6b78-11e0-93c3-18a97b8ca4dc"; + + List prescribedDrugOrders = orderDao.getPrescribedDrugOrders(Arrays.asList(visitUuid1, visitUuid2)); + + assertEquals(6, prescribedDrugOrders.size()); + } + + @Test + public void getDrugOrderForRegimenShouldRetrieveDrugOrdersAssignedToTheRegimen() throws Exception { + ApplicationDataDirectory applicationDataDirectory = mock(ApplicationDataDirectory.class); + when(applicationDataDirectory.getFile("ordertemplates/templates.json")) + .thenReturn(new File(this.getClass().getClassLoader().getResource("templates.json").toURI())); + orderDao.setApplicationDataDirectory(applicationDataDirectory); + + + Collection drugOrdersForCancerRegimen = orderDao.getDrugOrderForRegimen("Cancer Regimen, CAF"); + Collection drugOrdersForBreastCancer = orderDao.getDrugOrderForRegimen("Breast Cancer - AC"); + + assertEquals(1, drugOrdersForCancerRegimen.size()); + EncounterTransaction.DrugOrder drugOrder = drugOrdersForCancerRegimen.iterator().next(); + assertThat(drugOrder.getDrug().getName(), is(equalTo("DNS"))); + assertEquals(10, drugOrdersForBreastCancer.size()); + + } + + @Test(expected = NullPointerException.class) + public void getDrugOrderForRegimenShouldFailWhenFileDoesNotExist() { + ApplicationDataDirectory applicationDataDirectory = mock(ApplicationDataDirectory.class); + when(applicationDataDirectory.getFile("ordertemplates/templates.json")).thenThrow(NullPointerException.class); + orderDao.setApplicationDataDirectory(applicationDataDirectory); + + orderDao.getDrugOrderForRegimen("Breast Cancer - AC"); + } + + @Test + public void getDrugOrderForRegimenShouldReturnEmptyListWhenRegimenNotFound() throws URISyntaxException { + ApplicationDataDirectory applicationDataDirectory = mock(ApplicationDataDirectory.class); + when(applicationDataDirectory.getFile("ordertemplates/templates.json")) + .thenReturn(new File(this.getClass().getClassLoader().getResource("templates.json").toURI())); + orderDao.setApplicationDataDirectory(applicationDataDirectory); + + Collection drugOrders = orderDao.getDrugOrderForRegimen("Non existing regimen"); + assertThat(drugOrders.size(), is(equalTo(0))); + + } + + @Test + public void getAllOrdersForVisitsShouldReturnEmptyListWhenNoVisitsFound() { + assertThat(orderDao.getAllOrdersForVisits(null, null).size(), is(equalTo(0))); + assertThat(orderDao.getAllOrdersForVisits(null, new ArrayList()).size(), is(equalTo(0))); + } + + @Test + public void getAllOrdersForVisitsShouldReturnAllOrdersGivenAVisitAndAPatient() throws Exception { + executeDataSet("patientWithOrders.xml"); + Visit visit = Context.getVisitService().getVisit(1); + OrderType orderType = Context.getOrderService().getOrderType(15); + + List allOrdersForVisits = orderDao.getAllOrdersForVisits(orderType, Arrays.asList(visit)); + + assertThat(allOrdersForVisits.size(), is(equalTo(2))); + + Order firstOrder = Context.getOrderService().getOrder(15); + Order secondOrder = Context.getOrderService().getOrder(16); + assertThat(allOrdersForVisits, hasItems(firstOrder, secondOrder)); + } + + @Test + public void getActiveDrugOrdersForPatient() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + List activeOrders = orderDao.getActiveOrders(patient, orderType, null, new Date(), null, null, null, null, null); + + assertEquals(3, activeOrders.size()); + assertEquals(activeOrders.get(0).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f836"); + assertEquals(activeOrders.get(1).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f838"); + assertEquals(activeOrders.get(2).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f841"); + } + + @Test + public void getActiveDrugOrdersForPatientFilteredByEncounters() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + Encounter encounter1 = Context.getEncounterService().getEncounter(19); + Encounter encounter2 = Context.getEncounterService().getEncounter(20); + Concept concept = Context.getConceptService().getConcept(16); + HashSet concepts = new HashSet(); + concepts.add(concept); + + List activeOrders = orderDao.getActiveOrders(patient, orderType, null, new Date(), null, null, null, null, Arrays.asList(encounter1, encounter2)); + assertEquals(activeOrders.size(), 2); + assertEquals(activeOrders.get(0).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f836"); + assertEquals(activeOrders.get(1).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f841"); + + List activeOrdersOfConcept = orderDao.getActiveOrders(patient, orderType, null, new Date(), concepts, null, null, null, Arrays.asList(encounter1, encounter2)); + assertEquals(activeOrdersOfConcept.size(), 1); + assertEquals(activeOrdersOfConcept.get(0).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f836"); + + } + + @Test + public void getActiveDrugOrdersForPatientFilteredByDrugConcepts() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + Concept concept = Context.getConceptService().getConcept(16); + HashSet concepts = new HashSet(); + concepts.add(concept); + + List activeOrders = orderDao.getActiveOrders(patient, orderType, null, new Date(), concepts, null, null, null, null); + + assertEquals(activeOrders.size(), 1); + assertEquals(activeOrders.get(0).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f836"); + } + + @Test + public void getInactiveDrugOrdersForPatient() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + List activeOrders = orderDao.getInactiveOrders(patient, orderType, null, new Date(), null, null, null); + + assertEquals(3, activeOrders.size()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f837", activeOrders.get(0).getUuid()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f839", activeOrders.get(1).getUuid()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f987", activeOrders.get(2).getUuid()); + } + + @Test + public void getInactiveDrugOrdersForPatientFilteredByEncounters() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + Encounter encounter = Context.getEncounterService().getEncounter(19); + + List activeOrders = orderDao.getInactiveOrders(patient, orderType, null, new Date(), null, null, Arrays.asList(encounter)); + + assertEquals(activeOrders.size(), 1); + assertEquals(activeOrders.get(0).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f839"); + } + + @Test + public void getActiveDrugOrdersForPatientWithinDateRange() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + Date startDate = BahmniDateUtil.convertToDate("2014-01-01T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate("2014-09-09T00:00:00.000", BahmniDateUtil.DateFormatType.UTC); + + List activeOrders = orderDao.getActiveOrders(patient, orderType, null, new Date(), null, null, startDate, endDate, null); + + assertEquals(activeOrders.size(), 3); + assertEquals(activeOrders.get(0).getUuid(), "cba00378-0c03-11e4-bb80-f18addb6f836"); + } + + @Test + public void getInactiveDrugOrdersForPatientFilteredByDrugConcepts() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + Concept concept = Context.getConceptService().getConcept(16); + HashSet concepts = new HashSet(); + concepts.add(concept); + + List activeOrders = orderDao.getInactiveOrders(patient, orderType, null, new Date(), concepts, null, null); + + assertEquals(activeOrders.size(), 2); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f839", activeOrders.get(0).getUuid()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f987", activeOrders.get(1).getUuid()); + } + + @Test + public void getChildOrder() throws Exception { + executeDataSet("patientWithOrders.xml"); + Order order = Context.getOrderService().getOrderByUuid("cba00378-0c03-11e4-bb80-f18addb6f837"); + Order childOrder = Context.getOrderService().getOrderByUuid("cba00378-0c03-11e4-bb80-f18addb6f838"); + Order actual = orderDao.getChildOrder(order); + assertEquals(actual, childOrder); + } + + @Test + public void getOrdersByPatientProgram() throws Exception { + executeDataSet("patientWithOrders.xml"); + OrderType orderType = Context.getOrderService().getOrderType(1); + Concept concept = Context.getConceptService().getConcept(16); + HashSet concepts = new HashSet(); + concepts.add(concept); + + List activeOrders = orderDao.getOrdersByPatientProgram("dfdfoifo-dkcd-475d-b990-6d82327f36a3", orderType, null); + + assertEquals(2, activeOrders.size()); + assertEquals(activeOrders.get(0).getUuid(), "0246222e-f5f5-11e3-b47b-c8b69a44dcba"); + assertEquals(activeOrders.get(1).getUuid(), "0246222e-f5f5-11e3-b47b-c8b69a44badc"); + } + + @Test + public void getOrdersByPatientProgramWithConceptNames() throws Exception { + executeDataSet("patientWithOrders.xml"); + OrderType orderType = Context.getOrderService().getOrderType(1); + HashSet concepts = new HashSet(); + Concept paracetamolConcept = Context.getConceptService().getConcept(24); + concepts.add(paracetamolConcept); + Concept nonOrderedDrugConcept = Context.getConceptService().getConcept(26); + concepts.add(nonOrderedDrugConcept); + + List activeOrders = orderDao.getOrdersByPatientProgram("dfdfoifo-dkcd-475d-b990-6d82327f36a3", orderType, concepts); + + assertEquals(1, activeOrders.size()); + assertEquals(activeOrders.get(0).getUuid(), "0246222e-f5f5-11e3-b47b-c8b69a44dcba"); + } + + @Test + public void getOrdersByLocationsWhenLocationUuidsAreProvided() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + List locationUuids = new ArrayList<>(); + + locationUuids.add("8d6c993e-c2cc-11de-7921-0010c6affd0f"); + locationUuids.add("8d6c993e-c2cc-11de-7000-0010c6affd0f"); + + List activeOrders = orderDao.getAllOrders(patient, orderType, null, null, locationUuids); + + assertEquals(4, activeOrders.size()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f836", activeOrders.get(0).getUuid()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f839", activeOrders.get(1).getUuid()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f841", activeOrders.get(2).getUuid()); + assertEquals("cba00378-0c03-11e4-bb80-f18addb6f987", activeOrders.get(3).getUuid()); + } + + @Test + public void shouldReturnAllOrdersWhenLocationUuidsAreNotProvided() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + List locationUuids = new ArrayList<>(); + + List activeOrders = orderDao.getAllOrders(patient, orderType, null, null, locationUuids); + + assertEquals(3, activeOrders.size()); + } + + @Test + public void shouldReturnEmptyListOfOrdersWhenEncountersAreNotThereForGivenLocationUuids() throws Exception { + executeDataSet("patientWithOrders.xml"); + Patient patient = Context.getPatientService().getPatient(1001); + OrderType orderType = Context.getOrderService().getOrderType(1); + List locationUuids = new ArrayList<>(); + locationUuids.add("8d6c993e-c2cc-11de-8d13-0010c6dffd0f"); + + List activeOrders = orderDao.getAllOrders(patient, orderType, null, null, locationUuids); + + assertEquals(0, activeOrders.size()); + } + + private boolean visitWithUuidExists(String uuid, List visits) { + boolean exists = false; + for (Visit visit : visits) { + exists |= visit.getUuid().equals(uuid); + } + return exists; + } + + private List getOrderIds(List drugOrders) { + ArrayList ids = new ArrayList<>(); + for (DrugOrder drugOrder : drugOrders) { + ids.add(drugOrder.getOrderId()); + } + return ids; + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/PersonAttributeDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/PersonAttributeDaoImplIT.java new file mode 100644 index 0000000000..6cb138d58f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/PersonAttributeDaoImplIT.java @@ -0,0 +1,37 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +@Ignore +public class PersonAttributeDaoImplIT extends BaseIntegrationTest { + + @Autowired + private PersonAttributeDaoImpl personAttributeDao; + + @Test + @Ignore + public void shouldRetrieveUniqueCasteList() throws Exception { + assertEquals(0, personAttributeDao.getUnique("caste", "caste").size()); + + executeDataSet("apiTestData.xml"); + + ResultList result = personAttributeDao.getUnique("caste", "caste"); + assertEquals(2, result.size()); + } + + @Test + @Ignore + public void shouldRetrieveOnly20Results() throws Exception { + executeDataSet("apiTestData.xml"); + + ResultList result = personAttributeDao.getUnique("caste", "test"); + assertTrue(result.size() <= 20); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/PersonNameDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/PersonNameDaoImplIT.java new file mode 100644 index 0000000000..4ec515864a --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/PersonNameDaoImplIT.java @@ -0,0 +1,35 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +@Ignore +public class PersonNameDaoImplIT extends BaseIntegrationTest { + + @Autowired + PersonNameDaoImpl personNameDao; + + @Test + @Ignore + public void shouldRetrievePatientListIfLastNameExists() throws Exception { + executeDataSet("apiTestData.xml"); + String key = "familyName"; + assertEquals(2, personNameDao.getUnique(key, "singh").size()); + assertEquals(2, personNameDao.getUnique(key, "Singh").size()); + assertEquals(1, personNameDao.getUnique(key, "Banka").size()); + assertEquals(3, personNameDao.getUnique(key, "sin").size()); + } + + @Test + @Ignore + public void shouldReturnMaxOf20Results() throws Exception { + executeDataSet("apiTestData.xml"); + String key = "familyName"; + assertTrue(personNameDao.getUnique(key, "test").size() <= 20); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/VisitDaoImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/VisitDaoImplIT.java new file mode 100644 index 0000000000..16875df3dc --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/dao/impl/VisitDaoImplIT.java @@ -0,0 +1,49 @@ +package org.bahmni.module.bahmnicore.dao.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicommons.api.dao.PatientDao; +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class VisitDaoImplIT extends BaseIntegrationTest { + + @Autowired + VisitDao visitDao; + + @Autowired + PatientDao patientDao; + + @Before + public void setUp() throws Exception { + executeDataSet("visitTestData.xml"); + } + + @Test + public void shouldGetLatestObsForConceptSetByVisit() { + Visit latestVisit = visitDao.getLatestVisit("86526ed5-3c11-11de-a0ba-001e378eb67a", "Weight"); + assertEquals(901, latestVisit.getVisitId().intValue()); + } + + @Test + public void shouldGetVisitsByPatient(){ + Patient patient = patientDao.getPatient("GAN200000"); + List visits = visitDao.getVisitsByPatient(patient, 1); + assertEquals(1, visits.size()); + assertEquals(901, visits.get(0).getVisitId().intValue()); + } + + @Test + public void shouldNotGetVoidedEncounter() throws Exception { + List admitAndDischargeEncounters = visitDao.getAdmitAndDischargeEncounters(902); + assertEquals(1, admitAndDischargeEncounters.size()); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommandIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommandIT.java new file mode 100644 index 0000000000..519c56cb09 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommandIT.java @@ -0,0 +1,74 @@ +package org.bahmni.module.bahmnicore.encounterTransaction.command; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.PatientProgram; +import org.openmrs.api.EncounterService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertTrue; + +public class EpisodeEncounterCreateCommandIT extends BaseIntegrationTest { + + @Autowired + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + @Autowired + private EncounterService encounterService; + + @Autowired + private EpisodeService episodeService; + + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + + @Before + public void setUp() throws Exception { + bahmniProgramWorkflowService = Context.getService(BahmniProgramWorkflowService.class); + executeDataSet("visitAttributeDataSet.xml"); + } + + @Test + public void shouldAddEncounterToEpisodeWhenProgramUuidIsSpecified() { + String visitUuid = "4e663d66-6b78-11e0-93c3-18a905e044dc"; + String patientUuid = "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"; + String patientProgramUuid = "b75462a0-4c92-451e-b8bc-e98b38b76534"; //for patient 2 in standardDataset.xml + + EncounterTransaction.Provider provider = new EncounterTransaction.Provider(); + provider.setUuid(Context.getProviderService().getProvider(1).getUuid()); + Set providerSet = new HashSet<>(); + providerSet.add(provider); + + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setProviders(providerSet); + + bahmniEncounterTransaction.setEncounterTypeUuid("07000be2-26b6-4cce-8b40-866d8435b613"); + bahmniEncounterTransaction.setPatientUuid(patientUuid); + bahmniEncounterTransaction.setVisitUuid(visitUuid); + + bahmniEncounterTransaction.setPatientProgramUuid(patientProgramUuid); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + + + Encounter encounter = encounterService + .getEncounterByUuid(encounterTransaction.getEncounterUuid()); + + PatientProgram patientProgram = bahmniProgramWorkflowService.getPatientProgramByUuid(patientProgramUuid); + Episode episodeForPatientProgram = episodeService.getEpisodeForPatientProgram(patientProgram); + + assertTrue(episodeForPatientProgram.getEncounters().contains(encounter)); + assertTrue(episodeForPatientProgram.getPatientPrograms().contains(patientProgram)); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommandTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommandTest.java new file mode 100644 index 0000000000..08fe6f7050 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/encounterTransaction/command/EpisodeEncounterCreateCommandTest.java @@ -0,0 +1,103 @@ +package org.bahmni.module.bahmnicore.encounterTransaction.command; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.openmrs.Encounter; +import org.openmrs.PatientProgram; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class EpisodeEncounterCreateCommandTest { + + @Mock + private EpisodeService episodeService; + + @Mock + BahmniProgramWorkflowService programWorkflowService; + + @Before + public void setup() { + initMocks(this); + } + + @Test + public void shouldAddEncounterToEpisode() { + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + encounterTransaction.setPatientProgramUuid("foo"); + + PatientProgram testPatientProgram = testPatientProgram(); + when(programWorkflowService.getPatientProgramByUuid("foo")).thenReturn(testPatientProgram); + Episode testEpisode = testEpisode(testPatientProgram); + when(episodeService.getEpisodeForPatientProgram(testPatientProgram)).thenReturn(testEpisode); + + Encounter currentEncounter = new Encounter(); + new EpisodeEncounterCreateCommand(episodeService, programWorkflowService).save(encounterTransaction, currentEncounter, null); + + verify(programWorkflowService).getPatientProgramByUuid("foo"); + verify(episodeService).getEpisodeForPatientProgram(testPatientProgram); + verify(episodeService).save(testEpisode); + assertTrue(testEpisode.getEncounters().contains(currentEncounter)); + } + + @Test + public void shouldIgnoreIfEncounterHasNoPatientProgramAssociated() { + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + + PatientProgram testPatientProgram = testPatientProgram(); + when(programWorkflowService.getPatientProgramByUuid("foo")).thenReturn(testPatientProgram); + Episode testEpisode = testEpisode(testPatientProgram); + when(episodeService.getEpisodeForPatientProgram(testPatientProgram)).thenReturn(testEpisode); + + Encounter currentEncounter = new Encounter(); + new EpisodeEncounterCreateCommand(episodeService, programWorkflowService).save(encounterTransaction, currentEncounter, null); + + verify(programWorkflowService, times(0)).getPatientProgramByUuid("foo"); + verify(episodeService, times(0)).getEpisodeForPatientProgram(testPatientProgram); + verify(episodeService, times(0)).save(testEpisode); + } + + @Test + public void shouldCreateEpisodeAndAssociatePatientProgramIfItDoesntExist() { + BahmniEncounterTransaction encounterTransaction = new BahmniEncounterTransaction(); + encounterTransaction.setPatientProgramUuid("foo"); + + PatientProgram testPatientProgram = testPatientProgram(); + when(programWorkflowService.getPatientProgramByUuid("foo")).thenReturn(testPatientProgram); + + when(episodeService.getEpisodeForPatientProgram(testPatientProgram)).thenReturn(null); + + Encounter currentEncounter = new Encounter(); + new EpisodeEncounterCreateCommand(episodeService, programWorkflowService).save(encounterTransaction, currentEncounter, null); + + verify(programWorkflowService).getPatientProgramByUuid("foo"); + verify(episodeService).getEpisodeForPatientProgram(testPatientProgram); + ArgumentCaptor episodeArgumentCaptor = ArgumentCaptor.forClass(Episode.class); + verify(episodeService).save(episodeArgumentCaptor.capture()); + Episode episode = episodeArgumentCaptor.getValue(); + assertTrue(episode.getEncounters().contains(currentEncounter)); + assertTrue(episode.getPatientPrograms().contains(testPatientProgram)); + } + + + private Episode testEpisode(PatientProgram testPatientProgram) { + Episode episode = new Episode(); + episode.addPatientProgram(testPatientProgram); + return episode; + } + + private PatientProgram testPatientProgram() { + PatientProgram bahmniPatientProgram = new PatientProgram(); + bahmniPatientProgram.setUuid("bar"); + return bahmniPatientProgram; + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/extensions/MonthCalculationExtensionTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/extensions/MonthCalculationExtensionTest.java new file mode 100644 index 0000000000..cc69fa6df1 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/extensions/MonthCalculationExtensionTest.java @@ -0,0 +1,11 @@ +package org.bahmni.module.bahmnicore.extensions; + +import org.junit.Test; + +public class MonthCalculationExtensionTest { + + @Test + public void testName() throws Exception { + + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/contract/form/FormTypeTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/contract/form/FormTypeTest.java new file mode 100644 index 0000000000..62c5aa8d0f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/contract/form/FormTypeTest.java @@ -0,0 +1,34 @@ +package org.bahmni.module.bahmnicore.forms2.contract.form; + +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class FormTypeTest { + + @Test + public void shouldReturnAllObservationTemplateFormsTypeAsV1() { + assertEquals("FORMS1", FormType.FORMS1.toString()); + assertEquals(FormType.FORMS1, FormType.valueOfType("v1")); + } + + @Test + public void shouldReturnFormBuilderFormsTypeAsV2() { + assertEquals("FORMS2", FormType.FORMS2.toString()); + assertEquals(FormType.FORMS2, FormType.valueOfType("v2")); + + } + + @Test + public void shouldReturnFormTypeAsString() { + assertEquals("v1", FormType.FORMS1.getType()); + assertEquals("v2", FormType.FORMS2.getType()); + + } + + @Test(expected = IllegalArgumentException.class) + public void shouldErrorOutForInvalidTypeString() { + assertEquals(FormType.FORMS1, FormType.valueOfType("v0")); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/contract/form/data/FormDetailsTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/contract/form/data/FormDetailsTest.java new file mode 100644 index 0000000000..67ce3b3c38 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/contract/form/data/FormDetailsTest.java @@ -0,0 +1,64 @@ +package org.bahmni.module.bahmnicore.forms2.contract.form.data; + +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class FormDetailsTest { + + private String formName = "FormName"; + private int formVersion = 2; + private String encounterUuid = "encounter-uuid"; + + private FormDetails formDetails; + + @Before + public void setUp() { + formDetails = new FormDetails(); + formDetails.setFormName(formName); + formDetails.setFormVersion(formVersion); + formDetails.setEncounterUuid(encounterUuid); + } + + @Test + public void shouldReturnTrueWhenTwoFormDetailsAreSameByReference() { + + assertEquals(formDetails, formDetails); + } + + @Test + public void shouldReturnFalseWhenOneOfTheFormDetailsIsNull() { + + assertNotEquals(formDetails, null); + } + + @Test + public void shouldReturnFalseWhenTypeOfTheObjectDoesNotEqualToFormDetails() { + + assertNotEquals(formDetails, ""); + } + + @Test + public void shouldReturnFalseWhenFormNameDoesNotMatch() { + FormDetails otherFormDetails = new FormDetails(); + otherFormDetails.setFormName("some form name"); + otherFormDetails.setFormVersion(formVersion); + otherFormDetails.setEncounterUuid(encounterUuid); + + assertNotEquals(formDetails, otherFormDetails); + } + + @Test + public void shouldReturnTrueWhenFormNameFormVersionAndEncounterUuidMatches() { + + FormDetails otherFormDetails = new FormDetails(); + otherFormDetails.setFormName(formName); + otherFormDetails.setFormVersion(formVersion); + otherFormDetails.setEncounterUuid(encounterUuid); + + assertEquals(otherFormDetails, otherFormDetails); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/mapper/FormDetailsMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/mapper/FormDetailsMapperTest.java new file mode 100644 index 0000000000..f55e9bc34f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/mapper/FormDetailsMapperTest.java @@ -0,0 +1,226 @@ +package org.bahmni.module.bahmnicore.forms2.mapper; + +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.util.FormUtil; +import org.bahmni.module.bahmnicore.model.Provider; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.internal.verification.VerificationModeFactory; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.PersonName; +import org.openmrs.User; +import org.openmrs.Visit; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; + +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.verifyStatic; + +@PrepareForTest({FormUtil.class}) +@RunWith(PowerMockRunner.class) +public class FormDetailsMapperTest { + + private String formFieldPath = "formName.2/1-0"; + private String encounterUuid = "encounter-Uuid"; + private String visitUuid = "visitUuid"; + private String providerName = "Super Man"; + private String providerUuid = "provider-uuid"; + private String formName = "formName"; + private int formVersion = 2; + private Date encounterDateTime = new Date(); + private Date visitStartDateTime = new Date(); + + private Obs obs = mock(Obs.class); + private Encounter encounter = mock(Encounter.class); + private Visit visit = mock(Visit.class); + private User anotherCreator = mock(User.class); + private PersonName personName = mock(PersonName.class); + + @Before + public void setUp() { + + //mockStatic(FormUtil.class); + + when(obs.getEncounter()).thenReturn(encounter); + when(obs.getCreator()).thenReturn(anotherCreator); + when(obs.getFormFieldPath()).thenReturn(formFieldPath); + when(encounter.getVisit()).thenReturn(visit); +// when(FormUtil.getFormNameFromFieldPath(formFieldPath)).thenReturn(formName); +// when(FormUtil.getFormVersionFromFieldPath(formFieldPath)).thenReturn(formVersion); + + when(encounter.getUuid()).thenReturn(encounterUuid); + when(encounter.getEncounterDatetime()).thenReturn(encounterDateTime); + + when(visit.getUuid()).thenReturn(visitUuid); + when(visit.getStartDatetime()).thenReturn(visitStartDateTime); + + when(anotherCreator.getPersonName()).thenReturn(personName); + when(personName.getFullName()).thenReturn(providerName); + when(anotherCreator.getUuid()).thenReturn(providerUuid); + } + + @Test + public void shouldReturnFormDetailsFromGivenObsAndFormTypeOfFormBuilder() { + + Collection formDetailsCollection = FormDetailsMapper + .createFormDetails(singletonList(obs), FormType.FORMS2); + + assertEquals(1, formDetailsCollection.size()); + + FormDetails formDetails = formDetailsCollection.iterator().next(); + assertEquals("v2", formDetails.getFormType()); + assertEquals(formName, formDetails.getFormName()); + assertEquals(formVersion, formDetails.getFormVersion()); + + verifyCommonData(formDetails); + + verify(obs, times(2)).getFormFieldPath(); + //verifyStatic(VerificationModeFactory.times(1)); + assertEquals(formName, FormUtil.getFormNameFromFieldPath(formFieldPath)); + //verifyStatic(VerificationModeFactory.times(1)); + assertEquals(formVersion, FormUtil.getFormVersionFromFieldPath(formFieldPath)); + verifyCommonMockCalls(); + + } + + @Test + public void shouldReturnFormDetailsFromGivenObsAndFormTypeOfAllObservationTemplates() { + Concept concept = mock(Concept.class); + when(obs.getConcept()).thenReturn(concept); + ConceptName conceptName = mock(ConceptName.class); + when(concept.getName()).thenReturn(conceptName); + String obsName = "some obs name"; + when(conceptName.getName()).thenReturn(obsName); + + Collection formDetailsCollection = FormDetailsMapper + .createFormDetails(singletonList(obs), FormType.FORMS1); + + assertEquals(1, formDetailsCollection.size()); + + FormDetails formDetails = formDetailsCollection.iterator().next(); + + assertEquals("v1", formDetails.getFormType()); + assertEquals(formDetails.getFormName(), obsName); + assertEquals(0, formDetails.getFormVersion()); + verifyCommonData(formDetails); + verifyCommonMockCalls(); + + } + + @Test + public void shouldReturnFormDetailsWithTwoProvidersFromGivenTwoObsAndFormTypeOfFormBuilder() { + + String anotherObsFormFieldPath = "formName.2/2-0"; + String anotherProviderName = "Another Super Man"; + String anotherProviderUuid = "Another provider-uuid"; + + Obs anotherObs = mock(Obs.class); + User anotherCreator = mock(User.class); + PersonName anotherPersonName = mock(PersonName.class); + + when(anotherObs.getEncounter()).thenReturn(encounter); + when(anotherObs.getCreator()).thenReturn(anotherCreator); + when(anotherObs.getFormFieldPath()).thenReturn(anotherObsFormFieldPath); +// when(FormUtil.getFormNameFromFieldPath(anotherObsFormFieldPath)).thenReturn(formName); +// when(FormUtil.getFormVersionFromFieldPath(anotherObsFormFieldPath)).thenReturn(formVersion); + + when(anotherCreator.getPersonName()).thenReturn(anotherPersonName); + when(anotherPersonName.getFullName()).thenReturn(anotherProviderName); + when(anotherCreator.getUuid()).thenReturn(anotherProviderUuid); + +// FormType formType = mock(FormType.class); +// Whitebox.setInternalState(FormType.class, "FORMS2", formType); +// when(formType.toString()).thenReturn("v2"); + FormType formType = FormType.FORMS2; + + FormDetails formDetails = mock(FormDetails.class); + when(formDetails.getFormName()).thenReturn(formName); + when(formDetails.getFormVersion()).thenReturn(2); + when(formDetails.getEncounterUuid()).thenReturn(encounterUuid); + Provider provider = mock(Provider.class); + when(provider.getProviderName()).thenReturn(providerName); + when(provider.getUuid()).thenReturn(providerUuid); + when(formDetails.getProviders()).thenReturn(new HashSet<>(singletonList(provider))); + + FormDetails anotherFormDetails = mock(FormDetails.class); + when(anotherFormDetails.getFormName()).thenReturn(formName); + when(anotherFormDetails.getFormVersion()).thenReturn(2); + when(anotherFormDetails.getEncounterUuid()).thenReturn(encounterUuid); + Provider anotherProvider = mock(Provider.class); + when(anotherProvider.getProviderName()).thenReturn(anotherProviderName); + when(anotherProvider.getUuid()).thenReturn(anotherProviderUuid); + when(anotherFormDetails.getProviders()).thenReturn(new HashSet<>(singletonList(anotherProvider))); + + + Collection formDetailsCollection = FormDetailsMapper + .createFormDetails(Arrays.asList(obs, anotherObs), formType); + + assertEquals(1, formDetailsCollection.size()); + + FormDetails actualFormDetails = formDetailsCollection.iterator().next(); + assertEquals("v2", actualFormDetails.getFormType()); + assertEquals(formName, actualFormDetails.getFormName()); + assertEquals(formVersion, actualFormDetails.getFormVersion()); + + verifyVisitAndEncounterData(actualFormDetails); + + verify(obs, times(2)).getFormFieldPath(); + verify(anotherObs, times(2)).getFormFieldPath(); + //verifyStatic(VerificationModeFactory.times(1)); + FormUtil.getFormNameFromFieldPath(formFieldPath); + //verifyStatic(VerificationModeFactory.times(1)); + FormUtil.getFormNameFromFieldPath(anotherObsFormFieldPath); + //verifyStatic(VerificationModeFactory.times(1)); + FormUtil.getFormVersionFromFieldPath(formFieldPath); + //verifyStatic(VerificationModeFactory.times(1)); + FormUtil.getFormVersionFromFieldPath(anotherObsFormFieldPath); + //verify(formType, times(2)).toString(); + } + + private void verifyCommonData(FormDetails formDetails) { + + verifyVisitAndEncounterData(formDetails); + + assertEquals(1, formDetails.getProviders().size()); + Provider provider = formDetails.getProviders().iterator().next(); + assertEquals(providerName, provider.getProviderName()); + assertEquals(providerUuid, provider.getUuid()); + } + + private void verifyVisitAndEncounterData(FormDetails formDetails) { + assertEquals(visitStartDateTime, formDetails.getVisitStartDateTime()); + assertEquals(visitUuid, formDetails.getVisitUuid()); + assertEquals(encounterDateTime, formDetails.getEncounterDateTime()); + assertEquals(encounterUuid, formDetails.getEncounterUuid()); + } + + private void verifyCommonMockCalls() { + verify(obs, times(1)).getEncounter(); + verify(obs, times(1)).getCreator(); + verify(encounter, times(1)).getVisit(); + verify(encounter, times(1)).getUuid(); + verify(encounter, times(1)).getEncounterDatetime(); + verify(visit, times(1)).getUuid(); + verify(visit, times(1)).getStartDatetime(); + verify(anotherCreator, times(1)).getPersonName(); + verify(anotherCreator, times(1)).getUuid(); + verify(personName, times(1)).getFullName(); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java new file mode 100644 index 0000000000..84d96f4bc6 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/service/impl/BahmniFormDetailsServiceImplTest.java @@ -0,0 +1,339 @@ +package org.bahmni.module.bahmnicore.forms2.service.impl; + +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.mapper.FormDetailsMapper; +import org.bahmni.module.bahmnicore.forms2.util.FormUtil; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.service.BahmniVisitService; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.internal.verification.VerificationModeFactory; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ObsService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.parameter.EncounterSearchCriteria; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.security.InvalidParameterException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static java.util.Collections.singletonList; +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.verifyStatic; + +@PrepareForTest({FormType.class, FormUtil.class, FormDetailsMapper.class}) +@RunWith(PowerMockRunner.class) +public class BahmniFormDetailsServiceImplTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private BahmniVisitService bahmniVisitService = mock(BahmniVisitService.class); + private FormDetails formDetails = mock(FormDetails.class); + private FormDetails anotherFormDetails = mock(FormDetails.class); + private VisitService visitService = mock(VisitService.class); + private BahmniProgramWorkflowService bahmniProgramWorkflowService = mock(BahmniProgramWorkflowService.class); + private PatientService patientService = mock(PatientService.class); + private EncounterService encounterService = mock(EncounterService.class); + private ObsService obsService = mock(ObsService.class); + private Patient patient = mock(Patient.class); + private Person person = mock(Person.class); + private Visit visit = mock(Visit.class); + private Encounter encounter = mock(Encounter.class); + private Obs height = mock(Obs.class); + private Obs weight = mock(Obs.class); + private List obs = Arrays.asList(height, weight); + private BahmniFormDetailsServiceImpl bahmniFormDetailsService; + private String patientUuid = "patient-uuid"; + private String patientProgramUuid = "patient-program-uuid"; + private String visitUuid = "visit-uuid"; + + @Before + public void setUp() { + bahmniFormDetailsService = new BahmniFormDetailsServiceImpl(patientService, visitService, + encounterService, obsService, bahmniVisitService, bahmniProgramWorkflowService); + + when(patientService.getPatientByUuid(patientUuid)).thenReturn(patient); + when(visitService.getVisitsByPatient(patient)).thenReturn(singletonList(visit)); + List encounters = singletonList(encounter); + when(encounterService.getEncounters(any(EncounterSearchCriteria.class))).thenReturn(encounters); + when(patient.getPerson()).thenReturn(person); + when(obsService.getObservations(anyListOf(Person.class), anyListOf(Encounter.class), eq(null), eq(null), eq(null), eq(null), + eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(obs); + } + + @Test + public void shouldReturnInvalidParameterExceptionIfPatientDoesNotFound() { + + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(null); + expectedException.expect(InvalidParameterException.class); + expectedException.expectMessage("Patient does not exist"); + + Collection formDetailsCollection = bahmniFormDetailsService.getFormDetails("patient uuid", FormType.FORMS1, -1); + + assertEquals(0, formDetailsCollection.size()); + + } + + @Test + public void shouldReturnFormDetailsForGivenPatientUuidAndFormTypeIsV2() { + mockFilterFormBuilderObs(); + mockStatic(FormDetailsMapper.class); + List expectedFormDetails = Arrays.asList(formDetails, anotherFormDetails); + when(FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class))) + .thenReturn(expectedFormDetails); + Collection formBuilderFormDetails = bahmniFormDetailsService.getFormDetails("patient-uuid", FormType.FORMS2, -1); + + assertEquals(2, formBuilderFormDetails.size()); + containsInAnyOrder(expectedFormDetails, formBuilderFormDetails.toArray()); + + verifyCommonMockCalls(); + verifyFilterFormBuilderObsMockCall(1); + verifyCreateFormDetailsMockCall(1); + } + + @Test + public void shouldReturnFormDetailsOfTypeV2ForGivenPatientUuidAndNoFormTypeIsProvided() { + mockFilterFormBuilderObs(); + + mockStatic(FormDetailsMapper.class); + List expectedFormDetails = Arrays.asList(formDetails, anotherFormDetails); + when(FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class))) + .thenReturn(expectedFormDetails); + Collection formBuilderFormDetails = bahmniFormDetailsService.getFormDetails("patient-uuid", null, -1); + + assertEquals(2, formBuilderFormDetails.size()); + containsInAnyOrder(expectedFormDetails, formBuilderFormDetails.toArray()); + + verifyCommonMockCalls(); + verifyFilterFormBuilderObsMockCall(1); + verifyCreateFormDetailsMockCall(1); + } + + @Test + public void shouldReturnEmptyCollectionOfFormDetailsIfFormTypeIsAvailableButNotV2() { + Collection formBuilderFormDetails = bahmniFormDetailsService.getFormDetails("patient-uuid", FormType.FORMS1, -1); + + assertEquals(0, formBuilderFormDetails.size()); + } + + @Test + public void shouldReturnFormDetailsGivenPatientUuidFormTypeAsV2AndNumberOfVisitsAreOne() { + Visit anotherVisit = mock(Visit.class); + when(visitService.getVisitsByPatient(patient)).thenReturn(Arrays.asList(anotherVisit, visit)); + + mockFilterFormBuilderObs(); + + mockStatic(FormDetailsMapper.class); + when(FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class))) + .thenReturn(singletonList(formDetails)); + Collection formBuilderFormDetails = bahmniFormDetailsService.getFormDetails("patient-uuid", FormType.FORMS2, 1); + + assertEquals(1, formBuilderFormDetails.size()); + assertEquals(formDetails, formBuilderFormDetails.iterator().next()); + + verifyCommonMockCalls(); + + verifyFilterFormBuilderObsMockCall(1); + + verifyCreateFormDetailsMockCall(1); + + } + + @Test + public void shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveVisits() { + when(visitService.getVisitsByPatient(patient)).thenReturn(Collections.emptyList()); + Collection formDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, -1); + + assertEquals(0, formDetailsCollection.size()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(visitService, times(1)).getVisitsByPatient(patient); + verify(encounterService, times(0)).getEncounters(any(EncounterSearchCriteria.class)); + + verify(patient, times(0)).getPerson(); + verify(obsService, times(0)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); + + } + + @Test + public void shouldReturnEmptyCollectionsOfFormDetailsIfPatientDoesNotHaveEncounters() { + when(encounterService.getEncounters(any(EncounterSearchCriteria.class))).thenReturn(Collections.emptyList()); + Collection formDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, -1); + + assertEquals(0, formDetailsCollection.size()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(visitService, times(1)).getVisitsByPatient(patient); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + + verify(patient, times(0)).getPerson(); + verify(obsService, times(0)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); + } + + @Test + public void shouldReturnFormDetailsGivenPatientUuidFormTypeAsV2AndVisitUuid() { + when(bahmniVisitService.getVisitSummary(visitUuid)).thenReturn(visit); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(any(String.class))) + .thenReturn(Collections.emptyList()); + + mockFilterFormBuilderObs(); + + mockStatic(FormDetailsMapper.class); + when(FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class))) + .thenReturn(singletonList(formDetails)); + + Collection actualFormDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, visitUuid, null); + + assertEquals(1, actualFormDetailsCollection.size()); + assertEquals(formDetails, actualFormDetailsCollection.iterator().next()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + verify(patient, times(1)).getPerson(); + verify(obsService, times(1)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); + verify(bahmniVisitService, times(1)).getVisitSummary(visitUuid); + verify(bahmniProgramWorkflowService, times(1)).getEncountersByPatientProgramUuid(null); + + verifyFilterFormBuilderObsMockCall(1); + + verifyCreateFormDetailsMockCall(1); + } + + @Test + public void shouldReturnFormDetailsGivenPatientUuidFormTypeAsV2AndPatientProgramUuid() { + when(bahmniVisitService.getVisitSummary(null)).thenReturn(null); + when(encounterService.getEncounters(any(EncounterSearchCriteria.class))).thenReturn(null); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)) + .thenReturn(singletonList(encounter)); + + mockFilterFormBuilderObs(); + + mockStatic(FormDetailsMapper.class); + when(FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class))) + .thenReturn(singletonList(formDetails)); + + Collection actualFormDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, null, patientProgramUuid); + + assertEquals(1, actualFormDetailsCollection.size()); + assertEquals(formDetails, actualFormDetailsCollection.iterator().next()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + verify(patient, times(1)).getPerson(); + verify(obsService, times(1)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); + verify(bahmniVisitService, times(1)).getVisitSummary(null); + verify(bahmniProgramWorkflowService, times(1)).getEncountersByPatientProgramUuid(patientProgramUuid); + + verifyFilterFormBuilderObsMockCall(1); + + verifyCreateFormDetailsMockCall(1); + } + + @Test + public void shouldReturnFormDetailsGivenPatientUuidFormTypeAsV2VisitUuidAndPatientProgramUuid() { + when(bahmniVisitService.getVisitSummary(visitUuid)).thenReturn(visit); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)) + .thenReturn(singletonList(encounter)); + when(encounter.getVisit()).thenReturn(visit); + + mockFilterFormBuilderObs(); + + mockStatic(FormDetailsMapper.class); + when(FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class))) + .thenReturn(singletonList(formDetails)); + + Collection actualFormDetailsCollection = bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, visitUuid, patientProgramUuid); + + assertEquals(1, actualFormDetailsCollection.size()); + assertEquals(formDetails, actualFormDetailsCollection.iterator().next()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + verify(patient, times(1)).getPerson(); + verify(obsService, times(1)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); + verify(bahmniVisitService, times(1)).getVisitSummary(visitUuid); + verify(bahmniProgramWorkflowService, times(1)).getEncountersByPatientProgramUuid(patientProgramUuid); + + verifyFilterFormBuilderObsMockCall(1); + + verifyCreateFormDetailsMockCall(1); + } + + @Test + public void shouldReturnEmptyCollectionOfFormDetailsGivenPatientUuidFormTypeAsV2InvalidVisitUuidAndInvalidPatientProgramUuid() { + when(bahmniVisitService.getVisitSummary(visitUuid)).thenReturn(null); + when(encounterService.getEncounters(any(EncounterSearchCriteria.class))).thenReturn(null); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)) + .thenReturn(null); + + Collection actualFormDetailsCollection = bahmniFormDetailsService + .getFormDetails(patientUuid, FormType.FORMS2, visitUuid, patientProgramUuid); + + assertEquals(0, actualFormDetailsCollection.size()); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + verify(bahmniVisitService, times(1)).getVisitSummary(visitUuid); + verify(bahmniProgramWorkflowService, times(1)).getEncountersByPatientProgramUuid(patientProgramUuid); + } + + public void verifyCreateFormDetailsMockCall(int wantedNumberOfInvocations) { + verifyStatic(FormDetailsMapper.class, VerificationModeFactory.times(wantedNumberOfInvocations)); + FormDetailsMapper.createFormDetails(anyListOf(Obs.class), any(FormType.class)); + } + + private void verifyFilterFormBuilderObsMockCall(int wantedNumberOfInvocations) { + verifyStatic(FormUtil.class, VerificationModeFactory.times(wantedNumberOfInvocations)); + FormUtil.filterFormBuilderObs(obs); + } + + private void mockFilterFormBuilderObs() { + mockStatic(FormUtil.class); + when(FormUtil.filterFormBuilderObs(obs)).thenReturn(obs); + } + + private void verifyCommonMockCalls() { + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(visitService, times(1)).getVisitsByPatient(patient); + verify(encounterService, times(1)).getEncounters(any(EncounterSearchCriteria.class)); + verify(patient, times(1)).getPerson(); + verify(obsService, times(1)).getObservations(anyListOf(Person.class), + anyListOf(Encounter.class), any(), any(), any(), any(), any(), any(), any(), any(), any(), + any(Boolean.class)); + } + +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/util/FormUtilTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/util/FormUtilTest.java new file mode 100644 index 0000000000..f45ebcaeff --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/forms2/util/FormUtilTest.java @@ -0,0 +1,129 @@ +package org.bahmni.module.bahmnicore.forms2.util; + +import org.junit.Test; +import org.openmrs.Obs; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FormUtilTest { + + @Test + public void shouldReturnFormNameFromGivenFormFieldPath() { + assertEquals("FormName", FormUtil.getFormNameFromFieldPath("FormName.1/1-0")); + } + + @Test + public void shouldReturnEmptyStringAsFormNameIfGivenFormFieldPathDoesNotHaveFormName() { + assertEquals("", FormUtil.getFormNameFromFieldPath(".1/1-0")); + } + + @Test + public void shouldReturnEmptyStringAsFormNameIfGivenFormFieldPathIsNull() { + assertEquals("", FormUtil.getFormNameFromFieldPath(null)); + } + + @Test + public void shouldReturnEmptyStringAsFormNameIfGivenFormFieldPathIsEmpty() { + assertEquals("", FormUtil.getFormNameFromFieldPath("")); + } + + @Test + public void shouldReturnEmptyStringAsFormNameIfGivenFormFieldPathDoesNotHaveDot() { + assertEquals("", FormUtil.getFormNameFromFieldPath("FormName1/1-0")); + } + + @Test + public void shouldReturnFormVersionFromGivenFormFieldPath() { + assertEquals(2, FormUtil.getFormVersionFromFieldPath("FormName.2/1-0")); + } + + @Test + public void shouldReturnFormVersionAsZeroIfGivenFormFieldPathDoesNotHaveVersion() { + assertEquals(0, FormUtil.getFormVersionFromFieldPath("FormName./1-0")); + } + + @Test + public void shouldReturnFormVersionAsZeroIfGivenFormFieldPathIsNull() { + assertEquals(0, FormUtil.getFormVersionFromFieldPath(null)); + } + + @Test + public void shouldReturnFormVersionAsZeroIfGivenFormFieldPathIsEmpty() { + assertEquals(0, FormUtil.getFormVersionFromFieldPath("")); + } + + @Test + public void shouldReturnFormVersionAsZeroIfGivenFormFieldPathDoesNotHaveDot() { + assertEquals(0, FormUtil.getFormVersionFromFieldPath("FormName2/1-0")); + } + + @Test + public void shouldReturnFormVersionAsZeroIfGivenFormFieldPathDoesNotHaveSlash() { + assertEquals(0, FormUtil.getFormVersionFromFieldPath("FormName.21-0")); + } + + @Test + public void shouldReturnEmptyObsWhenPassedInObsListIsNull() { + List obs = FormUtil.filterFormBuilderObs(null); + assertEquals(0, obs.size()); + } + + @Test + public void shouldReturnEmptyObsWhenPassedInObsListIsEmpty() { + List obs = FormUtil.filterFormBuilderObs(new ArrayList<>()); + assertEquals(0, obs.size()); + } + + @Test + public void shouldReturnEmptyObsWhenPassedInObsDontHaveFormFieldPath() { + Obs observation = mock(Obs.class); + List obs = FormUtil.filterFormBuilderObs(singletonList(observation)); + assertEquals(0, obs.size()); + } + + @Test + public void shouldReturnObsWhichHaveFormFieldPath() { + Obs observation = mock(Obs.class); + Obs anotherObservation = mock(Obs.class); + when(observation.getFormFieldPath()).thenReturn("FormName.1/1-0"); + + List obs = FormUtil.filterFormBuilderObs(asList(observation, anotherObservation)); + assertEquals(1, obs.size()); + assertEquals(observation, obs.get(0)); + } + + @Test + public void shouldReturnParentFormFieldPathForGivenFormFieldPath() { + String expectedFormNameWithVersion = "FormName.1"; + String actualFormNameWithVersion = FormUtil.getParentFormFieldPath("FormName.1/1-0"); + assertEquals(expectedFormNameWithVersion, actualFormNameWithVersion); + } + + @Test + public void shouldReturnParentFormFieldPathForGivenThreeLevelFormFieldPath() { + String expectedFormNameWithVersion = "FormName.1/1-0/2-0"; + String actualFormNameWithVersion = FormUtil.getParentFormFieldPath("FormName.1/1-0/2-0/3-0"); + assertEquals(expectedFormNameWithVersion, actualFormNameWithVersion); + } + + @Test + public void shouldReturnFormNameAlongWithVersionIfGivenFormFieldPathDoesNotHaveSlash() { + String expectedFormNameWithVersion = ""; + String actualFormNameWithVersion = FormUtil.getParentFormFieldPath("FormName.1"); + assertEquals(expectedFormNameWithVersion, actualFormNameWithVersion); + } + + @Test + public void shouldReturnEmptyStringWhenFormFieldPathIsNull() { + String expectedFormNameWithVersion = ""; + String actualFormNameWithVersion = FormUtil.getParentFormFieldPath(null); + assertEquals(expectedFormNameWithVersion, actualFormNameWithVersion); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/AddressMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/AddressMapperTest.java new file mode 100644 index 0000000000..9b44201409 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/AddressMapperTest.java @@ -0,0 +1,109 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniAddress; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.util.AddressMother; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.PersonAddress; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +public class AddressMapperTest { + + @Test + public void shouldAddASingleAddressIfNonePresent() { + Patient patient = new Patient(); + SimpleObject simpleObjectForAddress = new AddressMother().getSimpleObjectForAddress(); + AddressMapper addressMapper = new AddressMapper(); + + BahmniAddress bahmniAddress = new BahmniAddress(simpleObjectForAddress); + addressMapper.map(patient, Arrays.asList(bahmniAddress)); + + Set addresses = patient.getAddresses(); + assertEquals(addresses.size(), 1); + PersonAddress personAddress = addresses.iterator().next(); + assertAllFieldsAreMapped("Added address should map to passed in Bahmni address", bahmniAddress, personAddress); + } + + @Test + public void shouldUpdateExistingAddressIfANonVoidedAddressPresent() { + Patient patient = new Patient(); + PersonAddress address = createPersonAddress("old", 1); + patient.addAddress(address); + + + SimpleObject simpleObjectForAddress = new AddressMother().getSimpleObjectForAddress(); + AddressMapper addressMapper = new AddressMapper(); + + + BahmniAddress bahmniAddress = new BahmniAddress(simpleObjectForAddress); + addressMapper.map(patient, Arrays.asList(bahmniAddress)); + + Set addresses = patient.getAddresses(); + assertEquals(addresses.size(), 1); + assertAllFieldsAreMapped("Existing address should map to passed in Bahmni address", bahmniAddress, address); + } + + @Test + public void shouldUpdateExistingNonVoidedAddressOnly() { + Patient patient = new Patient(); + PersonAddress nonVoidedAddress = createPersonAddress("nonVoided", 1); + PersonAddress voidedAddress = createPersonAddress("voided", 2); + voidedAddress.setVoided(true); + patient.addAddress(nonVoidedAddress); + patient.addAddress(voidedAddress); + + SimpleObject simpleObjectForAddress = new AddressMother().getSimpleObjectForAddress(); + AddressMapper addressMapper = new AddressMapper(); + + + BahmniAddress bahmniAddress = new BahmniAddress(simpleObjectForAddress); + addressMapper.map(patient, Arrays.asList(bahmniAddress)); + + Set addresses = patient.getAddresses(); + assertEquals("Size of address should not change", addresses.size(), 2); + assertAllFieldsAreMapped("Existing nonVoided address should map to passed in Bahmni address", bahmniAddress, nonVoidedAddress); + assertTrue("Details of voided address should not change", voidedAddress.equalsContent(createPersonAddress("voided", 2))); + } + + @Test + public void shouldMapPatientToBahmniPatient() { + Patient patient = new Patient(); + PersonAddress address = createPersonAddress("foo", 123); + patient.setAddresses(new HashSet(Arrays.asList(address))); + + BahmniPatient bahmniPatient = new AddressMapper().mapFromPatient(null, patient); + + PersonAddress personAddress = patient.getPersonAddress(); + BahmniAddress bahmniAddress = bahmniPatient.getAddresses().get(0); + assertAllFieldsAreMapped("Address should be mapped from Patient", bahmniAddress, personAddress); + } + + private PersonAddress createPersonAddress(String randomPrefix, Integer id) { + PersonAddress address = new PersonAddress(); + address.setAddress1(randomPrefix + "address1"); + address.setAddress2(randomPrefix + "address2"); + address.setAddress3(randomPrefix + "address3"); + address.setCityVillage(randomPrefix + "cityVillage"); + address.setCountyDistrict(randomPrefix + "countyDistrict"); + address.setStateProvince(randomPrefix + "stateProvince"); + address.setId(id); + return address; + } + + private void assertAllFieldsAreMapped(String message, BahmniAddress bahmniAddress, PersonAddress personAddress) { + assertEquals(message + "address1", bahmniAddress.getAddress1(), personAddress.getAddress1()); + assertEquals(bahmniAddress.getAddress2(), personAddress.getAddress2()); + assertEquals(bahmniAddress.getAddress3(), personAddress.getAddress3()); + assertEquals(bahmniAddress.getCityVillage(), personAddress.getCityVillage()); + assertEquals(bahmniAddress.getCountyDistrict(), personAddress.getCountyDistrict()); + assertEquals(bahmniAddress.getStateProvince(), personAddress.getStateProvince()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/BirthDateMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/BirthDateMapperTest.java new file mode 100644 index 0000000000..09806a861a --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/BirthDateMapperTest.java @@ -0,0 +1,25 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.Age; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.junit.Test; +import org.openmrs.Patient; + +import java.util.Date; + +import static junit.framework.Assert.assertEquals; + +public class BirthDateMapperTest { + + @Test + public void shouldMapFromPatientToBahmniPatient() { + Patient patient = new Patient(); + patient.setBirthdate(new Date()); + + BirthDateMapper mapper = new BirthDateMapper(); + BahmniPatient bahmniPatient = mapper.mapFromPatient(null, patient); + + assertEquals(patient.getBirthdate(),bahmniPatient.getBirthdate()); + assertEquals(new Age(0,0,0), bahmniPatient.getAge()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/ObservationTemplateMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/ObservationTemplateMapperTest.java new file mode 100644 index 0000000000..fb226631ad --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/ObservationTemplateMapperTest.java @@ -0,0 +1,90 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.contract.diseasetemplate.ObservationTemplate; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.test.TestUtil; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +public class ObservationTemplateMapperTest { + + private ObservationTemplateMapper observationTemplateMapper; + private BahmniObservation bahmniObservation1; + private BahmniObservation bahmniObservation2; + private BahmniObservation bahmniObservation3; + private BahmniObservation bahmniObservation4; + private BahmniObservation bahmniObservation5; + private Concept observationTemplateConcept; + @Mock + private ConceptMapper conceptMapper; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + bahmniObservation1 = new BahmniObservation(); + bahmniObservation2 = new BahmniObservation(); + bahmniObservation3 = new BahmniObservation(); + bahmniObservation4 = new BahmniObservation(); + bahmniObservation5 = new BahmniObservation(); + observationTemplateConcept = new ConceptBuilder().withUUID("otUUID").build(); + EncounterTransaction.Concept conceptData = new EncounterTransaction.Concept(); + conceptData.setName("Observation Template"); + conceptData.setConceptClass("otClass"); + conceptData.setDataType("N/A"); + conceptData.setUuid("otUUID"); + when(conceptMapper.map(observationTemplateConcept)).thenReturn(conceptData); + observationTemplateMapper = new ObservationTemplateMapper(conceptMapper); + } + + @Test + public void mapObsToObservationTemplatesGroupByVisitDate() throws Exception { + bahmniObservation1.setVisitStartDateTime(TestUtil.createDateTime("2012-01-01")); + bahmniObservation2.setVisitStartDateTime(TestUtil.createDateTime("2012-01-01")); + bahmniObservation3.setVisitStartDateTime(TestUtil.createDateTime("2012-03-01")); + bahmniObservation4.setVisitStartDateTime(TestUtil.createDateTime("2012-03-01")); + bahmniObservation5.setVisitStartDateTime(TestUtil.createDateTime("2012-05-01")); + List bahmniObservations = new ArrayList<>(); + bahmniObservations.add(bahmniObservation1); + bahmniObservations.add(bahmniObservation2); + bahmniObservations.add(bahmniObservation3); + bahmniObservations.add(bahmniObservation4); + bahmniObservations.add(bahmniObservation5); + List observationTemplates = observationTemplateMapper.map(bahmniObservations, observationTemplateConcept); + assertEquals(3, observationTemplates.size()); + ObservationTemplate observationTemplate1 = observationTemplates.get(0); + ObservationTemplate observationTemplate2 = observationTemplates.get(1); + ObservationTemplate observationTemplate3 = observationTemplates.get(2); + assertEquals("Observation Template", observationTemplate1.getConcept().getName()); + assertEquals(2, observationTemplate1.getBahmniObservations().size()); + assertEquals(TestUtil.createDateTime("2012-01-01"), observationTemplate1.getVisitStartDate()); + Iterator observationTemplate1Iterator = observationTemplate1.getBahmniObservations().iterator(); + assertEquals(observationTemplate1.getVisitStartDate(), observationTemplate1Iterator.next().getVisitStartDateTime()); + assertEquals(observationTemplate1.getVisitStartDate(), observationTemplate1Iterator.next().getVisitStartDateTime()); + assertEquals(TestUtil.createDateTime("2012-03-01"), observationTemplate2.getVisitStartDate()); + Iterator observationTemplate2Iterator = observationTemplate2.getBahmniObservations().iterator(); + assertEquals(observationTemplate2.getVisitStartDate(), observationTemplate2Iterator.next().getVisitStartDateTime()); + assertEquals(observationTemplate2.getVisitStartDate(), observationTemplate2Iterator.next().getVisitStartDateTime()); + assertEquals(TestUtil.createDateTime("2012-05-01"), observationTemplate3.getVisitStartDate()); + Iterator observationTemplate3Iterator = observationTemplate3.getBahmniObservations().iterator(); + assertEquals(observationTemplate3.getVisitStartDate(), observationTemplate3Iterator.next().getVisitStartDateTime()); + assertEquals("Observation Template", observationTemplate1.getConcept().getName()); + assertEquals("Observation Template", observationTemplate2.getConcept().getName()); + assertEquals("Observation Template", observationTemplate3.getConcept().getName()); + assertEquals(2, observationTemplate2.getBahmniObservations().size()); + assertEquals(1, observationTemplate3.getBahmniObservations().size()); + } + +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PatientIdentifierMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PatientIdentifierMapperTest.java new file mode 100644 index 0000000000..09e0c2d3e4 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PatientIdentifierMapperTest.java @@ -0,0 +1,44 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PatientService; + +import java.util.Arrays; +import java.util.HashSet; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +public class PatientIdentifierMapperTest { + + @Mock + private PatientService patientService; + + @Mock + private AdministrationService administrationService; + + @Before + public void setUp() throws Exception { + initMocks(this); + } + + @Test + public void shouldMapIdentifierFromPatientToBahmniPatient() { + PatientIdentifier identifier = new PatientIdentifier("GAN001", new PatientIdentifierType(), new Location()); + Patient patient = new Patient(); + patient.setIdentifiers(new HashSet<>(Arrays.asList(identifier))); + + BahmniPatient bahmniPatient = new PatientIdentifierMapper(patientService, administrationService).mapFromPatient(null, patient); + + assertEquals(patient.getPatientIdentifier().getIdentifier(), bahmniPatient.getIdentifier()); + + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PatientMapperIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PatientMapperIT.java new file mode 100644 index 0000000000..c3b8fc582e --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PatientMapperIT.java @@ -0,0 +1,60 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniName; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.util.PatientMother; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static junit.framework.Assert.assertEquals; + +@Ignore +public class PatientMapperIT extends BaseModuleWebContextSensitiveTest { + + @Autowired + private PatientMapper patientMapper; + + @Test + @Ignore + public void shouldMapPersonNameToPatient() throws ParseException { + BahmniPatient bahmniPatient = new PatientMother().buildBahmniPatient(); + + Patient patient = patientMapper.map(new Patient(), bahmniPatient); + + BahmniName name = bahmniPatient.getNames().get(0); + assertEquals(name.getGivenName(), patient.getGivenName()); + assertEquals(name.getFamilyName(), patient.getFamilyName()); + } + + @Test + @Ignore + public void shouldMapDateCreatedForNewPatient() throws ParseException { + Date dateCreated = new SimpleDateFormat("dd-MM-yyyy").parse("11-03-2013"); + + BahmniPatient bahmniPatient = new PatientMother().withDateCreated(dateCreated).buildBahmniPatient(); + + Patient patient = patientMapper.map(null, bahmniPatient); + + assertEquals(dateCreated, patient.getPersonDateCreated()); + } + + @Test + @Ignore + public void shouldNotMapDateCreatedForExistingPatient() throws ParseException { + Date dateCreatedBeforeMapping = new SimpleDateFormat("dd-MM-yyyy").parse("11-03-2013"); + BahmniPatient bahmniPatient = new PatientMother().withDateCreated(null).buildBahmniPatient(); + Patient patient = new PatientMother().withDateCreated(dateCreatedBeforeMapping).build(); + + Patient mappedPatient = patientMapper.map(patient, bahmniPatient); + + assertEquals(dateCreatedBeforeMapping, mappedPatient.getPersonDateCreated()); + } + +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PersonAttributeMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PersonAttributeMapperTest.java new file mode 100644 index 0000000000..47c0e21b30 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PersonAttributeMapperTest.java @@ -0,0 +1,46 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.model.BahmniPersonAttribute; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.openmrs.PersonAttribute; +import org.openmrs.PersonAttributeType; +import org.openmrs.api.PersonService; + +import java.util.Arrays; +import java.util.HashSet; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +public class PersonAttributeMapperTest { + + @Mock + private PersonService personService; + + @Before + public void setUp() throws Exception { + initMocks(this); + } + + @Test + public void shouldMapPersonAttributesToPatientAttributes() { + Patient patient = new Patient(); + PersonAttribute attribute = new PersonAttribute(); + PersonAttributeType attributeType = new PersonAttributeType(); + attributeType.setUuid("myuuid"); + attribute.setAttributeType(attributeType); + attribute.setValue("blah"); + + patient.setAttributes(new HashSet<>(Arrays.asList(attribute))); + + BahmniPatient bahmniPatient = new PersonAttributeMapper(personService).mapFromPatient(null, patient); + + BahmniPersonAttribute bahmniPersonAttribute = bahmniPatient.getAttributes().get(0); + assertEquals(attribute.getAttributeType().getUuid(), bahmniPersonAttribute.getPersonAttributeUuid()); + assertEquals(attribute.getValue(), bahmniPersonAttribute.getValue()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PersonNameMapperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PersonNameMapperTest.java new file mode 100644 index 0000000000..aa765dc3f3 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/PersonNameMapperTest.java @@ -0,0 +1,66 @@ +package org.bahmni.module.bahmnicore.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniName; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.util.NameMother; +import org.bahmni.module.bahmnicore.util.PatientMother; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.PersonName; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +public class PersonNameMapperTest { + + @Test + public void shouldCreateNewNameIfNoNameExists() { + Patient patient = new Patient(); + List names = Arrays.asList(new BahmniName(new NameMother().getSimpleObjectForName())); + + new PersonNameMapper().map(patient, names); + + assertEquals(names.get(0).getGivenName(), patient.getGivenName()); + assertEquals(names.get(0).getFamilyName(), patient.getFamilyName()); + } + + @Test + public void shouldVoidNamesSavedBeforeIfThereIsAChangeInName() { + Patient patient = new Patient(); + + List names = Arrays.asList(new BahmniName(new NameMother().getSimpleObjectForName())); + BahmniName bahmniName = names.get(0); + PersonName name = new PersonName(bahmniName.getGivenName() + "old", null, bahmniName + .getFamilyName()); + name.setId(10); + patient.addName(name); + + new PersonNameMapper().map(patient, names); + + Set nameList = patient.getNames(); + PersonName oldName = getByFirstName(bahmniName.getGivenName() + "old", nameList); + + assertTrue(oldName.isVoided()); + } + + @Test + public void shouldMapNameFromPatientToBahmniPatient() { + PersonNameMapper mapper = new PersonNameMapper(); + Patient patient = new PatientMother().withName("ram", null, "singh").build(); + BahmniPatient bahmniPatient = mapper.mapFromPatient(null, patient); + assertEquals(patient.getGivenName(), bahmniPatient.getNames().get(0).getGivenName()); + assertEquals(patient.getFamilyName(), bahmniPatient.getNames().get(0).getFamilyName()); + } + + private PersonName getByFirstName(String s, Set nameList) { + for (PersonName personName : nameList) { + if (personName.getGivenName().equals(s)) + return personName; + } + return null; + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/builder/BahmniDrugOrderBuilder.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/builder/BahmniDrugOrderBuilder.java new file mode 100644 index 0000000000..059b4850d9 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/mapper/builder/BahmniDrugOrderBuilder.java @@ -0,0 +1,51 @@ +/** + * 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.bahmni.module.bahmnicore.mapper.builder; + +import org.bahmni.module.bahmnicore.model.BahmniFeedDrugOrder; + +import java.util.UUID; + +public class BahmniDrugOrderBuilder { + + private final BahmniFeedDrugOrder bahmniDrugOrder; + + public BahmniDrugOrderBuilder() { + bahmniDrugOrder = new BahmniFeedDrugOrder(); + bahmniDrugOrder.setDosage(2.5); + bahmniDrugOrder.setProductUuid(UUID.randomUUID().toString()); + bahmniDrugOrder.setQuantity(3.0); + bahmniDrugOrder.setUnit("ml"); + } + + public BahmniDrugOrderBuilder withProductUuid(String productUuid) { + bahmniDrugOrder.setProductUuid(productUuid); + return this; + } + + public BahmniFeedDrugOrder build() { + return bahmniDrugOrder; + } + + public BahmniDrugOrderBuilder withNumberOfDaysAndDosage(int numberOfDays, Double dosage) { + bahmniDrugOrder.setDosage(dosage); + bahmniDrugOrder.setNumberOfDays(numberOfDays); + bahmniDrugOrder.setQuantity(bahmniDrugOrder.getDosage() * numberOfDays); + return this; + } + + public BahmniDrugOrderBuilder withNumberOfDaysAndDosage(int numberOfDays, int dosage) { + return withNumberOfDaysAndDosage(numberOfDays, (double)dosage); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/matcher/EncounterSessionMatcherTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/matcher/EncounterSessionMatcherTest.java new file mode 100644 index 0000000000..33f8d8186f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/matcher/EncounterSessionMatcherTest.java @@ -0,0 +1,486 @@ +package org.bahmni.module.bahmnicore.matcher; + +import org.apache.commons.lang3.time.DateUtils; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.EncounterType; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.api.impl.EncounterServiceImpl; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.EncounterTypeIdentifier; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.module.emrapi.encounter.EncounterParameters; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +@PowerMockIgnore( {"javax.management.*"} ) +public class EncounterSessionMatcherTest { + @Mock + private AdministrationService administrationService; + @Mock + private EncounterTypeIdentifier encounterTypeIdentifier; + @Mock + private EncounterServiceImpl encounterService; + private Set providers; + private Set encounterProviders; + private User creator; + @Mock + private UserContext userContext; + private EncounterType encounterType; + @Mock + private Encounter encounter; + private Person person; + private Patient patient; + private Visit visit; + private EncounterSessionMatcher encounterSessionMatcher; + private Location location; + @Mock + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + + @Mock + private BahmniVisitLocationService bahmniVisitLocationService; + + @Mock + private EpisodeService episodeService; + + @Before + public void setUp(){ + initMocks(this); + encounterSessionMatcher = new EncounterSessionMatcher(administrationService, encounterTypeIdentifier, encounterService, bahmniProgramWorkflowService, episodeService, bahmniVisitLocationService); + visit = new Visit(); + visit.setId(3); + + providers = new HashSet<>(); + Provider provider = new Provider(); + provider.setId(1234); + provider.setProviderId(1234); + providers.add(provider); + + encounterProviders = new HashSet<>(); + EncounterProvider encounterProvider = new EncounterProvider(); + encounterProvider.setProvider(provider); + encounterProviders.add(encounterProvider); + + encounterType = new EncounterType("Test", "Test"); + + location = new Location(); + location.setUuid("location-uuid"); + + creator = new User(person); + creator.setId(1234); + + encounter = mock(Encounter.class); + + Encounter encounterOne = new Encounter(); + encounterOne.setLocation(location); + encounterOne.setCreator(creator); + encounterOne.setEncounterDatetime(new Date()); + + person = new Person(); + person.setId(1234); + provider.setPerson(person); + location = new Location(); + location.setUuid("location"); + + patient = new Patient(); + patient.setId(1111); + patient.setUuid("patient_uuid"); + + userContext = mock(UserContext.class); + + when(administrationService.getGlobalProperty("bahmni.encountersession.duration")).thenReturn("60"); + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("Consultation"); + when(encounter.getCreator()).thenReturn(creator); + when(encounter.getEncounterDatetime()).thenReturn(new Date()); + + PowerMockito.mockStatic(Context.class); + BDDMockito.given(Context.getUserContext()).willReturn(userContext); + + when(userContext.getAuthenticatedUser()).thenReturn(creator); + + when(encounterService.getEncounters(any(Patient.class), eq(null), + any(Date.class), any(Date.class), any(Collection.class), + any(Collection.class), any(Collection.class), eq(null), + any(Collection.class), eq(false))).thenReturn(Arrays.asList(encounterOne)); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(null)).thenReturn(Collections.emptyList()); + } + + @Test + public void shouldReturnEncounterOfDefaultTypeIfEncounterParameterDoesNotHaveEncounterTypeAndLocationIsNotSet(){ + visit.addEncounter(encounter); + EncounterType defaultEncounterType = new EncounterType(); + when(encounter.getEncounterType()).thenReturn(defaultEncounterType); + when(encounter.getDateChanged()).thenReturn(new Date()); + when(encounter.getLocation()).thenReturn(null); + when(encounter.getEncounterProviders()).thenReturn(encounterProviders); + when(encounter.getCreator()).thenReturn(creator); + when(encounterTypeIdentifier.getDefaultEncounterType()).thenReturn(defaultEncounterType); + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(visit, getEncounterParameters(providers, location, null)); + + assertNotNull(encounterReturned); + assertTrue(encounter.getEncounterType().equals(defaultEncounterType)); + } + + @Test + public void shouldGetEncounter() throws ParseException { + EncounterParameters encounterParameters = getEncounterParameters(providers, location); + Date encounterDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2015-05-21 13:05:00"); + encounterParameters.setEncounterDateTime(encounterDate); + encounterParameters.setLocation(new Location(1)); + + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + Encounter encounterReturned = encounterSessionMatcher.findEncounter(visit, encounterParameters); + + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + ArgumentCaptor locationArgumentCaptor = ArgumentCaptor.forClass(Location.class); + ArgumentCaptor dateArgumentCaptor = ArgumentCaptor.forClass(Date.class); + ArgumentCaptor collectionArgumentCaptor = ArgumentCaptor.forClass(Collection.class); + + verify(encounterService).getEncounters(patientArgumentCaptor.capture(), locationArgumentCaptor.capture(), dateArgumentCaptor.capture(), dateArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(),collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), eq(false)); + assertEquals(encounterDate, dateArgumentCaptor.getAllValues().get(1)); + assertEquals(DateUtils.addMinutes(encounterDate, -60), dateArgumentCaptor.getAllValues().get(0)); + assertNotNull(encounterReturned); + } + + @Test + public void shouldReturnNullWhenNewlyCreatedVisitIsPassedEncounter(){ + EncounterParameters encounterParameters = getEncounterParameters(providers, location); + encounterParameters.setEncounterDateTime(DateUtils.addDays(new Date(), -10)); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(new Visit(), encounterParameters); + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + ArgumentCaptor locationArgumentCaptor = ArgumentCaptor.forClass(Location.class); + ArgumentCaptor dateArgumentCaptor = ArgumentCaptor.forClass(Date.class); + ArgumentCaptor collectionArgumentCaptor = ArgumentCaptor.forClass(Collection.class); + + verify(encounterService, times(0)).getEncounters(patientArgumentCaptor.capture(), locationArgumentCaptor.capture(), dateArgumentCaptor.capture(), dateArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(),collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), eq(false)); + assertNull(encounterReturned); + } + + @Test + public void shouldGetEncounterFromSameDay(){ + EncounterParameters encounterParameters = getEncounterParameters(providers, location); + Date encounterDateTime = DateUtils.addMinutes(DateUtils.truncate(new Date(), Calendar.DATE), 15); + encounterParameters.setEncounterDateTime(encounterDateTime); + + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + Encounter encounterReturned = encounterSessionMatcher.findEncounter(visit, encounterParameters); + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + ArgumentCaptor locationArgumentCaptor = ArgumentCaptor.forClass(Location.class); + ArgumentCaptor dateArgumentCaptor = ArgumentCaptor.forClass(Date.class); + ArgumentCaptor collectionArgumentCaptor = ArgumentCaptor.forClass(Collection.class); + + verify(encounterService).getEncounters(patientArgumentCaptor.capture(), locationArgumentCaptor.capture(), dateArgumentCaptor.capture(), dateArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), eq(false)); + assertEquals(DateUtils.truncate(encounterParameters.getEncounterDateTime(), Calendar.DATE), dateArgumentCaptor.getAllValues().get(0)); + assertEquals(encounterParameters.getEncounterDateTime(), dateArgumentCaptor.getAllValues().get(1)); + assertNotNull(encounterReturned); + } + + @Test + public void shouldGetRetrospectiveEncounter(){ + EncounterParameters encounterParameters = getEncounterParameters(providers, location); + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + Encounter encounterReturned = encounterSessionMatcher.findEncounter(visit, encounterParameters); + ArgumentCaptor patientArgumentCaptor = ArgumentCaptor.forClass(Patient.class); + ArgumentCaptor locationArgumentCaptor = ArgumentCaptor.forClass(Location.class); + ArgumentCaptor dateArgumentCaptor = ArgumentCaptor.forClass(Date.class); + ArgumentCaptor collectionArgumentCaptor = ArgumentCaptor.forClass(Collection.class); + + verify(encounterService).getEncounters(patientArgumentCaptor.capture(), locationArgumentCaptor.capture(), dateArgumentCaptor.capture(), dateArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), collectionArgumentCaptor.capture(), eq(false)); + assertEquals(dateArgumentCaptor.getAllValues().get(0), dateArgumentCaptor.getAllValues().get(1)); + assertEquals(encounterParameters.getEncounterDateTime(), dateArgumentCaptor.getAllValues().get(0)); + assertNotNull(encounterReturned); + } + + @Test + public void shouldMatchEncounterBasedOnUserWhenNoProviderIsSupplied(){ + EncounterParameters encounterParameters = getEncounterParameters(null, location); + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + e1.setLocation(location); + + Encounter e2 = new Encounter(); + User creator2 = new User(2); + e2.setCreator(creator2); + e2.setLocation(location); + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), eq(null), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(e1, e2)); + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + assertNotNull(encounterReturned); + assertEquals(encounterReturned.getCreator(), creator1); + } + + @Test + public void shouldNotReturnExistingEncounterIfItDoesNotMatchPatientProgram() { + EncounterParameters encounterParameters = getEncounterParameters(null, location); + HashMap context = new HashMap<>(); + String patientProgramUuid = "94393942-dc4d-11e5-b5d2-0a1d41d68578"; + context.put("patientProgramUuid", patientProgramUuid); + encounterParameters.setContext(context); + + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), eq(false))) + .thenReturn(Arrays.asList(e1)); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)).thenReturn(Collections.emptyList()); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + assertNull(encounterReturned); + } + + @Test + public void shouldThrowExceptionWhenMultipleEncountersAreMatched() throws Exception { + EncounterParameters encounterParameters = getEncounterParameters(null, location); + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + e1.setLocation(location); + + Encounter e2 = new Encounter(); + e2.setCreator(creator1); + e2.setLocation(location); + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), eq(false))).thenReturn(Arrays.asList(e1, e2)); + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + + try { + encounterSessionMatcher.findEncounter(null, encounterParameters); + assertFalse("should not have matched encounter", false); + }catch (RuntimeException e){ + assertEquals("More than one encounter matches the criteria", e.getMessage()); + } + } + + @Test + public void shouldReturnNullIfProgramUuidIsNotSpecifiedAndOnlyEncountersRelatedToProgramsAreOpen(){ + EncounterParameters encounterParameters = getEncounterParameters(null, location); + HashMap context = new HashMap<>(); + context.put("patientProgramUuid", null); + encounterParameters.setContext(context); + + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + List encounters = new ArrayList<>(); + encounters.add(e1); + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), eq(null), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), eq(null), eq(null), eq(null), eq(false))) + .thenReturn(encounters); + when(episodeService.getEpisodeForEncounter(e1)).thenReturn(new Episode()); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + + verify(episodeService, times(1)).getEpisodeForEncounter(e1); + assertThat(encounterReturned, is(nullValue())); + } + + @Test + public void shouldRemoveAllEncountersAssociatedWithEpisodes(){ + EncounterParameters encounterParameters = getEncounterParameters(null, location); + HashMap context = new HashMap<>(); + context.put("patientProgramUuid", null); + encounterParameters.setContext(context); + + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + e1.setLocation(location); + Encounter e2 = new Encounter(); + e2.setCreator(creator1); + e2.setLocation(location); + List encounters = new ArrayList<>(); + encounters.add(e1); + encounters.add(e2); + + when(bahmniVisitLocationService.getVisitLocation(any(String.class))).thenReturn(location); + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), eq(null), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), eq(null), eq(null), eq(null), eq(false))) + .thenReturn(encounters); + when(episodeService.getEpisodeForEncounter(e1)).thenReturn(new Episode()); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + + verify(episodeService, times(1)).getEpisodeForEncounter(e1); + verify(episodeService, times(1)).getEpisodeForEncounter(e2); + assertThat(encounterReturned, is(equalTo(e2))); + } + + @Test + public void shouldReturnTheEncountersPresentInCurrentVisitLocation() { + EncounterParameters encounterParameters = getEncounterParameters(null, location); + Location loginLocation = new Location(); + loginLocation.setUuid("login-location"); + Location encounterLocation = new Location(); + encounterLocation.setUuid("encounter-location"); + + encounterParameters.setContext(null); + + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + encounterParameters.setLocation(loginLocation); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + e1.setLocation(encounterLocation); + + Location otherLocation = new Location(); + otherLocation.setUuid("other-location-uuid"); + Encounter e2 = new Encounter(); + e2.setCreator(creator1); + e2.setLocation(otherLocation); + + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), eq(null), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), eq(null), eq(null), eq(null), eq(false))) + .thenReturn(Arrays.asList(e1)); + when(bahmniVisitLocationService.getVisitLocation(loginLocation.getUuid())).thenReturn(loginLocation); + when(bahmniVisitLocationService.getVisitLocation(encounterLocation.getUuid())).thenReturn(loginLocation); + when(bahmniVisitLocationService.getVisitLocation(otherLocation.getUuid())).thenReturn(otherLocation); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + assertNotNull(encounterReturned); + } + + @Test + public void shouldReturnNullIfThereIsNoEncounterInCurrentVisitLocation() { + EncounterParameters encounterParameters = getEncounterParameters(null, location); + Location loginLocation = new Location(); + loginLocation.setUuid("login-location"); + Location encounterLocation = new Location(); + encounterLocation.setUuid("encounter-location"); + + encounterParameters.setContext(null); + + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + encounterParameters.setLocation(loginLocation); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + e1.setLocation(encounterLocation); + + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), eq(false))) + .thenReturn(Arrays.asList(e1)); + when(bahmniVisitLocationService.getVisitLocation(loginLocation.getUuid())).thenReturn(loginLocation); + when(bahmniVisitLocationService.getVisitLocation(encounterLocation.getUuid())).thenReturn(encounterLocation); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + assertNull(encounterReturned); + } + + @Test + public void shouldNotReturnEncouterIfItsLocationIsNull() { + EncounterParameters encounterParameters = getEncounterParameters(null, location); + Location loginLocation = new Location(); + loginLocation.setUuid("login-location"); + + encounterParameters.setContext(null); + + encounterParameters.setEncounterDateTime(DateUtils.truncate(new Date(), Calendar.DATE)); + encounterParameters.setLocation(loginLocation); + + Encounter e1 = new Encounter(); + User creator1 = new User(1); + e1.setCreator(creator1); + e1.setLocation(null); + + + when(userContext.getAuthenticatedUser()).thenReturn(creator1); + when(encounterService.getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), eq(false))) + .thenReturn(Arrays.asList(e1)); + when(bahmniVisitLocationService.getVisitLocation(loginLocation.getUuid())).thenReturn(loginLocation); + + Encounter encounterReturned = encounterSessionMatcher.findEncounter(null, encounterParameters); + assertNull(encounterReturned); + } + + private EncounterParameters getEncounterParameters(Set providers, Location location) { + return getEncounterParameters(providers, location, this.encounterType); + } + + private EncounterParameters getEncounterParameters(Set providers, Location location, EncounterType encounterType) { + EncounterParameters encounterParameters = EncounterParameters.instance(); + encounterParameters.setPatient(patient); + encounterParameters.setEncounterType(encounterType); + encounterParameters.setProviders(providers); + encounterParameters.setLocation(location); + return encounterParameters; + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/AgeTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/AgeTest.java new file mode 100644 index 0000000000..5e321e0c4d --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/AgeTest.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.model; + +import org.joda.time.LocalDate; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.util.Date; + +import static junit.framework.Assert.assertEquals; + +public class AgeTest { + + @Test + public void shouldConvertHashToAgeWhenOneOfThePropertiesDoNotExist() { + assertEquals(new Age(2010, 0, 0), Age.fromHash(new SimpleObject().add("years", 2010))); + assertEquals(new Age(0, 12, 0), Age.fromHash(new SimpleObject().add("months", 12))); + assertEquals(new Age(0, 0, 31), Age.fromHash(new SimpleObject().add("days", 31))); + assertEquals(new Age(0, 0, 0), Age.fromHash(new SimpleObject())); + } + + @Test + public void shouldCalculateAgeFromDateOfBirth() { + Date birthDate = new LocalDate(1990, 6, 15).toDate(); + Date today = new LocalDate(2013, 12, 5).toDate(); + + Age age = Age.fromDateOfBirth(birthDate, today); + + assertEquals(new Age(23, 5, 20), age); + } + + @Test + public void shouldCalculateDateOfBirthFromAge() { + Age age = new Age(20, 5, 21); + Date today = new LocalDate(2013, 6, 20).toDate(); + + Date dateOfBirth = age.getDateOfBirth(today); + + assertEquals(new LocalDate(1992, 12, 30).toDate(), dateOfBirth); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniAddressTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniAddressTest.java new file mode 100644 index 0000000000..d835d3c5b3 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniAddressTest.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.model; + +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; + +import static junit.framework.Assert.assertEquals; + +public class BahmniAddressTest { + + @Test + public void shouldCreateAddressFromSimpleObject() { + String address1 = "someAddress1"; + String address2 = "someAddress2"; + String address3 = "someAddress3"; + String address4 = "someAddress4"; + String address5 = "someAddress5"; + String address6 = "someAddress6"; + String stateProvince = "somestateProvince"; + String countyDistrict = "somecountyDistrict"; + String cityVillage = "somecityVillage"; + String postalCode = "somepostalCode"; + String country = "somecountry"; + String latitude = "somelatitude"; + String longitude = "longitude"; + SimpleObject addressObject = new SimpleObject().add("address1", address1).add("address2", address2).add("address3", + address3).add("address4", address4).add("address5", address5).add("address6", + address6).add("cityVillage", cityVillage).add("countyDistrict", countyDistrict).add("stateProvince", + stateProvince).add("postalCode", postalCode).add("country", country).add("latitude", + latitude).add("longitude", longitude); + + BahmniAddress address = new BahmniAddress(addressObject); + + assertEquals(address1, address.getAddress1()); + assertEquals(address2, address.getAddress2()); + assertEquals(address3, address.getAddress3()); + assertEquals(address4, address.getAddress4()); + assertEquals(address5, address.getAddress5()); + assertEquals(address6, address.getAddress6()); + assertEquals(cityVillage, address.getCityVillage()); + assertEquals(countyDistrict, address.getCountyDistrict()); + assertEquals(stateProvince, address.getStateProvince()); + assertEquals(postalCode, address.getPostalCode()); + assertEquals(country, address.getCountry()); + assertEquals(latitude, address.getLatitude()); + assertEquals(longitude, address.getLongitude()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrdersTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrdersTest.java new file mode 100644 index 0000000000..c1515b48bb --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniFeedDrugOrdersTest.java @@ -0,0 +1,44 @@ +/** + * 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.bahmni.module.bahmnicore.model; + +import org.bahmni.module.bahmnicore.mapper.builder.BahmniDrugOrderBuilder; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class BahmniFeedDrugOrdersTest { + @Test + public void testGetUniqueOrdersReturnsUniqueOrdersWithDosageAndQuantityAdjusted() throws Exception { + BahmniFeedDrugOrder order1 = new BahmniDrugOrderBuilder().withProductUuid("11").withNumberOfDaysAndDosage(10, 2).build(); + BahmniFeedDrugOrder order2 = new BahmniDrugOrderBuilder().withProductUuid("22").withNumberOfDaysAndDosage(5, 1).build(); + BahmniFeedDrugOrder order3 = new BahmniDrugOrderBuilder().withProductUuid("11").withNumberOfDaysAndDosage(10, 1).build(); + BahmniFeedDrugOrders bahmniFeedDrugOrders = new BahmniFeedDrugOrders(Arrays.asList(order1, order2, order3)); + + List uniqueOrders = bahmniFeedDrugOrders.getUniqueOrders(); + + assertEquals(2, uniqueOrders.size()); + assertEquals("11", uniqueOrders.get(0).getProductUuid()); + assertEquals(30.0, (Object)uniqueOrders.get(0).getQuantity()); + assertEquals(20, uniqueOrders.get(0).getNumberOfDays()); + assertEquals(1.5, (Object)uniqueOrders.get(0).getDosage()); + assertEquals("22", uniqueOrders.get(1).getProductUuid()); + assertEquals(5.0, (Object)uniqueOrders.get(1).getQuantity()); + assertEquals(5, uniqueOrders.get(1).getNumberOfDays()); + assertEquals(1.0, (Object)uniqueOrders.get(1).getDosage()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniNameTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniNameTest.java new file mode 100644 index 0000000000..84b8794965 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniNameTest.java @@ -0,0 +1,23 @@ +package org.bahmni.module.bahmnicore.model; + +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; + +import static junit.framework.Assert.assertEquals; + +public class BahmniNameTest { + + @Test + public void shouldCreateNameFromSimpleObject() { + String givenName = "SomeGivenName"; + String middleName = "SomeMiddleName"; + String familyName = "SomeFamilyName"; + SimpleObject nameObject = new SimpleObject().add("givenName", givenName).add("middleName", middleName).add( + "familyName", familyName); + + BahmniName name = new BahmniName(nameObject); + + assertEquals(givenName, name.getGivenName()); + assertEquals(familyName, name.getFamilyName()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniPatientTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniPatientTest.java new file mode 100644 index 0000000000..e5d5049ec3 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniPatientTest.java @@ -0,0 +1,44 @@ +package org.bahmni.module.bahmnicore.model; + +import junit.framework.Assert; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; + +public class BahmniPatientTest { + + @Test + public void shouldCreateAPersonFromASimpleObject() throws ParseException { + String birthdate = "01-01-2012"; + String registrationDateStr = "25-04-1988"; + String centerName = "Ganiyari"; + double expectedBalance = 123; + SimpleObject age = new SimpleObject().add("years", 21).add("months", 10).add("days", 30); + SimpleObject personObject = new SimpleObject().add("birthdate", birthdate).add("age", age).add("gender", "M").add( + "attributes", Arrays.asList(new SimpleObject().add("attributeType", "caste").add("value", "someCaste"))).add( + "addresses", Arrays.asList(new SimpleObject().add("address1", "7143 Koramangala"))).add("centerID", centerName) + .add("names", Arrays.asList(new SimpleObject().add("givenName", "first").add("familyName", "Last"))) + .add("identifier", "someIdentifier") + .add("balance", "123") + .add("dateOfRegistration", registrationDateStr); + + + BahmniPatient person = new BahmniPatient(personObject); + + Date date = new SimpleDateFormat("dd-MM-yyyy").parse(birthdate); + Date registrationDate = new SimpleDateFormat("dd-MM-yyyy").parse(registrationDateStr); + Assert.assertEquals(date, person.getBirthdate()); + Assert.assertEquals("M", person.getGender()); + Assert.assertEquals("someIdentifier", person.getIdentifier()); + Assert.assertEquals(1, person.getAttributes().size()); + Assert.assertEquals(1, person.getAddresses().size()); + Assert.assertEquals(1, person.getNames().size()); + Assert.assertEquals(centerName, person.getCenterName()); + Assert.assertEquals(expectedBalance, person.getBalance()); + Assert.assertEquals(registrationDate, person.getPersonDateCreated()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniPersonAttributeTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniPersonAttributeTest.java new file mode 100644 index 0000000000..bc8dbd06fa --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/BahmniPersonAttributeTest.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.model; + +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; + +import static org.junit.Assert.assertEquals; + +public class BahmniPersonAttributeTest { + + @Test + public void shouldCreatePersonAttributeFromSimpleObject() { + String value = "someCaste"; + String attributeUUId = "casteAttributeUUId"; + SimpleObject personAttributeObject = new SimpleObject().add("attributeType", attributeUUId).add("value", value); + + BahmniPersonAttribute personAttribute = new BahmniPersonAttribute(personAttributeObject); + + assertEquals(attributeUUId, personAttribute.getPersonAttributeUuid()); + assertEquals(value, personAttribute.getValue()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/ProviderTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/ProviderTest.java new file mode 100644 index 0000000000..3e5974548c --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/ProviderTest.java @@ -0,0 +1,58 @@ +package org.bahmni.module.bahmnicore.model; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class ProviderTest { + + private String providerName = "providerName"; + private String providerUuid = "provider-uuid"; + private Provider provider; + + @Before + public void setUp() { + provider = new Provider(); + provider.setProviderName(providerName); + provider.setUuid(providerUuid); + } + + @Test + public void shouldReturnTrueWhenTwoProvidersAreSameByReference() { + + assertEquals(provider, provider); + } + + @Test + public void shouldReturnFalseWhenOneOfTheProvidersIsNull() { + + assertNotEquals(provider, null); + } + + @Test + public void shouldReturnFalseWhenTypeOfTheObjectDoesNotEqualToProvider() { + + assertNotEquals(provider, ""); + } + + @Test + public void shouldReturnFalseWhenProviderNameDoesNotMatch() { + Provider otherProvider = new Provider(); + otherProvider.setProviderName("some provider name"); + otherProvider.setUuid(providerUuid); + + assertNotEquals(provider, otherProvider); + } + + @Test + public void shouldReturnTrueWhenProviderNameAndUuidMatches() { + + Provider otherProvider = new Provider(); + otherProvider.setProviderName(providerName); + otherProvider.setUuid(providerUuid); + + assertEquals(provider, otherProvider); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/SimpleObjectExtractorTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/SimpleObjectExtractorTest.java new file mode 100644 index 0000000000..b132dfab21 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/model/SimpleObjectExtractorTest.java @@ -0,0 +1,15 @@ +package org.bahmni.module.bahmnicore.model; + +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; + +import static org.junit.Assert.assertEquals; + +public class SimpleObjectExtractorTest { + @Test + public void shouldReturnDefaultValueWhenKeyDoesNotExist() { + SimpleObjectExtractor simpleObjectExtractor = new SimpleObjectExtractor(new SimpleObject().add("foo", 4)); + + assertEquals(0, (int)simpleObjectExtractor.getValueOrDefault("bar", int.class)); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniAddressHierarchyServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniAddressHierarchyServiceImplTest.java new file mode 100644 index 0000000000..2f95b341e6 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniAddressHierarchyServiceImplTest.java @@ -0,0 +1,46 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniAddressHierarchyDao; +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; +import org.bahmni.module.bahmnicore.service.BahmniAddressHierarchyService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniAddressHierarchyServiceImplTest { + private BahmniAddressHierarchyService bahmniAddressHierarchyService; + + @Mock + private BahmniAddressHierarchyDao bahmniAddressHierarchyDao; + + @Before + public void setUp() throws Exception { + initMocks(this); + bahmniAddressHierarchyService = new BahmniAddressHierarchyServiceImpl(bahmniAddressHierarchyDao); + } + + @Test + public void shouldGetAddressHierarchyEntryByUuid() throws Exception { + List addressHierarchyEntries = new ArrayList<>(); + BahmniAddressHierarchyEntry addressHierarchyEntry = new BahmniAddressHierarchyEntry(); + addressHierarchyEntry.setName("test"); + addressHierarchyEntries.add(addressHierarchyEntry); + List uuids = new ArrayList<>(); + uuids.add("uuid"); + when(bahmniAddressHierarchyDao.getAddressHierarchyEntriesByUuid(uuids)).thenReturn(addressHierarchyEntries); + + List hierarchyEntriesByUuid = bahmniAddressHierarchyService.getAddressHierarchyEntriesByUuid(uuids); + + verify(bahmniAddressHierarchyDao, times(1)).getAddressHierarchyEntriesByUuid(uuids); + assertEquals(addressHierarchyEntry.getName(), hierarchyEntriesByUuid.get(0).getName()); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java new file mode 100644 index 0000000000..492d909346 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniBridgeTest.java @@ -0,0 +1,198 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.test.builder.DrugOrderBuilder; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.DrugOrder; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.api.ConceptService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + + +@RunWith(PowerMockRunner.class) +public class BahmniBridgeTest { + + @Mock + private ObsDao obsDao; + @Mock + private PatientService patientService; + @Mock + private PersonService personService; + @Mock + private OrderDao orderDao; + @Mock + private BahmniDrugOrderService bahmniDrugOrderService; + @Mock + private ConceptService conceptService; + @Mock + private OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper; + @Mock + private BahmniConceptService bahmniConceptService; + + BahmniBridge bahmniBridge; + + String patientUuid = "patient-uuid"; + String patientProgramUuid = "patient-program-uuid"; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + bahmniBridge = new BahmniBridge(obsDao, patientService, personService, conceptService, orderDao, bahmniDrugOrderService, omrsObsToBahmniObsMapper, bahmniConceptService); + bahmniBridge.forPatient(patientUuid); + } + + @Test + public void shouldNotGetOrdersWhichAreScheduledInFuture() throws Exception { + Date futureDate = DateTime.now().plusDays(10).toDate(); + Date autoExpireDate = DateTime.now().plusDays(40).toDate(); + DrugOrder scheduledDrugOrder = new DrugOrderBuilder().withScheduledDate(futureDate).withAutoExpireDate(autoExpireDate).build(); + PowerMockito.when(bahmniDrugOrderService.getActiveDrugOrders(patientUuid)).thenReturn(Arrays.asList(scheduledDrugOrder)); + + List drugOrders = bahmniBridge.activeDrugOrdersForPatient(); + Assert.assertEquals(0, drugOrders.size()); + } + + @Test + public void shouldGetActiveOrders() throws Exception { + DrugOrder activeOrder = new DrugOrderBuilder().withScheduledDate(null).withAutoExpireDate(DateTime.now().plusMonths(2).toDate()).build(); + PowerMockito.when(bahmniDrugOrderService.getActiveDrugOrders(patientUuid)).thenReturn(Arrays.asList(activeOrder)); + + List drugOrders = bahmniBridge.activeDrugOrdersForPatient(); + Assert.assertEquals(1, drugOrders.size()); + } + + @Test + public void shouldGetScheduledOrdersWhichHasBecomeActive() throws Exception { + DrugOrder scheduledDrugOrder = new DrugOrderBuilder().withScheduledDate(DateTime.now().minusMonths(1).toDate()).build(); + PowerMockito.when(bahmniDrugOrderService.getActiveDrugOrders(patientUuid)).thenReturn(Arrays.asList(scheduledDrugOrder)); + + List drugOrders = bahmniBridge.activeDrugOrdersForPatient(); + Assert.assertEquals(1, drugOrders.size()); + } + + @Test + public void shouldGetFirstDrugActivatedDate() throws Exception { + List allDrugOrders = new ArrayList<>(); + Order order1 = new Order(); + Date now = new Date(); + order1.setDateActivated(addDays(now, 10)); + allDrugOrders.add(order1); + Order order2 = new Order(); + order2.setDateActivated(now); + allDrugOrders.add(order2); + PowerMockito.when(bahmniDrugOrderService.getAllDrugOrders(patientUuid, null, null, null, null)).thenReturn(allDrugOrders); + + Assert.assertEquals(now, bahmniBridge.getStartDateOfTreatment()); + + } + + @Test + public void shouldGetSchuledDateIfTheDrugIsScheduled() throws Exception { + List allDrugOrders = new ArrayList<>(); + Order order1 = new Order(); + Date now = new Date(); + order1.setDateActivated(addDays(now, 10)); + allDrugOrders.add(order1); + Order order2 = new Order(); + order2.setScheduledDate(addDays(now, 2)); + order2.setDateActivated(now); + allDrugOrders.add(order2); + + PowerMockito.when(bahmniDrugOrderService.getAllDrugOrders(patientUuid, null, null, null, null)).thenReturn(allDrugOrders); + + Assert.assertEquals(addDays(now, 2), bahmniBridge.getStartDateOfTreatment()); + + } + + @Test + public void shouldGetChildObservationFromParent() throws Exception { + Concept vitalsConcept = new Concept(); + ConceptName vitalConceptName = new ConceptName(); + vitalConceptName.setName("vital concept name"); + Locale locale = new Locale("En"); + vitalConceptName.setLocale(locale); + vitalsConcept.setFullySpecifiedName(vitalConceptName); + + PowerMockito.when(conceptService.getConceptByName("vital concept name")).thenReturn(vitalsConcept); + + Obs obs = new Obs(); + obs.setUuid("observation uuid"); + + BahmniObservation bahmniObs = new BahmniObservation(); + bahmniObs.setUuid("observation uuid"); + + PowerMockito.when(obsDao.getChildObsFromParent("parent obs uuid", vitalsConcept)).thenReturn(obs); + PowerMockito.when(omrsObsToBahmniObsMapper.map(obs, null)).thenReturn(bahmniObs); + Assert.assertEquals("observation uuid", bahmniBridge.getChildObsFromParentObs("parent obs uuid", "vital concept name").getUuid()); + + } + + @Test + public void shouldGetConceptByFullySpecifiedName() throws Exception { + Concept vitalsConcept = new Concept(); + ConceptName vitalConceptName = new ConceptName(); + vitalConceptName.setName("vital concept name"); + Locale locale = new Locale("En"); + vitalConceptName.setLocale(locale); + vitalsConcept.setFullySpecifiedName(vitalConceptName); + + PowerMockito.when(bahmniConceptService.getConceptByFullySpecifiedName("vital concept name")).thenReturn(vitalsConcept); + + Assert.assertEquals(vitalsConcept, bahmniBridge.getConceptByFullySpecifiedName("vital concept name")); + } + + @Test + public void shouldGetTheLatestAmongAllTheObservationsWithPatientUuid() throws Exception { + bahmniBridge.forPatient(patientUuid); + + bahmniBridge.latestObs("conceptName"); + + verify(obsDao, times(1)).getLatestObsFor(patientUuid, "conceptName", 1); + } + + @Test + public void shouldGetTheLatestAmongAllTheObservationsWithPatientProgramUuid() throws Exception { + bahmniBridge.forPatientProgram(patientProgramUuid); + List conceptNames = new ArrayList<>(); + conceptNames.add("conceptName"); + bahmniBridge.latestObs("conceptName"); + + verify(obsDao, times(1)).getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, conceptNames, 1, ObsDaoImpl.OrderBy.DESC, null, null); + } + + public Date addDays(Date now, int days) { + Calendar c = Calendar.getInstance(); + c.setTime(now); + c.add(Calendar.DATE, days); + return c.getTime(); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniConceptServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniConceptServiceImplTest.java new file mode 100644 index 0000000000..1571e44a9d --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniConceptServiceImplTest.java @@ -0,0 +1,126 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.BahmniConceptDao; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniConceptServiceImplTest { + + public static final String QUESTION = "question"; + public static final String SEARCH_QUERY = "q"; + @Mock + private BahmniConceptDao bahmniConceptDao; + @Mock + private ConceptService conceptService; + private BahmniConceptServiceImpl bahmniConceptService; + + @Before + public void setUp() { + initMocks(this); + bahmniConceptService = new BahmniConceptServiceImpl(conceptService, bahmniConceptDao); + } + + @Test + public void searchByQuestionShouldUseBahmniConceptDaoToSearchConcepts() { + Concept questionConcept = new Concept(); + when(bahmniConceptDao.getConceptByFullySpecifiedName(QUESTION)).thenReturn(questionConcept); + ConceptAnswer resultConceptAnswer = new ConceptAnswer(); + when(bahmniConceptDao.searchByQuestion(questionConcept, SEARCH_QUERY)).thenReturn(Arrays.asList(resultConceptAnswer)); + + Collection conceptAnswers = bahmniConceptService.searchByQuestion(QUESTION, SEARCH_QUERY); + assertThat(conceptAnswers.size(), is(equalTo(1))); + assertThat(conceptAnswers.iterator().next().getUuid(), is(equalTo(resultConceptAnswer.getUuid()))); + } + + @Test(expected = ConceptNotFoundException.class) + public void searchByQuestionShouldThrowExceptionWhenQuestionConceptNotFound() throws Exception { + bahmniConceptService.searchByQuestion("this concept doesn't exist", "headache"); + } + + @Test + public void getDrugsByConceptSetNameShouldRetrieveAllDrugsForMembersOfAConceptSet() { + Concept allTBDrugsConceptSet = new Concept(); + List allTBDrugConcepts = Arrays.asList(new Concept(), new Concept()); + String conceptSetName = "All TB Drugs"; + List allTBDrugs = Arrays.asList(new Drug(), new Drug()); + + when(bahmniConceptDao.getConceptByFullySpecifiedName(conceptSetName)).thenReturn(allTBDrugsConceptSet); + when(conceptService.getConceptsByConceptSet(allTBDrugsConceptSet)).thenReturn(allTBDrugConcepts); + when(bahmniConceptDao.searchDrugsByDrugName(allTBDrugsConceptSet.getId(), null)).thenReturn(allTBDrugs); + + Collection drugs = bahmniConceptService.getDrugsByConceptSetName(conceptSetName, null); + + assertThat(drugs, containsInAnyOrder(allTBDrugs.toArray())); + } + + @Test(expected = ConceptNotFoundException.class) + public void getDrugsByConceptSetNameShouldFailWhenConceptSetNameDoesNotExist() { + bahmniConceptService.getDrugsByConceptSetName("this concept doesn't exist", null); + } + + @Test + public void shouldMakeACallToGetConceptByFullySpecifiedName() throws Exception { + Concept expectedConcept = new Concept(); + String conceptName = "Concept Name"; + when(bahmniConceptDao.getConceptByFullySpecifiedName(conceptName)).thenReturn(expectedConcept); + + Concept actualConcept = bahmniConceptService.getConceptByFullySpecifiedName(conceptName); + + verify(bahmniConceptDao, times(1)).getConceptByFullySpecifiedName(conceptName); + assertEquals(expectedConcept, actualConcept); + } + + @Test + public void shouldReturnEmptyConceptsListIfConceptNamesListIsEmpty() throws Exception { + + List concepts = bahmniConceptService.getConceptsByFullySpecifiedName(new ArrayList()); + assertEquals(0, concepts.size()); + } + + @Test + public void shouldGetListOfConceptsByTakingListOfNamesAsParameters() throws Exception { + + List conceptNames = new ArrayList(); + conceptNames.add("concept1"); + conceptNames.add("concept2"); + List conceptList = new ArrayList<>(); + conceptList.add(new Concept(1)); + conceptList.add(new Concept(2)); + when(bahmniConceptDao.getConceptsByFullySpecifiedName(conceptNames)).thenReturn(conceptList); + + List concepts = bahmniConceptService.getConceptsByFullySpecifiedName(conceptNames); + + verify(bahmniConceptDao, times(1)).getConceptsByFullySpecifiedName(conceptNames); + assertEquals(2, concepts.size()); + assertEquals(1, concepts.get(0).getConceptId().intValue()); + assertEquals(2, concepts.get(1).getConceptId().intValue()); + } + + @Test + public void shouldGetEmptyListIfListOfNamesIsNull() throws Exception { + List concepts = bahmniConceptService.getConceptsByFullySpecifiedName(null); + + assertEquals(0, concepts.size()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java new file mode 100644 index 0000000000..1c050d0e3a --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDiagnosisServiceImplTest.java @@ -0,0 +1,308 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.DiagnosisBuilder; +import org.bahmni.test.builder.EncounterBuilder; +import org.bahmni.test.builder.ObsBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ObsService; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.diagnosis.helper.BahmniDiagnosisMetadata; +import org.openmrs.module.emrapi.EmrApiProperties; +import org.openmrs.module.emrapi.diagnosis.Diagnosis; +import org.openmrs.module.emrapi.encounter.DiagnosisMapper; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyList; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(LocaleUtility.class) +@RunWith(PowerMockRunner.class) +public class BahmniDiagnosisServiceImplTest { + @Mock + private EncounterService encounterService; + @Mock + private ObsService obsService; + @Mock + private PatientService patientService; + @Mock + private VisitService visitService; + @Mock + private BahmniDiagnosisMetadata bahmniDiagnosisMetadata; + @Mock + private ConceptService conceptService; + @Mock + private DiagnosisMapper diagnosisMapper; + @Mock + private EmrApiProperties emrApiProperties; + + @Mock + private AdministrationService administrationService; + + @InjectMocks + private BahmniDiagnosisServiceImpl bahmniDiagnosisService = new BahmniDiagnosisServiceImpl(encounterService, obsService, visitService, patientService, diagnosisMapper, bahmniDiagnosisMetadata, conceptService, emrApiProperties, administrationService); + + private String initialDiagnosisObsUUID = "initialDiagnosisObsUUID"; + private String modifiedDiagnosisObsUUID = "modifiedDiagnosisObsUUID"; + private String initialEncounterUUID = "initialEncounterUUID"; + private Obs initialVisitDiagnosesObs; + private Obs modifiedVisitDiagnosis; + private Encounter initialEncounter; + private Encounter modifiedEncounter; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + PowerMockito.mockStatic(LocaleUtility.class); + PowerMockito.when(LocaleUtility.getLocalesInOrder()).thenReturn(new HashSet<>(Arrays.asList(Locale.getDefault()))); + when(administrationService.getGlobalProperty(eq("bahmni.lookupExternalTerminologyServer"))).thenReturn("false"); + } + + @Test + public void deleteADiagnosis() throws Exception { + String diagnosisObsUUID = "diagnosisObsUUID"; + + Obs visitDiagnosisObs = new DiagnosisBuilder().withUuid(diagnosisObsUUID).withDefaults().withFirstObs(diagnosisObsUUID).build(); + Set allObsForDiagnosisEncounter = new HashSet<>(); + allObsForDiagnosisEncounter.add(new DiagnosisBuilder().withUuid("someOtherDiagnosisUUID").withDefaults().withFirstObs("initialDiagnosisObsUUID").build()); + allObsForDiagnosisEncounter.add(visitDiagnosisObs); + allObsForDiagnosisEncounter.add(new ObsBuilder().withUUID("nonDiagnosisUuid").withConcept("Some Concept", Locale.getDefault()).build()); + + Encounter diagnosisEncounter = new EncounterBuilder().withDatetime(new Date()).build(); + visitDiagnosisObs.setEncounter(diagnosisEncounter); + diagnosisEncounter.setObs(allObsForDiagnosisEncounter); + + when(obsService.getObsByUuid(diagnosisObsUUID)).thenReturn(visitDiagnosisObs); + when(obsService.getObservationsByPersonAndConcept(visitDiagnosisObs.getPerson(), visitDiagnosisObs.getConcept())).thenReturn(Arrays.asList(visitDiagnosisObs)); + when(encounterService.saveEncounter(diagnosisEncounter)).thenReturn(diagnosisEncounter); + when(bahmniDiagnosisMetadata.findInitialDiagnosisUuid(visitDiagnosisObs)).thenReturn(diagnosisObsUUID); + + bahmniDiagnosisService.delete(diagnosisObsUUID); + ArgumentCaptor argToCapture = ArgumentCaptor.forClass(Encounter.class); + verify(encounterService).saveEncounter(argToCapture.capture()); + assertVoided(argToCapture.getValue(), diagnosisObsUUID); + } + + @Test + public void initialDiagnosisIsDeletedOnDeletingADiagnosis() throws Exception { + setUpInitialVisitDiagnosis(); + setUpModifiedVisitDiagnosis(); + + when(obsService.getObsByUuid(modifiedDiagnosisObsUUID)).thenReturn(modifiedVisitDiagnosis); + when(obsService.getObservationsByPersonAndConcept(modifiedVisitDiagnosis.getPerson(), modifiedVisitDiagnosis.getConcept())). + thenReturn(Arrays.asList(modifiedVisitDiagnosis, initialVisitDiagnosesObs)); + when(encounterService.saveEncounter(initialEncounter)).thenReturn(initialEncounter); + when(encounterService.saveEncounter(modifiedEncounter)).thenReturn(modifiedEncounter); + when(bahmniDiagnosisMetadata.findInitialDiagnosisUuid(modifiedVisitDiagnosis)).thenReturn(initialDiagnosisObsUUID); + + bahmniDiagnosisService.delete(modifiedDiagnosisObsUUID); + + ArgumentCaptor argToCapture = ArgumentCaptor.forClass(Encounter.class); + verify(encounterService, times(2)).saveEncounter(argToCapture.capture()); + + assertVoided(argToCapture.getAllValues().get(0), modifiedDiagnosisObsUUID); + assertVoided(argToCapture.getAllValues().get(1), initialDiagnosisObsUUID); + } + + @Test + public void otherDiagnosisWithSameInitialDiagnosisIsDeletedOnDeletingADiagnosis() throws Exception { + setUpInitialVisitDiagnosis(); + setUpModifiedVisitDiagnosis(); + String anotherDiagnosisUuid = "anotherDiagnosisUuid"; + + + Obs anotherVisitDiagnosis = new DiagnosisBuilder().withUuid(anotherDiagnosisUuid).withDefaults().withFirstObs(initialDiagnosisObsUUID).build(); + Encounter anotherEncounter = new EncounterBuilder().withDatetime(new Date()).withUUID("anotherEncounterUuid").build(); + anotherEncounter.addObs(anotherVisitDiagnosis); + anotherVisitDiagnosis.setEncounter(anotherEncounter); + + when(obsService.getObsByUuid(modifiedDiagnosisObsUUID)).thenReturn(modifiedVisitDiagnosis); + when(obsService.getObservationsByPersonAndConcept(modifiedVisitDiagnosis.getPerson(), modifiedVisitDiagnosis.getConcept())). + thenReturn(Arrays.asList(modifiedVisitDiagnosis, initialVisitDiagnosesObs, anotherVisitDiagnosis)); + when(encounterService.saveEncounter(initialEncounter)).thenReturn(initialEncounter); + when(encounterService.saveEncounter(modifiedEncounter)).thenReturn(modifiedEncounter); + when(bahmniDiagnosisMetadata.findInitialDiagnosisUuid(modifiedVisitDiagnosis)).thenReturn(initialDiagnosisObsUUID); + + bahmniDiagnosisService.delete(modifiedDiagnosisObsUUID); + + ArgumentCaptor argToCapture = ArgumentCaptor.forClass(Encounter.class); + verify(encounterService, times(3)).saveEncounter(argToCapture.capture()); + + assertVoided(argToCapture.getAllValues().get(0), modifiedDiagnosisObsUUID); + assertVoided(argToCapture.getAllValues().get(1), initialDiagnosisObsUUID); + assertVoided(argToCapture.getAllValues().get(2), anotherDiagnosisUuid); + } + + @Test + public void shouldGetBahmniDiagnosisByPatientAndVisit() { + Patient patient = mock(Patient.class); + Visit visit = new Visit(); + visit.addEncounter(new Encounter()); + Concept diagnosisSetConcept = new ConceptBuilder().withUUID("uuid").build(); + + BahmniDiagnosisRequest bahmniDiagnosisRequest = new BahmniDiagnosisRequest(); + BahmniDiagnosis bahmniDiagnosis = new BahmniDiagnosis(); + bahmniDiagnosis.setExistingObs("existing"); + bahmniDiagnosisRequest.setFirstDiagnosis(bahmniDiagnosis); + + Diagnosis diagnosis = getDiagnosis(); + Diagnosis updatedDiagnosis = getUpdatedDiagnosis(); + + when(visitService.getVisitByUuid("visitId")).thenReturn(visit); + when(patientService.getPatientByUuid("patientId")).thenReturn(patient); + when(bahmniDiagnosisMetadata.getDiagnosisSetConcept()).thenReturn(diagnosisSetConcept); + when(obsService.getObservations(eq(Arrays.asList((Person) patient)), eq(new ArrayList<>(visit.getEncounters())), eq(Arrays.asList(diagnosisSetConcept)), eq(null), eq(null), eq(null), anyList(), + eq(null), eq(null), eq(null), eq(null), eq(false))) + .thenReturn(Arrays.asList(diagnosis.getExistingObs())); + when(bahmniDiagnosisMetadata.buildDiagnosisFromObsGroup(diagnosis.getExistingObs(), new ArrayList(), new ArrayList())).thenReturn(diagnosis); + when(diagnosisMapper.convert(any(Diagnosis.class))).thenReturn(null); + when(bahmniDiagnosisMetadata.findInitialDiagnosisUuid(diagnosis.getExistingObs())).thenReturn("firstDiagnosisObsId"); + when(bahmniDiagnosisMetadata.findInitialDiagnosis(updatedDiagnosis.getExistingObs())).thenReturn(diagnosis.getExistingObs()); + when(bahmniDiagnosisMetadata.mapBahmniDiagnosis(eq(null), eq(null), eq(true), eq(false), eq(false), eq(true))).thenReturn(bahmniDiagnosisRequest); + + List bahmniDiagnosisRequests = bahmniDiagnosisService.getBahmniDiagnosisByPatientAndVisit("patientId", "visitId"); + + assertEquals(1, bahmniDiagnosisRequests.size()); + assertEquals(bahmniDiagnosisRequest, bahmniDiagnosisRequests.get(0)); + } + + + @Test + public void shouldNotReturnDiagnosisIfNoEncounterExists() throws Exception { + + String visitId = "visitId"; + Visit visit = new Visit(); + when(visitService.getVisitByUuid(visitId)).thenReturn(visit); + + List bahmniDiagnosisRequests = bahmniDiagnosisService.getBahmniDiagnosisByPatientAndVisit("patientId", visitId); + + assertEquals(0, bahmniDiagnosisRequests.size()); + } + + @Test + public void shouldReturnEmptyListIfNoVisitFound() throws Exception { + String visitId = "visitId"; + when(visitService.getVisitByUuid(visitId)).thenReturn(null); + + List bahmniDiagnosisRequests = bahmniDiagnosisService.getBahmniDiagnosisByPatientAndVisit("patientId", visitId); + + assertEquals(0, bahmniDiagnosisRequests.size()); + } + + @Test + public void shouldReturnFalseWhenNoExternalTerminologyServerLookupNeeded() { + boolean externalTerminologyServerLookupNeeded = bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded(); + assertFalse(externalTerminologyServerLookupNeeded); + } + + @Test + public void shouldReturnTrueWhenExternalTerminologyServerLookupNeeded() { + when(administrationService.getGlobalProperty(eq("bahmni.lookupExternalTerminologyServer"))).thenReturn("TRUE"); + boolean externalTerminologyServerLookupNeeded = bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded(); + assertTrue(externalTerminologyServerLookupNeeded); + } + + @Test + public void shouldCallDiagosisSetofSetsInEmrApiWhenNoExternalTerminologyServerLookupNeeded() { + bahmniDiagnosisService.getDiagnosisSets(); + verify(emrApiProperties, times(1)).getDiagnosisSets(); + } + + private Diagnosis getDiagnosis() { + Diagnosis diagnosis = new Diagnosis(); + Obs diagnosisObs = new DiagnosisBuilder() + .withDefaults() + .withFirstObs("firstDiagnosisObsId") + .withUuid("firstDiagnosisObsId") + .build(); + diagnosis.setExistingObs(diagnosisObs); + + return diagnosis; + } + + private Diagnosis getUpdatedDiagnosis() { + Diagnosis diagnosis = new Diagnosis(); + + Obs updatedDiagnosisObs = new DiagnosisBuilder() + .withDefaults() + .withFirstObs("firstDiagnosisObsId") + .withUuid("finalDiagnosisUuid") + .build(); + + diagnosis.setExistingObs(updatedDiagnosisObs); + return diagnosis; + } + + + private void setUpModifiedVisitDiagnosis() { + modifiedVisitDiagnosis = new DiagnosisBuilder().withUuid(modifiedDiagnosisObsUUID).withDefaults().withFirstObs(initialDiagnosisObsUUID).build(); + modifiedEncounter = new EncounterBuilder().withDatetime(new Date()).withUUID("modifiedEncounterUUID").build(); + modifiedEncounter.addObs(modifiedVisitDiagnosis); + modifiedVisitDiagnosis.setEncounter(modifiedEncounter); + } + + private void setUpInitialVisitDiagnosis() { + initialVisitDiagnosesObs = new DiagnosisBuilder().withUuid(initialDiagnosisObsUUID).withDefaults().withFirstObs(initialDiagnosisObsUUID).build(); + initialEncounter = new EncounterBuilder().withDatetime(new Date()).withUUID(initialEncounterUUID).build(); + initialEncounter.addObs(initialVisitDiagnosesObs); + initialVisitDiagnosesObs.setEncounter(initialEncounter); + } + + + private void assertVoided(Encounter encounter, String observationUuid) { + Obs visitDiagnosesObsToSave = getAllObsFor(encounter, observationUuid); + assertTrue("Parent Diagnosis Obs should be voided", visitDiagnosesObsToSave.isVoided()); + for (Obs childObs : visitDiagnosesObsToSave.getGroupMembers(true)) { + assertTrue("Child Diagnosis Obs should be voided", childObs.isVoided()); + } + } + + private Obs getAllObsFor(Encounter encounterToSave, String visitDiagnosisUuid) { + Set allObs = encounterToSave.getAllObs(true); + for (Obs anObs : allObs) { + if (anObs.getUuid().equals(visitDiagnosisUuid)) + return anObs; + } + return null; + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplIT.java new file mode 100644 index 0000000000..dffb6cfe83 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplIT.java @@ -0,0 +1,71 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.contract.drugorder.DrugOrderConfigResponse; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.DrugOrder; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class BahmniDrugOrderServiceImplIT extends BaseIntegrationTest { + + @Autowired + private BahmniDrugOrderServiceImpl bahmniDrugOrderService; + + @Before + public void setUp() throws Exception { + executeDataSet("drugOrdersTestData.xml"); + executeDataSet("visitAttributeDataSet.xml"); + } + + + @Test + public void shouldReturnOrderAttributeConceptNamesWithGetConfig() throws ParseException { + DrugOrderConfigResponse config = bahmniDrugOrderService.getConfig(); + List orderAttributes = config.getOrderAttributes(); + + assertEquals(2, orderAttributes.size()); + assertEquals("dispensed", orderAttributes.get(0).getName()); + assertEquals("administered", orderAttributes.get(1).getName()); + } + + @Test + public void shouldReturnDiscontinuedOrderMap() throws Exception { + executeDataSet("patientWithStoppedOrders.xml"); + DrugOrder newFirstOrder = (DrugOrder) Context.getOrderService().getOrder(15); + DrugOrder revisedFirstOrder = (DrugOrder) Context.getOrderService().getOrder(16); + DrugOrder newSecondOrder = (DrugOrder) Context.getOrderService().getOrder(18); + DrugOrder discontinuedFirstOrder = (DrugOrder) Context.getOrderService().getOrder(17); + DrugOrder discontinuedSecondOrder = (DrugOrder) Context.getOrderService().getOrder(19); + + List drugOrdersList = Arrays.asList(newFirstOrder, revisedFirstOrder, newSecondOrder); + Map discontinuedOrderMap = bahmniDrugOrderService.getDiscontinuedDrugOrders(drugOrdersList); + assertEquals(discontinuedOrderMap.get("2").getUuid(), discontinuedFirstOrder.getUuid()); + assertEquals(discontinuedOrderMap.get("4").getUuid(), discontinuedSecondOrder.getUuid()); + assertNull(discontinuedOrderMap.get("1")); + + } + + @Test + public void shouldReturnEmptyDiscontinuedOrderMapWhenThereAreNoActiveDrugOrders() throws Exception { + List drugOrdersList = new ArrayList<>(); + Map discontinuedOrderMap = bahmniDrugOrderService.getDiscontinuedDrugOrders(drugOrdersList); + Assert.assertNotNull(discontinuedOrderMap); + assertEquals(0, discontinuedOrderMap.size()); + + } + + +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java new file mode 100644 index 0000000000..cbc9983503 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniDrugOrderServiceImplTest.java @@ -0,0 +1,117 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.CareSetting; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; + +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyCollection; +import static org.mockito.Matchers.anySet; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.times; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniDrugOrderServiceImplTest { + + public static final String PATIENT_PROGRAM_UUID = "patient-program-uuid"; + public static final String PATIENT_UUID = "patient-uuid"; + + @Mock + BahmniProgramWorkflowService bahmniProgramWorkflowService; + @Mock + PatientService patientService; + @Mock + OrderService orderService; + @Mock + OrderDao orderDao; + + @InjectMocks + BahmniDrugOrderServiceImpl bahmniDrugOrderService; + private final CareSetting mockCareSetting = mock(CareSetting.class); + private final Patient mockPatient = mock(Patient.class); + private final OrderType mockOrderType = mock(OrderType.class); + private HashSet conceptsToFilter; + private final ArgumentCaptor dateArgumentCaptor = ArgumentCaptor.forClass(Date.class); + private final List encounters = new ArrayList<>(); + + + @Before + public void setUp() throws Exception { + initMocks(this); + encounters.add(new Encounter()); + + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(PATIENT_PROGRAM_UUID)).thenReturn(encounters); + when(patientService.getPatientByUuid(PATIENT_UUID)).thenReturn(mockPatient); + when(orderService.getCareSettingByName(anyString())).thenReturn(mockCareSetting); + when(orderService.getOrderTypeByName("Drug order")).thenReturn(mockOrderType); + when(orderService.getOrderTypeByUuid(OrderType.DRUG_ORDER_TYPE_UUID)).thenReturn(mockOrderType); + + final Concept concept = mock(Concept.class); + conceptsToFilter = new HashSet() {{ + add(concept); + }}; + + } + + @Test + public void shouldGetActiveDrugOrdersOfAPatientProgram() throws ParseException { + when(orderDao.getActiveOrders(any(Patient.class), any(OrderType.class), any(CareSetting.class), + dateArgumentCaptor.capture(), anySet(), eq(null), eq(null), eq(null), anyCollection())).thenReturn(new ArrayList()); + + bahmniDrugOrderService.getDrugOrders(PATIENT_UUID, true, conceptsToFilter, null, PATIENT_PROGRAM_UUID); + + final Date value = dateArgumentCaptor.getValue(); + verify(orderDao, times(2)).getActiveOrders(mockPatient, mockOrderType, mockCareSetting, value, conceptsToFilter, null, null, null, encounters); + } + + @Test + public void shouldReturnEmptyListWhenNoEncountersAssociatedWithPatientProgram() throws ParseException { + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(PATIENT_PROGRAM_UUID)).thenReturn(new HashSet()); + + final List drugOrders = bahmniDrugOrderService.getDrugOrders(PATIENT_UUID, true, null, null, PATIENT_PROGRAM_UUID); + + verifyNoMoreInteractions(orderDao); + assertTrue(drugOrders.isEmpty()); + } + + @Test + public void shouldGetAllDrugOrdersOfAPatientProgram() throws ParseException { + bahmniDrugOrderService.getDrugOrders(PATIENT_UUID, null, conceptsToFilter, null, PATIENT_PROGRAM_UUID); + + verify(orderDao).getAllOrders(mockPatient, mockOrderType, conceptsToFilter, null, encounters); + } + + @Test + public void shouldNotConsiderEncountersToFetchDrugOrdersIfPatientProgramUuidIsNull() throws Exception { + bahmniDrugOrderService.getDrugOrders(PATIENT_UUID, null, conceptsToFilter, null, null); + List encounters = null ; + + verify(orderDao).getAllOrders(mockPatient, mockOrderType,conceptsToFilter, null, encounters); + verifyNoMoreInteractions(bahmniProgramWorkflowService); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniFeedDrugOrderServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniFeedDrugOrderServiceImplTest.java new file mode 100644 index 0000000000..ff5069468a --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniFeedDrugOrderServiceImplTest.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.junit.Rule; +import org.junit.rules.ExpectedException; + +public class BahmniFeedDrugOrderServiceImplTest { + public static final String TEST_VISIT_TYPE = "TEST VISIT TYPE"; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplIT.java new file mode 100644 index 0000000000..b02a3cf76f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplIT.java @@ -0,0 +1,328 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.bahmni.module.bahmnicore.obs.handler.LocationObsHandler; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.obs.ComplexObsHandler; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class BahmniObsServiceImplIT extends BaseIntegrationTest { + + @Autowired + BahmniObsService bahmniObsService; + @Autowired + private ConceptService conceptService; + @Autowired + private VisitService visitService; + + @Autowired + ObsDao obsDao; + + private HashMap metaDataSet = new HashMap() { + { + put("diagnosis", "diagnosisMetadata.xml"); + put("disposition", "dispositionMetadata.xml"); + put("observation", "observationsTestData.xml"); + put("program", "patientProgramTestData.xml"); + put("complexObs", "complexObsData.xml"); + } + }; + + @Before + public void setUp() throws Exception { + setupMetaData(new String[] {"diagnosis", "disposition", "observation", "program" } ); + } + + private void setupMetaData(String[] list) throws Exception { + for (String item : list) { + String xmlFile = metaDataSet.get(item); + if (!StringUtils.isBlank(xmlFile)) { + executeDataSet(xmlFile); + } + } + } + + @Test + public void shouldGetComplexObsLocationData() throws Exception { + setupMetaData(new String[] {"complexObs"}); + ObsService os = Context.getObsService(); + //TODO: this need to changed. os.getObs() should be called once the fix in core is in + Obs complexObs = os.getComplexObs(44, ComplexObsHandler.RAW_VIEW); + Assert.assertNotNull(complexObs); + Assert.assertTrue(complexObs.isComplex()); + Assert.assertNotNull(complexObs.getValueComplex()); + Assert.assertNotNull(complexObs.getComplexData()); + Assert.assertEquals(Location.class, complexObs.getComplexData().getData().getClass()); + Assert.assertEquals(LocationObsHandler.class, os.getHandler(complexObs).getClass()); + } + + @Test + public void shouldReturnLatestObsForEachConcept() { + Concept vitalsConcept = conceptService.getConceptByName("Vitals"); + Collection bahmniObservations = bahmniObsService.getLatest("86526ed5-3c11-11de-a0ba-001e378eb67a", + Arrays.asList(vitalsConcept), 3, null, false, null); + BahmniObservation vitalObservation = bahmniObservations.iterator().next(); + Collection vitalsGroupMembers = vitalObservation.getGroupMembers(); + assertEquals(2, vitalsGroupMembers.size()); + Iterator observationIterator = vitalsGroupMembers.iterator(); + + BahmniObservation weight = observationIterator.next(); + BahmniObservation pulse = observationIterator.next(); + assertEquals("Pulse", pulse.getConcept().getName()); + assertEquals("Weight", weight.getConcept().getName()); + } + + @Test + public void shouldReturnLatestObsForEachConceptForSpecifiedNumberOfVisits() { + Concept sittingConcept = conceptService.getConceptByName("Vitals"); + //Latest limited by last two visits. + Collection bahmniObservations = bahmniObsService.getLatest("86526ed5-3c11-11de-a0ba-001e378eb67a", + Arrays.asList(sittingConcept), 2, null, false, null); + assertEquals(0, bahmniObservations.size()); + bahmniObservations = bahmniObsService.getLatest("86526ed5-3c11-11de-a0ba-001e378eb67a", Arrays.asList(sittingConcept), 3, null, false, null); + assertEquals(1, bahmniObservations.size()); + + BahmniObservation sittingObservation = bahmniObservations.iterator().next(); + assertEquals("Vitals", sittingObservation.getConcept().getName()); + } + + @Test + public void shouldReturnLatestObsForEachConceptForSpecifiedVisitUuid() { + Concept sittingConcept = conceptService.getConceptByName("Sitting"); + Visit visit = visitService.getVisitByUuid("e10186d8-1c8e-11e4-bb80-f18add123456"); + + Collection latestObsByVisit = bahmniObsService.getLatestObsByVisit(visit, Arrays.asList(sittingConcept), null, false); + assertEquals(1, latestObsByVisit.size()); + BahmniObservation sittingObservation = latestObsByVisit.iterator().next(); + assertEquals("1.5", sittingObservation.getValueAsString()); + } + + @Test + public void shouldReturnEmptyListIfTheVisitDoesnotHaveData() throws Exception { + Concept sittingConcept = conceptService.getConceptByName("Sitting"); + Visit visit = visitService.getVisitByUuid("e10186d8-1c8e-11e4-bb80-f1badd123456"); + + Collection latestObsByVisit = bahmniObsService.getLatestObsByVisit(visit, Arrays.asList(sittingConcept), null, false); + + assertEquals(0, latestObsByVisit.size()); + } + + @Test + public void shouldReturnLatestObsFromAllEncountersInVisit() { + Concept concept = conceptService.getConcept("100"); + Visit visit = visitService.getVisitByUuid("e10186d8-1c8e-11e4-bb80-f18add123456"); + Collection latestObsByVisit = bahmniObsService.getLatestObsByVisit(visit, Arrays.asList(concept), null, false); + + assertEquals(1, latestObsByVisit.size()); + BahmniObservation obs = latestObsByVisit.iterator().next(); + assertEquals("100.0", obs.getValueAsString()); + + } + + @Test + public void returnOrphanedObsForPatient() throws Exception { + Concept bloodPressureConcept = new ConceptBuilder().withName("Blood Pressure").build(); + Collection obsForConceptSet = bahmniObsService.observationsFor("86526ed5-3c11-11de-a0ba-001e378eb67a", + Arrays.asList(bloodPressureConcept), null, null, false, null, null, null); + assertEquals(1, obsForConceptSet.size()); + Collection bloodPressureMembers = obsForConceptSet.iterator().next().getGroupMembers(); + Iterator bloodPressureMembersIterator = bloodPressureMembers.iterator(); + assertEquals(2, bloodPressureMembers.size()); + Collection systolicMembers = bloodPressureMembersIterator.next().getGroupMembers(); + Collection diastolicMembers = bloodPressureMembersIterator.next().getGroupMembers(); + assertEquals(2, systolicMembers.size()); + assertEquals(2, diastolicMembers.size()); + } + + @Test + public void shouldReturnObsForAllConceptForGivenVisit() { + List bahmniObservations = (List) bahmniObsService.getObservationForVisit("ad41fb41-a41a-4ad6-8835-2f59099acf5b", null, null, false, null); + assertEquals(2, bahmniObservations.size()); + assertEquals(2, bahmniObservations.get(0).getGroupMembers().size()); + assertEquals(1, bahmniObservations.get(1).getGroupMembers().size()); + } + + @Test + public void shouldReturnObsForGivenConceptForGivenVisitWithoutTakingObservationNamesCaseIntoAccount() { + Collection bahmniObservations = + bahmniObsService.getObservationForVisit("ad41fb41-a41a-4ad6-8835-2f59099acf5b", Arrays.asList("SYSTOlic", "Diastolic"), null, false, null); + assertEquals(2, bahmniObservations.size()); + } + + @Test + public void shouldRetrieveObsForEncounter() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("Systolic"); + + Collection observations = bahmniObsService.getObservationsForEncounter("bb0af6767-707a-4629-9850-f15206e63ab0", conceptNames); + + assertEquals(1, observations.size()); + assertEquals("6d8f507a-fb89-11e3-bb80-f18addb6f9bd", observations.iterator().next().getUuid()); + } + + @Test + public void shouldRetrieveObsForPatientProgram() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("conceptABC"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, null); + + assertEquals(1, observations.size()); + assertEquals("6d8f507a-fb899-11e3-bb80-996addb6f9we", observations.iterator().next().getUuid()); + + } + + @Test + public void shouldRetrieveEmptyObsListWhenPatientProgramUuidDoesNotExist() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("conceptABC"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("patientProgramUuid", conceptNames, null); + + assertEquals(0, observations.size()); + } + + @Test + public void shouldRetrieveEmptyObsIfPatientProgramDoesNotHaveAnyEncounters() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("conceptABC"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("df0foifo-dkcd-475d-b939-6d82327f36a3", conceptNames, null); + + assertEquals(0, observations.size()); + } + + @Test + public void shouldRetrieveBahmniObservationByObservationUuid() throws Exception { + BahmniObservation bahmniObservation = bahmniObsService.getBahmniObservationByUuid("633dc076-1c8f-11e4-bkk0-f18addb6fmtb"); + + assertNotNull("BahmniObservation should not be null", bahmniObservation); + assertEquals("633dc076-1c8f-11e4-bkk0-f18addb6fmtb", bahmniObservation.getUuid()); + } + + @Test + public void shouldRetrieveAllLatestObservationsForMultiSelectConcept() { + List observations = (List) bahmniObsService.getLatestObservationsForPatientProgram("df0foif1-dkcd-475d-b939-6d82327f36a3", Arrays.asList("Systolic"), null); + assertEquals(3, observations.size()); + } + + @Test + public void shouldRetrieveAllLatestObservationSingleValueConcept() { + List observations = (List) bahmniObsService.getLatestObservationsForPatientProgram("df0foif1-dkcd-475d-b939-6d82327f36a3", Arrays.asList("Diastolic"), null); + assertEquals(1, observations.size()); + assertEquals(100.0, observations.get(0).getValue()); + } + + @Test + public void shouldRetrieveRevisionBahmniObservationByObservationUuid() throws Exception { + BahmniObservation bahmniObservation = bahmniObsService.getRevisedBahmniObservationByUuid("uuid99998"); + + assertNotNull("BahmniObservation should not be null", bahmniObservation); + assertEquals("uuid999982", bahmniObservation.getUuid()); + } + + @Test + @Ignore("org.openmrs.api.UnchangeableObjectException: editing.fields.not.allowed") // This requires bean refactoring + public void shouldNotRetrieveIgnoreObsAndItsChildrenForPatientProgram() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("Health Education"); + List obsIgnoreList = new ArrayList<>(); + obsIgnoreList.add("HE, Marital status"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, obsIgnoreList); + + assertEquals(1, observations.size()); + assertEquals(1, observations.iterator().next().getGroupMembers().size()); + assertEquals("HE, Date of consultation", observations.iterator().next().getGroupMembers().iterator().next().getConceptNameToDisplay()); + } + + @Test + @Ignore("org.openmrs.api.UnchangeableObjectException: editing.fields.not.allowed") // This requires bean refactoring + public void shouldRetrieveAllObsIncludingChildrenForPatientProgram() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("Health Education"); + List obsIgnoreList = new ArrayList<>(); + obsIgnoreList.add("HE, Date of consultation"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, obsIgnoreList); + + Collection groupMembers = observations.iterator().next().getGroupMembers(); + Iterator iterator = groupMembers.iterator(); + BahmniObservation observationOne = iterator.next(); + Collection childMembers = observationOne.getGroupMembers(); + + assertEquals(1, observations.size()); + assertEquals(1, groupMembers.size()); + assertEquals("HE, Marital status",observationOne.getConceptNameToDisplay()); + assertEquals(1, childMembers.size()); + assertEquals("HE, Date Of Marriage", childMembers.iterator().next().getConceptNameToDisplay()); + } + + @Test + public void shouldReturnEmptyArrayIfConceptNameIsSameAsIgnoreListForPatientProgram() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("Health Education"); + List obsIgnoreList = new ArrayList<>(); + obsIgnoreList.add("Health Education"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, obsIgnoreList); + + assertEquals(0, observations.size()); + } + + @Test + public void shouldReturnAllObsInConceptNamesIfThereAreNoMatchesInObsIgnoreListForPatientProgram() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + conceptNames.add("HE, Date Of Marriage"); + List obsIgnoreList = new ArrayList<>(); + obsIgnoreList.add("HE, Da Of Marriage"); + + Collection observations = bahmniObsService.getObservationsForPatientProgram("dfdfoifo-dkcd-475d-b939-6d82327f36a3", conceptNames, obsIgnoreList); + + assertEquals(1, observations.size()); + } + + @Test + public void shouldRetrieveLatestObservationsNotInIgnoreListForMultiSelectConcept() { + List observations = (List) bahmniObsService.getLatestObservationsForPatientProgram("df0foif1-dkcd-475d-b939-6d82327f36a3", Arrays.asList("Systolic"), Arrays.asList("Systolic")); + assertEquals(0, observations.size()); + } + + @Test + public void shouldRetrieveInitalObservationsNotInIgnoreListForPatientProgram() throws Exception { + List observations = (List) bahmniObsService.getInitialObservationsForPatientProgram("df0foif1-dkcd-475d-b939-6d82327f36a3", Arrays.asList("Systolic"), Arrays.asList("Systolic")); + assertEquals(0, observations.size()); + } + + @Test + public void shouldRetrieveAllInitalObservationsForPatientProgram() throws Exception { + List observations = (List) bahmniObsService.getInitialObservationsForPatientProgram("df0foif1-dkcd-475d-b939-6d82327f36a3", Arrays.asList("Systolic"), null); + assertEquals(1, observations.size()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java new file mode 100644 index 0000000000..4cb5f5e368 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniObsServiceImplTest.java @@ -0,0 +1,273 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.dao.ObsDao; +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.bahmni.module.bahmnicore.dao.impl.ObsDaoImpl; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.VisitBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +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.ObsService; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.OMRSObsToBahmniObsMapper; +import org.openmrs.module.emrapi.encounter.matcher.ObservationTypeMatcher; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static java.util.Arrays.asList; +import static java.util.Collections.EMPTY_LIST; +import static java.util.Collections.singletonList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(LocaleUtility.class) +public class BahmniObsServiceImplTest { + + private BahmniObsService bahmniObsService; + + private String personUUID = "12345"; + + @Mock + private ObsDao obsDao; + @Mock + private VisitDao visitDao; + @Mock + private ObservationTypeMatcher observationTypeMatcher; + @Mock + private VisitService visitService; + @Mock + private ConceptService conceptService; + @Mock + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + @Mock + private ObsService obsService; + @Mock + private OMRSObsToBahmniObsMapper omrsObsToBahmniObsMapper; + + @Before + public void setUp() { + initMocks(this); + + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + when(observationTypeMatcher.getObservationType(any(Obs.class))).thenReturn(ObservationTypeMatcher.ObservationType.OBSERVATION); + bahmniObsService = new BahmniObsServiceImpl(obsDao, omrsObsToBahmniObsMapper, visitService, conceptService, visitDao, bahmniProgramWorkflowService, obsService); + } + + @Test + public void shouldGetPersonObs() throws Exception { + bahmniObsService.getObsForPerson(personUUID); + verify(obsDao).getNumericObsByPerson(personUUID); + } + + @Test + public void shouldGetNumericConcepts() throws Exception { + bahmniObsService.getNumericConceptsForPerson(personUUID); + verify(obsDao).getNumericConceptsForPerson(personUUID); + } + + @Test + public void shouldGetObsByPatientUuidConceptNameAndNumberOfVisits() throws Exception { + Concept bloodPressureConcept = new ConceptBuilder().withName("Blood Pressure").build(); + Integer numberOfVisits = 3; + bahmniObsService.observationsFor(personUUID, asList(bloodPressureConcept), numberOfVisits, null, false, null, null, null); + verify(obsDao).getObsByPatientAndVisit(personUUID, asList("Blood Pressure"), + visitDao.getVisitIdsFor(personUUID, numberOfVisits), Integer.MAX_VALUE, ObsDaoImpl.OrderBy.DESC, null, false, null, null, null); + } + + @Test + public void shouldGetInitialObservations() throws Exception { + Concept weightConcept = new ConceptBuilder().withName("Weight").build(); + Integer limit = 1; + VisitBuilder visitBuilder = new VisitBuilder(); + Visit visit = visitBuilder.withUUID("visitId").withEncounter(new Encounter(1)).withPerson(new Person()).build(); + List obsIgnoreList = new ArrayList<>(); + bahmniObsService.getInitialObsByVisit(visit, asList(weightConcept), obsIgnoreList, true); + verify(obsDao).getObsByPatientAndVisit(visit.getPatient().getUuid(), asList("Weight"), + asList(visit.getVisitId()), limit, ObsDaoImpl.OrderBy.ASC, obsIgnoreList, true, null, null, null); + } + + @Test + public void shouldGetAllObsForOrder() throws Exception { + bahmniObsService.getObservationsForOrder("orderUuid"); + verify(obsDao, times(1)).getObsForOrder("orderUuid"); + } + + @Test + public void shouldGetObsForPatientProgram() { + Collection encounters = asList(new Encounter(), new Encounter()); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(any(String.class))).thenReturn(encounters); + Concept bloodPressureConcept = new ConceptBuilder().withName("Blood Pressure").build(); + Integer numberOfVisits = 3; + + bahmniObsService.observationsFor(personUUID, bloodPressureConcept, bloodPressureConcept, numberOfVisits, null, null, "patientProgramUuid"); + verify(obsDao).getObsFor(personUUID, bloodPressureConcept, bloodPressureConcept, visitDao.getVisitIdsFor(personUUID, numberOfVisits), encounters, null, null); + verify(bahmniProgramWorkflowService).getEncountersByPatientProgramUuid("patientProgramUuid"); + } + + @Test + public void shouldMakeACallToGetObservationsForEncounterAndConcepts() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + String encounterUuid = "encounterUuid"; + + bahmniObsService.getObservationsForEncounter(encounterUuid, conceptNames); + + verify(obsDao, times(1)).getObsForConceptsByEncounter(encounterUuid, conceptNames); + } + + @Test + public void shouldReturnEmptyObservationListIfProgramDoesNotHaveEncounters() { + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(any(String.class))).thenReturn(EMPTY_LIST); + Concept bloodPressureConcept = new ConceptBuilder().withName("Blood Pressure").build(); + + Collection observations = bahmniObsService.observationsFor(personUUID, bloodPressureConcept, bloodPressureConcept, 3, null, null, "patientProgramUuid"); + + verify(obsDao, times(0)).getObsFor(anyString(), any(Concept.class), any(Concept.class), any(List.class), any(Collection.class), any(Date.class), any(Date.class)); + assertThat(observations.size(), is(equalTo(0))); + } + + @Test + public void shouldCallObsServiceWithEmptyListOfEncountersWhenProgramUuidIsNull() { + Concept bloodPressureConcept = new ConceptBuilder().withName("Blood Pressure").build(); + + int numberOfVisits = 3; + bahmniObsService.observationsFor(personUUID, bloodPressureConcept, bloodPressureConcept, numberOfVisits, null, null, null); + + verify(obsDao).getObsFor(personUUID, bloodPressureConcept, bloodPressureConcept, visitDao.getVisitIdsFor(personUUID, numberOfVisits), new ArrayList(), null, null); + } + + @Test + public void shouldGetObsbyPatientProgramUuid() throws Exception { + String patientProgramUuid = "patientProgramUuid"; + ArrayList conceptNames = new ArrayList<>(); + List obs = new ArrayList<>(); + conceptNames.add("Paracetamol"); + Collection names = new ArrayList() {{add(null);}}; + + bahmniObsService.getObservationsForPatientProgram(patientProgramUuid, conceptNames, null); + + verify(obsDao).getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, asList("Paracetamol"), null, ObsDaoImpl.OrderBy.DESC, null, null); + verify(omrsObsToBahmniObsMapper, times(1)).map(obs, names); + } + + @Test + public void shouldGetLatestObsbyPatientProgramUuid() throws Exception { + String patientProgramUuid = "patientProgramUuid"; + List conceptNames = new ArrayList<>(); + conceptNames.add("Paracetamol"); + List obs = new ArrayList<>(); + Collection names = new ArrayList() {{add(null);}}; + + bahmniObsService.getLatestObservationsForPatientProgram(patientProgramUuid, conceptNames, null); + + verify(obsDao).getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, asList("Paracetamol"), null, ObsDaoImpl.OrderBy.DESC, null, null); + verify(omrsObsToBahmniObsMapper, times(1)).map(obs, names); + } + + @Test + public void shouldGetInitialObsbyPatientProgramUuid() throws Exception { + String patientProgramUuid = "patientProgramUuid"; + List conceptNames = new ArrayList<>(); + conceptNames.add("Paracetamol"); + List obs = new ArrayList<>(); + Collection names = new ArrayList() {{add(null);}}; + + bahmniObsService.getInitialObservationsForPatientProgram(patientProgramUuid, conceptNames, null); + + verify(obsDao).getObsByPatientProgramUuidAndConceptNames(patientProgramUuid, asList("Paracetamol"), 1, ObsDaoImpl.OrderBy.ASC, null, null); + verify(omrsObsToBahmniObsMapper, times(1)).map(obs, names); + } + + @Test + public void shouldGetBahmniObservationByObservationUuid() throws Exception { + String observationUuid = "observationUuid"; + Obs obs = new Obs(); + BahmniObservation expectedBahmniObservation = new BahmniObservation(); + when(obsService.getObsByUuid(observationUuid)).thenReturn(obs); + when(omrsObsToBahmniObsMapper.map(obs, null)).thenReturn(expectedBahmniObservation); + + BahmniObservation actualBahmniObservation = bahmniObsService.getBahmniObservationByUuid(observationUuid); + + verify(obsService, times(1)).getObsByUuid(observationUuid); + verify(omrsObsToBahmniObsMapper, times(1)).map(obs, null); + assertNotNull(actualBahmniObservation); + assertEquals(expectedBahmniObservation, actualBahmniObservation); + } + + @Test + public void shouldCallGetObsForFormBuilderFormsWithEncountersAndVisits() { + String patientUuid = "patient-uuid"; + String patientProgramUuid = "patient-program-uuid"; + int numberOfVisits = 2; + List visitIds = asList(100, 101); + List formNames = singletonList("First Aid Form"); + List encounters = singletonList(mock(Encounter.class)); + + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)) + .thenReturn(encounters); + when(visitDao.getVisitIdsFor(patientUuid, numberOfVisits)).thenReturn(visitIds); + when(obsDao.getObsForFormBuilderForms(patientUuid, formNames, visitIds, encounters, null, null)) + .thenReturn(EMPTY_LIST); + + bahmniObsService.getObsForFormBuilderForms(patientUuid, formNames, numberOfVisits, null, null, patientProgramUuid); + + verify(bahmniProgramWorkflowService).getEncountersByPatientProgramUuid(patientProgramUuid); + verify(visitDao).getVisitIdsFor(patientUuid, numberOfVisits); + verify(obsDao).getObsForFormBuilderForms(patientUuid, formNames, visitIds, encounters, null, null); + } + + @Test + public void shouldReturnBahmniObservationWhenGetObsForFormBuilderFormsCalled() { + String patientUuid = "patient-uuid"; + String patientProgramUuid = "patient-program-uuid"; + int numberOfVisits = 2; + List visitIds = asList(100, 101); + List formNames = singletonList("First Aid Form"); + List encounters = singletonList(mock(Encounter.class)); + Obs observation = mock(Obs.class); + BahmniObservation bahmniObservation = mock(BahmniObservation.class); + + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid)) + .thenReturn(encounters); + when(visitDao.getVisitIdsFor(patientUuid, numberOfVisits)).thenReturn(visitIds); + when(obsDao.getObsForFormBuilderForms(patientUuid, formNames, visitIds, encounters, null, null)) + .thenReturn(singletonList(observation)); + when(omrsObsToBahmniObsMapper.map(observation, null)).thenReturn(bahmniObservation); + + Collection bahmniObservations = bahmniObsService.getObsForFormBuilderForms(patientUuid, + formNames, numberOfVisits, null, null, patientProgramUuid); + + assertEquals(1, bahmniObservations.size()); + assertEquals(bahmniObservation, bahmniObservations.iterator().next()); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderServiceImplTest.java new file mode 100644 index 0000000000..40c82f5c3f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniOrderServiceImplTest.java @@ -0,0 +1,165 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.service.BahmniOrderService; +import org.bahmni.module.bahmnicore.service.OrderService; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.CareSetting; +import org.openmrs.Concept; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.PersonName; +import org.openmrs.Provider; +import org.openmrs.module.bahmniemrapi.order.contract.BahmniOrder; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(LocaleUtility.class) +public class BahmniOrderServiceImplTest { + + private BahmniOrderService bahmniOrderService; + + private String personUUID = "12345"; + private String visitUUID = "54321"; + private Order order; + private Concept concept; + private Provider provider; + private Patient patient; + + @Mock + private BahmniObsService bahmniObsService; + @Mock + private OrderService orderService; + @Mock + private ConceptMapper conceptMapper; + + + @Before + public void setUp() { + initMocks(this); + + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + concept= new org.bahmni.test.builder.ConceptBuilder().withUUID("otUUID").build(); + EncounterTransaction.Concept encounterTransactionconcept = new EncounterTransaction.Concept(); + encounterTransactionconcept.setName("Concept for order"); + encounterTransactionconcept.setConceptClass("otClass"); + encounterTransactionconcept.setDataType("N/A"); + encounterTransactionconcept.setUuid("otUUID"); + when(conceptMapper.map(any(Concept.class))).thenReturn(encounterTransactionconcept); + bahmniOrderService = new BahmniOrderServiceImpl(orderService, bahmniObsService, conceptMapper); + + } + + @Test + public void shouldGetBahmniOrdersForOrderType() throws Exception { + when(orderService.getAllOrdersForVisits(personUUID, "someOrderTypeUuid", 2)).thenReturn(Arrays.asList(createOrder(), createOrder(), createOrder())); + List bahmniOrders = bahmniOrderService.ordersForOrderType(personUUID, Arrays.asList(concept), 2, null, "someOrderTypeUuid", true, null); + verify(orderService).getAllOrdersForVisits(personUUID, "someOrderTypeUuid", 2); + Assert.assertEquals(3, bahmniOrders.size()); + } + + @Test + public void shouldGetAllOrdersIfNumberOfVisitsIsNullOrZero() throws Exception { + when(orderService.getAllOrders(personUUID, "someOrderTypeUuid", null, null, null)).thenReturn(Arrays.asList(createOrder(), createOrder(), createOrder())); + List bahmniOrders = bahmniOrderService.ordersForOrderType(personUUID, Arrays.asList(concept), null, null, "someOrderTypeUuid", true, null); + verify(orderService).getAllOrders(personUUID, "someOrderTypeUuid", null, null, null); + Assert.assertEquals(3, bahmniOrders.size()); + } + + @Test + public void shouldNotSetObservationIfIncludeObsFlagIsSetToFalse() throws Exception { + when(orderService.getAllOrders(personUUID, "someOrderTypeUuid", null, null, null)).thenReturn(Arrays.asList(createOrder(), createOrder(), createOrder())); + List bahmniOrders = bahmniOrderService.ordersForOrderType(personUUID, Arrays.asList(concept), null, null, "someOrderTypeUuid", false, null); + verify(orderService).getAllOrders(personUUID, "someOrderTypeUuid", null, null, null); + Assert.assertEquals(3, bahmniOrders.size()); + Assert.assertNull(bahmniOrders.get(0).getBahmniObservations()); + } + + @Test + public void shouldGetBahmniOrdersForOrder() throws Exception { + Order order = createOrder(); + when(orderService.getOrderByUuid("someOrderUuid")).thenReturn(order); + bahmniOrderService.ordersForOrderUuid(personUUID, Arrays.asList(concept), null, "someOrderUuid"); + verify(bahmniObsService).observationsFor(personUUID, Arrays.asList(concept), null, null, false, order, null, null); + } + + @Test + public void shouldGetBahmniOrdersForVisit() throws Exception { + when(orderService.getAllOrdersForVisitUuid(visitUUID, "someOrderTypeUuid")).thenReturn(Arrays.asList(createOrder(), createOrder())); + List bahmniOrders = bahmniOrderService.ordersForVisit(visitUUID, "someOrderTypeUuid", null, Arrays.asList(concept)); + verify(bahmniObsService).getObservationForVisit(visitUUID, null, Arrays.asList(concept), false, order); + verify(orderService).getAllOrdersForVisitUuid(visitUUID, "someOrderTypeUuid"); + Assert.assertEquals(2, bahmniOrders.size()); + } + + + @Test + public void shouldGetChildOrder() throws Exception { + Order order = createOrder(); + bahmniOrderService.getChildOrder(order); + verify(orderService,times(1)).getChildOrder(order); + } + + @Test + public void shouldGetAppropriateBahmniOrdersDetails() { + Order order = createOrder(); + when(orderService.getAllOrdersForVisits(personUUID, "someOrderTypeUuid", 2)).thenReturn(Collections.singletonList(order)); + List bahmniOrders = bahmniOrderService.ordersForOrderType(personUUID, Collections.singletonList(concept), 2, null, "someOrderTypeUuid", true, null); + BahmniOrder bahmniOrder = bahmniOrders.get(0); + verify(orderService).getAllOrdersForVisits(personUUID, "someOrderTypeUuid", 2); + Assert.assertEquals("otUUID", bahmniOrder.getConcept().getUuid()); + Assert.assertEquals("someOrderTypeUuid", bahmniOrder.getOrderTypeUuid()); + Assert.assertEquals("88887777-eeee-4326-bb05-c6e11fe31234", bahmniOrder.getProviderUuid()); + Assert.assertEquals("Superman", bahmniOrder.getProvider()); + Assert.assertEquals(Order.FulfillerStatus.COMPLETED, bahmniOrder.getFulfillerStatus()); + } + + private Order createOrder() { + order = new Order(); + patient = new Patient(); + patient.setId(1); + patient.setUuid(personUUID); + Person person = new Person(); + person.setNames(Collections.singleton(new PersonName("Superman","", ""))); + OrderType orderType = new OrderType(); + provider = new Provider(); + orderType.setId(1); + orderType.setUuid("someOrderTypeUuid"); + order.setOrderType(orderType); + provider.setId(2); + provider.setUuid("88887777-eeee-4326-bb05-c6e11fe31234"); + provider.setPerson(person); + order.setOrderer(provider); + order.setConcept(concept); + order.setId(1); + order.setPatient(patient); + CareSetting careSetting = new CareSetting(); + careSetting.setId(1); + order.setCareSetting(careSetting); + order.setFulfillerStatus(Order.FulfillerStatus.COMPLETED); + return order; + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramWorkflowServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramWorkflowServiceImplTest.java new file mode 100644 index 0000000000..3746ae707d --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/BahmniProgramWorkflowServiceImplTest.java @@ -0,0 +1,168 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.openmrs.ProgramAttributeType; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Program; +import org.openmrs.api.db.ProgramWorkflowDAO; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +public class BahmniProgramWorkflowServiceImplTest { + + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + + @Mock + private ProgramWorkflowDAO bahmniProgramWorkflowDAO; + + @Mock + private EpisodeService episodeService; + + @Mock + private PatientProgram patientProgram; + + private Integer sampleId = 1234; + private String sampleUuid = "a1b2c3"; + + @Before + public void before() { + bahmniProgramWorkflowService = new BahmniProgramWorkflowServiceImpl(bahmniProgramWorkflowDAO, episodeService); + } + + @Test + public void testGetAllProgramAttributeTypes() throws Exception { + bahmniProgramWorkflowService.getAllProgramAttributeTypes(); + verify(bahmniProgramWorkflowDAO).getAllProgramAttributeTypes(); + } + + @Test + public void testGetProgramAttributeType() throws Exception { + bahmniProgramWorkflowService.getProgramAttributeType(sampleId); + verify(bahmniProgramWorkflowDAO).getProgramAttributeType(sampleId); + } + + @Test + public void testGetProgramAttributeTypeByUuid() throws Exception { + bahmniProgramWorkflowService.getProgramAttributeTypeByUuid(sampleUuid); + verify(bahmniProgramWorkflowDAO).getProgramAttributeTypeByUuid(sampleUuid); + } + + @Test + public void testSaveProgramAttributeType() throws Exception { + ProgramAttributeType programAttributeType = new ProgramAttributeType(); + bahmniProgramWorkflowService.saveProgramAttributeType(programAttributeType); + verify(bahmniProgramWorkflowDAO).saveProgramAttributeType(programAttributeType); + } + + @Test + public void testPurgeProgramAttributeType() throws Exception { + ProgramAttributeType programAttributeType = new ProgramAttributeType(); + bahmniProgramWorkflowService.purgeProgramAttributeType(programAttributeType); + verify(bahmniProgramWorkflowDAO).purgeProgramAttributeType(programAttributeType); + } + + @Test + public void testGetPatientProgramAttributeByUuid() throws Exception { + bahmniProgramWorkflowService.getPatientProgramAttributeByUuid(sampleUuid); + verify(bahmniProgramWorkflowDAO).getPatientProgramAttributeByUuid(sampleUuid); + } + + @Test + public void testSavePatientProgramShouldCreateEpisode() throws Exception { + PatientProgram patientProgram = new PatientProgram(); + patientProgram.setPatient(new Patient()); + patientProgram.setProgram(new Program()); + when(bahmniProgramWorkflowDAO.savePatientProgram(patientProgram)).thenReturn(patientProgram); + + bahmniProgramWorkflowService.savePatientProgram(patientProgram); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Episode.class); + verify(episodeService).save(argumentCaptor.capture()); + verify(bahmniProgramWorkflowDAO).savePatientProgram(patientProgram); + PatientProgram savedPatientProgram = argumentCaptor.getValue().getPatientPrograms().iterator().next(); + assertThat(savedPatientProgram.getUuid(), is(equalTo(patientProgram.getUuid()))); + } + + @Test + public void testUpdatePatientProgramShouldNotCreateNewEpisode() throws Exception { + Episode episode = new Episode(); + PatientProgram patientProgram = new PatientProgram(); + patientProgram.setPatient(new Patient()); + patientProgram.setProgram(new Program()); + when(bahmniProgramWorkflowDAO.savePatientProgram(patientProgram)).thenReturn(patientProgram); + when(episodeService.getEpisodeForPatientProgram(patientProgram)).thenReturn(episode); + + bahmniProgramWorkflowService.savePatientProgram(patientProgram); + + verify(episodeService, times(0)).save(any(Episode.class)); + verify(bahmniProgramWorkflowDAO).savePatientProgram(patientProgram); + } + + @Test + public void testGetEncountersByPatientProgram() { + Episode episode = new Episode(); + String patientProgramUuid = "patientProgramUuid"; + PatientProgram patientProgram = new PatientProgram(); + patientProgram.setUuid(patientProgramUuid); + patientProgram.setPatient(new Patient()); + patientProgram.setProgram(new Program()); + + when(bahmniProgramWorkflowDAO.getPatientProgramByUuid(patientProgramUuid)).thenReturn(patientProgram); + when(episodeService.getEpisodeForPatientProgram(patientProgram)).thenReturn(episode); + + bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); + + verify(bahmniProgramWorkflowDAO).getPatientProgramByUuid(patientProgramUuid); + verify(episodeService).getEpisodeForPatientProgram(patientProgram); + } + + @Test + public void testNullEncountersByPatientProgramIfEpisodeCannotBeFound() { + String patientProgramUuid = "patientProgramUuid"; + PatientProgram patientProgram = new PatientProgram(); + patientProgram.setUuid(patientProgramUuid); + patientProgram.setPatient(new Patient()); + patientProgram.setProgram(new Program()); + + when(bahmniProgramWorkflowDAO.getPatientProgramByUuid(patientProgramUuid)).thenReturn(patientProgram); + when(episodeService.getEpisodeForPatientProgram(patientProgram)).thenReturn(null); + + bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); + + verify(bahmniProgramWorkflowDAO).getPatientProgramByUuid(patientProgramUuid); + verify(episodeService).getEpisodeForPatientProgram(patientProgram); + } + + @Test + public void shouldSetDateCompletedOfAProgramWhenItsOutcomeIsSetAndDateCompletedIsNull() { + when(patientProgram.getPatient()).thenReturn(new Patient()); + when(patientProgram.getProgram()).thenReturn(new Program()); + when(patientProgram.getOutcome()).thenReturn(new Concept()); + when(patientProgram.getDateCompleted()).thenReturn(null); + + bahmniProgramWorkflowService.savePatientProgram(patientProgram); + + verify(patientProgram, times(1)).getOutcome(); + verify(patientProgram, times(1)).setDateCompleted(any(Date.class)); + verify(patientProgram, times(2)).getDateCompleted(); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/DiseaseTemplateServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/DiseaseTemplateServiceImplIT.java new file mode 100644 index 0000000000..91ced14533 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/DiseaseTemplateServiceImplIT.java @@ -0,0 +1,204 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplate; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplateConfig; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplatesConfig; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.ObservationTemplate; +import org.bahmni.module.bahmnicore.service.DiseaseTemplateService; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class DiseaseTemplateServiceImplIT extends BaseIntegrationTest { + @Before + public void setUp() throws Exception { + executeDataSet("dispositionMetadata.xml"); + executeDataSet("obsTestData.xml"); + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("diseaseTemplate.xml"); + } + + @Autowired + private DiseaseTemplateService diseaseTemplateService; + + @Test + public void getDiseaseTemplateForObservationTemplateConcept() throws Exception { + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + List diseaseTemplateConfigList = new ArrayList<>(); + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Blood Pressure"); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + diseaseTemplatesConfig.setPatientUuid("b2a59310-58e8-11e4-8ed6-0800200c9a66"); + diseaseTemplatesConfig.setStartDate(null); + diseaseTemplatesConfig.setEndDate(null); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + DiseaseTemplate diseaseTemplate = diseaseTemplateService.diseaseTemplateFor(diseaseTemplatesConfig); + assertEquals(1, diseaseTemplate.getObservationTemplates().size()); + ObservationTemplate observationTemplate = diseaseTemplate.getObservationTemplates().get(0); + assertEquals(1, observationTemplate.getBahmniObservations().size()); + BahmniObservation obs = observationTemplate.getBahmniObservations().iterator().next(); + assertTrue(obs.getValue().equals(100.0)); + } + + @Test + public void getDiseaseTemplateIgnoresInvalidTemplateName() throws Exception { + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + List diseaseTemplateConfigList = new ArrayList<>(); + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Non existing Concept"); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + diseaseTemplatesConfig.setPatientUuid("b2a59310-58e8-11e4-8ed6-0800200c9a66"); + diseaseTemplatesConfig.setStartDate(null); + diseaseTemplatesConfig.setEndDate(null); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + DiseaseTemplate diseaseTemplate = diseaseTemplateService.diseaseTemplateFor(diseaseTemplatesConfig); + assertEquals("Non existing Concept", diseaseTemplate.getConcept().getName()); + assertEquals(0, diseaseTemplate.getObservationTemplates().size()); + } + + @Test + public void getAllDiseaseTemplateForSpecifiedObservationTemplateForDisease() throws Exception { + ArrayList showOnly = new ArrayList<>(); + showOnly.add("Breast Cancer Intake"); + + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Breast Cancer"); + diseaseTemplateConfig.setShowOnly(showOnly); + + ArrayList diseaseTemplateConfigList = new ArrayList<>(); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + diseaseTemplatesConfig.setPatientUuid("86526ed5-3c11-11de-a0ba-001e378eb67a"); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + List diseaseTemplates = diseaseTemplateService.allDiseaseTemplatesFor(diseaseTemplatesConfig); + assertEquals(1, diseaseTemplates.size()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().size()); + assertEquals("Breast Cancer Intake", diseaseTemplates.get(0).getObservationTemplates().get(0).getConcept().getName()); + } + + @Test + public void getAllDiseaseTemplateForSpecifiedConceptForDisease() throws Exception { + ArrayList showOnly = new ArrayList<>(); + showOnly.add("Receptor Status"); + + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Breast Cancer"); + diseaseTemplateConfig.setShowOnly(showOnly); + + ArrayList diseaseTemplateConfigList = new ArrayList<>(); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + diseaseTemplatesConfig.setPatientUuid("86526ed5-3c11-11de-a0ba-001e378eb67a"); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + List diseaseTemplates = diseaseTemplateService.allDiseaseTemplatesFor(diseaseTemplatesConfig); + assertEquals(1, diseaseTemplates.size()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().size()); + + assertEquals("Breast Cancer Intake", diseaseTemplates.get(0).getObservationTemplates().get(0).getConcept().getName()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().get(0).getBahmniObservations().size()); + assertEquals("Receptor Status", diseaseTemplates.get(0).getObservationTemplates().get(0).getBahmniObservations().iterator().next().getConcept().getName()); + } + + @Test + public void getAllDiseaseTemplateForSpecifiedConceptForDiseaseExistsInBothIntakeAndProgress() throws Exception { + ArrayList showOnly = new ArrayList<>(); + showOnly.add("Histopathology"); + + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Breast Cancer"); + diseaseTemplateConfig.setShowOnly(showOnly); + + ArrayList diseaseTemplateConfigList = new ArrayList<>(); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + diseaseTemplatesConfig.setPatientUuid("86526ed5-3c11-11de-a0ba-001e378eb67a"); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + List diseaseTemplates = diseaseTemplateService.allDiseaseTemplatesFor(diseaseTemplatesConfig); + assertEquals(1, diseaseTemplates.size()); + assertEquals(2, diseaseTemplates.get(0).getObservationTemplates().size()); + + assertEquals("Breast Cancer Intake", diseaseTemplates.get(0).getObservationTemplates().get(0).getConcept().getName()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().get(0).getBahmniObservations().size()); + assertEquals("Histopathology", diseaseTemplates.get(0).getObservationTemplates().get(0).getBahmniObservations().iterator().next().getConcept().getName()); + + assertEquals("Breast Cancer Progress", diseaseTemplates.get(0).getObservationTemplates().get(1).getConcept().getName()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().get(1).getBahmniObservations().size()); + assertEquals("Histopathology", diseaseTemplates.get(0).getObservationTemplates().get(1).getBahmniObservations().iterator().next().getConcept().getName()); + } + + @Test + public void getAllDiseaseTemplateShouldGetLatestAcrossAllVisitsForClassCaseIntake() throws Exception { + executeDataSet("diseaseTemplateScopeLatest.xml"); + ArrayList showOnly = new ArrayList<>(); + + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Anaemia"); + diseaseTemplateConfig.setShowOnly(showOnly); + + ArrayList diseaseTemplateConfigList = new ArrayList<>(); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + diseaseTemplatesConfig.setPatientUuid("86526ed5-3c11-11de-a0ba-001e378eb67a"); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + List diseaseTemplates = diseaseTemplateService.allDiseaseTemplatesFor(diseaseTemplatesConfig); + assertEquals(1, diseaseTemplates.size()); + assertEquals("Anaemia", diseaseTemplates.get(0).getConcept().getName()); + + assertEquals("Anaemia Intake", diseaseTemplates.get(0).getObservationTemplates().get(0).getConcept().getName()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().get(0).getBahmniObservations().size()); + BahmniObservation bahmniObservations = diseaseTemplates.get(0).getObservationTemplates().get(0).getBahmniObservations().iterator().next(); + assertEquals("Anaemia Intake", bahmniObservations.getConcept().getName()); + + assertEquals(2, bahmniObservations.getGroupMembers().size()); + Iterator groupMembersIterator = bahmniObservations.getGroupMembers().iterator(); + BahmniObservation diastolicConceptSet = groupMembersIterator.next(); + assertEquals("Diastolic", diastolicConceptSet.getConcept().getName()); + + assertEquals(1, diastolicConceptSet.getGroupMembers().size()); + assertEquals("Diastolic value", diastolicConceptSet.getGroupMembers().iterator().next().getConcept().getName()); + + assertEquals("Anaemia value", groupMembersIterator.next().getConcept().getName()); + } + + @Test + public void getAllDiseaseTemplateShouldNotFailWhenInvalidShowonlyProvided() throws Exception { + ArrayList showOnly = new ArrayList<>(); + showOnly.add("Breast Cancer Intake"); + showOnly.add("Non existing concept"); + + DiseaseTemplateConfig diseaseTemplateConfig = new DiseaseTemplateConfig(); + diseaseTemplateConfig.setTemplateName("Breast Cancer"); + diseaseTemplateConfig.setShowOnly(showOnly); + + ArrayList diseaseTemplateConfigList = new ArrayList<>(); + diseaseTemplateConfigList.add(diseaseTemplateConfig); + + DiseaseTemplatesConfig diseaseTemplatesConfig = new DiseaseTemplatesConfig(); + diseaseTemplatesConfig.setPatientUuid("86526ed5-3c11-11de-a0ba-001e378eb67a"); + diseaseTemplatesConfig.setDiseaseTemplateConfigList(diseaseTemplateConfigList); + + List diseaseTemplates = diseaseTemplateService.allDiseaseTemplatesFor(diseaseTemplatesConfig); + assertEquals(1, diseaseTemplates.size()); + assertEquals(1, diseaseTemplates.get(0).getObservationTemplates().size()); + assertEquals("Breast Cancer Intake", diseaseTemplates.get(0).getObservationTemplates().get(0).getConcept().getName()); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/EpisodeServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/EpisodeServiceImplIT.java new file mode 100644 index 0000000000..ba9d028558 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/EpisodeServiceImplIT.java @@ -0,0 +1,74 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.PatientProgram; +import org.openmrs.api.context.Context; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Set; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +public class EpisodeServiceImplIT extends BaseIntegrationTest { + @Autowired + private EpisodeService episodeService; + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + @Before + public void setUp() throws Exception { + bahmniProgramWorkflowService = Context.getService(BahmniProgramWorkflowService.class); + } + + @Test + public void shouldCreateANewEpisode() { + Episode episode = createAnEpisode(); + assertThat(episode.getId(), is(notNullValue())); + Episode savedEpisode = episodeService.get(episode.getId()); + assertThat(savedEpisode.getEncounters(), is(notNullValue())); + } + + @Test + public void shouldRetrieveEpisodeForAProgram() { + createAnEpisode(); + PatientProgram patientProgram = testPatientProgram(); + + Episode episodeForPatientProgram = episodeService.getEpisodeForPatientProgram(patientProgram); + + Set patientPrograms = episodeForPatientProgram.getPatientPrograms(); + assertThat(patientPrograms.size(), is(equalTo(1))); + assertThat(patientPrograms.iterator().next().getUuid(), is(equalTo(patientProgram.getUuid()))); + } + + @Test + public void shouldReturnNullIfPatientProgramIsNotLinkedToAnEpisode() { + Episode episodeForPatientProgram = episodeService.getEpisodeForPatientProgram(testPatientProgram()); + + assertThat(episodeForPatientProgram, is(nullValue())); + } + + @Test + public void shouldReturnNullEpisodeIfPatientProgramIsNull() { + Episode episodeForPatientProgram = episodeService.getEpisodeForPatientProgram(null); + + assertThat(episodeForPatientProgram, is(nullValue())); + } + + private Episode createAnEpisode() { + Episode episode = new Episode(); + episode.addPatientProgram(testPatientProgram()); + episodeService.save(episode); + return episode; + } + + private PatientProgram testPatientProgram() { + return bahmniProgramWorkflowService.getPatientProgram(1); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java new file mode 100644 index 0000000000..532a7434fb --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/NoteServiceImplIT.java @@ -0,0 +1,123 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.contract.drugorder.DrugOrderConfigResponse; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.hibernate.HibernateException; +import org.hibernate.PropertyValueException; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.DrugOrder; +import org.openmrs.api.APIException; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +import static org.junit.Assert.*; + +public class NoteServiceImplIT extends BaseIntegrationTest { + + @Before + public void setUp() throws Exception { + executeDataSet("notesData.xml"); + } + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void shouldCreateNewNoteOfSpecificNoteType() { + NoteService noteService = Context.getService(NoteService.class); + Note note = new Note(); + NoteType noteType = noteService.getNoteType("OT module"); + note.setNoteType(noteType); + note.setNoteText("note one"); + note.setNoteDate(new Date()); + noteService.createNote(note); + assertNotNull(note.getId()); + assertNotNull(note.getUuid()); + assertEquals(note.getNoteText(), "note one"); + assertEquals(note.getNoteType().getName(), "OT module"); + assertNotNull(note.getNoteDate()); + } + + @Test + public void shouldCreateNewNotesOfSpecificNoteType() { + NoteService noteService = Context.getService(NoteService.class); + NoteType noteType = noteService.getNoteType("OT module"); + Note note1 = new Note(); + note1.setNoteType(noteType); + note1.setNoteText("note one"); + note1.setNoteDate(new Date()); + + Note note2 = new Note(); + note2.setNoteType(noteType); + note2.setNoteText("Hello World Two"); + note2.setNoteDate(new Date()); + + Note noteObjectOne = noteService.createNote(note1); + Note noteObjectTwo = noteService.createNote(note2); + + assertNotNull(noteObjectOne); + assertEquals(noteObjectOne.getNoteText(), note1.getNoteText()); + assertEquals(noteObjectOne.getNoteType().getName(), note1.getNoteType().getName()); + assertNotNull(noteObjectOne.getNoteDate()); + + assertNotNull(noteObjectTwo); + assertEquals(noteObjectTwo.getNoteText(), note2.getNoteText()); + assertEquals(noteObjectTwo.getNoteType().getName(), note2.getNoteType().getName()); + assertNotNull(noteObjectTwo.getNoteDate()); + + } + + @Test + public void shouldGetNoteOfSpecificTypeAndDate() throws Exception { + NoteService noteService = Context.getService(NoteService.class); + NoteType noteType = new NoteType(); + noteType.setName("OT module"); + Note note = new Note(); + note.setNoteType(noteType); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + Date date = format.parse("2023-08-16 00:00:00.0"); + note.setNoteDate(date); + Note noteResponse = noteService.getNote(date,"OT module" ); + assertNotNull(noteResponse); + assertEquals(noteResponse.getNoteText(), "note one"); + assertEquals(noteResponse.getNoteType().getName(), "OT module"); + assertNotNull(noteResponse.getNoteDate()); + } + + + @Test + public void shouldThrowExceptionWhenNoteTypeIsEmpty() throws Exception { + NoteService noteService = Context.getService(NoteService.class); + Note note = new Note(); + note.setNoteText("Hello World"); + note.setNoteDate(new Date()); + expectedException.expect(HibernateException.class); + noteService.createNote(note); + } + + @Test + public void shouldExceptionWhenNoteDateIsEmpty() throws Exception { + NoteService noteService = Context.getService(NoteService.class); + Note note = new Note(); + note.setNoteText("Hello World"); + note.setNoteDate(new Date()); + expectedException.expect(HibernateException.class); + noteService.createNote(note); + + } + + +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/OrderServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/OrderServiceImplIT.java new file mode 100644 index 0000000000..df8c7e9cda --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/OrderServiceImplIT.java @@ -0,0 +1,110 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.service.OrderService; +import org.junit.Assert; +import org.junit.Test; +import org.openmrs.CareSetting; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.List; + +public class OrderServiceImplIT extends BaseIntegrationTest { + + @Autowired + private OrderService bahmniOrderService; + @Autowired + private org.openmrs.api.OrderService orderService; + @Autowired + private PatientService patientService; + + @Test + public void shouldCheckForExistenceOfConcept() throws Exception { + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + String radiologyOrderTypeUuid = "92c1bdef-72d4-49d9-8a1f-804892f66abd"; + + executeDataSet("radiologyOrderTestData.xml"); + ensureCorrectDataSetup(patientUuid, radiologyOrderTypeUuid); + + List pendingOrders = bahmniOrderService.getPendingOrders(patientUuid, radiologyOrderTypeUuid); + + Assert.assertEquals(1, pendingOrders.size()); + + Order pendingOrder = pendingOrders.get(0); + Assert.assertEquals("6d0ae386-707a-4629-9850-f15206e63ab0", pendingOrder.getUuid()); + Assert.assertEquals(patientUuid, pendingOrder.getPatient().getUuid()); + Assert.assertEquals(radiologyOrderTypeUuid, pendingOrder.getOrderType().getUuid()); + Assert.assertEquals("Radiology Order", pendingOrder.getOrderType().getName()); + } + + @Test + public void shouldGetAllVisitsWhenNumberOfVisitsIsNull() throws Exception{ + executeDataSet("drugOrdersForVisits.xml"); + String patientUuid = "86526ed5-3c11-11de-a0ba-001ed98eb67a"; + Patient patient = patientService.getPatientByUuid(patientUuid); + List visitsWithOrders = bahmniOrderService.getVisitsWithOrders(patient, "DrugOrder", true, null); + Assert.assertFalse(visitsWithOrders.isEmpty()); + Assert.assertEquals(2, visitsWithOrders.size()); + Assert.assertNotEquals((Integer)3001, visitsWithOrders.get(0).getId()); + Assert.assertNotEquals((Integer)3001, visitsWithOrders.get(1).getId()); + } + + + @Test + public void shouldGetOrdersForPatientAndOrderType() throws Exception{ + executeDataSet("patientWithOrders.xml"); + String orderTypeUuid = "bf7f3ab0-ae06-11e3-a5e2-0800200c9a66"; + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + + List allOrders = bahmniOrderService.getAllOrders(patientUuid, orderTypeUuid, null, null, null); + Assert.assertEquals(5, allOrders.size()); + Assert.assertEquals((Integer)20, allOrders.get(0).getId()); + Assert.assertEquals((Integer)19, allOrders.get(1).getId()); + Assert.assertEquals((Integer)15, allOrders.get(2).getId()); + Assert.assertEquals((Integer)16, allOrders.get(3).getId()); + Assert.assertEquals((Integer)17, allOrders.get(4).getId()); + + } + + @Test + public void shouldGetPagedOrdersForPatientAndOrderType() throws Exception{ + executeDataSet("patientWithOrders.xml"); + String orderTypeUuid = "bf7f3ab0-ae06-11e3-a5e2-0800200c9a66"; + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + + List allOrders = bahmniOrderService.getAllOrders(patientUuid, orderTypeUuid, 1, 3, null); + Assert.assertEquals(3, allOrders.size()); + Assert.assertEquals((Integer)19, allOrders.get(0).getId()); + Assert.assertEquals((Integer)15, allOrders.get(1).getId()); + Assert.assertEquals((Integer)16, allOrders.get(2).getId()); + } + + @Test + public void shouldGetOrdersForPatientAndOrderTypeAndLocationUuid() throws Exception{ + executeDataSet("patientWithOrders.xml"); + String orderTypeUuid = "131168f4-15f5-102d-96e4-000c29c2a5d7"; + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + List locationUuids = new ArrayList<>(); + locationUuids.add("8d6c993e-c2cc-11de-7921-0010c6affd0f"); + + List allOrders = bahmniOrderService.getAllOrders(patientUuid, orderTypeUuid, 1, 1,locationUuids); + + Assert.assertEquals(2, allOrders.size()); + Assert.assertEquals((Integer)26, allOrders.get(0).getId()); + } + + private void ensureCorrectDataSetup(String patientUuid, String radiologyOrderTypeUuid) { + Patient patient = patientService.getPatientByUuid(patientUuid); + OrderType orderType = orderService.getOrderTypeByUuid(radiologyOrderTypeUuid); + CareSetting careSetting = orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString()); + List allRadiologyOrdersForPatient = orderService.getOrders(patient, careSetting, orderType, true); + Assert.assertTrue("More than 1 radiology orders are setup for the patient", allRadiologyOrdersForPatient.size() > 1); + } + +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplIT.java new file mode 100644 index 0000000000..4080884f6f --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplIT.java @@ -0,0 +1,71 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.io.FileUtils; +import org.apache.xerces.impl.dv.util.Base64; +import org.bahmni.module.bahmnicore.BaseIntegrationTest; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertTrue; + +public class PatientDocumentServiceImplIT extends BaseIntegrationTest{ + + public static final String TMP_FOLDER = "/tmp"; + @Autowired + PatientDocumentServiceImpl patientDocumentService; + + + @Test + public void shouldNotCreateThumbnailForVideo() throws Exception { + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + FileUtils.writeStringToFile(new File(TMP_FOLDER + "/bahmnicore.properties"), + "bahmnicore.documents.baseDirectory=" + TMP_FOLDER); + OpenmrsUtil.setApplicationDataDirectory(TMP_FOLDER); + + BahmniCoreProperties.load(); + + byte[] allBytes = Files.readAllBytes(Paths.get("src/test/resources/SampleVideo.mkv")); + String content = Base64.encode(allBytes); + String url = patientDocumentService.saveDocument(1, "Consultation", content, "mkv", "video", "file-name"); + assertTrue(url.matches(".*1-Consultation-.*.mkv")); + String videoUrl = BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory") + "/" + url; + String thumbnailUrl = BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory") + "/" + url.split("\\.")[0] + "_thumbnail.jpg"; + assertTrue(Files.exists(Paths.get(videoUrl))); + assertFalse(Files.exists(Paths.get(thumbnailUrl))); + } + + @Test + public void shouldCreateThumbnailForVideo() throws Exception { + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + FileUtils.writeStringToFile(new File(TMP_FOLDER + "/bahmnicore.properties"), + "bahmnicore.documents.baseDirectory=" + TMP_FOLDER); + OpenmrsUtil.setApplicationDataDirectory(TMP_FOLDER); + + BahmniCoreProperties.load(); + + byte[] allBytes = Files.readAllBytes(Paths.get("src/test/resources/SampleVideo.mov")); + String content = Base64.encode(allBytes); + String url = patientDocumentService.saveDocument(1, "Consultation", content, "mov", "video", "file-name"); + assertTrue(url.matches(".*1-Consultation-.*.mov")); + String videoUrl = BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory") + "/" + url; + String thumbnailUrl = BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory") + "/" + url.split("\\.")[0] + "_thumbnail.jpg"; + assertTrue(Files.exists(Paths.get(videoUrl))); + assertTrue(Files.exists(Paths.get(thumbnailUrl))); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java new file mode 100644 index 0000000000..33dde79176 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/PatientDocumentServiceImplTest.java @@ -0,0 +1,225 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.apache.commons.io.FileUtils; +import org.apache.xerces.impl.dv.util.Base64; +import org.bahmni.module.bahmnicore.bahmniexceptions.FileTypeNotSupportedException; +import org.bahmni.module.bahmnicore.bahmniexceptions.VideoFormatNotSupportedException; +import org.bahmni.module.bahmnicore.model.VideoFormats; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.bahmni.module.bahmnicore.service.ThumbnailGenerator; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.ResponseEntity; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.verifyStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({BahmniCoreProperties.class, FileInputStream.class, FileUtils.class, ImageIO.class}) +public class PatientDocumentServiceImplTest { + + private PatientDocumentServiceImpl patientDocumentService; + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Rule + TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Mock + ThumbnailGenerator thumbnailGenerator; + + + @Test + public void shouldCreateRightDirectoryAccordingToPatientId() { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(""); + + patientDocumentService = new PatientDocumentServiceImpl(); + + String url = patientDocumentService.createFilePath(".", 280, "Radiology", "jpeg", "file-name"); + + assertFalse(url.isEmpty()); + assertTrue(url.startsWith("300/280-Radiology-")); + assertTrue(url.endsWith(".jpeg")); + + File absoluteFileDirectory = new File("./300"); + absoluteFileDirectory.delete(); + } + + @Test + public void shouldGetImageNotFoundForIfNoImageCapturedForPatientAndNoDefaultImageNotPresent() throws Exception { + final FileInputStream fileInputStreamMock = PowerMockito.mock(FileInputStream.class); + PowerMockito.whenNew(FileInputStream.class).withArguments(Matchers.anyString()).thenReturn(fileInputStreamMock); + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.images.directory")).thenReturn(""); + when(BahmniCoreProperties.getProperty("bahmnicore.images.directory.defaultImage")).thenReturn(""); + patientDocumentService = new PatientDocumentServiceImpl(); + + ResponseEntity responseEntity = patientDocumentService.retriveImage("patientUuid"); + + assertEquals(404, responseEntity.getStatusCode().value()); + } + + @Test + public void shouldThrowExceptionWhenVideoFormatIsNotSupported() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(""); + PowerMockito.mockStatic(FileUtils.class); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + expectedException.expect(VideoFormatNotSupportedException.class); + expectedException.expectMessage(String.format("The video format '%s' is not supported. Supported formats are %s", + "xyz", Arrays.toString(VideoFormats.values()))); + + patientDocumentService = new PatientDocumentServiceImpl(); + patientDocumentService.saveDocument(1, "Consultation", "videoContent", "xyz", "video", "file-name"); + } + + @Test + public void shouldSavePDF() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(""); + PowerMockito.mockStatic(FileUtils.class); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + patientDocumentService = new PatientDocumentServiceImpl(); + String url = patientDocumentService.saveDocument(1, "Consultation", "pdfContent", "pdf", "file", "file-name"); + + assertTrue(url.matches(".*1-Consultation-.*.pdf")); + } + + @Test + public void shouldSaveImage() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + PowerMockito.mockStatic(ImageIO.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(""); + BufferedImage bufferedImage = new BufferedImage(1,2, 2); + when(ImageIO.read(Matchers.any(ByteArrayInputStream.class))).thenReturn(bufferedImage); + when(ImageIO.write(eq(bufferedImage),eq("jpg"), Matchers.any(File.class))).thenReturn(true); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + patientDocumentService = new PatientDocumentServiceImpl(); + String url = patientDocumentService.saveDocument(1, "Consultation", "imageContent", "jpg", "image", "file-name"); + + assertTrue(url.matches(".*1-Consultation-.*.jpg")); + } + + @Test + public void shouldThrowExceptionWhenFileTypeIsNotSupported() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(""); + PowerMockito.mockStatic(FileUtils.class); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + expectedException.expect(FileTypeNotSupportedException.class); + expectedException.expectMessage("The file type is not supported. Supported types are image/video/pdf"); + + patientDocumentService = new PatientDocumentServiceImpl(); + patientDocumentService.saveDocument(1, "Consultation", "otherfileContent", "xyz", "csv", "file-name"); + } + + @Test + public void shouldThrowExceptionWhenImageTypeOtherThanPngJpegGif() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(""); + PowerMockito.mockStatic(FileUtils.class); + PowerMockito.mockStatic(ImageIO.class); + BufferedImage bufferedImage = new BufferedImage(1,2, 2); + when(ImageIO.read(Matchers.any(ByteArrayInputStream.class))).thenReturn(bufferedImage); + when(ImageIO.write(eq(bufferedImage),eq("bmp"), Matchers.any(File.class))).thenReturn(false); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + expectedException.expect(FileTypeNotSupportedException.class); + expectedException.expectMessage("The image format 'bmp' is not supported. Supported formats are [png, jpeg, gif]"); + + patientDocumentService = new PatientDocumentServiceImpl(); + patientDocumentService.saveDocument(1, "Consultation", "otherfileContent", "bmp", "image", "file-name"); + } + + @Test + public void shouldCreateThumbnailForVideo() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(temporaryFolder.getRoot().getAbsolutePath()); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + byte[] allBytes = Files.readAllBytes(Paths.get("src/test/resources/SampleVideo.mov")); + String content = Base64.encode(allBytes); + List thumbnailGenerators = new ArrayList<>(); + thumbnailGenerators.add(thumbnailGenerator); + + patientDocumentService = new PatientDocumentServiceImpl(); + patientDocumentService.setThumbnailGenerators(thumbnailGenerators); + when(thumbnailGenerator.isFormatSupported("mov")).thenReturn(true); + when(thumbnailGenerator.generateThumbnail(any(File.class))).thenReturn(new BufferedImage(20,20, 1)); + patientDocumentService.saveDocument(1, "Consultation", content, "mov", "video", "file-name"); + verify(thumbnailGenerator,times(1)).isFormatSupported("mov"); + verify(thumbnailGenerator,times(1)).generateThumbnail(any(File.class)); + } + + @Test + public void shouldNotCreateThumbnailForVideo() throws Exception { + PowerMockito.mockStatic(BahmniCoreProperties.class); + when(BahmniCoreProperties.getProperty("bahmnicore.documents.baseDirectory")).thenReturn(temporaryFolder.getRoot().getAbsolutePath()); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + byte[] allBytes = Files.readAllBytes(Paths.get("src/test/resources/SampleVideo.mov")); + String content = Base64.encode(allBytes); + List thumbnailGenerators = new ArrayList<>(); + thumbnailGenerators.add(thumbnailGenerator); + + patientDocumentService = new PatientDocumentServiceImpl(); + patientDocumentService.setThumbnailGenerators(thumbnailGenerators); + when(thumbnailGenerator.isFormatSupported("mkv")).thenReturn(false); + when(thumbnailGenerator.generateThumbnail(any(File.class))).thenReturn(new BufferedImage(20,20, 1)); + patientDocumentService.saveDocument(1, "Consultation", content, "mkv", "video", "file-name"); + verify(thumbnailGenerator,times(1)).isFormatSupported("mkv"); + verify(thumbnailGenerator,times(0)).generateThumbnail(any(File.class)); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java new file mode 100644 index 0000000000..a577ca7eac --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/service/impl/TsConceptSearchServiceImplTest.java @@ -0,0 +1,88 @@ +package org.bahmni.module.bahmnicore.service.impl; + +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.emrapi.concept.EmrConceptService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.*; + + +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +@PowerMockIgnore("javax.management.*") +public class TsConceptSearchServiceImplTest { + + + @Mock + BahmniDiagnosisService bahmniDiagnosisService; + @Mock + EmrConceptService emrConceptService; + @InjectMocks + TsConceptSearchServiceImpl tsConceptSearchService; + @Mock + private UserContext userContext; + @Mock + private AdministrationService administrationService; + + String searchTerm = "Malaria"; + int searchLimit = 20; + String locale = LocaleUtility.getDefaultLocale().toString(); + List locales = Collections.singletonList(LocaleUtility.getDefaultLocale()); + @Before + public void setUp() { + PowerMockito.mockStatic(Context.class); + Locale defaultLocale = new Locale("en", "GB"); + when(Context.getLocale()).thenReturn(defaultLocale); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getAllowedLocales()).thenReturn(locales); + } + + @Test + public void shouldReturnEmptyListWhenExternalTerminologyServerLookUpIsEnabled() { + when(bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded()).thenReturn(true); + List diagnosisList = tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale); + assertNotNull(diagnosisList); + assertEquals(0, diagnosisList.size()); + } + @Test + public void shouldReturnListFromEmrConceptServiceWhenExternalTerminologyServerLookUpIsNotEnabled() { + Concept malariaConcept = new Concept(); + ConceptName malariaConceptName = new ConceptName(searchTerm, LocaleUtility.getDefaultLocale()); + String malariaConceptUuid = "uuid1"; + malariaConcept.setUuid(malariaConceptUuid); + malariaConcept.setFullySpecifiedName(malariaConceptName); + malariaConcept.setPreferredName(malariaConceptName); + ConceptSearchResult conceptSearchResult = new ConceptSearchResult(searchTerm, malariaConcept, malariaConceptName); + + when(emrConceptService.conceptSearch(searchTerm, LocaleUtility.getDefaultLocale(), null, Collections.EMPTY_LIST, Collections.EMPTY_LIST, searchLimit)).thenReturn(Collections.singletonList(conceptSearchResult)); + when(bahmniDiagnosisService.isExternalTerminologyServerLookupNeeded()).thenReturn(false); + List diagnosisList = tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale); + assertNotNull(diagnosisList); + assertEquals(1, diagnosisList.size()); + assertEquals(diagnosisList.get(0).get("conceptName"), searchTerm); + assertEquals(diagnosisList.get(0).get("conceptUuid"), malariaConceptUuid); + } + +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/AddressMother.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/AddressMother.java new file mode 100644 index 0000000000..b85ff4ba12 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/AddressMother.java @@ -0,0 +1,25 @@ +package org.bahmni.module.bahmnicore.util; + +import org.openmrs.PersonAddress; +import org.openmrs.module.webservices.rest.SimpleObject; + +public class AddressMother { + public SimpleObject getSimpleObjectForAddress() { + return new SimpleObject() + .add("address1", "House No. 23") + .add("address2", "8th cross") + .add("address3", "3rd block") + .add("cityVillage", "Bengaluru") + .add("countyDistrict", "Bengaluru south") + .add("stateProvince", "Karnataka"); + } + + public PersonAddress build() { + PersonAddress personAddress = new PersonAddress(); + personAddress.setCityVillage("village"); + personAddress.setCountyDistrict("district"); + personAddress.setAddress3("tehsil"); + personAddress.setStateProvince("state"); + return personAddress; + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java new file mode 100644 index 0000000000..83b428a468 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/MiscUtilsTest.java @@ -0,0 +1,58 @@ +package org.bahmni.module.bahmnicore.util; + +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; + +import java.util.Arrays; +import java.util.Collection; + +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.mockito.Matchers.anyString; +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 MiscUtilsTest { + + @Test + public void shouldReturnConceptsWhenTheyAreAvailable() { + ConceptService conceptService = mock(ConceptService.class); + String nonExistantConceptName = "doesNotExist"; + String sampleConceptName = "sampleConcept"; + when(conceptService.getConceptByName(nonExistantConceptName)).thenReturn(null); + Concept sampleConcept = new Concept(); + when(conceptService.getConceptByName(sampleConceptName)).thenReturn(sampleConcept); + Collection concepts = MiscUtils.getConceptsForNames(Arrays.asList(sampleConceptName, nonExistantConceptName), conceptService); + assertThat(concepts.size(), is(equalTo(1))); + assertThat(concepts.iterator().next(), is(sampleConcept)); + } + + @Test + public void shouldSetUuidForObservationNotHavingUuid() { + BahmniObservation observation1 = new BahmniObservation(); + observation1.setUuid("123"); + BahmniObservation observation2 = mock(BahmniObservation.class); + Collection bahmniObservations = Arrays.asList(observation1, observation2); + + MiscUtils.setUuidsForObservations(bahmniObservations); + + assertThat(observation1.getUuid(), is("123")); + verify(observation2, times(1)).setUuid(anyString()); + } + + @Test + public void onlyDigits_shouldReturnTrueGivenStringIsAllNumericFalseOtherswise() { + + assertTrue(MiscUtils.onlyDigits("123")); + assertFalse(MiscUtils.onlyDigits("400d7e07-6de6-40ac-1186-dcce12408e71")); + + } + +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/NameMother.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/NameMother.java new file mode 100644 index 0000000000..c7b5735600 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/NameMother.java @@ -0,0 +1,32 @@ +package org.bahmni.module.bahmnicore.util; + +import org.openmrs.PersonName; +import org.openmrs.module.webservices.rest.SimpleObject; + +public class NameMother { + + private String firstName; + private String lastName; + private String middleName; + + public NameMother() { + firstName = "first"; + lastName = "last"; + middleName = "middle"; + } + + public SimpleObject getSimpleObjectForName() { + return new SimpleObject().add("givenName", firstName).add("familyName", lastName).add("middleName", middleName); + } + + public NameMother withName(String firstName, String middleName, String lastName) { + this.firstName = firstName; + this.middleName = middleName; + this.lastName = lastName; + return this; + } + + public PersonName build() { + return new PersonName(firstName, middleName, lastName); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/PatientMother.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/PatientMother.java new file mode 100644 index 0000000000..1c84b09cb3 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/PatientMother.java @@ -0,0 +1,86 @@ +package org.bahmni.module.bahmnicore.util; + +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PersonAttribute; +import org.openmrs.PersonAttributeType; +import org.openmrs.module.webservices.rest.SimpleObject; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; + +public class PatientMother { + + private String patientIdentifier; + private NameMother nameMother = new NameMother(); + private AddressMother addressMother = new AddressMother(); + private String balance; + private Date dateCreated; + + public PatientMother() { + patientIdentifier = "GAN11223344"; + } + + public PatientMother withName(String firstName, String middleName, String lastName) { + nameMother = nameMother.withName(firstName, middleName, lastName); + return this; + } + + public PatientMother withPatientIdentifier(String patientIdentifier) { + this.patientIdentifier = patientIdentifier; + return this; + } + + public PatientMother withBalance(String balance) { + this.balance = balance; + return this; + } + + public PatientMother withDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + return this; + } + + public Patient build() { + Patient patient = new Patient(); + patient.addIdentifier(new PatientIdentifier(patientIdentifier, null, null)); + patient.addName(nameMother.build()); + patient.setPersonDateCreated(this.dateCreated); + patient.setAddresses(new HashSet<>(Arrays.asList(addressMother.build()))); + PersonAttributeType personAttributeType = new PersonAttributeType(); + personAttributeType.setName("healthCenter"); + patient.setAttributes(new HashSet<>(Arrays.asList(new PersonAttribute(personAttributeType, "Ganiyari")))); + return patient; + } + + public SimpleObject buildSimpleObject() { + String dateCreatedString = dateCreated != null ? new SimpleDateFormat("dd-MM-yyyy").format(dateCreated) : ""; + SimpleObject simpleObject = new SimpleObject().add("birthdate", "01-01-2012") + .add("age", new SimpleObject().add("years", 21).add("months", 1).add("days", 3)) + .add("gender", "M") + .add("attributes", Arrays.asList(new SimpleObject() + .add("attributeType", "b3b6d540-a32e-44c7-91b3-292d97667518") + .add("value", "someCaste"))) + .add("addresses", Arrays.asList(addressMother.getSimpleObjectForAddress())) + .add("centerID", "Ganiyari") + .add("names", Arrays.asList(nameMother.getSimpleObjectForName())) + .add("dateOfRegistration", dateCreatedString) + .add("identifier", patientIdentifier); + if (balance != null) { + simpleObject.add("balance", balance); + } + + return simpleObject; + } + + public BahmniPatient buildBahmniPatient() throws ParseException { + SimpleObject simpleObject = buildSimpleObject(); + return new BahmniPatient(simpleObject); + } +} + + diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java new file mode 100644 index 0000000000..c78e550722 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/SqlQueryHelperTest.java @@ -0,0 +1,75 @@ +package org.bahmni.module.bahmnicore.util; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.api.AdministrationService; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +public class SqlQueryHelperTest { + + @Mock + private AdministrationService administrationService; + private SqlQueryHelper sqlQueryHelper; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + sqlQueryHelper = new SqlQueryHelper(); + } + + @Test + public void shouldReturnQueryParamsInOrder(){ + String queryString ="select * from encounter where date_started=${en_date_started} AND visit_id=${en_visit_id} and patient_id=${en_patient_id}"; + List paramNamesFromPlaceHolders = sqlQueryHelper.getParamNamesFromPlaceHolders(queryString); + assertEquals("en_date_started",paramNamesFromPlaceHolders.get(0)); + assertEquals("en_visit_id",paramNamesFromPlaceHolders.get(1)); + assertEquals("en_patient_id",paramNamesFromPlaceHolders.get(2)); + } + + @Test + public void shouldTransformQueryIntoPreparedStatementFormat(){ + String queryString ="select * from encounter where date_started=${en_date_started} AND visit_id=${en_visit_id} and patient_id=${en_patient_id}"; + String expectQueryString = "select * from encounter where date_started=? AND visit_id=? and patient_id=?"; + String result = sqlQueryHelper.transformIntoPreparedStatementFormat(queryString); + assertEquals(expectQueryString,result); + } + + @Test + public void shouldParseAdditionalParams(){ + String queryString ="SELECT *\n" + + "FROM person p\n" + + " INNER JOIN person_name pn ON pn.person_id = p.person_id\n" + + " INNER join (SELECT * FROM obs\n" + + " WHERE concept_id IN\n" + + " (SELECT concept_id\n" + + " FROM concept_name cn cn.name in (${testName})) as tests on tests.person_id = p.person_id"; + String additionalParams = "{\"tests\": \"'HIV (Blood)','Gram Stain (Sputum)'\"}"; + + when(administrationService.getGlobalProperty("emrapi.sqlSearch.additionalSearchHandler")).thenReturn(" cn.name = '${testName}'"); + + String expectedQueryString ="SELECT *\n" + + "FROM person p\n" + + " INNER JOIN person_name pn ON pn.person_id = p.person_id\n" + + " INNER join (SELECT * FROM obs\n" + + " WHERE concept_id IN\n" + + " (SELECT concept_id\n" + + " FROM concept_name cn cn.name in ('HIV (Blood)','Gram Stain (Sputum)')) as tests on tests.person_id = p.person_id"; + String result = sqlQueryHelper.parseAdditionalParams(additionalParams, queryString); + + assertEquals(expectedQueryString,result); + } + + @Test + public void shouldEscapeSQLInjection() { + assertEquals("0X3", SqlQueryHelper.escapeSQL("0x3", true, null)); + assertEquals("DROP sampletable\\;--", SqlQueryHelper.escapeSQL("DROP sampletable;--", true, null)); + assertEquals("admin\\'--", SqlQueryHelper.escapeSQL("admin'--", true, null)); + assertEquals("admin\\'\\\\/*", SqlQueryHelper.escapeSQL("admin'/*", true, null)); + } +} diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/VisitIdentificationHelperIT.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/VisitIdentificationHelperIT.java new file mode 100644 index 0000000000..1a60a949e9 --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/util/VisitIdentificationHelperIT.java @@ -0,0 +1,142 @@ +package org.bahmni.module.bahmnicore.util; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.LocationTag; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitIdentificationHelper; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class VisitIdentificationHelperIT extends BaseModuleWebContextSensitiveTest { + public static final String TEST_VISIT_TYPE = "TEST VISIT TYPE"; + + @Autowired + VisitService visitService; + @Autowired + BahmniVisitLocationService bahmniVisitLocationService; + @Autowired + PatientService patientService; + + VisitIdentificationHelper visitIdentificationHelper; + + @Before + public void setUp() throws Exception { + executeDataSet("visitIdentificationHelper.xml"); + + visitIdentificationHelper = new VisitIdentificationHelper(visitService, bahmniVisitLocationService); + } + + @Test + public void shouldInitializeNewVisitWhenNextVisitWithIn24Hours() throws Exception { + Patient patient = patientService.getPatient(1); + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-13 03:00:00"); + + Visit visit = visitIdentificationHelper.getVisitFor(patient, TEST_VISIT_TYPE, accessionDate, null, null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + assertEquals(8, visit.getId().intValue()); + + Date stopTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-13 06:00:00"); + assertEquals(accessionDate, visit.getStartDatetime()); + assertEquals(stopTime, visit.getStopDatetime()); + } + + @Test + public void shouldInitializeNewVisitWhenNextVisitNotWithIn24Hours() throws Exception { + Patient patient = patientService.getPatient(1); + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-18 03:00:00"); + Date stopTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-18 23:59:59"); + + Visit visit = visitIdentificationHelper.getVisitFor(patient, TEST_VISIT_TYPE, accessionDate, null, null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + + assertTrue("Setup (visitIdentificationHelper.xml) creates visit ids 1-5. New visit id should be greater than 5", visit.getId() > 5); + assertEquals(accessionDate, visit.getStartDatetime()); + assertEquals(stopTime, visit.getStopDatetime()); + } + + @Test + public void shouldInitializeNewVisitWhenNextVisitDoesNotExist() throws Exception { + Patient patient = patientService.getPatient(1); + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-21 03:00:00"); + Date stopTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-21 23:59:59"); + + Visit visit = visitIdentificationHelper.getVisitFor(patient, TEST_VISIT_TYPE, accessionDate, null,null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + + assertTrue("Setup (visitIdentificationHelper.xml) creates visit ids 1-5. New visit id should be greater than 5", visit.getId() > 5); + assertEquals(accessionDate, visit.getStartDatetime()); + assertEquals(stopTime, visit.getStopDatetime()); + } + + @Test + public void stretchEarlierVisitWhenMultipleVisitsForADate() throws Exception { + Patient patient = patientService.getPatient(1); + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-05-20 00:00:00"); + + Context.getLocationService().getLocationByUuid("9356400c-a5a2-4532-8f2b-2361b3446eb8").addTag(new LocationTag("Visit Location","Visit Location")); + Visit visit = visitIdentificationHelper.getVisitFor(patient, TEST_VISIT_TYPE, accessionDate,null,null, "9356400c-a5a2-4532-8f2b-2361b3446eb8"); + + assertNotNull(visit); + assertEquals(accessionDate, visit.getStartDatetime()); + + Date stopTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-05-20 04:00:00"); + assertEquals(stopTime, visit.getStopDatetime()); + } + + @Test + public void shouldSetVisitLocationWhileCreatingNewVisit() throws Exception { + Patient patient = patientService.getPatient(1); + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-21 03:00:00"); + + Visit visit = visitIdentificationHelper.getVisitFor(patient,TEST_VISIT_TYPE,accessionDate,null,null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + + assertEquals(visit.getLocation().getUuid(),"l38923e5-9fhb-4f20-866b-0ece24561525"); + } + + @Test + public void shouldFetchTheExistingVisitForTheVisitLocation() throws Exception { + + Patient patient = patientService.getPatient(1); + + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-13 01:00:00"); + Visit visit = visitIdentificationHelper.getVisitFor(patient,TEST_VISIT_TYPE,accessionDate,null,null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + assertNotEquals(2, visit.getId().intValue()); + assertEquals(8, visit.getId().intValue()); + } + + @Test + public void shouldCreateNewVisitIfThereIsNoExistingVisitForThatVisitLocation() throws Exception { + Patient patient = patientService.getPatient(1); + + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-02-10 10:00:00"); + Visit visit = visitIdentificationHelper.getVisitFor(patient,TEST_VISIT_TYPE,accessionDate,null,null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + int existingActiveVisitIdInAnotherLocation = 1; + String locationUuidOfNewVisitCreated = "l38923e5-9fhb-4f20-866b-0ece24561525"; + assertNotEquals(existingActiveVisitIdInAnotherLocation, visit.getId().intValue()); + assertEquals(visit.getLocation().getUuid(), locationUuidOfNewVisitCreated); + } + + @Test + public void shouldGetVisitAndUpdateLocationWhenThereIsActiveVisitWithoutLocationForPatient() throws Exception { + Patient patient = patientService.getPatient(1); + + Date accessionDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-13 00:00:00"); + Visit visit = visitIdentificationHelper.getVisitFor(patient,TEST_VISIT_TYPE,accessionDate,null,null,"l3602jn5-9fhb-4f20-866b-0ece24561525"); + int existingActiveVisitIdWithLocationNull = 9; + + assertEquals(existingActiveVisitIdWithLocationNull, visit.getId().intValue()); + assertEquals(visit.getLocation().getUuid(), "l38923e5-9fhb-4f20-866b-0ece24561525"); + } +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java new file mode 100644 index 0000000000..e81f7cb00e --- /dev/null +++ b/bahmnicore-api/src/test/java/org/bahmni/module/bahmnicore/validator/NoteValidatorTest.java @@ -0,0 +1,101 @@ +package org.bahmni.module.bahmnicore.validator; + +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.dao.NoteDao; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.model.NoteType; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.MockitoAnnotations.initMocks; + +public class NoteValidatorTest { + + @InjectMocks + private NoteValidator validator; + @Mock + private NoteDao noteDao; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void ensureNoteTypeIsNotNull() { + initMocks(this); + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteRequest.setNoteTypeName(null); + noteRequest.setNoteText("Note Text"); + noteRequest.setNoteDate(new Date()); + Note note = new Note(); + note.setId(1); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note.noteType.required".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } + + @Test + public void ensureNoteDateIsNotNull() { + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteRequest.setNoteTypeName("OT module"); + noteRequest.setNoteText("Note Text"); + noteRequest.setNoteDate(null); + Note note = new Note(); + note.setId(1); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note.noteDate.required".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } + + @Test + public void ensureNoteTextIsNotNull() { + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteRequest.setNoteTypeName("OT module"); + noteRequest.setNoteDate(new Date()); + noteRequest.setNoteText(null); + Note note = new Note(); + note.setId(1); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note.noteText.required".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } + + @Test + public void ensureNoteDoesntExistForSameNoteDateAndNoteType() throws ParseException { + NoteRequestResponse noteRequest = new NoteRequestResponse(); + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + Date noteDate1 = format.parse("2023-08-16 00:00:00.0"); + noteRequest.setNoteTypeName("OT module"); + noteRequest.setNoteDate(noteDate1); + noteRequest.setNoteText("Some text"); + + Note note = new Note(); + NoteType noteType = new NoteType(); + Date existingNote = format.parse("2023-08-16 00:00:00.0"); + noteType.setName("OT module"); + note.setId(1); + note.setNoteDate(existingNote); + note.setNoteType(noteType); + Mockito.when(noteDao.getNote(any(Date.class), any(String.class))).thenReturn(note); + validator.validate(noteRequest, noteRequestErrors); + assertEquals(true, "Note entry exist for noteType and noteDate".matches(noteRequestErrors.getAllErrors().get(0).getCode().toString())); + } +} diff --git a/bahmnicore-api/src/test/resources/SampleVideo.mkv b/bahmnicore-api/src/test/resources/SampleVideo.mkv new file mode 100644 index 0000000000..196d300902 Binary files /dev/null and b/bahmnicore-api/src/test/resources/SampleVideo.mkv differ diff --git a/bahmnicore-api/src/test/resources/SampleVideo.mov b/bahmnicore-api/src/test/resources/SampleVideo.mov new file mode 100644 index 0000000000..196d300902 Binary files /dev/null and b/bahmnicore-api/src/test/resources/SampleVideo.mov differ diff --git a/bahmnicore-api/src/test/resources/TestingApplicationContext.xml b/bahmnicore-api/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..b7b812da9a --- /dev/null +++ b/bahmnicore-api/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,35 @@ + + + + + + + + classpath:hibernate.cfg.xml + classpath:test-hibernate.cfg.xml + + + + + + + + org.openmrs + + + + + AddressHierarchyEntry.hbm.xml + AddressHierarchyLevel.hbm.xml + + + + + + diff --git a/bahmnicore-api/src/test/resources/apiTestData.xml b/bahmnicore-api/src/test/resources/apiTestData.xml new file mode 100644 index 0000000000..7fc41381aa --- /dev/null +++ b/bahmnicore-api/src/test/resources/apiTestData.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/complexObsData.xml b/bahmnicore-api/src/test/resources/complexObsData.xml new file mode 100644 index 0000000000..573fc1d9c8 --- /dev/null +++ b/bahmnicore-api/src/test/resources/complexObsData.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/conceptSetApiData.xml b/bahmnicore-api/src/test/resources/conceptSetApiData.xml new file mode 100644 index 0000000000..9f20ad1433 --- /dev/null +++ b/bahmnicore-api/src/test/resources/conceptSetApiData.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/diagnosisMetadata.xml b/bahmnicore-api/src/test/resources/diagnosisMetadata.xml new file mode 100644 index 0000000000..f5c16e31c2 --- /dev/null +++ b/bahmnicore-api/src/test/resources/diagnosisMetadata.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/diseaseTemplateScopeLatest.xml b/bahmnicore-api/src/test/resources/diseaseTemplateScopeLatest.xml new file mode 100644 index 0000000000..24dfd007e6 --- /dev/null +++ b/bahmnicore-api/src/test/resources/diseaseTemplateScopeLatest.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/dispositionMetadata.xml b/bahmnicore-api/src/test/resources/dispositionMetadata.xml new file mode 100644 index 0000000000..edf8d0328f --- /dev/null +++ b/bahmnicore-api/src/test/resources/dispositionMetadata.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/drugOrdersForVisits.xml b/bahmnicore-api/src/test/resources/drugOrdersForVisits.xml new file mode 100644 index 0000000000..4366bc1f45 --- /dev/null +++ b/bahmnicore-api/src/test/resources/drugOrdersForVisits.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-api/src/test/resources/drugOrdersTestData.xml b/bahmnicore-api/src/test/resources/drugOrdersTestData.xml new file mode 100644 index 0000000000..1ba4c3c42d --- /dev/null +++ b/bahmnicore-api/src/test/resources/drugOrdersTestData.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/notesData.xml b/bahmnicore-api/src/test/resources/notesData.xml new file mode 100644 index 0000000000..35d6812658 --- /dev/null +++ b/bahmnicore-api/src/test/resources/notesData.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/bahmnicore-api/src/test/resources/obsTestData.xml b/bahmnicore-api/src/test/resources/obsTestData.xml new file mode 100644 index 0000000000..cc67c8368c --- /dev/null +++ b/bahmnicore-api/src/test/resources/obsTestData.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/observationsTestData.xml b/bahmnicore-api/src/test/resources/observationsTestData.xml new file mode 100644 index 0000000000..270cffcc74 --- /dev/null +++ b/bahmnicore-api/src/test/resources/observationsTestData.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/orderSet.xml b/bahmnicore-api/src/test/resources/orderSet.xml new file mode 100644 index 0000000000..0808ecb029 --- /dev/null +++ b/bahmnicore-api/src/test/resources/orderSet.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/patientProgramTestData.xml b/bahmnicore-api/src/test/resources/patientProgramTestData.xml new file mode 100644 index 0000000000..949eb832de --- /dev/null +++ b/bahmnicore-api/src/test/resources/patientProgramTestData.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-api/src/test/resources/patientWithDiscontinuedOrders.xml b/bahmnicore-api/src/test/resources/patientWithDiscontinuedOrders.xml new file mode 100644 index 0000000000..43c48ba1ed --- /dev/null +++ b/bahmnicore-api/src/test/resources/patientWithDiscontinuedOrders.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/patientWithOrderRevisedInDifferentEncounter.xml b/bahmnicore-api/src/test/resources/patientWithOrderRevisedInDifferentEncounter.xml new file mode 100644 index 0000000000..5c80d665e3 --- /dev/null +++ b/bahmnicore-api/src/test/resources/patientWithOrderRevisedInDifferentEncounter.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/patientWithOrderRevisedInSameEncounter.xml b/bahmnicore-api/src/test/resources/patientWithOrderRevisedInSameEncounter.xml new file mode 100644 index 0000000000..1f3ae0bee3 --- /dev/null +++ b/bahmnicore-api/src/test/resources/patientWithOrderRevisedInSameEncounter.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/patientWithOrders.xml b/bahmnicore-api/src/test/resources/patientWithOrders.xml new file mode 100644 index 0000000000..1d931690e0 --- /dev/null +++ b/bahmnicore-api/src/test/resources/patientWithOrders.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/patientWithStoppedOrders.xml b/bahmnicore-api/src/test/resources/patientWithStoppedOrders.xml new file mode 100644 index 0000000000..190f24f568 --- /dev/null +++ b/bahmnicore-api/src/test/resources/patientWithStoppedOrders.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/programAttributesDataSet.xml b/bahmnicore-api/src/test/resources/programAttributesDataSet.xml new file mode 100644 index 0000000000..e59ffd1fa5 --- /dev/null +++ b/bahmnicore-api/src/test/resources/programAttributesDataSet.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/bahmnicore-api/src/test/resources/radiologyOrderTestData.xml b/bahmnicore-api/src/test/resources/radiologyOrderTestData.xml new file mode 100644 index 0000000000..d022528c00 --- /dev/null +++ b/bahmnicore-api/src/test/resources/radiologyOrderTestData.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/sampleCodedConcept.xml b/bahmnicore-api/src/test/resources/sampleCodedConcept.xml new file mode 100644 index 0000000000..f8fbe93afe --- /dev/null +++ b/bahmnicore-api/src/test/resources/sampleCodedConcept.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/templates.json b/bahmnicore-api/src/test/resources/templates.json new file mode 100644 index 0000000000..ab430c48ba --- /dev/null +++ b/bahmnicore-api/src/test/resources/templates.json @@ -0,0 +1,25 @@ +{ + "orderTemplates": [{ + "name": "Cancer Regimen, CAF", + "drugOrders": [ + {"drug": {"name": "DNS", "form": "Injection"}, "dosingInstructions": {"dose": 1000.0, "doseUnits": "ml", "route": "Intravenous", "frequency": "Immediately", "quantity": 2.0, "quantityUnits": "Unit(s)"}, "duration": 4, "durationUnits": "Hour(s)", "additionalInstructions": null} + + ] + }, + { + "name": "Breast Cancer - AC", + "drugOrders": [ + {"drug": {"name": "DNS", "form": "Injection"}, "dosingInstructions": {"dose": 1000.0, "doseUnits": "ml", "route": "Intravenous", "frequency": "Immediately", "quantity": 2.0, "quantityUnits": "Unit(s)"}, "duration": 4, "durationUnits": "Hour(s)", "additionalInstructions": null}, + {"drug": {"name": "Dexamethasone 8mg/2ml", "form": "Injection"}, "dosingInstructions": {"dose": 2.0, "doseUnits": "ml", "route": "Intravenous", "frequency": "Immediately", "quantity": 1.0, "quantityUnits": "Unit(s)"}, "duration": 1, "durationUnits": "Minute(s)", "additionalInstructions": null}, + {"drug": {"name": "Ondansetron 8mg/4ml", "form": "Injection"}, "dosingInstructions": {"dose": 2.0, "doseUnits": "ml", "route": "Intravenous", "frequency": "Immediately", "quantity": 1.0, "quantityUnits": "Unit(s)"}, "duration": 1, "durationUnits": "Minute(s)", "additionalInstructions": null}, + {"drug": {"name": "Cyclophosphamide 500mg", "form": "Injection"}, "dosingInstructions": {"doseUnits": "mg", "route": "Intravenous", "frequency": "Immediately", "quantityUnits": "Unit(s)"}, "duration": 4, "durationUnits": "Hour(s)", "additionalInstructions": "with Dextrox 5% (Injection)"}, + {"drug": {"name": "Doxorubicin Hydrochloride 50mg", "form": "Injection"}, "dosingInstructions": {"doseUnits": "mg", "route": "Intravenous", "frequency": "Immediately", "quantityUnits": "Unit(s)"}, "duration": 4, "durationUnits": "Hour(s)", "additionalInstructions": "with Dextrox 5% (Injection)"}, + {"drug": {"name": "Dextrox 5%", "form": "Injection"}, "dosingInstructions": {"dose": 500.0, "doseUnits": "ml", "route": "Intravenous", "frequency": "Immediately", "quantity": 0, "quantityUnits": "Unit(s)"}, "duration": 1, "durationUnits": "Day(s)", "additionalInstructions": "diluent"}, + {"drug": {"name": "Ondan Setron 4mg", "form": "Tablet(s)"}, "dosingInstructions": {"route": "Oral", "doseUnits": "Tablet(s)", "quantity": 6, "quantityUnits": "Tablet(s)", "administrationInstructions": "{\"instructions\":\"As directed\",\"morningDose\":1,\"afternoonDose\":0,\"eveningDose\":1}"}, "durationUnits": "Day(s)", "duration": 3}, + {"drug": {"name": "Chlorpromazine 50mg", "form": "Tablet(s)"}, "dosingInstructions": {"route": "Oral", "doseUnits": "Tablet(s)", "quantity": 10, "quantityUnits": "Tablet(s)", "administrationInstructions": "{\"instructions\":\"As directed\",\"morningDose\":0.5,\"afternoonDose\":0,\"eveningDose\":0.5}"}, "durationUnits": "Day(s)", "duration": 10 }, + {"drug": {"name": "B-Complex", "form": "Tablet"}, "dosingInstructions": {"dose": 1, "doseUnits": "Tablet(s)", "route": "Oral", "frequency": "Once a day", "quantity": 30, "quantityUnits": "Tablet(s)"}, "duration": 1, "durationUnits": "Month(s)", "additionalInstructions": null}, + {"drug": {"name": "Ferrous Sulphate with Folic Acid Large", "form": "Tablet"}, "dosingInstructions": {"dose": 1, "doseUnits": "Tablet(s)", "route": "Oral", "frequency": "Once a day", "quantity": 30, "quantityUnits": "Tablet(s)"}, "duration": 1, "durationUnits": "Month(s)", "additionalInstructions": null} + ] + } + ] +} \ No newline at end of file diff --git a/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml b/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml new file mode 100644 index 0000000000..f37c2985b0 --- /dev/null +++ b/bahmnicore-api/src/test/resources/test-hibernate.cfg.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/visitAttributeDataSet.xml b/bahmnicore-api/src/test/resources/visitAttributeDataSet.xml new file mode 100644 index 0000000000..9a3a3bf17d --- /dev/null +++ b/bahmnicore-api/src/test/resources/visitAttributeDataSet.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/bahmnicore-api/src/test/resources/visitIdentificationHelper.xml b/bahmnicore-api/src/test/resources/visitIdentificationHelper.xml new file mode 100644 index 0000000000..d80d130748 --- /dev/null +++ b/bahmnicore-api/src/test/resources/visitIdentificationHelper.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-api/src/test/resources/visitTestData.xml b/bahmnicore-api/src/test/resources/visitTestData.xml new file mode 100644 index 0000000000..56de4070e8 --- /dev/null +++ b/bahmnicore-api/src/test/resources/visitTestData.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/pom.xml b/bahmnicore-omod/pom.xml new file mode 100644 index 0000000000..d987a02bc7 --- /dev/null +++ b/bahmnicore-omod/pom.xml @@ -0,0 +1,535 @@ + + 4.0.0 + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + bahmnicore-omod + jar + Bahmni EMR Core OMOD + + + bahmnicore + ${project.name} + ${project.version} + ${project.groupId}.${MODULE_ID} + + ${basedir}/.rubygems + ${basedir}/.rubygems + 3.3.1 + 5.13.0 + + + + + org.bahmni.module + episodes-api + ${episodes.version} + provided + + + org.bahmni.module + mail-appender + ${bahmniJavaUtilsVersion} + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + + + org.bahmni.module + idgen-webservices-omod + ${idgenWebServicesVersion} + provided + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.bahmni.module + communication-api + + + org.bahmni.module + bahmnicore-api + ${project.parent.version} + + + javax.persistence + persistence-api + + + + + org.bahmni.module + admin + ${project.parent.version} + + + org.bahmni.module + common + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + file-uploader + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + bahmni-migrator + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + bahmni-commons-api + ${bahmniCommons.version} + jar + provided + + + org.bahmni.module + bahmnicore-api + ${project.parent.version} + test-jar + test + + + org.openmrs.api + openmrs-api + jar + + + org.openmrs.web + openmrs-web + jar + + + org.ict4h.openmrs + openmrs-atomfeed-api + ${openmrsAtomfeedVersion} + test + + + org.openmrs.api + openmrs-api + test-jar + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + org.openmrs.test + openmrs-test + pom + test + + + + org.openmrs.module + reporting-api + ${reportingModuleVersion} + test + + + org.openmrs.module + calculation-api + ${calculationModuleVersion} + test + + + org.openmrs.module + serialization.xstream-api-2.0 + ${serializationXstreamModuleVersion} + test + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + tests + test + + + org.openmrs.module + providermanagement-api + ${providermanagementVersion} + test + + + org.openmrs.module + appframework-api + test + + + + + org.openmrs.module + webservices.rest-omod + provided + + + org.openmrs.module + webservices.rest-omod-common + provided + + + org.openmrs.module + idgen-api + provided + + + javax.servlet + javax.servlet-api + + + joda-time + joda-time + 2.0 + + + org.bahmni.module + bahmni-emr-api + ${project.version} + + + org.bahmni.module + bahmni-emr-api + test-jar + test + ${project.version} + + + org.bahmni.module + reference-data-api + ${project.parent.version} + provided + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test-jar + test + + + org.openmrs.module + addresshierarchy-api + ${addressHierarchyVersion} + provided + + + org.openmrs.module + addresshierarchy-omod + ${addressHierarchyVersion} + provided + + + org.openmrs.module + legacyui-omod + + + org.bahmni.module + bahmnicore-ui + ${project.version} + + + org.bahmni.module + bahmni-mapping + + + org.openmrs.module + uiframework-api + ${uiframeworkVersion} + provided + + + org.openmrs.module + bacteriology-omod + ${bacteriology.version} + test + + + org.openmrs.module + bacteriology-api + ${bacteriology.version} + provided + + + org.bahmni.module + rulesengine-api + ${rulesEngineVersion} + provided + + + org.openmrs.module + bedmanagement-api + ${bedManagementVersion} + provided + + + junit + junit + test + + + com.google.code.gson + gson + 2.3.1 + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + test + + + org.bahmni.module + auditlog-api + provided + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + org.projectlombok + lombok + + + + + ${project.artifactId}-${project.version} + + + src/main/resources + true + + + src/main/webapp + false + + resources + + web/module + + + src/main/webapp + false + + resources + + web/module + + + + + src/test/resources + true + + + + + + maven-resources-plugin + + true + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.openmrs.maven.plugins + + + maven-openmrs-plugin + + + [1.0.1,) + + + + initialize-module + + + + + + + + + + + org.apache.maven.plugins + + + maven-dependency-plugin + + + [2.4,) + + + + unpack-dependencies + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.16 + + + BRANCH + COVEREDRATIO + 0.14 + + + + + + + + + + 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 + + + + Fetch SASS sources from uicommons + + unpack + + generate-resources + + + + org.openmrs.module + uicommons-scss + 1.6 + zip + true + src/main/compass/sass-external + + + + + + + + exec-maven-plugin + org.codehaus.mojo + + + Running compass for bahmnicore css + generate-resources + + exec + + + bash + ${basedir}/scripts/run-compass.sh ${basedir}/src/main/compass + + + + + + + diff --git a/bahmnicore-omod/scripts/run-compass.sh b/bahmnicore-omod/scripts/run-compass.sh new file mode 100644 index 0000000000..173ebf6c99 --- /dev/null +++ b/bahmnicore-omod/scripts/run-compass.sh @@ -0,0 +1 @@ +compass compile $1 diff --git a/bahmnicore-omod/src/main/compass/config.rb b/bahmnicore-omod/src/main/compass/config.rb new file mode 100644 index 0000000000..86294a832a --- /dev/null +++ b/bahmnicore-omod/src/main/compass/config.rb @@ -0,0 +1,26 @@ +# Require any additional compass plugins here. + +# Set this to the root of your project when deployed: +Encoding.default_external = "utf-8" +http_path = "/" +css_dir = "../webapp/resources/styles" +sass_dir = "sass" +images_dir = "images" +javascripts_dir = "javascripts" +add_import_path "sass-external/uicommons-scss" + +# You can select your preferred output style here (can be overridden via the command line): +# output_style = :expanded or :nested or :compact or :compressed + +# To enable relative paths to assets via compass helper functions. Uncomment: +# relative_assets = true + +# To disable debugging comments that display the original location of your selectors. Uncomment: +# line_comments = false + + +# If you prefer the indented syntax, you might want to regenerate this +# project again passing --syntax sass, or you can uncomment this: +# preferred_syntax = :sass +# and then run: +# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass diff --git a/bahmnicore-omod/src/main/compass/sass/bahmnicore.scss b/bahmnicore-omod/src/main/compass/sass/bahmnicore.scss new file mode 100644 index 0000000000..652600f3b5 --- /dev/null +++ b/bahmnicore-omod/src/main/compass/sass/bahmnicore.scss @@ -0,0 +1,4 @@ +@charset "UTF-8"; +@import "variables"; +$fontPath: "../../uicommons/fonts"; +@import "reference"; diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/filter/CacheHeadersFilter.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/filter/CacheHeadersFilter.java new file mode 100644 index 0000000000..14cd1017c9 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/filter/CacheHeadersFilter.java @@ -0,0 +1,69 @@ +/** + * 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.bahmni.module.bahmnicore.web.filter; + +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.api.context.Context; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; + +/** + * Filter intended for all /ws/rest/* calls to sets Expires headers + * based on global property bahmni.cacheHeadersFilter.expiresDuration + */ +public class CacheHeadersFilter implements Filter { + + protected final Log log = LogFactory.getLog(getClass()); + + @Override + public void init(FilterConfig arg0) throws ServletException { + log.debug("Initializing CacheHeadersFilter"); + } + + @Override + public void destroy() { + log.debug("Destroying CacheHeadersFilter"); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, + ServletException { + + chain.doFilter(request, response); + + if (response instanceof HttpServletResponse) { + HttpServletResponse httpResponse = (HttpServletResponse) response; + HttpServletRequest httpRequest = (HttpServletRequest) request; + if ("GET".equals(httpRequest.getMethod()) && httpResponse.getStatus() == 200) { + int expiresDuration = NumberUtils.toInt(Context.getAdministrationService().getGlobalProperty("bahmni.cacheHeadersFilter.expiresDuration"), 0); + log.debug(String.format("Setting expires header with duration %s", expiresDuration)); + httpResponse.setDateHeader("Expires", DateUtils.addMinutes(new Date(), expiresDuration).getTime()); + } + } + } +} + + diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/filter/LocaleFilter.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/filter/LocaleFilter.java new file mode 100644 index 0000000000..213963a5a6 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/filter/LocaleFilter.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.web.filter; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.util.OpenmrsConstants; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +public class LocaleFilter implements Filter { + + protected final Log log = LogFactory.getLog(getClass()); + + @Override + public void init(FilterConfig arg0) throws ServletException { + log.debug("Initializing LocaleFilter"); + } + + @Override + public void destroy() { + log.debug("Destroying LocaleFilter"); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + String locale = request.getParameter("locale"); + User user = Context.getAuthenticatedUser(); + if(!StringUtils.isEmpty(locale) && user != null) { + user.setUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE, locale); + } + + chain.doFilter(request, response); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/InvalidInputException.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/InvalidInputException.java new file mode 100644 index 0000000000..64e34b22f7 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/InvalidInputException.java @@ -0,0 +1,30 @@ +/** + * 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.bahmni.module.bahmnicore.web.v1_0; + +import org.openmrs.api.APIException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Incorrect or incomplete data passed.") +public class InvalidInputException extends APIException { + + public InvalidInputException(String message) { + super(message); + } + + public InvalidInputException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java new file mode 100644 index 0000000000..cb53511c5a --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolver.java @@ -0,0 +1,21 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import org.openmrs.api.APIException; +import org.openmrs.util.LocaleUtility; + +import java.util.Locale; + +public class LocaleResolver { + + public static Locale identifyLocale(String locale) { + if (locale != null && !locale.isEmpty()) { + Locale searchLocale = LocaleUtility.fromSpecification(locale); + if (searchLocale.getLanguage().isEmpty()) { + throw new APIException("Invalid locale: " + locale); + } + return searchLocale; + } else { + return LocaleUtility.getDefaultLocale(); + } + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/MvcConfiguration.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/MvcConfiguration.java new file mode 100644 index 0000000000..20413958fe --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/MvcConfiguration.java @@ -0,0 +1,9 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@EnableWebMvc +@ControllerAdvice +public class MvcConfiguration { +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/VisitClosedException.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/VisitClosedException.java new file mode 100644 index 0000000000..ad72948809 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/VisitClosedException.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import org.openmrs.api.APIException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Visit for this patient is closed. You cannot do an 'Undo Discharge' for the patient.") +public class VisitClosedException extends APIException { + public VisitClosedException(String message){ + super(message); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/contract/BahmniConceptAnswer.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/contract/BahmniConceptAnswer.java new file mode 100644 index 0000000000..e4a59f7ea0 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/contract/BahmniConceptAnswer.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.web.v1_0.contract; + +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.Drug; + +public class BahmniConceptAnswer { + private Drug drug; + private Concept concept; + + public static BahmniConceptAnswer create(ConceptAnswer answer) { + BahmniConceptAnswer bahmniConceptAnswer = new BahmniConceptAnswer(); + if(answer.getAnswerDrug() != null){ + bahmniConceptAnswer.setDrug(answer.getAnswerDrug()); + } + else{ + bahmniConceptAnswer.setConcept(answer.getAnswerConcept()); + } + return bahmniConceptAnswer; + } + + public Drug getDrug() { + return drug; + } + + public void setDrug(Drug drug) { + this.drug = drug; + } + + public Concept getConcept() { + return concept; + } + + public void setConcept(Concept concept) { + this.concept = concept; + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/contract/BahmniMailContent.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/contract/BahmniMailContent.java new file mode 100644 index 0000000000..486223cab4 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/contract/BahmniMailContent.java @@ -0,0 +1,13 @@ +package org.bahmni.module.bahmnicore.web.v1_0.contract; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.bahmni.module.communication.model.MailContent; + +@Getter +@Setter +@AllArgsConstructor +public class BahmniMailContent extends MailContent { + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/AdminExportController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/AdminExportController.java new file mode 100644 index 0000000000..a3240a0d28 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/AdminExportController.java @@ -0,0 +1,62 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.fileexport.FileExporter; +import org.bahmni.module.admin.csv.exporter.ConceptSetExporter; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.admin.csv.models.ConceptRows; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +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.stereotype.Controller; +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 javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +@Controller +public class AdminExportController extends BaseRestController { + private final String baseUrl = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/admin/export"; + private static Logger logger = LogManager.getLogger(AdminExportController.class); + + @Autowired + private ConceptSetExporter conceptSetExporter; + + @RequestMapping(value = baseUrl + "/conceptset", method = RequestMethod.GET) + @ResponseBody + public void export(HttpServletResponse response, @RequestParam(value = "conceptName", required = true) String conceptName) { + try { + ConceptRows conceptRows = conceptSetExporter.exportConcepts(conceptName); + createZipFile(response, conceptRows); + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment; filename=\"" + conceptName + ".zip" + "\""); + response.flushBuffer(); + } catch (Exception e) { + logger.error("Could not upload file", e); + } + } + + private void createZipFile(HttpServletResponse response, ConceptRows conceptRows) throws java.io.IOException { + FileExporter conceptFileExporter = new FileExporter<>(); + FileExporter conceptSetFileExporter = new FileExporter<>(); + ByteArrayOutputStream conceptOutputStream = new ByteArrayOutputStream(); + ByteArrayOutputStream conceptSetOutputStream = new ByteArrayOutputStream(); + conceptOutputStream = conceptFileExporter.exportCSV(conceptRows.getConceptRows(), conceptOutputStream); + conceptSetOutputStream = conceptSetFileExporter.exportCSV(conceptRows.getConceptSetRows(), conceptSetOutputStream); + ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream()); + zipOutputStream.putNextEntry(new ZipEntry("concepts.csv")); + zipOutputStream.write(conceptOutputStream.toByteArray()); + zipOutputStream.closeEntry(); + zipOutputStream.putNextEntry(new ZipEntry("concept_sets.csv")); + zipOutputStream.write(conceptSetOutputStream.toByteArray()); + zipOutputStream.closeEntry(); + zipOutputStream.close(); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/AdminImportController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/AdminImportController.java new file mode 100644 index 0000000000..23ce11efc0 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/AdminImportController.java @@ -0,0 +1,381 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.common.config.registration.service.RegistrationPageReaderService; +import org.bahmni.common.config.registration.service.RegistrationPageService; +import org.bahmni.common.config.registration.service.impl.RegistrationPageReaderServiceImpl; +import org.bahmni.common.config.registration.service.impl.RegistrationPageServiceImpl; +import org.bahmni.common.db.JDBCConnectionProvider; +import org.bahmni.csv.CSVFile; +import org.bahmni.csv.EntityPersister; +import org.bahmni.fileimport.FileImporter; +import org.bahmni.fileimport.ImportStatus; +import org.bahmni.fileimport.dao.ImportStatusDao; +import org.bahmni.module.admin.csv.models.ConceptRow; +import org.bahmni.module.admin.csv.models.ConceptSetRow; +import org.bahmni.module.admin.csv.models.DrugRow; +import org.bahmni.module.admin.csv.models.LabResultsRow; +import org.bahmni.module.admin.csv.models.MultipleEncounterRow; +import org.bahmni.module.admin.csv.models.PatientProgramRow; +import org.bahmni.module.admin.csv.models.PatientRow; +import org.bahmni.module.admin.csv.models.FormerConceptReferenceRow; +import org.bahmni.module.admin.csv.models.ReferenceTermRow; +import org.bahmni.module.admin.csv.models.RelationshipRow; +import org.bahmni.module.admin.csv.persister.ConceptPersister; +import org.bahmni.module.admin.csv.persister.ConceptReferenceTermPersister; +import org.bahmni.module.admin.csv.persister.ConceptSetPersister; +import org.bahmni.module.admin.csv.persister.DatabasePersister; +import org.bahmni.module.admin.csv.persister.DrugPersister; +import org.bahmni.module.admin.csv.persister.EncounterPersister; +import org.bahmni.module.admin.csv.persister.LabResultPersister; +import org.bahmni.module.admin.csv.persister.PatientPersister; +import org.bahmni.module.admin.csv.persister.PatientProgramPersister; +import org.bahmni.module.admin.csv.persister.ReferenceTermPersister; +import org.bahmni.module.admin.csv.persister.RelationshipPersister; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.SessionImpl; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +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.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +@Controller +public class AdminImportController extends BaseRestController { + private final String baseUrl = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/admin/upload"; + private static Logger logger = LogManager.getLogger(AdminImportController.class); + + public static final String YYYY_MM_DD_HH_MM_SS = "_yyyy-MM-dd_HH:mm:ss"; + private static final int DEFAULT_NUMBER_OF_DAYS = 30; + private static final String HTTPS_PROTOCOL = "https"; + private static final String HTTP_PROTOCOL = "http"; + + public static final String PARENT_DIRECTORY_UPLOADED_FILES_CONFIG = "uploaded.files.directory"; + public static final String SHOULD_MATCH_EXACT_PATIENT_ID_CONFIG = "uploaded.should.matchExactPatientId"; + + private static final boolean DEFAULT_SHOULD_MATCH_EXACT_PATIENT_ID = false; + public static final String ENCOUNTER_FILES_DIRECTORY = "encounter/"; + private static final String PROGRAM_FILES_DIRECTORY = "program/"; + private static final String CONCEPT_FILES_DIRECTORY = "concept/"; + private static final String LAB_RESULTS_DIRECTORY = "labResults/"; + private static final String DRUG_FILES_DIRECTORY = "drug/"; + private static final String CONCEPT_SET_FILES_DIRECTORY = "conceptset/"; + private static final String PATIENT_FILES_DIRECTORY = "patient/"; + private static final String REFERENCETERM_FILES_DIRECTORY = "referenceterms/"; + private static final String RELATIONSHIP_FILES_DIRECTORY = "relationship/"; + + @Autowired + private EncounterPersister encounterPersister; + + @Autowired + private PatientProgramPersister patientProgramPersister; + + @Autowired + private DrugPersister drugPersister; + + @Autowired + private ConceptPersister conceptPersister; + + @Autowired + private LabResultPersister labResultPersister; + + @Autowired + private ConceptSetPersister conceptSetPersister; + + @Autowired + private PatientPersister patientPersister; + + @Autowired + private ReferenceTermPersister referenceTermPersister; + + @Autowired + private RelationshipPersister relationshipPersister; + + @Autowired + private ConceptReferenceTermPersister conceptReferenceTermPersister; + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + + private RegistrationPageReaderService registrationPageReaderService = new RegistrationPageReaderServiceImpl(); + + private RegistrationPageService registrationPageService = new RegistrationPageServiceImpl(registrationPageReaderService); + + @RequestMapping(value = baseUrl + "/patient", method = RequestMethod.POST) + @ResponseBody + public boolean upload(@RequestParam(value = "file") MultipartFile file, @RequestHeader("Host") String host, @RequestHeader(value = "Origin", required = false) String origin, @RequestHeader(value = "Referer", required = false) String referer) throws IOException { + try { + registrationPageService.setProtocol(getProtocol(origin, referer)); + registrationPageService.setHost(host); + patientPersister.init(Context.getUserContext()); + return importCsv(PATIENT_FILES_DIRECTORY, file, patientPersister, 1, true, PatientRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/encounter", method = RequestMethod.POST) + @ResponseBody + public boolean upload(@CookieValue(value="bahmni.user.location", required=true) String loginCookie, + @RequestParam(value = "file") MultipartFile file, + @RequestParam(value = "patientMatchingAlgorithm", required = false) String patientMatchingAlgorithm) throws IOException { + + return uploadEncounter(loginCookie, file, patientMatchingAlgorithm, false); + } + + @RequestMapping(value = baseUrl + "/form2encounter", method = RequestMethod.POST) + @ResponseBody + public boolean uploadForm2EncountersWithValidations(@CookieValue(value="bahmni.user.location", required=true) String loginCookie, + @RequestParam(value = "file") MultipartFile file, + @RequestParam(value = "patientMatchingAlgorithm", required = false) String patientMatchingAlgorithm) throws IOException { + + return uploadEncounter(loginCookie, file, patientMatchingAlgorithm, true); + } + + private boolean uploadEncounter(@CookieValue(value = "bahmni.user.location", required = true) String loginCookie, @RequestParam("file") MultipartFile file, @RequestParam(value = "patientMatchingAlgorithm", required = false) String patientMatchingAlgorithm, boolean performForm2Validations) throws IOException { + try { + String configuredExactPatientIdMatch = administrationService.getGlobalProperty(SHOULD_MATCH_EXACT_PATIENT_ID_CONFIG); + JsonParser jsonParser = new JsonParser(); + JsonObject jsonObject = (JsonObject) jsonParser.parse(loginCookie); + String loginUuid = jsonObject.get("uuid").getAsString(); + boolean shouldMatchExactPatientId = DEFAULT_SHOULD_MATCH_EXACT_PATIENT_ID; + if (configuredExactPatientIdMatch != null) + shouldMatchExactPatientId = Boolean.parseBoolean(configuredExactPatientIdMatch); + + encounterPersister.init(Context.getUserContext(), patientMatchingAlgorithm, shouldMatchExactPatientId, loginUuid, performForm2Validations); + return importCsv(ENCOUNTER_FILES_DIRECTORY, file, encounterPersister, 5, true, MultipleEncounterRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/referenceterms", method = RequestMethod.POST) + @ResponseBody + public boolean uploadReferenceTerms(@RequestParam(value = "file") MultipartFile file) throws IOException { + try { + referenceTermPersister.init(Context.getUserContext()); + return importCsv(REFERENCETERM_FILES_DIRECTORY, file, referenceTermPersister, 1, true, ReferenceTermRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + + } + + @RequestMapping(value = baseUrl + "/referenceterms/new", method = RequestMethod.POST) + @ResponseBody + public boolean uploadReferenceTermsForExistingConcepts(@RequestParam(value = "file") MultipartFile file) throws IOException { + try { + conceptReferenceTermPersister.init(Context.getUserContext()); + return importCsv(REFERENCETERM_FILES_DIRECTORY, file, new DatabasePersister<>(conceptReferenceTermPersister), 1, false, FormerConceptReferenceRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + + } + + @RequestMapping(value = baseUrl + "/program", method = RequestMethod.POST) + @ResponseBody + public boolean uploadProgram(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "patientMatchingAlgorithm", required = false) String patientMatchingAlgorithm) throws IOException { + try { + patientProgramPersister.init(Context.getUserContext(), patientMatchingAlgorithm); + return importCsv(PROGRAM_FILES_DIRECTORY, file, patientProgramPersister, 1, true, PatientProgramRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/drug", method = RequestMethod.POST) + @ResponseBody + public boolean uploadDrug(@RequestParam(value = "file") MultipartFile file) throws IOException { + try { + return importCsv(DRUG_FILES_DIRECTORY, file, new DatabasePersister<>(drugPersister), 1, false, DrugRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/concept", method = RequestMethod.POST) + @ResponseBody + public boolean uploadConcept(@RequestParam(value = "file") MultipartFile file) throws IOException { + try { + return importCsv(CONCEPT_FILES_DIRECTORY, file, new DatabasePersister<>(conceptPersister), 1, false, ConceptRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/labResults", method = RequestMethod.POST) + @ResponseBody + public boolean uploadLabResults(@CookieValue(value="bahmni.user.location", required=true) String loginCookie, @RequestParam(value = "file") MultipartFile file, @RequestParam(value = "patientMatchingAlgorithm", required = false) String patientMatchingAlgorithm) throws IOException { + try { + JsonParser jsonParser = new JsonParser(); + JsonObject jsonObject = (JsonObject) jsonParser.parse(loginCookie); + String loginUuid = jsonObject.get("uuid").getAsString(); + labResultPersister.init(Context.getUserContext(), patientMatchingAlgorithm, true,loginUuid); + return importCsv(LAB_RESULTS_DIRECTORY, file, new DatabasePersister<>(labResultPersister), 1, false, LabResultsRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/conceptset", method = RequestMethod.POST) + @ResponseBody + public boolean uploadConceptSet(@RequestParam(value = "file") MultipartFile file) throws IOException { + try { + return importCsv(CONCEPT_SET_FILES_DIRECTORY, file, new DatabasePersister<>(conceptSetPersister), 1, false, ConceptSetRow.class); + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/relationship", method = RequestMethod.POST) + @ResponseBody + public boolean uploadRelationship(@RequestParam(value = "file") MultipartFile file) throws IOException { + try { + relationshipPersister.init(Context.getUserContext()); + return importCsv(RELATIONSHIP_FILES_DIRECTORY, file, new DatabasePersister<>(relationshipPersister), 1, false, RelationshipRow.class); + + } catch (Throwable e) { + logger.error("Could not upload file", e); + throw e; + } + } + + @RequestMapping(value = baseUrl + "/status", method = RequestMethod.GET) + @ResponseBody + public List status(@RequestParam(required = false) Integer numberOfDays) throws SQLException { + numberOfDays = numberOfDays == null ? DEFAULT_NUMBER_OF_DAYS : numberOfDays; + ImportStatusDao importStatusDao = new ImportStatusDao(new CurrentThreadConnectionProvider()); + return importStatusDao.getImportStatusFromDate(DateUtils.addDays(new Date(), (numberOfDays * -1))); + } + + private boolean importCsv(String filesDirectory, MultipartFile file, EntityPersister persister, + int numberOfThreads, boolean skipValidation, Class entityClass) throws IOException { + String uploadedOriginalFileName = ((CommonsMultipartFile) file).getFileItem().getName(); + String systemId = Context.getUserContext().getAuthenticatedUser().getSystemId(); + CSVFile persistedUploadedFile = writeToLocalFile(file, filesDirectory); + return new FileImporter().importCSV(uploadedOriginalFileName, persistedUploadedFile, + persister, entityClass, new NewMRSConnectionProvider(), systemId, skipValidation, numberOfThreads); + } + + + private CSVFile writeToLocalFile(MultipartFile file, String filesDirectory) throws IOException { + String uploadedOriginalFileName = ((CommonsMultipartFile) file).getFileItem().getName(); + byte[] fileBytes = file.getBytes(); + CSVFile uploadedFile = getFile(uploadedOriginalFileName, filesDirectory); + FileOutputStream uploadedFileStream = null; + try { + uploadedFileStream = new FileOutputStream(new File(uploadedFile.getAbsolutePath())); + uploadedFileStream.write(fileBytes); + uploadedFileStream.flush(); + } catch (Throwable e) { + logger.error(e); + throw e; + // TODO : handle errors for end users. Give some good message back to users. + } finally { + if (uploadedFileStream != null) { + try { + uploadedFileStream.close(); + } catch (IOException e) { + logger.error(e); + } + } + return uploadedFile; + } + } + + private CSVFile getFile(String fileName, String filesDirectory) throws IOException { + String fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf(".")); + String fileExtension = fileName.substring(fileName.lastIndexOf(".")); + + String timestampForFile = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).format(new Date()); + + String uploadDirectory = administrationService.getGlobalProperty(PARENT_DIRECTORY_UPLOADED_FILES_CONFIG); + String relativePath = filesDirectory + fileNameWithoutExtension + timestampForFile + fileExtension; + FileUtils.forceMkdir(new File(uploadDirectory, filesDirectory)); + return new CSVFile(uploadDirectory, relativePath); + } + + private class NewMRSConnectionProvider implements JDBCConnectionProvider { + private ThreadLocal session = new ThreadLocal<>(); + + @Override + public Connection getConnection() { + if (session.get() == null || !session.get().isOpen()) + session.set(sessionFactory.openSession()); + + return ((SessionImpl)session.get()).connection(); + } + + @Override + public void closeConnection() { + session.get().close(); + } + } + + private class CurrentThreadConnectionProvider implements JDBCConnectionProvider { + @Override + public Connection getConnection() { + //TODO: ensure that only connection associated with current thread current transaction is given + SessionImplementor session = (SessionImpl) sessionFactory.getCurrentSession(); + return session.connection(); + } + + @Override + public void closeConnection() { + + } + } + + private String getProtocol(String origin, String referer) { + if(origin != null) { + if(origin.startsWith(HTTPS_PROTOCOL)) + return HTTPS_PROTOCOL; + else + return HTTP_PROTOCOL; + } + + if(referer != null) { + if(referer.startsWith(HTTPS_PROTOCOL)) + return HTTPS_PROTOCOL; + else + return HTTP_PROTOCOL; + } + + return HTTPS_PROTOCOL; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyController.java new file mode 100644 index 0000000000..e7f924648b --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyController.java @@ -0,0 +1,51 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; +import org.bahmni.module.bahmnicore.service.BahmniAddressHierarchyService; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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 java.util.Arrays; +import java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1) +public class BahmniAddressHierarchyController { + + private BahmniAddressHierarchyService bahmniAddressHierarchyService; + + @Autowired + public BahmniAddressHierarchyController(BahmniAddressHierarchyService bahmniAddressHierarchyService) { + this.bahmniAddressHierarchyService = bahmniAddressHierarchyService; + } + + @RequestMapping(method = RequestMethod.GET, value = "/addressHierarchy/{uuid}") + @ResponseBody + public BahmniAddressHierarchyEntry get(@PathVariable("uuid") String uuid) { + if (uuid == null) { + return null; + } + BahmniAddressHierarchyEntry bahmniAddressHierarchyEntry = null; + List addressHierarchyEntries = bahmniAddressHierarchyService.getAddressHierarchyEntriesByUuid(Arrays.asList(uuid)); + if(!addressHierarchyEntries.isEmpty()){ + bahmniAddressHierarchyEntry = addressHierarchyEntries.get(0); + } + return bahmniAddressHierarchyEntry; + } + + @RequestMapping(method = RequestMethod.GET, value = "/addressHierarchy") + @ResponseBody + public List getAddressHierarchyEntriesByUuid(@RequestParam(value = "uuids", required = true) List uuids) { + if (uuids.isEmpty()) { + return null; + } + return bahmniAddressHierarchyService.getAddressHierarchyEntriesByUuid(uuids); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java new file mode 100644 index 0000000000..81c578e638 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchController.java @@ -0,0 +1,35 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.TsConceptSearchService; +import org.bahmni.module.bahmnicore.service.impl.TsConceptSearchServiceImpl; +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.stereotype.Controller; +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 static org.springframework.web.bind.annotation.ValueConstants.DEFAULT_NONE; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmni/terminologies") +public class BahmniConceptSearchController extends BaseRestController { + + private TsConceptSearchService tsConceptSearchService; + + + + @Autowired + public BahmniConceptSearchController(TsConceptSearchService tsConceptSearchService) { + this.tsConceptSearchService = tsConceptSearchService; + } + + @RequestMapping(method = RequestMethod.GET, value = "concepts") + @ResponseBody + public Object search(@RequestParam("term") String query, @RequestParam Integer limit, + @RequestParam(required = false, defaultValue = DEFAULT_NONE) String locale) throws Exception { + return tsConceptSearchService.getConcepts(query, limit, locale); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConfigController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConfigController.java new file mode 100644 index 0000000000..4e455b9f3a --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConfigController.java @@ -0,0 +1,137 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.lang3.StringEscapeUtils; +import org.bahmni.module.admin.config.model.BahmniConfig; +import org.bahmni.module.admin.config.service.BahmniConfigService; +import org.bahmni.module.bahmnicore.contract.drugorder.DrugOrderConfigResponse; +import org.bahmni.module.bahmnicore.contract.encounter.data.ConceptData; +import org.bahmni.module.bahmnicore.contract.encounter.response.EncounterConfigResponse; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicommons.api.contract.patient.response.PatientConfigResponse; +import org.bahmni.module.bahmnicommons.api.service.BahmniPatientService; +import org.openmrs.Concept; +import org.openmrs.EncounterType; +import org.openmrs.OrderType; +import org.openmrs.VisitType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderService; +import org.openmrs.api.VisitService; +import org.openmrs.module.rulesengine.engine.RulesEngine; +import org.openmrs.module.rulesengine.engine.RulesEngineImpl; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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 java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/config") +public class BahmniConfigController extends BaseRestController { + + @Autowired + private BahmniConfigService bahmniConfigService; + @Autowired + private BahmniPatientService bahmniPatientService; + @Autowired + private BahmniDrugOrderService drugOrderService; + @Autowired + private VisitService visitService; + @Autowired + private EncounterService encounterService; + @Autowired + private ConceptService conceptService; + @Autowired + private OrderService orderService; + + private RulesEngine rulesEngine = new RulesEngineImpl(); + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public BahmniConfig get(@RequestParam("appName") String appName, @RequestParam(value = "configName") String configName) { + return bahmniConfigService.get(appName, configName); + } + + @RequestMapping(method = RequestMethod.GET, value = "/{appName}/{configName:.+}") + @ResponseBody + public String getConfig(@PathVariable("appName") String appName, @PathVariable(value = "configName") String configName) { + return StringEscapeUtils.unescapeJava(bahmniConfigService.get(appName, configName).getConfig()); + } + + @RequestMapping(method = RequestMethod.GET, value = "all") + @ResponseBody + public List getAll(@RequestParam("appName") String appName) { + return bahmniConfigService.getAllFor(appName); + } + + @RequestMapping(method = RequestMethod.GET, value = "allApps") + @ResponseBody + public List getAll() { + return bahmniConfigService.getAll(); + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public BahmniConfig insert(@RequestBody BahmniConfig bahmniConfig) { + return bahmniConfigService.save(bahmniConfig); + } + + @RequestMapping(method = RequestMethod.PUT) + @ResponseBody + public BahmniConfig update(@RequestBody BahmniConfig bahmniConfig) { + return bahmniConfigService.update(bahmniConfig); + } + + @RequestMapping(method = RequestMethod.GET, value = "/patient") + @ResponseBody + public PatientConfigResponse getPatientConfig() { + return bahmniPatientService.getConfig(); + } + + @RequestMapping(method = RequestMethod.GET, value = "/drugOrders") + @ResponseBody + public DrugOrderConfigResponse getDrugOrderConfig() throws Exception { + String[] ruleNames=rulesEngine.getRuleNames(); + DrugOrderConfigResponse configResponse=drugOrderService.getConfig(); + configResponse.setDosingRules(ruleNames); + return configResponse; + } + + @RequestMapping(method = RequestMethod.GET, value = "/bahmniencounter") + @ResponseBody + public EncounterConfigResponse getConfig(@RequestParam("callerContext")String callerContext) { + EncounterConfigResponse encounterConfigResponse = new EncounterConfigResponse(); + List visitTypes = visitService.getAllVisitTypes(); + for (VisitType visitType : visitTypes) { + if (!visitType.isRetired()) { + encounterConfigResponse.addVisitType(visitType.getName(), visitType.getUuid()); + } + } + List allEncounterTypes = encounterService.getAllEncounterTypes(false); + for (EncounterType encounterType : allEncounterTypes) { + encounterConfigResponse.addEncounterType(encounterType.getName(), encounterType.getUuid()); + } + Concept conceptSetConcept = conceptService.getConcept(callerContext); + if (conceptSetConcept != null) { + List conceptsByConceptSet = conceptService.getConceptsByConceptSet(conceptSetConcept); + for (Concept concept : conceptsByConceptSet) { + ConceptData conceptData = new ConceptData(concept.getUuid(), concept.getName().getName()); + encounterConfigResponse.addConcept(concept.getName().getName(), conceptData); + } + } + List orderTypes = orderService.getOrderTypes(true); + for (OrderType orderType : orderTypes) { + encounterConfigResponse.addOrderType(orderType.getName(), orderType.getUuid()); + } + return encounterConfigResponse; + } + + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDiagnosisController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDiagnosisController.java new file mode 100644 index 0000000000..5eeec7f5a7 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDiagnosisController.java @@ -0,0 +1,39 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +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.stereotype.Controller; +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 java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/diagnosis") +public class BahmniDiagnosisController extends BaseRestController { + + @Autowired + private BahmniDiagnosisService bahmniDiagnosisService; + + @RequestMapping(method = RequestMethod.GET, value = "search") + @ResponseBody + public List search(@RequestParam("patientUuid") String patientUuid, @RequestParam(value = "fromDate", required = false) String date, @RequestParam(value = "visitUuid", required = false) String visitUuid) throws Exception { + if (visitUuid != null) { + return bahmniDiagnosisService.getBahmniDiagnosisByPatientAndVisit(patientUuid, visitUuid); + } else { + return bahmniDiagnosisService.getBahmniDiagnosisByPatientAndDate(patientUuid, date); + } + } + + @RequestMapping(method = RequestMethod.GET, value = "delete") + @ResponseBody + public boolean delete(@RequestParam(value = "obsUuid", required = true) String obsUuid) throws Exception { + bahmniDiagnosisService.delete(obsUuid); + return true; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDischargeController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDischargeController.java new file mode 100644 index 0000000000..91180a302b --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDischargeController.java @@ -0,0 +1,34 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.bedmanagement.service.BedManagementService; +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.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/discharge") +public class BahmniDischargeController extends BaseRestController { + + @Autowired + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + @Transactional + public BahmniEncounterTransaction discharge(@RequestBody BahmniEncounterTransaction bahmniEncounterTransaction) { + Patient patientByUuid = Context.getPatientService().getPatientByUuid(bahmniEncounterTransaction.getPatientUuid()); + BedManagementService bedManagementService = (BedManagementService) (Context.getModuleOpenmrsServices(BedManagementService.class.getName()).get(0)); + bedManagementService.unAssignPatientFromBed(patientByUuid); + return bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDiseaseSummaryController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDiseaseSummaryController.java new file mode 100644 index 0000000000..50ab94698f --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDiseaseSummaryController.java @@ -0,0 +1,59 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.util.BahmniDateUtil; +import org.bahmni.module.bahmnicoreui.constant.DiseaseSummaryConstants; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.service.BahmniDiseaseSummaryService; +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.stereotype.Controller; +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 java.text.ParseException; +import java.util.Date; +import java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/diseaseSummaryData") +public class BahmniDiseaseSummaryController extends BaseRestController { + + @Autowired + private BahmniDiseaseSummaryService bahmniDiseaseSummaryService; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public DiseaseSummaryData getDiseaseSummaryData(@RequestParam(value = "patientUuid") String patientUuid, + @RequestParam(value = "visit",required = false) String visitUuid, + @RequestParam(value = "numberOfVisits",required = false) Integer numberOfVisits, + @RequestParam(value = "initialCount",required = false) Integer initialCount, + @RequestParam(value = "latestCount",required = false) Integer latestCount, + @RequestParam(value = "obsConcepts",required = false) List obsConcepts, + @RequestParam(value = "drugConcepts",required = false) List drugConcepts, + @RequestParam(value = "labConcepts",required = false) List labConcepts, + @RequestParam(value = "groupBy", defaultValue = DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS, required = false) String groupBy, + @RequestParam(value = "startDate",required = false) String startDateStr, + @RequestParam(value = "endDate",required = false) String endDateStr) throws ParseException { + + Date startDate = BahmniDateUtil.convertToDate(startDateStr, BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate(endDateStr, BahmniDateUtil.DateFormatType.UTC); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(numberOfVisits); + diseaseDataParams.setInitialCount(initialCount); + diseaseDataParams.setLatestCount(latestCount); + diseaseDataParams.setVisitUuid(visitUuid); + diseaseDataParams.setObsConcepts(obsConcepts); + diseaseDataParams.setLabConcepts(labConcepts); + diseaseDataParams.setDrugConcepts(drugConcepts); + diseaseDataParams.setGroupBy(groupBy); + diseaseDataParams.setStartDate(startDate); + diseaseDataParams.setEndDate(endDate); + return bahmniDiseaseSummaryService.getDiseaseSummary(patientUuid,diseaseDataParams); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDispositionController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDispositionController.java new file mode 100644 index 0000000000..d208c28c27 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDispositionController.java @@ -0,0 +1,72 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; +import org.openmrs.module.bahmniemrapi.disposition.service.BahmniDispositionService; +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.stereotype.Controller; +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 java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/disposition") +public class BahmniDispositionController extends BaseRestController { + + @Autowired + private BahmniDispositionService bahmniDispositionService; + + @Autowired + private VisitDao visitDao; + + @Autowired + private PatientService patientService; + + @RequestMapping(method = RequestMethod.GET, value = "visit") + @ResponseBody + public List getDispositionByVisitUuid(@RequestParam(value = "visitUuid") String visitUuid) { + return bahmniDispositionService.getDispositionByVisitUuid(visitUuid); + } + + @RequestMapping(method = RequestMethod.GET, value = "visitWithLocale") + @ResponseBody + public List getDispositionByVisitUuid(@RequestParam(value = "visitUuid") String visitUuid, @RequestParam(value = "locale") String locale) { + return bahmniDispositionService.getDispositionByVisitUuid(visitUuid , new Locale(locale)); + } + + @RequestMapping(method = RequestMethod.GET, value = "patient") + @ResponseBody + public List getDispositionByPatientUuid(@RequestParam(value = "patientUuid") String patientUuid, @RequestParam(value = "numberOfVisits") int numberOfVisits){ + Patient patient = patientService.getPatientByUuid(patientUuid); + + if(patient == null){ + return new ArrayList<>(); + } + + List visits = visitDao.getVisitsByPatient(patient,numberOfVisits); + return bahmniDispositionService.getDispositionByVisits(visits); + } + @RequestMapping(method = RequestMethod.GET, value = "patientWithLocale") + @ResponseBody + public List getDispositionByPatientUuid(@RequestParam(value = "patientUuid") String patientUuid, @RequestParam(value = "numberOfVisits") int numberOfVisits, @RequestParam(value = "locale") String locale){ + Patient patient = patientService.getPatientByUuid(patientUuid); + + if(patient == null){ + return new ArrayList<>(); + } + + List visits = visitDao.getVisitsByPatient(patient,numberOfVisits); + return bahmniDispositionService.getDispositionByVisits(visits, new Locale(locale)); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java new file mode 100644 index 0000000000..156f4b4d50 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderController.java @@ -0,0 +1,226 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.velocity.exception.ResourceNotFoundException; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.util.BahmniDateUtil; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniOrderAttribute; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniDrugOrderMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Controller +public class BahmniDrugOrderController extends BaseRestController { + + private final String baseUrl = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/drugOrders"; + @Autowired + private BahmniDrugOrderService drugOrderService; + + @Autowired + private BahmniObsService bahmniObsService; + + @Autowired + private ConceptService conceptService; + + private static Logger logger = LogManager.getLogger(BahmniDrugOrderController.class); + + private BahmniDrugOrderMapper bahmniDrugOrderMapper; + + public BahmniDrugOrderController(BahmniDrugOrderService drugOrderService) { + this.drugOrderService = drugOrderService; + this.bahmniDrugOrderMapper = new BahmniDrugOrderMapper(); + } + public BahmniDrugOrderController() { + this.bahmniDrugOrderMapper = new BahmniDrugOrderMapper(); + } + + + //TODO: Active orders are available in OMRS 1.10.x. Consider moving once we upgrade OpenMRS. + @RequestMapping(value = baseUrl + "/active", method = RequestMethod.GET) + @ResponseBody + public List getActiveDrugOrders(@RequestParam(value = "patientUuid") String patientUuid, + @RequestParam(value = "startDate", required = false) String startDateStr, + @RequestParam(value = "endDate", required = false) String endDateStr) throws ParseException { + logger.info("Retrieving active drug orders for patient with uuid {}", patientUuid); + Date startDate = BahmniDateUtil.convertToDate(startDateStr, BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate(endDateStr, BahmniDateUtil.DateFormatType.UTC); + return getActiveOrders(patientUuid, startDate, endDate); + } + + @RequestMapping(value = baseUrl + "/prescribedAndActive", method = RequestMethod.GET) + @ResponseBody + public Map> getVisitWisePrescribedAndOtherActiveOrders( + @RequestParam(value = "patientUuid") String patientUuid, + @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, + @RequestParam(value = "getOtherActive", required = false) Boolean getOtherActive, + @RequestParam(value = "visitUuids", required = false) List visitUuids, + @RequestParam(value = "startDate", required = false) String startDateStr, + @RequestParam(value = "endDate", required = false) String endDateStr, + @RequestParam(value = "getEffectiveOrdersOnly", required = false) Boolean getEffectiveOrdersOnly) throws ParseException { + + Map> visitWiseOrders = new HashMap<>(); + Date startDate = BahmniDateUtil.convertToDate(startDateStr, BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate(endDateStr, BahmniDateUtil.DateFormatType.UTC); + + List prescribedOrders = getPrescribedOrders(visitUuids, patientUuid, true, numberOfVisits, startDate, endDate, Boolean.TRUE.equals(getEffectiveOrdersOnly)); + visitWiseOrders.put("visitDrugOrders", prescribedOrders); + + if (Boolean.TRUE.equals(getOtherActive)) { + List activeDrugOrders = getActiveOrders(patientUuid, null, null); + activeDrugOrders.removeAll(prescribedOrders); + visitWiseOrders.put("Other Active DrugOrders", activeDrugOrders); + } + + return visitWiseOrders; + } + + @RequestMapping(value = baseUrl, method = RequestMethod.GET) + @ResponseBody + public List getPrescribedDrugOrders(@RequestParam(value = "patientUuid") String patientUuid, + @RequestParam(value = "includeActiveVisit", required = false) Boolean includeActiveVisit, + @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, + @RequestParam(value = "startDate", required = false) String startDateStr, + @RequestParam(value = "endDate", required = false) String endDateStr ) throws ParseException { + + Date startDate = BahmniDateUtil.convertToDate(startDateStr, BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate(endDateStr, BahmniDateUtil.DateFormatType.UTC); + + + return getPrescribedOrders(null, patientUuid, includeActiveVisit, numberOfVisits, startDate, endDate, false); + } + + + @RequestMapping(value = baseUrl + "/drugOrderDetails", method = RequestMethod.GET) + @ResponseBody + public List getDrugOrderDetails(@RequestParam(value = "patientUuid") String patientUuid, + @RequestParam(value = "isActive", required = false) Boolean isActive, + @RequestParam(value = "includeConceptSet", required = false) String drugConceptSetNameToBeFiltered, + @RequestParam(value = "excludeConceptSet", required = false) String drugConceptSetNameToBeExcluded, + @RequestParam(value = "patientProgramUuid", required = false) String patientProgramUuid) throws ParseException { + Set drugConceptsToBeFiltered = getDrugConcepts(drugConceptSetNameToBeFiltered); + Set drugConceptsToBeExcluded = getDrugConcepts(drugConceptSetNameToBeExcluded); + return drugOrderService.getDrugOrders(patientUuid, isActive, drugConceptsToBeFiltered, drugConceptsToBeExcluded, patientProgramUuid); + } + + @RequestMapping(value = baseUrl + "/{orderId}", method = RequestMethod.GET) + @ResponseBody + public BahmniDrugOrder getDrugOrderByOrderId(@PathVariable String orderId) { + DrugOrder drugOrder = drugOrderService.getDrugOrderByOrderId(orderId); + Map discontinuedDrugOrderMap = drugOrderService.getDiscontinuedDrugOrders(Collections.singletonList(drugOrder)); + if (drugOrder == null) { + throw new ResourceNotFoundException("Drug order not found with orderId: " + orderId); + } + return bahmniDrugOrderMapper.mapToResponse(drugOrder, discontinuedDrugOrderMap); + } + + Set getDrugConcepts(String drugConceptSetName){ + if(drugConceptSetName == null) return null; + Set drugConcepts = new HashSet<>(); + Concept concept = conceptService.getConceptByName(drugConceptSetName); + if(concept == null) return null; + populateDrugConcepts(concept, drugConcepts); + return drugConcepts; + } + + private void populateDrugConcepts(Concept concept, Set drugConcepts) { + if (concept.isSet()) { + for (Concept conceptSetMember : concept.getSetMembers()) { + populateDrugConcepts(conceptSetMember, drugConcepts); + } + } else { + drugConcepts.add(concept); + } + } + + private Collection getOrdAttributeConcepts() { + Concept orderAttribute = conceptService.getConceptByName(BahmniOrderAttribute.ORDER_ATTRIBUTES_CONCEPT_SET_NAME); + return orderAttribute == null ? Collections.EMPTY_LIST : orderAttribute.getSetMembers(); + } + + private List getActiveOrders(String patientUuid, Date startDate, Date endDate) { + List activeDrugOrders = drugOrderService.getActiveDrugOrders(patientUuid, startDate, endDate); + logger.info("{} active drug orders found", activeDrugOrders.size()); + return getBahmniDrugOrders(patientUuid,activeDrugOrders); + } + + private List getPrescribedOrders(List visitUuids, String patientUuid, Boolean includeActiveVisit, Integer numberOfVisits, Date startDate, Date endDate, Boolean getEffectiveOrdersOnly) { + List prescribedDrugOrders = drugOrderService.getPrescribedDrugOrders(visitUuids, patientUuid, includeActiveVisit, numberOfVisits, startDate, endDate, getEffectiveOrdersOnly); + logger.info("prescribed drug orders found {}", prescribedDrugOrders.size()); + return getBahmniDrugOrders(patientUuid, prescribedDrugOrders); + } + + private List getBahmniDrugOrders(String patientUuid, List drugOrders) { + Map drugOrderMap = drugOrderService.getDiscontinuedDrugOrders(drugOrders); + try { + Collection orderAttributeObs = bahmniObsService.observationsFor(patientUuid, getOrdAttributeConcepts(), null, null, false, null, null, null); + List bahmniDrugOrders = bahmniDrugOrderMapper.mapToResponse(drugOrders, orderAttributeObs, drugOrderMap , null); + return sortDrugOrdersAccordingToTheirSortWeight(bahmniDrugOrders); + } catch (IOException e) { + logger.error("Could not parse drug order", e); + throw new RuntimeException("Could not parse drug order", e); + } + } + + private List sortDrugOrdersAccordingToTheirSortWeight(List bahmniDrugOrders) { + Map> bahmniDrugOrderMap = groupDrugOrdersAccordingToOrderSet(bahmniDrugOrders); + List sortDrugOrders = new ArrayList<>(); + for (String key : bahmniDrugOrderMap.keySet()) { + if(key == null) { + continue; + } + List bahmniDrugOrder = bahmniDrugOrderMap.get(key); + Collections.sort(bahmniDrugOrder, new Comparator() { + @Override + public int compare(BahmniDrugOrder o1, BahmniDrugOrder o2) { + return o1.getSortWeight().compareTo(o2.getSortWeight()); + } + }); + } + + for (String s : bahmniDrugOrderMap.keySet()) { + sortDrugOrders.addAll(bahmniDrugOrderMap.get(s)); + } + return sortDrugOrders; + } + + private Map> groupDrugOrdersAccordingToOrderSet(List bahmniDrugOrders) { + Map> groupedDrugOrders = new LinkedHashMap<>(); + + for (BahmniDrugOrder bahmniDrugOrder: bahmniDrugOrders) { + String orderSetUuid = null == bahmniDrugOrder.getOrderGroup() ? null : bahmniDrugOrder.getOrderGroup().getOrderSet().getUuid(); + + if(!groupedDrugOrders.containsKey(orderSetUuid)){ + groupedDrugOrders.put(orderSetUuid, new ArrayList()); + } + + groupedDrugOrders.get(orderSetUuid).add(bahmniDrugOrder); + } + + return groupedDrugOrders; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java new file mode 100644 index 0000000000..b79abf3ab9 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterController.java @@ -0,0 +1,117 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.bahmni.module.bahmnicore.web.v1_0.VisitClosedException; +import org.openmrs.Encounter; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderEntryException; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.BahmniEncounterTransactionMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.emrapi.encounter.EmrEncounterService; +import org.openmrs.module.emrapi.encounter.EncounterTransactionMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +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.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import static org.bahmni.module.bahmnicore.util.MiscUtils.setUuidsForObservations; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/bahmniencounter") +public class BahmniEncounterController extends BaseRestController { + private EncounterService encounterService; + private EmrEncounterService emrEncounterService; + private EncounterTransactionMapper encounterTransactionMapper; + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + private BahmniEncounterTransactionMapper bahmniEncounterTransactionMapper; + private static Logger logger = LogManager.getLogger(BahmniEncounterController.class); + + public BahmniEncounterController() { + } + + @Autowired + public BahmniEncounterController(EncounterService encounterService, + EmrEncounterService emrEncounterService, EncounterTransactionMapper encounterTransactionMapper, + BahmniEncounterTransactionService bahmniEncounterTransactionService, + BahmniEncounterTransactionMapper bahmniEncounterTransactionMapper) { + this.encounterService = encounterService; + this.emrEncounterService = emrEncounterService; + this.encounterTransactionMapper = encounterTransactionMapper; + this.bahmniEncounterTransactionService = bahmniEncounterTransactionService; + this.bahmniEncounterTransactionMapper = bahmniEncounterTransactionMapper; + } + + @RequestMapping(method = RequestMethod.GET, value = "/{uuid}") + @ResponseBody + public BahmniEncounterTransaction get(@PathVariable("uuid") String uuid, @RequestParam(value = "includeAll", required = false) Boolean includeAll) { + EncounterTransaction encounterTransaction = emrEncounterService.getEncounterTransaction(uuid, includeAll); + return bahmniEncounterTransactionMapper.map(encounterTransaction, includeAll); + } + + @RequestMapping(method = RequestMethod.POST, value = "/find") + @ResponseBody + public BahmniEncounterTransaction find(@RequestBody BahmniEncounterSearchParameters encounterSearchParameters) { + EncounterTransaction encounterTransaction = bahmniEncounterTransactionService.find(encounterSearchParameters); + + if (encounterTransaction != null) { + return bahmniEncounterTransactionMapper.map(encounterTransaction, encounterSearchParameters.getIncludeAll()); + } else { + return bahmniEncounterTransactionMapper.map(new EncounterTransaction(), false); + } + } + + @RequestMapping(method = RequestMethod.DELETE, value = "/{uuid}") + @ResponseBody + public void delete(@PathVariable("uuid") String uuid, @RequestParam(value = "reason", defaultValue = "web service call") String reason){ + String errorMessage = "Visit for this patient is closed. You cannot do an 'Undo Discharge' for the patient."; + Visit visit = encounterService.getEncounterByUuid(uuid).getVisit(); + Date stopDate = visit.getStopDatetime(); + if(stopDate != null && stopDate.before(new Date())){ + throw new VisitClosedException(errorMessage); + } + else{ + BahmniEncounterTransaction bahmniEncounterTransaction = get(uuid,false); + bahmniEncounterTransaction.setReason(reason); + bahmniEncounterTransactionService.delete(bahmniEncounterTransaction); + } + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + @Transactional + public BahmniEncounterTransaction update(@RequestBody BahmniEncounterTransaction bahmniEncounterTransaction) { + setUuidsForObservations(bahmniEncounterTransaction.getObservations()); + return bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + } + + public BahmniEncounterTransaction get(String encounterUuid) { + Encounter encounter = encounterService.getEncounterByUuid(encounterUuid); + boolean includeAll = false; + EncounterTransaction encounterTransaction = encounterTransactionMapper.map(encounter, includeAll); + return bahmniEncounterTransactionMapper.map(encounterTransaction, includeAll); + } + @ExceptionHandler(OrderEntryException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleOrderEntryException(OrderEntryException ex) { + Map errorBody = new HashMap<>(); + errorBody.put("message", "[" + ex.getMessage() + "]"); + Map responseBody = new HashMap<>(); + responseBody.put("error", errorBody); + logger.warn("OrderEntryException: " + ex.getMessage()); + return new ResponseEntity(responseBody, HttpStatus.BAD_REQUEST); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterModifierController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterModifierController.java new file mode 100644 index 0000000000..8ee53305d8 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterModifierController.java @@ -0,0 +1,43 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.contract.encounter.data.EncounterModifierData; +import org.bahmni.module.bahmnicore.service.BahmniEncounterModifierService; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/bahmniencountermodifier") +public class BahmniEncounterModifierController extends BaseRestController { + + private static final Logger log = LogManager.getLogger(BahmniEncounterModifierController.class); + + + @Autowired + private BahmniEncounterModifierService bahmniEncounterModifierService; + + @Autowired + public BahmniEncounterModifierController(BahmniEncounterModifierService bahmniEncounterModifierService) { + this.bahmniEncounterModifierService = bahmniEncounterModifierService; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public EncounterModifierData get(@RequestBody EncounterModifierData encounterModifierData) throws Exception { + EncounterModifierData encounterTransaction; + try { + encounterTransaction = bahmniEncounterModifierService.getModifiedEncounter(encounterModifierData); + } catch (Throwable e) { + log.error("Error in running groovy script: " + e.getMessage(), e); + throw e; + } + return encounterTransaction; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsController.java new file mode 100644 index 0000000000..c3799a2f5c --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsController.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.service.BahmniFormDetailsService; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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 java.util.Collection; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; + + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/patient/{patientUuid}/forms") +public class BahmniFormDetailsController extends BaseRestController { + + private BahmniFormDetailsService bahmniFormDetailsService; + + @Autowired + public BahmniFormDetailsController(BahmniFormDetailsService bahmniFormDetailsService) { + this.bahmniFormDetailsService = bahmniFormDetailsService; + } + + /** + * To fetch all the forms available for a patient. + * + * @param patientUuid mandatory patient uuid + * @param formType optional parameter to fetch type of forms. "v1" fetches AllObservationTemplate Forms + * whereas "v2" fetches form builder forms. The default is "v2". API needs to be implemented + * for "v1" + * Refer {@link FormType} + * @param numberOfVisits optional parameter to limit form details to recent number of visits. Negative number will + * consider all visits + * @param visitUuid optional parameter to fetch forms filled under that visit(it takes precedence over numbersOfVisits) + * @param patientProgramUuid optional parameter to fetch forms filled under that patient program(works together with visitUuid if provided) + * @return collection of form Details. Refer {@link FormDetails} + */ + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public Collection getFormDetails( + @PathVariable(value = "patientUuid") String patientUuid, + @RequestParam(value = "formType", defaultValue = "v2") String formType, + @RequestParam(value = "numberOfVisits", defaultValue = "-1") Integer numberOfVisits, + @RequestParam(value = "visitUuid", required = false) String visitUuid, + @RequestParam(value = "patientProgramUuid", required = false) String patientProgramUuid) { + + FormType typeOfForm = FormType.valueOfType(formType); + if (isNotBlank(visitUuid) || isNotBlank(patientProgramUuid)) { + return bahmniFormDetailsService.getFormDetails(patientUuid, typeOfForm, visitUuid, patientProgramUuid); + } + return bahmniFormDetailsService.getFormDetails(patientUuid, typeOfForm, numberOfVisits); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java new file mode 100644 index 0000000000..cd079270cb --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniNotesController.java @@ -0,0 +1,89 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.contract.NoteRequestResponse; +import org.bahmni.module.bahmnicore.mapper.NoteMapper; +import org.bahmni.module.bahmnicore.model.Note; +import org.bahmni.module.bahmnicore.service.NoteService; +import org.bahmni.module.bahmnicore.validator.NoteValidator; +import org.openmrs.api.context.Context; +import org.openmrs.module.auditlog.util.DateUtil; +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.stereotype.Controller; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/notes") +public class BahmniNotesController extends BaseRestController { + + private Log log = LogFactory.getLog(this.getClass()); + + @Autowired + private NoteMapper noteMapper; + + @Autowired + private NoteValidator noteValidator; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List getNotes(@RequestParam(value = "noteStartDate") String noteStartDateString, @RequestParam(value = "noteEndDate", required = false) String noteEndDateString, + @RequestParam(value = "noteType") String noteType) throws Exception { + Date noteStartDate = DateUtil.convertToLocalDateFromUTC(noteStartDateString); + if (noteEndDateString != null) { + Date noteEndDate = DateUtil.convertToLocalDateFromUTC(noteEndDateString); + List notes = Context.getService(NoteService.class).getNotes(noteStartDate, noteEndDate, noteType); + return notes.stream().map(note -> noteMapper.mapResponse(note)).collect(Collectors.toList()); + } + + Note note = Context.getService(NoteService.class).getNote(noteStartDate, noteType); + List noteResponses = new ArrayList<>(); + if (note != null) { + noteResponses.add(noteMapper.mapResponse(note)); + } + return noteResponses; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public List save(@Valid @RequestBody List noteRequests) throws Exception { + List notes = new ArrayList<>(); + notes = noteRequests.stream().map(noteRequest -> { + Errors noteRequestErrors = new BeanPropertyBindingResult(noteRequest, "noteRequest"); + noteValidator.validate(noteRequest, noteRequestErrors); + if (!noteRequestErrors.getAllErrors().isEmpty()) { + throw new RuntimeException(noteRequestErrors.getAllErrors().get(0).toString()); + } + return noteMapper.mapRequest(noteRequest); + }).collect(Collectors.toList()); + List listOfNotes = Context.getService(NoteService.class).createNotes(notes); + return listOfNotes.stream().map(note -> noteMapper.mapResponse(note)).collect(Collectors.toList()); + } + + @RequestMapping(method = RequestMethod.POST, value = "/{id}") + @ResponseBody + public NoteRequestResponse update(@Valid @PathVariable("id") String id, @RequestBody NoteRequestResponse noteRequestResponse) { + Integer noteId = Integer.valueOf(id); + return noteMapper.mapResponse(Context.getService(NoteService.class).updateNote(noteId, noteRequestResponse)); + } + + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") + @ResponseBody + public NoteRequestResponse delete(@PathVariable("id") String id, @RequestParam(value = "reason", required = false) String reason ) { + Integer noteId = Integer.valueOf(id); + return noteMapper.mapResponse(Context.getService(NoteService.class).voidNote(noteId, reason)); + } + + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java new file mode 100644 index 0000000000..e0025bc841 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderController.java @@ -0,0 +1,69 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniOrderService; +import org.bahmni.module.bahmnicore.util.MiscUtils; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.order.contract.BahmniOrder; +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.stereotype.Controller; +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 java.util.ArrayList; +import java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/orders") +public class BahmniOrderController extends BaseRestController { + private ConceptService conceptService; + private BahmniOrderService bahmniOrderService; + + @Autowired + public BahmniOrderController(ConceptService conceptService, BahmniOrderService bahmniOrderService) { + this.conceptService = conceptService; + this.bahmniOrderService = bahmniOrderService; + } + + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List get(@RequestParam(value = "patientUuid", required = true) String patientUuid, + @RequestParam(value = "concept", required = false) List rootConceptNames, + @RequestParam(value = "orderTypeUuid", required = false) String orderTypeUuid, + @RequestParam(value = "visitUuid", required = false) String visitUuid, + @RequestParam(value = "orderUuid", required = false) String orderUuid, + @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, + @RequestParam(value = "obsIgnoreList", required = false) List obsIgnoreList, + @RequestParam(value = "includeObs", required = false, defaultValue ="true") boolean includeObs, + @RequestParam(value = "locationUuids", required = false) List locationUuids) { + + + if (visitUuid != null) { + return bahmniOrderService.ordersForVisit(visitUuid, orderTypeUuid, rootConceptNames, MiscUtils.getConceptsForNames(obsIgnoreList, conceptService)); + } + + List rootConcepts = getConcepts(rootConceptNames); + if (orderUuid != null) { + return bahmniOrderService.ordersForOrderUuid(patientUuid, rootConcepts, obsIgnoreList, orderUuid); + } + else { + return bahmniOrderService.ordersForOrderType(patientUuid, rootConcepts, numberOfVisits, obsIgnoreList, orderTypeUuid, includeObs, locationUuids); + } + + } + + private List getConcepts(List rootConceptNames) { + List rootConcepts = new ArrayList<>(); + if(rootConceptNames!=null) { + for (String rootConceptName : rootConceptNames) { + rootConcepts.add(conceptService.getConceptByName(rootConceptName)); + } + } + return rootConcepts; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientImageController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientImageController.java new file mode 100644 index 0000000000..95bc8f5ac4 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientImageController.java @@ -0,0 +1,39 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.PatientDocumentService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +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.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +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; + + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/patientImage") +public class BahmniPatientImageController extends BaseRestController { + + private PatientDocumentService patientDocumentService; + + @Autowired + public BahmniPatientImageController(PatientDocumentService patientDocumentService) { + this.patientDocumentService = patientDocumentService; + } + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public ResponseEntity getImage(@RequestParam(value = "patientUuid", required = true) String patientUuid) { + UserContext userContext = Context.getUserContext(); + if (userContext.isAuthenticated()) { + return patientDocumentService.retriveImage(patientUuid); + } + return new ResponseEntity(new Object(), HttpStatus.UNAUTHORIZED); + } +} + diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResource.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResource.java new file mode 100644 index 0000000000..222b74f801 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResource.java @@ -0,0 +1,356 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + + +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.hibernate.NonUniqueObjectException; +import org.hibernate.exception.DataException; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.Person; +import org.openmrs.Relationship; +import org.openmrs.RelationshipType; +import org.openmrs.api.APIAuthenticationException; +import org.openmrs.api.ValidationException; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.ContextAuthenticationException; +import org.openmrs.module.emrapi.encounter.DateMapper; +import org.openmrs.module.emrapi.patient.EmrPatientProfileService; +import org.openmrs.module.emrapi.patient.PatientProfile; +import org.openmrs.module.idgen.webservices.services.IdentifierSourceServiceWrapper; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.ConversionUtil; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.RestUtil; +import org.openmrs.module.webservices.rest.web.api.RestService; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PatientResource1_8; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PersonResource1_8; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.RelationShipTypeResource1_8; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.RelationshipResource1_8; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Controller for REST web service access to + * the Search resource. + */ + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/patientprofile") +public class BahmniPatientProfileResource extends DelegatingCrudResource { + + private EmrPatientProfileService emrPatientProfileService; + private IdentifierSourceServiceWrapper identifierSourceServiceWrapper; + + @Autowired + public BahmniPatientProfileResource(EmrPatientProfileService emrPatientProfileService, IdentifierSourceServiceWrapper identifierSourceServiceWrapper) { + this.emrPatientProfileService = emrPatientProfileService; + this.identifierSourceServiceWrapper = identifierSourceServiceWrapper; + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseBody + public ResponseEntity create(@RequestHeader(value = "Jump-Accepted", required = false) boolean jumpAccepted, @RequestBody SimpleObject propertiesToCreate) throws Exception { + List identifiers = ((ArrayList) ((LinkedHashMap) propertiesToCreate.get("patient")).get("identifiers")); + List jumpSizes = new ArrayList<>(); + + for (final Object patientIdentifier : identifiers) { + LinkedHashMap identifierProperties = (LinkedHashMap) patientIdentifier; + Object identifierSource = identifierProperties.get("identifierSourceUuid"); + + if (identifierSource != null) { + String identifierPrefix = String.valueOf(identifierProperties.get("identifierPrefix")); + String identifierSourceUuid = String.valueOf(identifierProperties.get("identifierSourceUuid")); + identifierProperties.remove("identifierSourceUuid"); + identifierProperties.remove("identifierPrefix"); + + final String identifier = String.valueOf(identifierProperties.get("identifier")); + boolean isRegistrationIDNumeric = identifier.replace(identifierPrefix, "").matches("[0-9]+"); + + if (identifierProperties.get("identifier") != null && !Objects.equals(identifierPrefix, "") && isRegistrationIDNumeric) { + long givenRegistrationNumber = Long.parseLong(identifier.replace(identifierPrefix, "")); + long latestRegistrationNumber = Long.parseLong(identifierSourceServiceWrapper.getSequenceValueUsingIdentifierSourceUuid(identifierSourceUuid)); + if (!jumpAccepted) { + final long sizeOfJump = givenRegistrationNumber - latestRegistrationNumber; + if (sizeOfJump > 0) { + jumpSizes.add(new HashMap() {{ + put("identifierType", ((HashMap) patientIdentifier).get("identifierType")); + put("sizeOfJump", sizeOfJump); + }}); + } + } else if (latestRegistrationNumber < (givenRegistrationNumber + 1)) { + try { + identifierSourceServiceWrapper.saveSequenceValueUsingIdentifierSourceUuid(givenRegistrationNumber + 1, identifierSourceUuid); + } catch (DataException e) { + return getIdentifierErrorMessageResponseEntity(); + } + } + } else if (identifierProperties.get("identifier") == null) { + String generatedIdentifier = identifierSourceServiceWrapper.generateIdentifierUsingIdentifierSourceUuid(identifierSourceUuid, ""); + identifierProperties.put("identifier", generatedIdentifier); + } + } + } + + if (jumpSizes.size() > 0) { + return new ResponseEntity(new ObjectMapper().writeValueAsString(jumpSizes), HttpStatus.PRECONDITION_FAILED); + } + + PatientProfile delegate = mapForCreatePatient(propertiesToCreate); + + setConvertedProperties(delegate, propertiesToCreate, getCreatableProperties(), true); + try { + delegate = emrPatientProfileService.save(delegate); + setRelationships(delegate); + return new ResponseEntity<>(ConversionUtil.convertToRepresentation(delegate, Representation.FULL), HttpStatus.OK); + } catch (ContextAuthenticationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.FORBIDDEN); + } catch (NonUniqueObjectException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.BAD_REQUEST); + } catch (ValidationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, ""), HttpStatus.BAD_REQUEST); + } catch (DataIntegrityViolationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getRootCause().getMessage()), HttpStatus.BAD_REQUEST); + } catch (DataException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.BAD_REQUEST); + } catch (Exception e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + private ResponseEntity getIdentifierErrorMessageResponseEntity() throws IOException { + Map message = new LinkedHashMap<>(); + message.put("message", "Entered numeric patient identifier is too large"); + Map error = new LinkedHashMap<>(); + error.put("error", message); + return new ResponseEntity<>(new ObjectMapper().writeValueAsString(error), HttpStatus.BAD_REQUEST); + } + + @RequestMapping(method = RequestMethod.POST, value = "/{uuid}") + @ResponseBody + public ResponseEntity update(@PathVariable("uuid") String uuid, @RequestBody SimpleObject propertiesToUpdate) throws Exception { + PatientProfile delegate = null; + try { + delegate = mapForUpdatePatient(uuid, propertiesToUpdate); + } catch (APIAuthenticationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, "User is logged in but doesn't have the relevant privilege "), HttpStatus.FORBIDDEN); + } + setConvertedProperties(delegate, propertiesToUpdate, getUpdatableProperties(), true); + delegate.setRelationships(getRelationships(propertiesToUpdate, delegate.getPatient())); + try { + delegate = emrPatientProfileService.save(delegate); + setRelationships(delegate); + return new ResponseEntity<>(ConversionUtil.convertToRepresentation(delegate, Representation.FULL), HttpStatus.OK); + } catch (ContextAuthenticationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.FORBIDDEN); + } catch (ValidationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.BAD_REQUEST); + } catch (DataIntegrityViolationException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getRootCause().getMessage()), HttpStatus.BAD_REQUEST); + } catch (DataException e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.BAD_REQUEST); + } catch (Exception e) { + return new ResponseEntity(RestUtil.wrapErrorResponse(e, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + private void setRelationships(PatientProfile patientProfile) { + Person person = Context.getPersonService().getPersonByUuid(patientProfile.getPatient().getUuid()); + List relationships = Context.getPersonService().getRelationshipsByPerson(person); + patientProfile.setRelationships(relationships); + } + + private PatientProfile mapForCreatePatient(SimpleObject propertiesToCreate) { + final Object patientProperty = propertiesToCreate.get("patient"); + if (propertiesToCreate.get("patient") == null || !(propertiesToCreate.get("patient") instanceof Map)) { + throw new ConversionException("The patient property is missing"); + } + + PatientProfile delegate = new PatientProfile(); + PatientResource1_8 patientResource1_9 = (PatientResource1_8) Context.getService(RestService.class).getResourceBySupportedClass(Patient.class); + delegate.setPatient(patientResource1_9.getPatient(new SimpleObject() {{ + putAll((Map) patientProperty); + }})); + propertiesToCreate.removeProperty("patient"); + delegate.setRelationships(getRelationships(propertiesToCreate, delegate.getPatient())); + propertiesToCreate.removeProperty("relationships"); + return delegate; + } + + private PatientProfile mapForUpdatePatient(String uuid, SimpleObject propertiesToUpdate) { + if (propertiesToUpdate.get("patient") == null || !(propertiesToUpdate.get("patient") instanceof Map)) { + throw new ConversionException("The patient property is missing"); + } + + PatientProfile delegate = new PatientProfile(); + + PatientResource1_8 patientResource1_9 = (PatientResource1_8) Context.getService(RestService.class).getResourceBySupportedClass(Patient.class); + Patient patient = patientResource1_9.getPatientForUpdate(uuid, (Map) propertiesToUpdate.get("patient")); + List identifiers = (List) ((Map) propertiesToUpdate.get("patient")).get("identifiers"); + for (Object identifier : identifiers) { + LinkedHashMap identifierProperties = (LinkedHashMap) identifier; + identifierProperties.remove("identifierSourceUuid"); + identifierProperties.remove("identifierPrefix"); + PatientIdentifier patientIdentifier = (PatientIdentifier) ConversionUtil.convert(identifierProperties, PatientIdentifier.class); + patient.addIdentifier(patientIdentifier); + } + delegate.setPatient(patient); + + propertiesToUpdate.removeProperty("patient"); + return delegate; + } + + private List getRelationships(SimpleObject propertiesToCreate, Person currentPerson) { + Object relationshipsList = propertiesToCreate.get("relationships"); + List relationships = new ArrayList(); + List> relationshipProperties = (List>) relationshipsList; + for (final Map relationshipProperty : relationshipProperties) { + String uuid = getValueFromMap(relationshipProperty, "uuid"); + Relationship relationship; + if (StringUtils.isBlank(uuid)) { + relationship = createRelationship(currentPerson, relationshipProperty); + } else { + relationship = updateRelationship(relationshipProperty); + } + relationships.add(relationship); + } + return relationships; + } + + private String getValueFromMap(Map jsonMap, String key) { + Object value = jsonMap.get(key); + return ObjectUtils.toString(value); + } + + private Relationship createRelationship(Person currentPerson, Map relationshipJson) { + Relationship relationship = new Relationship(currentPerson, + getPerson((Map) relationshipJson.get("personB")), + getRelationshipType((Map) relationshipJson.get("relationshipType"))); + relationship.setEndDate(new DateMapper().convertUTCToDate(getValueFromMap(relationshipJson, "endDate"))); + + return relationship; + } + + private Person getPerson(Map personJson) { + String personUuid = getValueFromMap(personJson, "uuid"); + + if (StringUtils.isBlank(personUuid)) { + throw new ConversionException("The personUuid is not present."); + } + + return getPersonFromUuid(personUuid); + } + + private Person getPersonFromUuid(String personUuid) { + PersonResource1_8 personResource = (PersonResource1_8) Context.getService(RestService.class).getResourceBySupportedClass(Person.class); + Person person = personResource.getByUniqueId(personUuid); + + if (person == null) { + throw new ConversionException("The person does not exist."); + } + return person; + } + + private RelationshipType getRelationshipType(Map relationshipTypeJson) { + + String relationshipTypeUuid = getValueFromMap(relationshipTypeJson, "uuid"); + + if (StringUtils.isBlank(relationshipTypeUuid)) { + throw new ConversionException("The relationshipTypeUuid is not present"); + } + + RelationShipTypeResource1_8 relationshipResource = (RelationShipTypeResource1_8) Context.getService(RestService.class).getResourceBySupportedClass(RelationshipType.class); + RelationshipType relationshipType = relationshipResource.getByUniqueId(relationshipTypeUuid); + + if (relationshipType == null) { + throw new ConversionException("The relationship type does not exist."); + } + + return relationshipType; + } + + private Relationship updateRelationship(final Map relationshipJson) { + String relationshipUuid = getValueFromMap(relationshipJson, "uuid"); + + if (StringUtils.isBlank(relationshipUuid)) { + throw new ConversionException("The relationshipUuid is not present"); + } + + RelationshipResource1_8 relationshipResource = (RelationshipResource1_8) Context.getService(RestService.class).getResourceBySupportedClass(Relationship.class); + Relationship relationship = relationshipResource.getByUniqueId(relationshipUuid); + + if (null == relationship) { + throw new ConversionException("Invalid relationship for relationshipUuid " + relationshipUuid); + } + + relationshipResource.setConvertedProperties(relationship, relationshipJson, relationshipResource.getUpdatableProperties(), true); + + RelationshipType updatedRelationshipType = getRelationshipType((Map) relationshipJson.get("relationshipType")); + relationship.setRelationshipType(updatedRelationshipType); + + return relationship; + } + + @Override + public PatientProfile getByUniqueId(String s) { + return null; + } + + @Override + protected void delete(PatientProfile patientProfile, String s, RequestContext requestContext) throws ResponseException { + + } + + @Override + public PatientProfile newDelegate() { + return null; + } + + @Override + public PatientProfile save(PatientProfile patientProfile) { + return null; + } + + @Override + public void purge(PatientProfile patientProfile, RequestContext requestContext) throws ResponseException { + + } + + public DelegatingResourceDescription getCreatableProperties() throws ResourceDoesNotSupportOperationException { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("patient", Representation.DEFAULT); + description.addProperty("image", Representation.DEFAULT); + description.addProperty("relationships", Representation.DEFAULT); + return description; + } + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation representation) { + return null; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniTrendsController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniTrendsController.java new file mode 100644 index 0000000000..dbf17f3493 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniTrendsController.java @@ -0,0 +1,63 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.contract.encounter.data.ConceptData; +import org.bahmni.module.bahmnicore.contract.encounter.data.PersonObservationData; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.openmrs.Concept; +import org.openmrs.ConceptNumeric; +import org.openmrs.Obs; +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.stereotype.Controller; +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 java.util.ArrayList; +import java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/bahmniobs") +public class BahmniTrendsController extends BaseRestController { + @Autowired + private BahmniObsService personObsService; + + @Autowired + + public BahmniTrendsController(BahmniObsService personObsService) { + this.personObsService = personObsService; + } + + public BahmniTrendsController() { + } + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List get(@RequestParam(value = "patientUUID", required = true) String patientUUID) { + List obsForPerson = personObsService.getObsForPerson(patientUUID); + List observationDataList = new ArrayList<>(); + for (Obs obs : obsForPerson) { + Concept concept = obs.getConcept(); + String units = null; + if(concept.isNumeric()){ + units = ((ConceptNumeric)concept).getUnits(); + } + observationDataList.add(new PersonObservationData(concept.getName().getName(), obs.getValueNumeric(), obs.getDateCreated(),concept.isNumeric(),units)); + } + return observationDataList; + } + + @RequestMapping(method = RequestMethod.GET, value = "concepts") + @ResponseBody + public List getConceptsfor(@RequestParam(value = "patientUUID", required = true) String patientUUID) { + List numericConcepts = personObsService.getNumericConceptsForPerson(patientUUID); + List conceptDataList = new ArrayList<>(); + for (Concept concept : numericConcepts){ + conceptDataList.add(new ConceptData(concept.getUuid(), concept.getName().getName())); + } + return conceptDataList; + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitController.java new file mode 100644 index 0000000000..e64ee5449e --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitController.java @@ -0,0 +1,86 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.contract.visit.VisitSummary; +import org.bahmni.module.bahmnicore.mapper.BahmniVisitSummaryMapper; +import org.bahmni.module.bahmnicore.service.BahmniVisitService; +import org.openmrs.Encounter; +import org.openmrs.Visit; +import org.openmrs.VisitAttribute; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +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.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; +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 java.util.ArrayList; +import java.util.List; + +import static org.bahmni.module.bahmnicore.util.MiscUtils.setUuidsForObservations; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/visit") +public class BahmniVisitController extends BaseRestController { + + private static final String VISIT_STATUS_ATTRIBUTE_TYPE = "Visit Status"; + private static final String IPD_VISIT_STATUS = "IPD"; + private VisitService visitService; + private BahmniVisitService bahmniVisitService; + private BahmniVisitSummaryMapper bahmniVisitSummaryMapper; + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + public BahmniVisitController() { + } + + @Autowired + public BahmniVisitController(VisitService visitService, BahmniVisitService bahmniVisitService, BahmniEncounterTransactionService bahmniEncounterTransactionService) { + this.visitService = visitService; + this.bahmniVisitService = bahmniVisitService; + this.bahmniEncounterTransactionService = bahmniEncounterTransactionService; + this.bahmniVisitSummaryMapper = new BahmniVisitSummaryMapper(); + } + + @RequestMapping(method = RequestMethod.POST, value = "endVisit") + @ResponseBody + public VisitSummary endVisitNow(@RequestParam(value = "visitUuid") String visitUuid) { + Visit visit = endVisit(visitUuid); + return bahmniVisitSummaryMapper.map(visit, new ArrayList()); + } + + private Visit endVisit(String visitUuid) { + Visit visit = visitService.getVisitByUuid(visitUuid); + return visitService.endVisit(visit, null); + } + + @RequestMapping(method = RequestMethod.GET, value = "summary") + @ResponseBody + public VisitSummary getVisitInfo(@RequestParam(value = "visitUuid") String visitUuid) { + Visit visit = bahmniVisitService.getVisitSummary(visitUuid); + if (visit != null) { + List admitAndDischargeEncounters = null; + for (VisitAttribute visitAttribute : visit.getAttributes()) { + if (VISIT_STATUS_ATTRIBUTE_TYPE.equalsIgnoreCase(visitAttribute.getAttributeType().getName()) && IPD_VISIT_STATUS.equalsIgnoreCase(visitAttribute.getValueReference())) { + admitAndDischargeEncounters = bahmniVisitService.getAdmitAndDischargeEncounters(visit.getId()); + } + } + return bahmniVisitSummaryMapper.map(visit, admitAndDischargeEncounters); + } + return null; + } + + @RequestMapping(method = RequestMethod.POST, value = "endVisitAndCreateEncounter") + @ResponseBody + @Transactional + public BahmniEncounterTransaction endVisitAndCreateNewEncounter(@RequestParam(value = "visitUuid") String visitUuid, @RequestBody BahmniEncounterTransaction bahmniEncounterTransaction) { + endVisit(visitUuid); + setUuidsForObservations(bahmniEncounterTransaction.getObservations()); + return bahmniEncounterTransactionService.save(bahmniEncounterTransaction); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitLocationController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitLocationController.java new file mode 100644 index 0000000000..279abf5981 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitLocationController.java @@ -0,0 +1,60 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.Location; +import org.openmrs.api.context.Context; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.HashMap; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore") +public class BahmniVisitLocationController extends BaseRestController { + + private BahmniVisitLocationService bahmniVisitLocationService; + + @Autowired + public BahmniVisitLocationController(BahmniVisitLocationService bahmniVisitLocationService) { + this.bahmniVisitLocationService = bahmniVisitLocationService; + } + + + @RequestMapping(method = RequestMethod.GET, value = "/visitLocation/{loginLocationUuid}") + @ResponseBody + public HashMap getVisitLocationInfo(@PathVariable("loginLocationUuid") String locationUuid ) { + HashMap visitLocation = new HashMap<>(); + visitLocation.put("uuid",bahmniVisitLocationService.getVisitLocationUuid(locationUuid)); + return visitLocation; + } + + @RequestMapping(method = RequestMethod.GET, value = "/facilityLocation/{locationUuid}") + @ResponseBody + public HashMap getFacilityVisitLocationInfo(@PathVariable("locationUuid") String locationUuid ) { + Location location = Context.getLocationService().getLocationByUuid(locationUuid); + HashMap facilityVisitLocation = new HashMap<>(); + Location facilityLocation = getParentVisitLocationUuid(location); + facilityVisitLocation.put("uuid", facilityLocation!=null ? facilityLocation.getUuid() : null); + facilityVisitLocation.put("name", facilityLocation!=null ? facilityLocation.getName() : null); + return facilityVisitLocation; + } + + private Location getParentVisitLocationUuid(Location location) { + if(isVisitLocation(location)) { + return location.getParentLocation() != null ? getParentVisitLocationUuid(location.getParentLocation()) : location; + } else { + return location.getParentLocation() != null ? getParentVisitLocationUuid(location.getParentLocation()) : null; + } + } + + private Boolean isVisitLocation(Location location) { + return (location.getTags().size() > 0 && location.getTags().stream().filter(tag -> tag.getName().equalsIgnoreCase("Visit Location")).count() != 0); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DiseaseTemplateController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DiseaseTemplateController.java new file mode 100644 index 0000000000..356bbc3d14 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DiseaseTemplateController.java @@ -0,0 +1,35 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplate; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplatesConfig; +import org.bahmni.module.bahmnicore.service.DiseaseTemplateService; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; + +@Controller +public class DiseaseTemplateController extends BaseRestController { + + private final String baseUrl = "/rest/v1/bahmnicore/"; + + @Autowired + private DiseaseTemplateService diseaseTemplateService; + + @RequestMapping(method = RequestMethod.POST, value = baseUrl + "diseaseTemplates") + @ResponseBody + public List get(@RequestBody DiseaseTemplatesConfig diseaseTemplatesConfig) { + return diseaseTemplateService.allDiseaseTemplatesFor(diseaseTemplatesConfig); + } + + @RequestMapping(method = RequestMethod.POST, value = baseUrl + "diseaseTemplate") + @ResponseBody + public DiseaseTemplate getDiseaseTemplate(@RequestBody DiseaseTemplatesConfig diseaseTemplatesConfig){ + return diseaseTemplateService.diseaseTemplateFor(diseaseTemplatesConfig); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DoseCalculatorController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DoseCalculatorController.java new file mode 100644 index 0000000000..0e0b34b219 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DoseCalculatorController.java @@ -0,0 +1,29 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.openmrs.module.rulesengine.domain.DosageRequest; +import org.openmrs.module.rulesengine.domain.Dose; +import org.openmrs.module.rulesengine.engine.RulesEngine; +import org.openmrs.module.rulesengine.engine.RulesEngineImpl; +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.stereotype.Controller; +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; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/calculateDose") +public class DoseCalculatorController extends BaseRestController { + + + private RulesEngine rulesEngine = new RulesEngineImpl(); + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public Dose calculateDose(@RequestParam(value = "dosageRequest") String dosageRequest) throws Exception { + DosageRequest request= new DosageRequest(dosageRequest); + return rulesEngine.calculateDose(request); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/EmailCommunicationController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/EmailCommunicationController.java new file mode 100644 index 0000000000..28cac1ad84 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/EmailCommunicationController.java @@ -0,0 +1,60 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.impl.DefaultHttpResponseFactory; +import org.apache.http.message.BasicStatusLine; +import org.bahmni.module.bahmnicore.web.v1_0.contract.BahmniMailContent; +import org.bahmni.module.communication.model.Recipient; +import org.bahmni.module.communication.service.CommunicationService; +import org.openmrs.Patient; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +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.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.PathVariable; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/patient/{patientUuid}/send/")//change to send-prescription-email +public class EmailCommunicationController extends BaseRestController { + + private final Log log = LogFactory.getLog(this.getClass()); + + @Autowired + PatientService patientService; + + @PostMapping(value = "email") + @ResponseBody + public Object sendEmail(@RequestBody BahmniMailContent bahmniMailContent, @PathVariable("patientUuid") String patientUuid) { + HttpResponseFactory factory = new DefaultHttpResponseFactory(); + HttpResponse response = null; + if(Boolean.valueOf(Context.getAdministrationService().getGlobalProperty("bahmni.enableEmailPrescriptionOption"))) { + try { + Patient patient = patientService.getPatientByUuid(patientUuid); + String recipientName = patient.getGivenName() + (patient.getMiddleName()!=null ? " " + patient.getMiddleName() : "") + (patient.getFamilyName()!=null ? " " + patient.getFamilyName() : ""); + String recipientEmail = patient.getAttribute("email").getValue(); + Recipient recipient = new Recipient(recipientName, recipientEmail); + bahmniMailContent.setRecipient(recipient); + Context.getService(CommunicationService.class).sendEmail(bahmniMailContent); + response = factory.newHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "Mail sent successfully"), null); + } catch (Exception exception) { + log.error("Unable to send email", exception); + response = factory.newHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unable to send email"), null); + } + } else { + response = factory.newHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_METHOD_NOT_ALLOWED, "Sending email is not enabled"), null); + } + return response; + } + +} \ No newline at end of file diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/GlobalPropertySearchController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/GlobalPropertySearchController.java new file mode 100644 index 0000000000..88662c19d7 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/GlobalPropertySearchController.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.openmrs.GlobalProperty; +import org.openmrs.api.AdministrationService; +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.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.HashMap; +import java.util.List; + +@Controller +@RequestMapping(method = RequestMethod.GET, value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/globalProperty") +public class GlobalPropertySearchController extends BaseRestController { + + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + + @RequestMapping(method = RequestMethod.GET, value = "passwordPolicyProperties") + @ResponseBody + public ResponseEntity> getPasswordPolicies() { + List allGlobalProperties = administrationService.getAllGlobalProperties(); + HashMap passwordPolicyProperties = new HashMap<>(); + + allGlobalProperties.forEach(globalProperty -> { + if (globalProperty.getProperty().contains("security.")) { + passwordPolicyProperties.put(globalProperty.getProperty(), globalProperty.getPropertyValue()); + } + }); + + return new ResponseEntity<>(passwordPolicyProperties, HttpStatus.OK); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/ObsRelationshipController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/ObsRelationshipController.java new file mode 100644 index 0000000000..11be165442 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/ObsRelationshipController.java @@ -0,0 +1,34 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.ObsRelationshipMapper; +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.stereotype.Controller; +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 java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/obsrelationships") +public class ObsRelationshipController extends BaseRestController{ + + @Autowired + private ObsRelationService obsRelationService; + @Autowired + private ObsRelationshipMapper obsRelationshipMapper; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List find(@RequestParam(value = "targetObsUuid", required = true) String targetObsUuid){ + List obsRelationships = obsRelationService.getObsRelationshipsByTargetObsUuid(targetObsUuid); + + return obsRelationshipMapper.map(obsRelationships); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/SqlSearchController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/SqlSearchController.java new file mode 100644 index 0000000000..6088f03b23 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/SqlSearchController.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.SqlSearchService; +import org.openmrs.api.AdministrationService; +import org.openmrs.module.webservices.rest.SimpleObject; +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.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +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 javax.servlet.http.HttpServletRequest; +import java.util.List; + +@Controller +@RequestMapping(method = RequestMethod.GET, value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/sql") +public class SqlSearchController extends BaseRestController { + + @Autowired + private SqlSearchService sqlSearchService; + + @Autowired + @Qualifier("adminService") + AdministrationService administrationService; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List search(@RequestParam("q") String query, HttpServletRequest request) throws Exception { + return sqlSearchService.search(query, request.getParameterMap()); + } + + @RequestMapping(method = RequestMethod.GET, value = "globalproperty") + @ResponseBody + public Object retrieve(@RequestParam(value = "property", required = true) String name) { + return administrationService.getGlobalProperty(name); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/TasksMonitoringController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/TasksMonitoringController.java new file mode 100644 index 0000000000..37d36bf69e --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/TasksMonitoringController.java @@ -0,0 +1,39 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.contract.monitoring.response.TasksMonitoringResponse; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.openmrs.scheduler.TaskDefinition; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/scheduledTasks") +public class TasksMonitoringController extends BaseRestController { + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody() + public List get() { + List allTasks = new ArrayList<>(); + + Collection scheduledTasks = Context.getSchedulerService().getScheduledTasks(); + for (TaskDefinition scheduledTask : scheduledTasks) { + allTasks.add(new TasksMonitoringResponse(scheduledTask.getStarted(), + scheduledTask.getTaskClass(), + scheduledTask.getLastExecutionTime(), + scheduledTask.getNextExecutionTime() + )); + } + + return allTasks; + } + + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java new file mode 100644 index 0000000000..080e759682 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentController.java @@ -0,0 +1,127 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.model.Document; +import org.bahmni.module.bahmnicore.security.PrivilegeConstants; +import org.bahmni.module.bahmnicore.service.PatientDocumentService; +import org.bahmni.module.bahmnicore.util.WebUtils; +import org.bahmni.module.bahmnicore.web.v1_0.InvalidInputException; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.User; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentRequest; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentResponse; +import org.openmrs.module.bahmniemrapi.document.service.VisitDocumentService; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.WSDoc; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.nio.file.Paths; +import java.util.HashMap; + +@Controller +public class VisitDocumentController extends BaseRestController { + private static final String INSUFFICIENT_PRIVILEGE = "Insufficient privilege"; + private static final String INVALID_USER_PRIVILEGE = "User [%d] does not have required privilege to delete patient file [%s]"; + private final String baseVisitDocumentUrl = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/visitDocument"; + + @Autowired + private VisitDocumentService visitDocumentService; + + @Autowired + private PatientDocumentService patientDocumentService; + + @Autowired + private BahmniVisitLocationService bahmniVisitLocationService; + + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + + private Log logger = LogFactory.getLog(this.getClass()); + + @RequestMapping(method = RequestMethod.POST, value = baseVisitDocumentUrl) + @WSDoc("Save Patient Document") + @ResponseBody + public VisitDocumentResponse save(@RequestBody VisitDocumentRequest visitDocumentUpload) { + String visitLocation = bahmniVisitLocationService.getVisitLocationUuid(visitDocumentUpload.getLocationUuid()); + visitDocumentUpload.setVisitLocationUuid(visitLocation); + final Encounter encounter = visitDocumentService.upload(visitDocumentUpload); + return new VisitDocumentResponse(encounter.getVisit().getUuid(), encounter.getUuid()); + } + + @RequestMapping(method = RequestMethod.POST, value = baseVisitDocumentUrl + "/uploadDocument") + @ResponseBody + public ResponseEntity> saveDocument(@RequestBody Document document) { + try { + HashMap savedDocument = new HashMap<>(); + Patient patient = Context.getPatientService().getPatientByUuid(document.getPatientUuid()); + String encounterTypeName = document.getEncounterTypeName(); + String maxDocumentSize = System.getenv("DOCUMENT_MAX_SIZE_MB"); + + if (StringUtils.isEmpty(encounterTypeName)) { + encounterTypeName = administrationService.getGlobalProperty("bahmni.encounterType.default"); + } + String fileName = sanitizeFileName(document.getFileName()); + Paths.get(fileName); + + if (!StringUtils.isEmpty(maxDocumentSize)) { + Long maxDocumentSizeMb = Long.parseLong(maxDocumentSize); + Long maxDocumentSizeBytes = maxDocumentSizeMb * 1024 * 1024; + if (document.getContent().length() > maxDocumentSizeBytes) { + logger.warn("Uploaded document size is greater than the maximum size " + maxDocumentSizeMb + "MB"); + savedDocument.put("maxDocumentSizeMB", maxDocumentSizeMb); + return new ResponseEntity<>(savedDocument, HttpStatus.PAYLOAD_TOO_LARGE); + } + } + // Old files will follow: patientid-encounterName-uuid.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75.png) + // New ones will follow: patientid_encounterName_uuid__filename.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75__doc1.png) + String url = patientDocumentService.saveDocument(patient.getId(), encounterTypeName, document.getContent(), + document.getFormat(), document.getFileType(), fileName); + savedDocument.put("url", url); + return new ResponseEntity<>(savedDocument, HttpStatus.OK); + } catch (Exception e) { + throw new InvalidInputException("Could not save patient document", e); + } + } + + @RequestMapping(method = RequestMethod.DELETE, value = baseVisitDocumentUrl) + @ResponseBody + public ResponseEntity deleteDocument(@RequestParam(value = "filename") String fileName) { + if (!Context.getUserContext().hasPrivilege(PrivilegeConstants.DELETE_PATIENT_DOCUMENT_PRIVILEGE)) { + logger.error(String.format(INVALID_USER_PRIVILEGE, getAuthenticatedUserId(), fileName)); + return new ResponseEntity<>(WebUtils.wrapErrorResponse(null, INSUFFICIENT_PRIVILEGE), HttpStatus.FORBIDDEN); + } + try { + patientDocumentService.delete(fileName); + return new ResponseEntity<>(new HashMap<>(), HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(WebUtils.wrapErrorResponse(null, e.getMessage()), HttpStatus.BAD_REQUEST); + } + } + + private Integer getAuthenticatedUserId() { + User authenticatedUser = Context.getUserContext().getAuthenticatedUser(); + if (authenticatedUser == null) { + return null; + } + return Integer.valueOf(authenticatedUser.getUserId()); + } + + private String sanitizeFileName(String fileName) { + if (fileName == null) return ""; + return fileName.trim().replaceAll(" ", "-").replaceAll("__", "_"); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/WhoamiController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/WhoamiController.java new file mode 100644 index 0000000000..08ca198460 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/WhoamiController.java @@ -0,0 +1,36 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicoreui.contract.Privilege; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/whoami") +public class WhoamiController { + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody() + public List getPrivileges(HttpServletResponse response) { + User authenticatedUser = Context.getUserContext().getAuthenticatedUser(); + if (authenticatedUser != null) { + Collection privileges = authenticatedUser.getPrivileges(); + List responsePrivileges = new ArrayList<>(); + for (org.openmrs.Privilege privilege : privileges) { + responsePrivileges.add(new Privilege(privilege.getName())); + } + return responsePrivileges; + } + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return null; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniLabOrderResultController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniLabOrderResultController.java new file mode 100644 index 0000000000..c74710c7c1 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniLabOrderResultController.java @@ -0,0 +1,64 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.PatientService; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResults; +import org.openmrs.module.bahmniemrapi.laborder.service.LabOrderResultsService; +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.stereotype.Controller; +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 java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/labOrderResults") +public class BahmniLabOrderResultController extends BaseRestController{ + private PatientService patientService; + private OrderDao orderDao; + private LabOrderResultsService labOrderResultsService; + + @Autowired + public BahmniLabOrderResultController(PatientService patientService, + OrderDao orderDao, + LabOrderResultsService labOrderResultsService) { + this.patientService = patientService; + this.orderDao = orderDao; + this.labOrderResultsService = labOrderResultsService; + } + + @RequestMapping(method = RequestMethod.GET, params = {"visitUuids"}) + @ResponseBody + public LabOrderResults getForVisitUuids( + @RequestParam(value = "visitUuids", required = true) String[] visitUuids) { + List visits = orderDao.getVisitsForUUids(visitUuids); + return labOrderResultsService.getAll(patientFrom(visits), visits, Integer.MAX_VALUE); + } + + @RequestMapping(method = RequestMethod.GET, params = {"patientUuid"}) + @ResponseBody + public LabOrderResults getForPatient( + @RequestParam(value = "patientUuid", required = true) String patientUuid, + @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, + @RequestParam(value = "numberOfAccessions", required = false) Integer numberOfAccessions) { + Patient patient = patientService.getPatientByUuid(patientUuid); + List visits = null; + if (numberOfVisits != null) { + visits = orderDao.getVisitsWithAllOrders(patient, "Order", true, numberOfVisits); + } + if (numberOfAccessions == null) + numberOfAccessions = Integer.MAX_VALUE; + + return labOrderResultsService.getAll(patient, visits, numberOfAccessions); + } + + private Patient patientFrom(List visits) { + return visits.get(0).getPatient(); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java new file mode 100644 index 0000000000..b3ac3f1410 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java @@ -0,0 +1,166 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.obs.ObservationsAdder; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.util.MiscUtils; +import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; +import org.openmrs.Concept; +import org.openmrs.ConceptSearchResult; +import org.openmrs.Visit; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +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 java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/observations") +public class BahmniObservationsController extends BaseRestController { + + private static final String LATEST = "latest"; + private static final String INITIAL = "initial"; + private BahmniObsService bahmniObsService; + private ConceptService conceptService; + private VisitService visitService; + private BahmniExtensions bahmniExtensions; + + @Autowired + public BahmniObservationsController(BahmniObsService bahmniObsService, ConceptService conceptService, VisitService visitService, BahmniExtensions bahmniExtensions) { + this.bahmniObsService = bahmniObsService; + this.conceptService = conceptService; + this.visitService = visitService; + this.bahmniExtensions = bahmniExtensions; + } + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public Collection get(@RequestParam(value = "patientUuid", required = true) String patientUUID, + @RequestParam(value = "concept", required = true) List rootConceptNames, + @RequestParam(value = "locale", required = false) String locale, + @RequestParam(value = "scope", required = false) String scope, + @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, + @RequestParam(value = "obsIgnoreList", required = false) List obsIgnoreList, + @RequestParam(value = "filterObsWithOrders", required = false, defaultValue = "true") Boolean filterObsWithOrders ) throws ParseException { + + List conceptList = searchConceptsByName(rootConceptNames, identifyLocale(locale)); + Collection observations; + if (ObjectUtils.equals(scope, LATEST)) { + observations = bahmniObsService.getLatest(patientUUID, conceptList, numberOfVisits, obsIgnoreList, filterObsWithOrders, null); + } else if (ObjectUtils.equals(scope, INITIAL)) { + observations = bahmniObsService.getInitial(patientUUID, conceptList, numberOfVisits, obsIgnoreList, filterObsWithOrders, null); + } else { + observations = bahmniObsService.observationsFor(patientUUID, conceptList, numberOfVisits, obsIgnoreList, filterObsWithOrders, null, null, null); + } + + sendObsToGroovyScript(getConceptNames(conceptList), observations); + + return observations; + } + + private List searchConceptsByName(List conceptNames, Locale searchLocale) { + Set conceptSet = new LinkedHashSet<>(); + if (CollectionUtils.isNotEmpty(conceptNames)) { + List localeList = Collections.singletonList(searchLocale); + for (String name : conceptNames) { + List conceptsSearchResult = conceptService.getConcepts(name, localeList, false, null, null, null, null, null, 0, null); + List conceptsByName = conceptsSearchResult.stream().map(conceptSearchResult -> conceptSearchResult.getConcept()).collect(Collectors.toList()); + conceptSet.addAll(conceptsByName); + } + } + return new ArrayList<>(conceptSet); + } + + @RequestMapping(method = RequestMethod.GET, params = {"visitUuid"}) + @ResponseBody + public Collection get(@RequestParam(value = "visitUuid", required = true) String visitUuid, + @RequestParam(value = "scope", required = false) String scope, + @RequestParam(value = "concept", required = false) List conceptNames, + @RequestParam(value = "obsIgnoreList", required = false) List obsIgnoreList, + @RequestParam(value = "filterObsWithOrders", required = false, defaultValue = "true") Boolean filterObsWithOrders) { + + Visit visit = visitService.getVisitByUuid(visitUuid); + if (ObjectUtils.equals(scope, INITIAL)) { + return bahmniObsService.getInitialObsByVisit(visit, MiscUtils.getConceptsForNames(conceptNames, conceptService), obsIgnoreList, filterObsWithOrders); + } else if (ObjectUtils.equals(scope, LATEST)) { + return bahmniObsService.getLatestObsByVisit(visit, MiscUtils.getConceptsForNames(conceptNames, conceptService), obsIgnoreList, filterObsWithOrders); + } else { + // Sending conceptName and obsIgnorelist, kinda contradicts, since we filter directly on concept names (not on root concept) + return bahmniObsService.getObservationForVisit(visitUuid, conceptNames, MiscUtils.getConceptsForNames(obsIgnoreList, conceptService), filterObsWithOrders, null); + } + } + + @RequestMapping(method = RequestMethod.GET, params = {"encounterUuid"}) + @ResponseBody + public Collection get(@RequestParam(value = "encounterUuid", required = true) String encounterUuid, + @RequestParam(value = "concept", required = false) List conceptNames) { + return bahmniObsService.getObservationsForEncounter(encounterUuid, conceptNames); + } + + @RequestMapping(method = RequestMethod.GET, params = {"patientProgramUuid"}) + @ResponseBody + public Collection get(@RequestParam(value = "patientProgramUuid", required = true) String patientProgramUuid, + @RequestParam(value = "concept", required = false) List rootConceptNames, + @RequestParam(value = "scope", required = false) String scope, + @RequestParam(value = "obsIgnoreList", required = false) List obsIgnoreList) throws ParseException { + + Collection observations; + if (ObjectUtils.equals(scope, LATEST)) { + observations = bahmniObsService.getLatestObservationsForPatientProgram(patientProgramUuid, rootConceptNames, obsIgnoreList); + } else if (ObjectUtils.equals(scope, INITIAL)) { + observations = bahmniObsService.getInitialObservationsForPatientProgram(patientProgramUuid, rootConceptNames, obsIgnoreList); + } else { + observations = bahmniObsService.getObservationsForPatientProgram(patientProgramUuid, rootConceptNames, obsIgnoreList); + } + sendObsToGroovyScript(rootConceptNames, observations); + return observations; + } + + @RequestMapping(method = RequestMethod.GET, params = {"observationUuid"}) + @ResponseBody + public BahmniObservation get(@RequestParam(value = "observationUuid") String observationUuid, + @RequestParam(value = "revision", required = false) String revision) { + if (ObjectUtils.equals(revision, LATEST)) { + return bahmniObsService.getRevisedBahmniObservationByUuid(observationUuid); + } + return bahmniObsService.getBahmniObservationByUuid(observationUuid); + } + + private void sendObsToGroovyScript(List questions, Collection observations) throws ParseException { + ObservationsAdder observationsAdder = (ObservationsAdder) bahmniExtensions.getExtension("observationsAdder", "CurrentMonthOfTreatment.groovy"); + if (observationsAdder != null) + observationsAdder.addObservations(observations, questions); + } + + private List getConceptNames(Collection concepts) { + List conceptNames = new ArrayList<>(); + for (Concept concept : concepts) { + conceptNames.add(concept.getName().getName()); + } + return conceptNames; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextController.java new file mode 100644 index 0000000000..772c557977 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextController.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.BahmniPatientContextMapper; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifierType; +import org.openmrs.PatientProgram; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.patient.PatientContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +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 java.util.List; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/patientcontext") +public class BahmniPatientContextController { + private static final String BAHMNI_PRIMARY_IDENTIFIER_TYPE = "bahmni.primaryIdentifierType"; + @Autowired + private PatientService patientService; + @Autowired + @Qualifier("adminService") + private AdministrationService administrationService; + @Autowired + private BahmniPatientContextMapper mapper; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public PatientContext getPatientContext(@RequestParam(value = "patientUuid", required = true) String patientUuid, + @RequestParam(value = "programUuid", required = false) String programUuid, + @RequestParam(value = "personAttributes", required = false) List configuredPersonAttributes, + @RequestParam(value = "programAttributes", required = false) List configuredProgramAttributes, + @RequestParam(value = "patientIdentifiers", required = false) List configuredPatientIdentifiers) { + Patient patient = patientService.getPatientByUuid(patientUuid); + PatientProgram bahmniPatientProgram = (PatientProgram) Context.getService(BahmniProgramWorkflowService.class).getPatientProgramByUuid(programUuid); + PatientIdentifierType primaryIdentifierType = patientService.getPatientIdentifierTypeByUuid(administrationService.getGlobalProperty(BAHMNI_PRIMARY_IDENTIFIER_TYPE)); + return mapper.map(patient, bahmniPatientProgram, configuredPersonAttributes, configuredProgramAttributes, configuredPatientIdentifiers, primaryIdentifierType); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramController.java new file mode 100644 index 0000000000..6325bf22c8 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramController.java @@ -0,0 +1,96 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.DrugOrderToRegimenMapper; +import org.openmrs.Concept; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.drugogram.contract.BaseTableExtension; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +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 java.text.ParseException; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/drugOGram/regimen") +public class DrugOGramController { + + private BahmniDrugOrderService bahmniDrugOrderService; + private DrugOrderToRegimenMapper drugOrderToTreatmentRegimenMapper; + private BahmniConceptService bahmniConceptService; + private BahmniExtensions bahmniExtensions; + + @Autowired + public DrugOGramController(BahmniDrugOrderService bahmniDrugOrderService, DrugOrderToRegimenMapper drugOrderToTreatmentRegimenMapper, BahmniConceptService bahmniConceptService, BahmniExtensions bahmniExtensions) { + this.bahmniDrugOrderService = bahmniDrugOrderService; + this.drugOrderToTreatmentRegimenMapper = drugOrderToTreatmentRegimenMapper; + this.bahmniConceptService = bahmniConceptService; + this.bahmniExtensions = bahmniExtensions; + } + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public TreatmentRegimen getRegimen(@RequestParam(value = "patientUuid", required = true) String patientUuid, + @RequestParam(value = "patientProgramUuid", required = false) String patientProgramUuid, + @RequestParam(value = "drugs", required = false) List drugs) throws ParseException { + Set conceptsForDrugs = getConceptsForDrugs(drugs); + + + List allDrugOrders = bahmniDrugOrderService.getAllDrugOrders(patientUuid, patientProgramUuid, conceptsForDrugs,null, null); + if (!CollectionUtils.isEmpty(conceptsForDrugs)) { + conceptsForDrugs = filterConceptsForDrugOrders(conceptsForDrugs, allDrugOrders); + } + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(allDrugOrders, conceptsForDrugs); + BaseTableExtension extension = (BaseTableExtension) bahmniExtensions.getExtension("treatmentRegimenExtension" + , "TreatmentRegimenExtension.groovy"); + if (extension != null) + extension.update(treatmentRegimen, patientUuid, patientProgramUuid); + return treatmentRegimen; + } + + private Set filterConceptsForDrugOrders(Set conceptsForDrugs, List allDrugOrders) { + Set drugConcepts = new LinkedHashSet<>(); + for (Concept conceptsForDrug : conceptsForDrugs) { + for (Order drugOrder : allDrugOrders) { + if (conceptsForDrug.equals(drugOrder.getConcept()) && !drugConcepts.contains(conceptsForDrug)) { + drugConcepts.add(conceptsForDrug); + } + } + } + return drugConcepts; + } + + private Set getConceptsForDrugs(List drugs) { + if (drugs == null) return null; + Set drugConcepts = new LinkedHashSet<>(); + for (String drug : drugs) { + Concept concept = bahmniConceptService.getConceptByFullySpecifiedName(drug); + getDrugs(concept, drugConcepts); + } + return drugConcepts; + } + + private void getDrugs(Concept concept, Set drugConcepts) { + if (concept == null) { + return; + } + if (concept.isSet()) { + for (Concept drugConcept : concept.getSetMembers()) { + getDrugs(drugConcept, drugConcepts); + } + } else { + drugConcepts.add(concept); + } + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetController.java new file mode 100644 index 0000000000..b8be36ae50 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetController.java @@ -0,0 +1,326 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.util.BahmniDateUtil; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.BahmniFormBuilderObsToTabularViewMapper; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.BahmniObservationsToTabularViewMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.drugogram.contract.BaseTableExtension; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotRow; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +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 java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import static java.util.Objects.isNull; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/observations/flowSheet") +public class ObsToObsTabularFlowSheetController { + + public static final String CONCEPT_DETAILS = "Concept Details"; + private BahmniObsService bahmniObsService; + private ConceptService conceptService; + private BahmniObservationsToTabularViewMapper bahmniObservationsToTabularViewMapper; + private BahmniConceptService bahmniConceptService; + private BahmniFormBuilderObsToTabularViewMapper bahmniFormBuilderObsToTabularViewMapper; + private ConceptMapper conceptMapper; + private BahmniExtensions bahmniExtensions; + public static final String FLOWSHEET_EXTENSION = "flowsheetExtension"; + + private static Logger logger = LogManager.getLogger(ObsToObsTabularFlowSheetController.class); + + @Autowired + public ObsToObsTabularFlowSheetController(BahmniObsService bahmniObsService, ConceptService conceptService, + BahmniObservationsToTabularViewMapper bahmniObservationsToTabularViewMapper, + BahmniExtensions bahmniExtensions, + BahmniConceptService bahmniConceptService, + BahmniFormBuilderObsToTabularViewMapper bahmniFormBuilderObsToTabularViewMapper) { + this.bahmniObsService = bahmniObsService; + this.conceptService = conceptService; + this.bahmniObservationsToTabularViewMapper = bahmniObservationsToTabularViewMapper; + this.conceptMapper = new ConceptMapper(); + this.bahmniExtensions = bahmniExtensions; + this.bahmniConceptService = bahmniConceptService; + this.bahmniFormBuilderObsToTabularViewMapper = bahmniFormBuilderObsToTabularViewMapper; + } + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public PivotTable constructPivotTableFor( + @RequestParam(value = "patientUuid", required = true) String patientUuid, + @RequestParam(value = "numberOfVisits", required = false) Integer numberOfVisits, + @RequestParam(value = "conceptSet", required = false) String conceptSet, + @RequestParam(value = "groupByConcept", required = true) String groupByConcept, + @RequestParam(value = "orderByConcept", required = false) String orderByConcept, + @RequestParam(value = "conceptNames", required = false) List conceptNames, + @RequestParam(value = "initialCount", required = false) Integer initialCount, + @RequestParam(value = "latestCount", required = false) Integer latestCount, + @RequestParam(value = "name", required = false) String groovyExtension, + @RequestParam(value = "startDate", required = false) String startDateStr, + @RequestParam(value = "endDate", required = false) String endDateStr, + @RequestParam(value = "enrollment", required = false) String patientProgramUuid, + @RequestParam(value = "formNames", required = false) List formNames) throws ParseException { + + Date startDate = BahmniDateUtil.convertToDate(startDateStr, BahmniDateUtil.DateFormatType.UTC); + Date endDate = BahmniDateUtil.convertToDate(endDateStr, BahmniDateUtil.DateFormatType.UTC); + + PivotTable pivotTable; + if (conceptSet != null) { + pivotTable = getPivotTableByConceptSet(patientUuid, numberOfVisits, conceptSet, groupByConcept, + conceptNames, initialCount, latestCount, startDate, endDate, patientProgramUuid); + } else { + pivotTable = getPivotTableByFormNames(patientUuid, numberOfVisits, groupByConcept, conceptNames, + initialCount, latestCount, startDate, endDate, patientProgramUuid, formNames); + } + setNormalRangeAndUnits(pivotTable.getHeaders()); + + if(orderByConcept != null) { + orderPivotTableByGivenConcept(pivotTable, orderByConcept); + } + if(StringUtils.isEmpty(groovyExtension)){ + return pivotTable; + } + + BaseTableExtension extension = (BaseTableExtension) bahmniExtensions.getExtension(FLOWSHEET_EXTENSION, groovyExtension + BahmniExtensions.GROOVY_EXTENSION); + if (extension != null) + extension.update(pivotTable, patientUuid, patientProgramUuid); + return pivotTable; + } + + private PivotTable getPivotTableByConceptSet(String patientUuid, Integer numberOfVisits, String conceptSet, + String groupByConcept, List conceptNames, + Integer initialCount, Integer latestCount, Date startDate, + Date endDate, String patientProgramUuid) { + Concept rootConcept = conceptService.getConceptByName(conceptSet); + Concept childConcept = conceptService.getConceptByName(groupByConcept); + validate(conceptSet, groupByConcept, rootConcept, childConcept); + + Collection bahmniObservations = bahmniObsService.observationsFor( + patientUuid, rootConcept, childConcept, numberOfVisits, startDate, endDate, patientProgramUuid); + + Set leafConcepts = new LinkedHashSet<>(); + if (CollectionUtils.isEmpty(conceptNames)) { + getAllLeafConcepts(rootConcept, leafConcepts); + } else { + getSpecifiedLeafConcepts(rootConcept, conceptNames, leafConcepts); + } + if (!CollectionUtils.isEmpty(conceptNames)) { + leafConcepts = sortConcepts(conceptNames, leafConcepts); + } + if (conceptNames != null && !conceptNames.contains(groupByConcept)) { + leafConcepts.add(conceptMapper.map(childConcept)); + } + bahmniObservations = filterDataByCount(bahmniObservations, initialCount, latestCount); + return bahmniObservationsToTabularViewMapper.constructTable(leafConcepts, bahmniObservations, groupByConcept); + } + + private PivotTable getPivotTableByFormNames(String patientUuid, Integer numberOfVisits, String groupByConceptName, + List conceptNames, Integer initialCount, Integer latestCount, + Date startDate, Date endDate, String patientProgramUuid, + List formNames) { + if (isNull(conceptNames) || isNull(formNames) || formNames.size() < 1) { + logger.warn("Form name(s) and concept name(s) are required for forms 2.0"); + return new PivotTable(); + } + Collection bahmniObservations = bahmniObsService.getObsForFormBuilderForms(patientUuid, + formNames, numberOfVisits, startDate, endDate, patientProgramUuid); + conceptNames.add(groupByConceptName); + Set leafConcepts = + bahmniConceptService.getConceptsByFullySpecifiedName(conceptNames) + .stream().map(concept -> conceptMapper.map(concept)).collect(Collectors.toCollection(LinkedHashSet::new)); + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(leafConcepts, + bahmniObservations, groupByConceptName); + List rows = (List) filterDataByCount(pivotTable.getRows(), initialCount, latestCount); + pivotTable.setRows(bahmniFormBuilderObsToTabularViewMapper.getNonEmptyRows(rows, groupByConceptName)); + return pivotTable; + } + + private void setNormalRangeAndUnits(Set headers) { + for (EncounterTransaction.Concept header : headers) { + if (CONCEPT_DETAILS.equals(header.getConceptClass())) { + List setMembers = conceptService.getConceptsByConceptSet(conceptService.getConceptByUuid(header.getUuid())); + Concept primaryConcept = getNumeric(setMembers); + if (primaryConcept == null) continue; + header.setHiNormal(getHiNormal(primaryConcept)); + header.setLowNormal(getLowNormal(primaryConcept)); + header.setUnits(getUnits(primaryConcept)); + } + } + } + + private String getUnits(Concept primaryConcept) { + return conceptService.getConceptNumeric(primaryConcept.getConceptId()).getUnits(); + } + + private Double getLowNormal(Concept primaryConcept) { + return conceptService.getConceptNumeric(primaryConcept.getConceptId()).getLowNormal(); + } + + private Double getHiNormal(Concept primaryConcept) { + return conceptService.getConceptNumeric(primaryConcept.getConceptId()).getHiNormal(); + } + + private Concept getNumeric(List setMembers) { + for (Concept setMember : setMembers) { + if (setMember.getDatatype().isNumeric()) { + return setMember; + } + } + return null; + } + + private Set sortConcepts(List conceptNames, Set leafConcepts) { + Set sortedConcepts = new LinkedHashSet<>(); + for (String conceptName : conceptNames) { + for (EncounterTransaction.Concept leafConcept : leafConcepts) { + if (conceptName.equals(leafConcept.getName())) { + sortedConcepts.add(leafConcept); + } + } + } + return sortedConcepts; + } + + private Collection filterDataByCount(Collection observations, Integer initialCount, + Integer latestCount) { + if (initialCount == null && latestCount == null) return observations; + Collection observationCollection = new ArrayList<>(); + + if (observations.size() < (getIntegerValue(initialCount) + getIntegerValue(latestCount))) { + latestCount = observations.size(); + initialCount = 0; + } + observationCollection.addAll(filter(observations, 0, getIntegerValue(initialCount))); + observationCollection.addAll(filter(observations, observations.size() - getIntegerValue(latestCount), observations.size())); + + return observationCollection; + } + + private Collection filter(Collection observations, Integer fromIndex, Integer toIndex) { + Collection observationCollection = new ArrayList<>(); + fromIndex = (fromIndex > observations.size() || fromIndex < 0) ? 0 : fromIndex; + toIndex = (toIndex > observations.size()) ? observations.size() : toIndex; + for (int index = fromIndex; index < toIndex; index++) { + observationCollection.add((T) CollectionUtils.get(observations, index)); + } + return observationCollection; + } + + private int getIntegerValue(Integer value) { + if (value == null) return 0; + return value; + } + + private void getSpecifiedLeafConcepts(Concept rootConcept, List conceptNames, Set leafConcepts) { + for (Concept concept : rootConcept.getSetMembers()) { + if (conceptNames.contains(concept.getName().getName())) { + getAllLeafConcepts(concept, leafConcepts); + } else { + getSpecifiedLeafConcepts(concept, conceptNames, leafConcepts); + } + } + } + + private void getAllLeafConcepts(Concept rootConcept, Set leafConcepts) { + if (!rootConcept.isSet() || rootConcept.getConceptClass().getName().equals(CONCEPT_DETAILS)) { + leafConcepts.add(conceptMapper.map(rootConcept)); + } else { + for (Concept concept : rootConcept.getSetMembers()) { + getAllLeafConcepts(concept, leafConcepts); + } + } + } + + private void validate(String conceptSet, String groupByConcept, Concept rootConcept, Concept childConcept) { + if (rootConcept == null) { + logger.error("Root concept not found for the name: {} ", conceptSet); + throw new RuntimeException("Root concept not found for the name: " + conceptSet); + } + + if (!rootConcept.getSetMembers().contains(childConcept)) { + logger.error("GroupByConcept: {} doesn't belong to the Root concept: {} ", groupByConcept, conceptSet); + throw new RuntimeException("GroupByConcept: " + groupByConcept + " doesn't belong to the Root concept: " + conceptSet); + } + } + + private void orderPivotTableByGivenConcept(PivotTable pivotTable, String orderByConcept) throws ParseException { + TreeMap> orderConceptToPivotRowMap = new TreeMap<>(); + List allowedDataTypesForOrdering = Arrays.asList("Date", "Numeric", "Coded", "Text"); + Concept orderConcept = conceptService.getConceptByName(orderByConcept); + if(allowedDataTypesForOrdering.contains(orderConcept.getDatatype().getName())) { + List orderedRows = new ArrayList<>(); + for(PivotRow pivotRow : pivotTable.getRows()) { + List bahmniObservations = pivotRow.getColumns().get(orderByConcept); + Object value = null; + if(CollectionUtils.isEmpty(bahmniObservations)) { + value = getValueForNull(orderConcept.getDatatype().getName()); + } else { + value = getValue(bahmniObservations.get(0)); + } + if(orderConceptToPivotRowMap.containsKey(value)) { + orderConceptToPivotRowMap.get(value).add(pivotRow); + } else { + List pivotRows = new ArrayList<>(); + pivotRows.add(pivotRow); + orderConceptToPivotRowMap.put(value, pivotRows); + } + } + for(Entry> entry : orderConceptToPivotRowMap.entrySet()) { + orderedRows.addAll(entry.getValue()); + } + pivotTable.setRows(orderedRows); + } + } + + private Object getValue(BahmniObservation bahmniObservation) throws ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + if("Date".equals(bahmniObservation.getType())) { + return simpleDateFormat.parse(bahmniObservation.getValueAsString()); + } else if("Coded".equals(bahmniObservation.getType())) { + return ((EncounterTransaction.Concept)bahmniObservation.getValue()).getName(); + } else if("Text".equals(bahmniObservation.getType())) { + return bahmniObservation.getValue(); + } else if("Numeric".equals(bahmniObservation.getType())) { + return bahmniObservation.getValue(); + } + return null; + } + + private Object getValueForNull(String type) { + if ("Date".equals(type)) { + return new Date(); + } else if ("Numeric".equals(type)) { + return new Double(0); + } else { + return ""; + } + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonAttributeSearchController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonAttributeSearchController.java new file mode 100644 index 0000000000..84683a8db5 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonAttributeSearchController.java @@ -0,0 +1,30 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.search; + +import org.bahmni.module.bahmnicore.dao.PersonAttributeDao; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.WSDoc; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/search/personattribute") +public class PersonAttributeSearchController extends BaseRestController { + + private PersonAttributeDao personAttributeDao; + + @Autowired + public PersonAttributeSearchController(PersonAttributeDao personAttributeDao) { + this.personAttributeDao = personAttributeDao; + } + + @RequestMapping(method = RequestMethod.GET, params = { "q", "key" }) + @WSDoc("Get unique values for a person attribute") + public ResultList search(@RequestParam String key, @RequestParam String q) { + return personAttributeDao.getUnique(key, q); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonNameSearchController.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonNameSearchController.java new file mode 100644 index 0000000000..6e04a33936 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonNameSearchController.java @@ -0,0 +1,30 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.search; + +import org.bahmni.module.bahmnicore.dao.PersonNameDao; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.WSDoc; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@RequestMapping(value = "/rest/" + RestConstants.VERSION_1 + "/bahmnicore/search/personname") +public class PersonNameSearchController extends BaseRestController { + + private PersonNameDao namesDao; + + @Autowired + public PersonNameSearchController(PersonNameDao namesDao) { + this.namesDao = namesDao; + } + + @RequestMapping(method = RequestMethod.GET, params = { "q", "key" }) + @WSDoc("Returns unique patient attributes for the given key that match the query term") + public ResultList searchFor(@RequestParam String q, @RequestParam String key) { + return namesDao.getUnique(key, q); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniFormBuilderObsToTabularViewMapper.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniFormBuilderObsToTabularViewMapper.java new file mode 100644 index 0000000000..404fa099d5 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniFormBuilderObsToTabularViewMapper.java @@ -0,0 +1,90 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotRow; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.bahmni.module.bahmnicore.forms2.util.FormUtil.getParentFormFieldPath; + +@Component +public class BahmniFormBuilderObsToTabularViewMapper extends BahmniObservationsToTabularViewMapper { + public PivotTable constructTable(Set concepts, + Collection bahmniObservations, String groupByConcept) { + PivotTable pivotTable = new PivotTable(); + if (bahmniObservations == null) { + return pivotTable; + } + List rows = constructRows(concepts, bahmniObservations, groupByConcept); + + pivotTable.setHeaders(concepts); + pivotTable.setRows(rows); + return pivotTable; + } + + public List getNonEmptyRows(List rows, String groupByConceptName) { + return rows.stream().filter(row -> isNonNullRow(groupByConceptName, row)).collect(Collectors.toList()); + } + + private List constructRows(Set concepts, + Collection bahmniObservations, String groupByConceptName) { + Map> rowsMapper = getRowsMapper(bahmniObservations, groupByConceptName); + List rows = new ArrayList<>(); + rowsMapper.forEach((rowIdentifier, rowObservations) -> { + PivotRow row = new PivotRow(); + rowObservations.forEach(observation -> addColumn(concepts, row, observation)); + if (row.getColumns().containsKey(groupByConceptName)) { + rows.add(row); + } + }); + return rows; + } + + private Map> getRowsMapper(Collection bahmniObservations, + String groupByConceptName) { + final Map> obsRows = prepareMapWithRowIdentifier(bahmniObservations, + groupByConceptName); + for (BahmniObservation observation : bahmniObservations) { + final String currentObsRowIdentifier = getRowIdentifier(observation); + for (String rowIdentifier : obsRows.keySet()) { + if (currentObsRowIdentifier.startsWith(rowIdentifier)) { + obsRows.get(rowIdentifier).add(observation); + break; + } + } + } + return obsRows; + } + + // Observation rows are distinguished by encounter uuid and obs parent formFieldPath + private String getRowIdentifier(BahmniObservation bahmniObservation) { + return bahmniObservation.getEncounterUuid() + getParentFormFieldPath(bahmniObservation.getFormFieldPath()); + } + + + private Map> prepareMapWithRowIdentifier(Collection bahmniObservations, + String groupByConceptName) { + List groupByConceptObservations = getGroupByConceptObservations(bahmniObservations, + groupByConceptName); + Map> rowsMapper = new LinkedHashMap<>(); + groupByConceptObservations.forEach(observation + -> rowsMapper.put(getRowIdentifier(observation), new ArrayList<>())); + return rowsMapper; + } + + private List getGroupByConceptObservations(Collection bahmniObservations, + String groupByConceptName) { + return bahmniObservations.stream() + .filter(observation -> observation.getConcept().getName().equals(groupByConceptName)) + .collect(Collectors.toList()); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniObservationsToTabularViewMapper.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniObservationsToTabularViewMapper.java new file mode 100644 index 0000000000..f56f7a5432 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniObservationsToTabularViewMapper.java @@ -0,0 +1,87 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.Predicate; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotRow; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Component +public class BahmniObservationsToTabularViewMapper { + public PivotTable constructTable(Set conceptNames, Collection bahmniObservations, String groupByConcept) { + PivotTable pivotTable = new PivotTable(); + if (bahmniObservations == null) { + return pivotTable; + } + + List rows = new ArrayList<>(); + + for (BahmniObservation bahmniObservation : bahmniObservations) { + PivotRow pivotRow = constructRow(bahmniObservation, conceptNames); + if (isNonNullRow(groupByConcept, pivotRow)) { + rows.add(pivotRow); + } + } + + pivotTable.setRows(rows); + pivotTable.setHeaders(conceptNames); + return pivotTable; + } + + boolean isNonNullRow(String groupByConcept, PivotRow pivotRow) { + Map> pivotRowColumns = pivotRow.getColumns(); + boolean nonNullRow = false; + + for (String key : pivotRowColumns.keySet()) { + if (!key.equals(groupByConcept) && pivotRowColumns.get(key) != null) { + ArrayList obs = pivotRowColumns.get(key); + for (BahmniObservation ob : obs) { + if (ob.getValue() != null) + nonNullRow = true; + } + } + } + return nonNullRow; + } + + private PivotRow constructRow(BahmniObservation bahmniObservation, Set conceptNames) { + PivotRow row = new PivotRow(); + constructColumns(conceptNames, row, bahmniObservation); + return row; + } + + private void constructColumns(Set conceptNames, PivotRow row, BahmniObservation observation) { + if (observation.getConcept().isSet()) { + if (observation.getConcept().getConceptClass().equals("Concept Details")) { + addColumn(conceptNames, row, observation); + } + for (BahmniObservation bahmniObservation : observation.getGroupMembers()) { + constructColumns(conceptNames, row, bahmniObservation); + } + } else { + addColumn(conceptNames, row, observation); + } + } + + void addColumn(Set conceptNames, PivotRow row, final BahmniObservation observation) { + Object foundElement = CollectionUtils.find(conceptNames, new Predicate() { + @Override + public boolean evaluate(Object o) { + EncounterTransaction.Concept concept = (EncounterTransaction.Concept) o; + return concept.getUuid().equals(observation.getConcept().getUuid()); + } + }); + if (foundElement != null) { + row.addColumn(observation.getConcept().getName(), observation); + } + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniPatientContextMapper.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniPatientContextMapper.java new file mode 100644 index 0000000000..c2f6b20b25 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniPatientContextMapper.java @@ -0,0 +1,90 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.openmrs.PatientProgramAttribute; +import org.openmrs.Concept; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.PersonAttribute; +import org.openmrs.PatientProgram; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.patient.PatientContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class BahmniPatientContextMapper { + @Autowired + private ConceptService conceptService; + + public PatientContext map(Patient patient, PatientProgram patientProgram, List configuredPersonAttributes, List configuredProgramAttributes, List configuredPatientIdentifiers, PatientIdentifierType primaryIdentifierType) { + PatientContext patientContext = new PatientContext(); + + patientContext.setBirthdate(patient.getBirthdate()); + patientContext.setFamilyName(patient.getFamilyName()); + patientContext.setGivenName(patient.getGivenName()); + patientContext.setMiddleName(patient.getMiddleName()); + patientContext.setGender(patient.getGender()); + patientContext.setIdentifier(patient.getPatientIdentifier(primaryIdentifierType).getIdentifier()); + patientContext.setUuid(patient.getUuid()); + + mapConfiguredPersonAttributes(patient, configuredPersonAttributes, patientContext); + mapConfiguredProgramAttributes(patientProgram, configuredProgramAttributes, patientContext); + mapConfiguredPatientIdentifier(patient, configuredPatientIdentifiers, patientContext,primaryIdentifierType); + return patientContext; + } + + private void mapConfiguredPatientIdentifier(Patient patient, List configuredPatientIdentifiers, PatientContext patientContext, PatientIdentifierType primaryIdentifierType) { + if (CollectionUtils.isEmpty(configuredPatientIdentifiers)) { + return; + } + for (String configuredPatientIdentifier : configuredPatientIdentifiers) { + PatientIdentifier patientIdentifier = patient.getPatientIdentifier(configuredPatientIdentifier); + if (patientIdentifier != null && !configuredPatientIdentifier.equals(primaryIdentifierType.getName())) { + patientContext.addAdditionalPatientIdentifier(configuredPatientIdentifier, patientIdentifier.getIdentifier()); + } + } + } + + private void mapConfiguredProgramAttributes(PatientProgram patientProgram, List configuredProgramAttributes, PatientContext patientContext) { + if (patientProgram == null || configuredProgramAttributes == null) { + return; + } + for (String configuredProgramAttribute : configuredProgramAttributes) { + for (PatientProgramAttribute patientProgramAttribute : patientProgram.getActiveAttributes()) { + if (patientProgramAttribute.getAttributeType().getName().equals(configuredProgramAttribute)) { + if (patientProgramAttribute.getAttributeType().getDatatypeClassname().equals("org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype")) { + Concept concept = conceptService.getConcept(patientProgramAttribute.getValueReference()); + patientContext.addProgramAttribute(configuredProgramAttribute, patientProgramAttribute.getAttributeType().getDescription(), concept.getName().getName()); + } else { + patientContext.addProgramAttribute(configuredProgramAttribute, patientProgramAttribute.getAttributeType().getDescription(), patientProgramAttribute.getValueReference()); + } + } + } + } + } + + private void mapConfiguredPersonAttributes(Patient patient, List configuredPersonAttributes, PatientContext patientContext) { + if (configuredPersonAttributes == null) { + return; + } + for (String configuredPersonAttribute : configuredPersonAttributes) { + PersonAttribute personAttribute = patient.getAttribute(configuredPersonAttribute); + mapPersonAttribute(patientContext, configuredPersonAttribute, personAttribute); + } + } + + private void mapPersonAttribute(PatientContext patientContext, String configuredPersonAttribute, PersonAttribute personAttribute) { + if (personAttribute != null) { + if (personAttribute.getAttributeType().getFormat().equals("org.openmrs.Concept")) { + Concept concept = conceptService.getConcept(personAttribute.getValue()); + patientContext.addPersonAttribute(configuredPersonAttribute, personAttribute.getAttributeType().getDescription(), concept.getName().getName()); + } else { + patientContext.addPersonAttribute(configuredPersonAttribute, personAttribute.getAttributeType().getDescription(), personAttribute.getValue()); + } + } + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/CustomObjectMapper.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/CustomObjectMapper.java new file mode 100644 index 0000000000..507e0628e0 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/CustomObjectMapper.java @@ -0,0 +1,17 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; + +@Component +public class CustomObjectMapper extends ObjectMapper { + public CustomObjectMapper() { + super(); + configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); + configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false); + _serializationConfig.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToRegimenMapper.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToRegimenMapper.java new file mode 100644 index 0000000000..ec65bdfe79 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToRegimenMapper.java @@ -0,0 +1,135 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicoreui.mapper.DoseInstructionMapper; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.drugogram.contract.RegimenRow; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +@Component +public class DrugOrderToRegimenMapper { + + + public TreatmentRegimen map(List drugOrders, Set headersConfig) throws ParseException { + TreatmentRegimen treatmentRegimen = new TreatmentRegimen(); + Set headers = new LinkedHashSet<>(); + + for (Order drugOrder : drugOrders) { + Date stopDate = getDrugStopDate(drugOrder); + Date startDate = getDrugStartDate(drugOrder); + + treatmentRegimen.addRow(startDate); + if (stopDate != null) { + treatmentRegimen.addRow(stopDate); + } + } + + for (RegimenRow regimenRow : treatmentRegimen.getRows()) { + for (Order drugOrder : drugOrders) { + DrugOrder order = (DrugOrder) drugOrder; + headers.add(drugOrder.getConcept()); + String newValue = getValueForField(order, regimenRow.getDate()); + + if (!newValue.isEmpty()) { + String drugConceptName = order.getConcept().getName().getName(); + + String oldValue = regimenRow.getDrugValue(drugConceptName); + String value = oldValue.isEmpty() ? newValue : drugStartedOnTheStopDate(oldValue, newValue); + regimenRow.addDrugs(drugConceptName, value); + } + } + } + Set headersConcept; + if (!CollectionUtils.isEmpty(headersConfig)) + headersConcept = mapHeaders(headersConfig); + else + headersConcept = mapHeaders(headers); + treatmentRegimen.setHeaders(headersConcept); + + return treatmentRegimen; + } + + private Set mapHeaders(Set headers) { + Set headersConcept = new LinkedHashSet<>(); + for (Concept header : headers) { + headersConcept.add(new ConceptMapper().map(header)); + } + return headersConcept; + } + + private String drugStartedOnTheStopDate(String oldValue, String newValue) { + if(oldValue.equals("Stop")) + return newValue; + if(newValue.equals("Stop")) + return oldValue; + return "Error"; + } + + public String getValueForField(DrugOrder drugOrder, Date rowDate) throws ParseException { + Date startDate = getDrugStartDate(drugOrder); + Date stopDate = getDrugStopDate(drugOrder); + + if (startDate.equals(rowDate) || startDate.before(rowDate)) { + if(stopDate == null || (stopDate.after(rowDate))){ + return getDose(drugOrder); + } + + if (stopDate.equals(rowDate)) { + return startDate.equals(stopDate) ? "Error" : "Stop"; + } + } + return ""; + } + + private Date getOnlyDate(Date date) throws ParseException { + if (date == null) + return null; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(sdf.format(date)); + } + + private Date getDrugStartDate(Order drugOrder) throws ParseException { + + return drugOrder.getScheduledDate() != null ? + getOnlyDate(drugOrder.getScheduledDate()) : + getOnlyDate(drugOrder.getDateActivated()); + } + + private Date getDrugStopDate(Order drugOrder) throws ParseException { + return drugOrder.getDateStopped() != null ? + getOnlyDate(drugOrder.getDateStopped()) : + getOnlyDate(drugOrder.getAutoExpireDate()); + } + + private String getDose(DrugOrder drugOrder) { + String dosage = null; + if (drugOrder.getFrequency() == null) { + try { + dosage = DoseInstructionMapper.getFrequency(drugOrder); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + if (drugOrder.getDose() != null) { + dosage = drugOrder.getDose().toString(); + } else { + dosage = ""; + } + } + return dosage; + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/EntityMapper.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/EntityMapper.java new file mode 100644 index 0000000000..7df6a0590a --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/EntityMapper.java @@ -0,0 +1,53 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.bahmni.module.bahmnicore.contract.entityMapping.Entity; +import org.bahmni.module.bahmnicore.dao.EntityDao; +import org.openmrs.module.bahmnimapping.model.EntityMapping; +import org.openmrs.module.bahmnimapping.model.EntityMappingType; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class EntityMapper { + + public List map(Collection entityMappings, EntityDao entityDao, EntityMappingType entityMappingType,String entityUuid) { + List entityMappingList = new ArrayList(); + Class entity1Class = null; + Class entity2Class = null; + try { + entity1Class = Class.forName(entityMappingType.getEntity1Type()); + entity2Class = Class.forName(entityMappingType.getEntity2Type()); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + if (entityMappings.isEmpty() && entityUuid!=null) { + Object entity = entityDao.getByUuid(entityUuid, entity1Class); + entityMappingList.add(new Entity(entity, new ArrayList())); + return entityMappingList; + + } else { + + for (EntityMapping entityMapping : entityMappings) { + boolean foundEntity = false; + List mappings = new ArrayList<>(); + Object entity = entityDao.getByUuid(entityMapping.getEntity1Uuid(), entity1Class); + Object mappedEntity = entityDao.getByUuid(entityMapping.getEntity2Uuid(), entity2Class); + for (Entity entityMap : entityMappingList) { + if (entityMap.getEntity().equals(entity)) { + entityMap.addMapping(mappedEntity); + foundEntity = true; + break; + } + } + if (!foundEntity) { + mappings.add(mappedEntity); + entityMappingList.add(new Entity(entity, mappings)); + } + } + return entityMappingList; + } + + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandler.java new file mode 100644 index 0000000000..45661a7f96 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandler.java @@ -0,0 +1,80 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bacteriology.api.BacteriologyService; +import org.openmrs.module.bacteriology.api.encounter.domain.Specimen; +import org.openmrs.module.bacteriology.api.encounter.domain.Specimens; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static java.util.Arrays.asList; + +@Component +public class BacteriologySpecimenSearchHandler implements SearchHandler { + + private final String BACTERIOLOGY_CONCEPT_SET = "BACTERIOLOGY CONCEPT SET"; + private final String QUERY_INFORMATION = "Allows you to toString specimens based on the pateint program enrollment."; + + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + private ConceptService conceptService; + private ObsService obsService; + + @Autowired + public BacteriologySpecimenSearchHandler(@Qualifier("bahmniProgramWorkflowService") + BahmniProgramWorkflowService bahmniProgramWorkflowService, + ConceptService conceptService, + ObsService obsService) { + this.bahmniProgramWorkflowService = bahmniProgramWorkflowService; + this.conceptService = conceptService; + this.obsService = obsService; + } + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder(QUERY_INFORMATION).withRequiredParameters("patientProgramUuid").build(); + return new SearchConfig("byPatientProgram", RestConstants.VERSION_1 + "/specimen", asList("1.10.* - 2.*"), searchQuery); + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + + BacteriologyService bacteriologyService = Context.getService(BacteriologyService.class); + String patientProgramUuid = requestContext.getParameter("patientProgramUuid"); + Collection encounters = bahmniProgramWorkflowService.getEncountersByPatientProgramUuid(patientProgramUuid); + if (CollectionUtils.isEmpty(encounters)) { + return new EmptySearchResult(); + } + List encountersAsList = new ArrayList<>(encounters); + + Concept bacteriologyConceptSet = conceptService.getConceptByName(BACTERIOLOGY_CONCEPT_SET); + List concepts = Arrays.asList(bacteriologyConceptSet); + List observations = obsService.getObservations(null, encountersAsList, concepts, null, null, null, null, null, null, null, null, false); + + Specimens sortedSpecimens = bacteriologyService.getSpecimens(observations).sortByDateCollected(); + + return new NeedsPaging(sortedSpecimens, requestContext); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandler.java new file mode 100644 index 0000000000..e10610e281 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandler.java @@ -0,0 +1,52 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.web.v1_0.contract.BahmniConceptAnswer; +import org.openmrs.ConceptAnswer; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +@Component +public class BahmniConceptAnswerSearchHandler implements SearchHandler { + + public static final String QUESTION_KEY = "question"; + public static final String QUERY = "q"; + private BahmniConceptService bahmniConceptService; + + @Autowired + public BahmniConceptAnswerSearchHandler(BahmniConceptService bahmniConceptService) { + this.bahmniConceptService = bahmniConceptService; + } + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder("Allows you to search for concepts based on a question").withRequiredParameters(QUESTION_KEY).build(); + return new SearchConfig("byQuestion", RestConstants.VERSION_1 + "/bahmniconceptanswer", Arrays.asList("1.9.* - 2.*"), searchQuery); + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + String questionConceptName = requestContext.getParameter(QUESTION_KEY); + String query = requestContext.getParameter(QUERY); + Collection conceptAnswers = bahmniConceptService.searchByQuestion(questionConceptName, query); + + ArrayList bahmniConceptAnswers = new ArrayList<>(); + for (ConceptAnswer answer : conceptAnswers) { + bahmniConceptAnswers.add(BahmniConceptAnswer.create(answer)); + } + + return new NeedsPaging<>(bahmniConceptAnswers, requestContext); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java new file mode 100644 index 0000000000..af0b2c4f74 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandler.java @@ -0,0 +1,91 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +@Component +public class BahmniConceptSearchByDataTypeHandler implements SearchHandler { + + public static final String NAME = "name"; + public static final String DATA_TYPES = "dataTypes"; + + @Autowired + @Qualifier("conceptService") + private ConceptService conceptService; + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder("Allows you to search for concepts by data types").withRequiredParameters(NAME, DATA_TYPES).build(); + return new SearchConfig("byDataType", RestConstants.VERSION_1 + "/concept", Arrays.asList("1.9.* - 2.*"), searchQuery); + } + + @Override + public PageableResult search(RequestContext context) throws ResponseException { + + String conceptName = context.getParameter(NAME); + String dataTypes = context.getParameter(DATA_TYPES); + List supportedDataTypes = Arrays.asList(dataTypes.split(",")); + + List conceptDatatypes =new ArrayList<>(); + + for( String dataType: supportedDataTypes){ + ConceptDatatype conceptDatatype = conceptService.getConceptDatatypeByName(dataType.trim()); + if(conceptDatatype != null) { + conceptDatatypes.add(conceptDatatype); + } + } + + List concepts = new ArrayList<>(); + + List localeList = getLocales(context); + + List conceptsByName = + conceptService.getConcepts(conceptName, localeList, false, null, null, conceptDatatypes, null, null, context.getStartIndex(), context.getLimit()); + + for (ConceptSearchResult csr : conceptsByName) { + if (csr.getConcept() != null) + concepts.add(csr.getConcept()); + } + + return new NeedsPaging(concepts, context); + + } + + private List getLocales(RequestContext context) { + String locale = context.getParameter("locale"); + + List localeList = new ArrayList<>(); + + if (locale != null) { + localeList.add(LocaleUtility.fromSpecification(locale)); + } else { + localeList.add(Context.getLocale()); + if (!LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + localeList.add(LocaleUtility.getDefaultLocale()); + } + } + + return localeList; + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java new file mode 100644 index 0000000000..d401b7c432 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandler.java @@ -0,0 +1,102 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.apache.commons.collections.CollectionUtils; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +@Component +public class BahmniConceptSearchHandler implements SearchHandler { + + @Autowired + @Qualifier("conceptService") + ConceptService conceptService; + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder("Allows you to search for concepts by fully specified name").withRequiredParameters("name").build(); + return new SearchConfig("byFullySpecifiedName", RestConstants.VERSION_1 + "/concept", Arrays.asList("1.8.* - 2.*"), searchQuery); + } + + /** + * Searches for concepts by the given parameters. (Currently only supports name and locale (optional)) + * @return a list of concepts matching the given parameters. + * @throws APIException + * Should return concepts in the specified locale if specified. + * Should return concepts in the default locale as well as logged in locale if locale is not specified. + */ + + @Override + public PageableResult search(RequestContext context) throws ResponseException { + String conceptName = context.getParameter("name"); + List localeList = getLocales(context); + + List conceptsSearchResult = conceptService.getConcepts(conceptName, localeList, false, null, null, null, null, null, 0, null); + List conceptsByName = conceptsSearchResult.stream().map(conceptSearchResult -> conceptSearchResult.getConcept()).collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(conceptsByName)) { + return new EmptySearchResult(); + } else { + List concepts = new ArrayList(); + boolean isPreferredOrFullySpecified = false; + for (Concept concept : conceptsByName) { + for (ConceptName conceptname : concept.getNames()) { + if (conceptname.getName().equalsIgnoreCase(conceptName) && (conceptname.isPreferred() || conceptname.isFullySpecifiedName())) { + concepts.add(concept); + isPreferredOrFullySpecified = true; + break; + } + } + } + if (!isPreferredOrFullySpecified) + throw new APIException("The concept name should be either a fully specified or locale preferred name"); + return new NeedsPaging(concepts, context); + } + } + + /** + * Returns list of unique locales based on the context.getParameter("locale") parameter + * Should return List of results for locales: If locale is specified, then return results for that locale. + * If locale is not specified, then return results for logged in locale and default locale. + */ + + private List getLocales(RequestContext context) { + String locale = context.getParameter("locale"); + + List localeList = new ArrayList<>(); + + if (locale != null) { + localeList.add(LocaleUtility.fromSpecification(locale)); + } else { + localeList.add(Context.getLocale()); + if (!LocaleUtility.getDefaultLocale().equals(Context.getLocale())) { + localeList.add(LocaleUtility.getDefaultLocale()); + } + } + + return localeList; + } + +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniDrugSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniDrugSearchHandler.java new file mode 100644 index 0000000000..c103759fac --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniDrugSearchHandler.java @@ -0,0 +1,59 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.openmrs.Drug; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; + +@Component +public class BahmniDrugSearchHandler implements SearchHandler { + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder("Allows you to search for drugs").withRequiredParameters("q").build(); + return new SearchConfig("ordered", RestConstants.VERSION_1 + "/drug", Arrays.asList("1.10.* - 2.*"), searchQuery); + } + + @Override + public PageableResult search(RequestContext ctx) throws ResponseException { + boolean includeRetired = ctx.getIncludeAll(); + String searchPhrase = ctx.getParameter("q"); + LinkedHashSet drugs = new LinkedHashSet<>(findDrugsStartingWith(searchPhrase, includeRetired, ctx)); + LinkedHashSet drugsHavingConcept = new LinkedHashSet<>(); + + + drugs.addAll(findDrugsContaining(searchPhrase, includeRetired, ctx)); + + if(ctx.getParameter("conceptUuid") != null) { + String conceptUuid = ctx.getParameter("conceptUuid"); + for(Drug drug : drugs){ + if(drug.getConcept().getUuid().equals(conceptUuid)){ + drugsHavingConcept.add(drug); + } + } + return new NeedsPaging<>(new ArrayList<>(drugsHavingConcept), ctx); + } + + return new NeedsPaging<>(new ArrayList<>(drugs), ctx); + } + + private List findDrugsStartingWith(String searchPhrase, boolean includeRetired, RequestContext ctx) { + return Context.getConceptService().getDrugs(searchPhrase, null, false, true, includeRetired, ctx.getStartIndex(), ctx.getLimit()); + } + + private List findDrugsContaining(String searchPhrase, boolean includeRetired, RequestContext ctx) { + return Context.getConceptService().getDrugs(searchPhrase, null, true, true, includeRetired, ctx.getStartIndex(), ctx.getLimit()); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniProviderSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniProviderSearchHandler.java new file mode 100644 index 0000000000..2935e4843b --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniProviderSearchHandler.java @@ -0,0 +1,109 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.openmrs.Provider; +import org.openmrs.ProviderAttributeType; +import org.openmrs.api.ProviderService; +import org.openmrs.customdatatype.CustomDatatype; +import org.openmrs.customdatatype.CustomDatatypeUtil; +import org.openmrs.customdatatype.InvalidCustomValueException; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.AlreadyPaged; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class BahmniProviderSearchHandler implements SearchHandler { + + public static final String PARAM_ATTRIBUTE_NAME = "attrName"; + public static final String PARAM_ATTRIBUTE_VALUE = "attrValue"; + public static final String PARAM_INCLUDE_ALL = "includeAll"; + public static final String SEARCH_BY_ATTRIBUTE = "byAttribute"; + public static final String ERR_UNDEFINED_ATTRIBUTE_NAME = "Undefined attribute %s"; + public static final String INVALID_ATTRIBUTE_VALUE = "Invalid attribute value for %s"; + + private static final Logger log = LogManager.getLogger(BahmniProviderSearchHandler.class); + public static final String INVALID_ATTRIBUTE_TYPE_DEFINITION = "Invalid Attribute type definition for %s"; + + @Autowired + ProviderService providerService; + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder("Allows you to find providers by attribute") + .withRequiredParameters(PARAM_ATTRIBUTE_NAME, PARAM_ATTRIBUTE_VALUE) + .build(); + return new SearchConfig(SEARCH_BY_ATTRIBUTE, + RestConstants.VERSION_1 + "/provider", + Arrays.asList("2.0.* - 2.*"), + searchQuery); + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + String attributeName = requestContext.getParameter(PARAM_ATTRIBUTE_NAME); + String attributeValue = requestContext.getParameter(PARAM_ATTRIBUTE_VALUE); + String includeAllStr = requestContext.getParameter(PARAM_INCLUDE_ALL); + + String query = requestContext.getParameter("q"); + boolean includeRetired = false; + if (!StringUtils.isEmpty(includeAllStr)) { + includeRetired = Boolean.getBoolean(includeAllStr); + } + + Map attributeTypeObjectMap = getProviderAttributeTypeObjectMap(attributeName, attributeValue); + + List providers = providerService.getProviders(query, requestContext.getStartIndex(), requestContext.getLimit(), attributeTypeObjectMap, includeRetired); + return new AlreadyPaged<>(requestContext, providers, false); + } + + private Map getProviderAttributeTypeObjectMap(String attributeName, String attributeValue) { + ProviderAttributeType attributeType = findProviderAttributeType(attributeName); + if (attributeType == null) { + throw new IllegalArgumentException(String.format(ERR_UNDEFINED_ATTRIBUTE_NAME, attributeName)); + } + + CustomDatatype attrDataType = CustomDatatypeUtil.getDatatype(attributeType.getDatatypeClassname(), attributeType.getDatatypeConfig()); + if (attrDataType == null) { + throw new IllegalArgumentException(String.format(INVALID_ATTRIBUTE_TYPE_DEFINITION, attributeName)); + } + + try { + Object value = attrDataType.fromReferenceString(attributeValue); + Map attributeTypeObjectMap = new HashMap<>(); + if (attributeType != null) { + attributeTypeObjectMap.put(attributeType, value); + } + return attributeTypeObjectMap; + + } catch (InvalidCustomValueException e) { + String errorMessage = String.format(INVALID_ATTRIBUTE_VALUE, attributeName); + log.error(errorMessage, e); + throw new IllegalArgumentException(errorMessage); + } + } + + private ProviderAttributeType findProviderAttributeType(String attributeName) { + List allProviderAttributeTypes = providerService.getAllProviderAttributeTypes(); + for (ProviderAttributeType attributeType : allProviderAttributeTypes) { + boolean result = attributeType.getName().equalsIgnoreCase(attributeName); + if (result) { + return attributeType; + } + } + return null; + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/ConceptSetBasedDrugSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/ConceptSetBasedDrugSearchHandler.java new file mode 100644 index 0000000000..ffaebf12c6 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/ConceptSetBasedDrugSearchHandler.java @@ -0,0 +1,41 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.openmrs.Drug; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.AlreadyPaged; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +@Component +public class ConceptSetBasedDrugSearchHandler implements SearchHandler{ + + @Autowired + private BahmniConceptService bahmniConceptService; + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder("Allows you to search for Drugs based on concept set").withRequiredParameters("q").build(); + return new SearchConfig("byConceptSet", RestConstants.VERSION_1 + "/drug", Arrays.asList("1.9.* - 2.*"), searchQuery); + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + String conceptSetName = requestContext.getParameter("q"); + String searchTerm = requestContext.getParameter("searchTerm"); + Collection drugs = bahmniConceptService.getDrugsByConceptSetName(conceptSetName, searchTerm); + List drugResponse = new ArrayList<>(drugs); + return new AlreadyPaged<>(requestContext, drugResponse, false); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandler.java new file mode 100644 index 0000000000..c3db59535b --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandler.java @@ -0,0 +1,66 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.contract.entityMapping.Entity; +import org.bahmni.module.bahmnicore.dao.EntityDao; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.EntityMapper; +import org.openmrs.module.bahmnimapping.dao.EntityMappingDao; +import org.openmrs.module.bahmnimapping.model.EntityMapping; +import org.openmrs.module.bahmnimapping.model.EntityMappingType; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.AlreadyPaged; +import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Component +public class EntityMappingSearchHandler implements SearchHandler { + private EntityMappingDao entityMappingDao; + + private EntityDao entityDao; + + @Autowired + public EntityMappingSearchHandler(EntityMappingDao entityMappingDao, EntityDao entityDao) { + this.entityMappingDao = entityMappingDao; + this.entityDao = entityDao; + } + + @Override + public SearchConfig getSearchConfig() { + return new SearchConfig("byEntityAndMappingType", RestConstants.VERSION_1 + "/entitymapping", Arrays.asList("1.9.* - 2.*"), + new SearchQuery.Builder("Allows you to find entity relationships of entity with specific mapping type") + .withOptionalParameters("entityUuid") + .withRequiredParameters("mappingType") + .build()); + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + EntityMapper entityMapper = new EntityMapper(); + String entityMappingTypeName = requestContext.getParameter("mappingType"); + String entityUuid = requestContext.getParameter("entityUuid"); + EntityMappingType entityMappingType = entityMappingDao.getEntityMappingTypeByName(entityMappingTypeName); + List entityMappings = new ArrayList(); + if (entityMappingType == null) { + return new EmptySearchResult(); + } + if (entityUuid != null) { + entityMappings = entityMappingDao.getMappingsOfEntity(entityUuid, entityMappingTypeName); + } + else { + entityMappings = entityMappingDao.getAllEntityMappings(entityMappingTypeName); + } + List entityList = entityMapper.map(entityMappings, entityDao, entityMappingType, entityUuid); + return new AlreadyPaged<>(requestContext, entityList, false); + + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSearchHandler.java new file mode 100644 index 0000000000..fa608af6f4 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSearchHandler.java @@ -0,0 +1,42 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.OrderService; +import org.openmrs.Order; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.AlreadyPaged; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +@Component +public class OrderSearchHandler implements SearchHandler{ + + private OrderService bahmniOrderService; + + @Autowired + public OrderSearchHandler(OrderService bahmniOrderService) { + this.bahmniOrderService = bahmniOrderService; + } + + @Override + public SearchConfig getSearchConfig() { + return new SearchConfig("byOrderType", RestConstants.VERSION_1 + "/order", Arrays.asList("1.9.* - 2.*"), + new SearchQuery.Builder("Allows you to find orders by orderType for a patient").withRequiredParameters("patientUuid", "orderTypeUuid").build()); + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + String patientUuid = requestContext.getParameter("patientUuid"); + String orderTypeUuid = requestContext.getParameter("orderTypeUuid"); + List allOrders = bahmniOrderService.getAllOrders(patientUuid, orderTypeUuid, requestContext.getStartIndex(), requestContext.getLimit(), null); + return new AlreadyPaged<>(requestContext, allOrders, false); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandler.java new file mode 100644 index 0000000000..662e2700c6 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandler.java @@ -0,0 +1,44 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniOrderSetService; +import org.openmrs.OrderSet; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +@Component +public class OrderSetSearchHandler implements SearchHandler { + public static final String QUERY = "q"; + private BahmniOrderSetService bahmniOrderSetService; + + @Autowired + public OrderSetSearchHandler(BahmniOrderSetService bahmniOrderSetService) { + this.bahmniOrderSetService = bahmniOrderSetService; + } + + @Override + public SearchConfig getSearchConfig() { + return new SearchConfig("byQuery", RestConstants.VERSION_1 + "/bahmniorderset", Arrays.asList("1.9.* - 2.*"), + new SearchQuery.Builder("Allows you to find OrderSets by search query").withRequiredParameters("q").build()); + + } + + @Override + public PageableResult search(RequestContext requestContext) throws ResponseException { + String query = requestContext.getParameter(QUERY); + List orderSets = bahmniOrderSetService.getOrderSetByQuery(query); + + + return new NeedsPaging<>(orderSets, requestContext); + } +} diff --git a/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java new file mode 100644 index 0000000000..4100ff7c5e --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandler.java @@ -0,0 +1,149 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Visit; +import org.openmrs.api.APIException; +import org.openmrs.api.context.Context; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.api.SearchHandler; +import org.openmrs.module.webservices.rest.web.resource.api.SearchQuery; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.InvalidSearchException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static java.util.Arrays.asList; +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; + +@Component +public class VisitFormsSearchHandler implements SearchHandler { + @Autowired + private EpisodeService episodeService; + private final String ALL_OBSERVATION_TEMPLATES = "All Observation Templates"; + private final String QUERY_INFORMATION = "Allows you to search All Observation Templates by patientUuid"; + + @Override + public SearchConfig getSearchConfig() { + SearchQuery searchQuery = new SearchQuery.Builder(QUERY_INFORMATION).withRequiredParameters("patient", "numberOfVisits").withOptionalParameters("conceptNames").build(); + return new SearchConfig("byPatientUuid", RestConstants.VERSION_1 + "/obs", asList("1.10.* - 2.*"), searchQuery); + } + + @Override + public PageableResult search(RequestContext context) throws ResponseException { + + String patientUuid = context.getRequest().getParameter("patient"); + String patientProgramUuid = context.getRequest().getParameter("patientProgramUuid"); + int numberOfVisits = Integer.parseInt(context.getRequest().getParameter("numberOfVisits")); + String[] conceptNames = context.getRequest().getParameterValues("conceptNames"); + Locale searchLocale = identifyLocale(context.getRequest().getSession().getAttribute("locale").toString()); + + Patient patient = Context.getPatientService().getPatientByUuid(patientUuid); + if (patient == null) { + throw new InvalidSearchException("Patient does not exist."); + } + List conceptNamesList = new ArrayList<>(); + if (conceptNames == null) { + List concepts = Context.getConceptService().getConceptsByName(ALL_OBSERVATION_TEMPLATES, Locale.ENGLISH, false); + if(!concepts.isEmpty()){ + for (Concept concept : concepts) { + conceptNamesList = getConcepts(concept.getSetMembers(), searchLocale); + } + } + } else { + conceptNamesList = asList(conceptNames); + } + + List encounterList; + if (patientProgramUuid != null) { + encounterList = getEncountersWithinProgram(patientProgramUuid); + } else { + encounterList = getEncountersFor(numberOfVisits, patient); + } + + List finalObsList = getObservations(patient, conceptNamesList, encounterList, searchLocale); + + return new NeedsPaging(finalObsList, context); + } + + private List getObservations(Patient patient, List conceptNames, List encounterList, Locale searchLocale) { + List finalObsList = new ArrayList<>(); + if (CollectionUtils.isEmpty(encounterList)) { + return finalObsList; + } + + List initialObsList = Context.getObsService().getObservations(Collections.singletonList(patient.getPerson()), encounterList, null, null, null, null, null, null, null, null, null, false); + + for (Obs obs : initialObsList) { + String name = null; + if(obs.getConcept()!= null){ + name = getConceptName(obs.getConcept(), searchLocale); + } + if (conceptNames.contains(name)) { + finalObsList.add(obs); + } + } + return finalObsList; + } + + private List getEncountersFor(int numberOfVisits, Patient patient) { + List encounterList; + List listOfVisitsNeeded = listOfVisitsNeeded(numberOfVisits, patient); + encounterList = Context.getEncounterService().getEncounters(patient, null, null, null, null, null, null, null, listOfVisitsNeeded, false); + return encounterList; + } + + private List getEncountersWithinProgram(String patientProgramUuid) { + List encounterList = new ArrayList<>(); + PatientProgram patientProgram = Context.getService(BahmniProgramWorkflowService.class).getPatientProgramByUuid(patientProgramUuid); + Episode episode = episodeService.getEpisodeForPatientProgram(patientProgram); + if (episode != null) { + encounterList = new ArrayList<>(episode.getEncounters()); + } + return encounterList; + } + + private List getConcepts(List concepts, Locale searchLocale) { + List conceptNames = new ArrayList<>(); + if (concepts == null) + return conceptNames; + for (Concept concept : concepts) { + conceptNames.add(getConceptName(concept, searchLocale)); + } + return conceptNames; + } + + private String getConceptName(Concept concept, Locale searchLocale) { + if(concept.getFullySpecifiedName(searchLocale) != null) + return concept.getFullySpecifiedName(searchLocale).getName(); + else + return concept.getFullySpecifiedName(LocaleUtility.getDefaultLocale()).getName(); + } + + private List listOfVisitsNeeded(int numberOfVisits, Patient patient) { + List visitsByPatient = Context.getVisitService().getVisitsByPatient(patient); + int subsetVisits = numberOfVisits; + if (visitsByPatient.size() < numberOfVisits) { + subsetVisits = visitsByPatient.size(); + } + return visitsByPatient.subList(0, subsetVisits); + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniConceptAnswerResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniConceptAnswerResource.java new file mode 100644 index 0000000000..a16fbade14 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniConceptAnswerResource.java @@ -0,0 +1,53 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.bahmni.module.bahmnicore.web.v1_0.contract.BahmniConceptAnswer; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.CustomRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; + +@Resource(name = RestConstants.VERSION_1 + "/bahmniconceptanswer", supportedClass = BahmniConceptAnswer.class, supportedOpenmrsVersions = {"1.9.* - 2.*"}, order = 0) +public class BahmniConceptAnswerResource extends DelegatingCrudResource { + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + if(rep instanceof CustomRepresentation){ + return null; + } + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("concept"); + description.addProperty("drug"); + return description; + } + + @Override + public BahmniConceptAnswer getByUniqueId(String s) { + throw new ResourceDoesNotSupportOperationException(); + } + + @Override + protected void delete(BahmniConceptAnswer bahmniConceptAnswer, String s, RequestContext requestContext) throws ResponseException { + throw new ResourceDoesNotSupportOperationException(); + } + + @Override + public BahmniConceptAnswer newDelegate() { + throw new ResourceDoesNotSupportOperationException(); + } + + @Override + public BahmniConceptAnswer save(BahmniConceptAnswer bahmniConceptAnswer) { + throw new ResourceDoesNotSupportOperationException(); + } + + @Override + public void purge(BahmniConceptAnswer bahmniConceptAnswer, RequestContext requestContext) throws ResponseException { + throw new ResourceDoesNotSupportOperationException(); + } + +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniConceptResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniConceptResource.java new file mode 100644 index 0000000000..5748f0b283 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniConceptResource.java @@ -0,0 +1,138 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.openmrs.Concept; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptName; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.NamedRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs2_0.ConceptResource2_0; +import org.openmrs.util.LocaleUtility; +import org.openmrs.util.OpenmrsConstants; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Locale; + +@Resource(name = RestConstants.VERSION_1 + "/concept", supportedClass = Concept.class, supportedOpenmrsVersions = {"1.9.* - 2.*"}, order = 0) +public class BahmniConceptResource extends ConceptResource2_0 { + + public BahmniConceptResource() { + allowedMissingProperties.add("hiNormal"); + allowedMissingProperties.add("hiAbsolute"); + allowedMissingProperties.add("hiCritical"); + allowedMissingProperties.add("lowNormal"); + allowedMissingProperties.add("lowAbsolute"); + allowedMissingProperties.add("lowCritical"); + allowedMissingProperties.add("units"); + allowedMissingProperties.add("allowDecimal"); + allowedMissingProperties.add("handler"); + } + + @Override + protected PageableResult doSearch(RequestContext context) { + return super.doSearch(context); + } + + @Override + public Concept getByUniqueId(String uuidOrName) { + Concept byUniqueId = super.getByUniqueId(uuidOrName); + if (byUniqueId != null) { + return byUniqueId; + } + + return Context.getConceptService().getConceptByName(uuidOrName); + } + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + + DelegatingResourceDescription representationDescription = super.getRepresentationDescription(rep); + if (representationDescription == null) { + if (rep instanceof NamedRepresentation) { + if (rep.getRepresentation().equals("bahmni")) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("name",Representation.DEFAULT); + description.addProperty("names",Representation.DEFAULT); + description.addProperty("set"); + description.addProperty("datatype",Representation.DEFAULT); + description.addProperty("conceptClass",Representation.DEFAULT); + description.addProperty("hiNormal"); + description.addProperty("hiAbsolute"); + description.addProperty("hiCritical"); + description.addProperty("lowNormal"); + description.addProperty("lowAbsolute"); + description.addProperty("lowCritical"); + description.addProperty("units"); + description.addProperty("allowDecimal"); + description.addProperty("handler"); + description.addProperty("descriptions", Representation.DEFAULT); + description.addProperty("answers", new NamedRepresentation("bahmniAnswer")); + description.addProperty("setMembers", new NamedRepresentation("bahmni")); + return description; + } else if (rep.getRepresentation().equals("bahmniAnswer")) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid", Representation.DEFAULT); + description.addProperty("name", Representation.DEFAULT); + description.addProperty("names", Representation.DEFAULT); + description.addProperty("displayString"); + return description; + } else if (rep.getRepresentation().equals("bahmniFullAnswers")) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("name", Representation.DEFAULT); + description.addProperty("datatype", Representation.DEFAULT); + description.addProperty("conceptClass", Representation.DEFAULT); + description.addProperty("set"); + description.addProperty("version"); + description.addProperty("retired"); + + description.addProperty("names", Representation.DEFAULT); + description.addProperty("descriptions", Representation.DEFAULT); + + description.addProperty("mappings", Representation.DEFAULT); + + description.addProperty("answers", new NamedRepresentation("bahmniAnswer")); + description.addProperty("setMembers", Representation.DEFAULT); + description.addProperty("auditInfo"); + description.addSelfLink(); + return description; + } + } + } + return representationDescription; + } + + + @PropertyGetter("names") + public static Object getNames(Concept concept) { + Locale globalDefaultLocale = LocaleUtility.getDefaultLocale(); + Locale userDefaultLocale = LocaleUtility.fromSpecification(Context.getAuthenticatedUser().getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)); + + Collection names = concept.getNames(userDefaultLocale); + if (globalDefaultLocale != userDefaultLocale) { + names.addAll(concept.getNames(globalDefaultLocale)); + } + return names; + } + + @PropertyGetter("descriptions") + public static Object getDescriptions(Concept concept) { + Locale userDefaultLocale = LocaleUtility.fromSpecification(Context.getAuthenticatedUser().getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCALE)); + Collection conceptDescriptions = new ArrayList<>(); + ConceptDescription conceptDescription = concept.getDescription(userDefaultLocale, false); + if(conceptDescription != null){ + conceptDescriptions.add(conceptDescription); + } + return conceptDescriptions; + } + +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniDrugResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniDrugResource.java new file mode 100644 index 0000000000..d35f75a1a3 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniDrugResource.java @@ -0,0 +1,26 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.openmrs.module.webservices.rest.web.representation.NamedRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_12.DrugResource1_12; + +@org.openmrs.module.webservices.rest.web.annotation.Resource(name = "v1/drug", supportedClass = org.openmrs.Drug + .class, supportedOpenmrsVersions = {"1.10.* - 2.*"}, order = 0) +public class BahmniDrugResource extends DrugResource1_12 { + + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + + DelegatingResourceDescription representationDescription = super.getRepresentationDescription(rep); + if (representationDescription == null && rep instanceof NamedRepresentation && rep.getRepresentation().equals("bahmniAnswer")) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("name", Representation.DEFAULT); + description.addProperty("displayString", findMethod("getDisplayString")); + return description; + } + return representationDescription; + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniEncounterResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniEncounterResource.java new file mode 100644 index 0000000000..62a8196389 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniEncounterResource.java @@ -0,0 +1,32 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Person; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_9.EncounterResource1_9; + +import java.util.Set; + +@Resource(name = RestConstants.VERSION_1 + "/encounter", supportedClass = Encounter.class, supportedOpenmrsVersions = {"1.9.* - 2.*"},order=2) + +public class BahmniEncounterResource extends EncounterResource1_9 { + + @PropertyGetter("provider") + public static Person getProvider(Encounter encounter) { + Set encounterProviders = encounter.getEncounterProviders(); + if (encounterProviders == null || encounterProviders.isEmpty()) { + return null; + } else { + for (EncounterProvider encounterProvider : encounterProviders) { + // Return the first non-voided provider associated with a person in the list + if (!encounterProvider.isVoided() && encounterProvider.getProvider().getPerson() != null) { + return encounterProvider.getProvider().getPerson(); + } + } + } + return null; + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniObsResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniObsResource.java new file mode 100644 index 0000000000..f5eb80c660 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniObsResource.java @@ -0,0 +1,57 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + + +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.representation.NamedRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_11.ObsResource1_11; + +import java.util.Date; + +@org.openmrs.module.webservices.rest.web.annotation.Resource(name = RestConstants.VERSION_1 + "/obs", supportedClass = Obs.class, supportedOpenmrsVersions = {"1.10.* - 2.*"}, order = 0) +public class BahmniObsResource extends ObsResource1_11 { + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + + DelegatingResourceDescription representationDescription = super.getRepresentationDescription(rep); + if (representationDescription == null && rep instanceof NamedRepresentation && rep.getRepresentation().equals("visitFormDetails")) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("uuid"); + description.addProperty("concept", new NamedRepresentation("bahmniAnswer")); + description.addProperty("display"); + description.addProperty("obsDatetime"); + description.addProperty("visitUuid"); + description.addProperty("encounterUuid"); + description.addProperty("visitStartDateTime"); + return description; + } + return representationDescription; + } + + @PropertyGetter("visitUuid") + public String getvisitUuid(Obs obs) { + Encounter encounter = obs.getEncounter(); + Visit visit = encounter.getVisit(); + return visit.getUuid(); + } + + @PropertyGetter("visitStartDateTime") + public Date getVisitDateTime(Obs obs) { + Encounter encounter = obs.getEncounter(); + Visit visit = encounter.getVisit(); + return visit.getStartDatetime(); + } + + @PropertyGetter("encounterUuid") + public String getEncounterUuid(Obs obs) { + Encounter encounter = obs.getEncounter(); + return encounter.getUuid(); + } +} + diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderResource.java new file mode 100644 index 0000000000..71fd9c802a --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderResource.java @@ -0,0 +1,28 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.bahmni.module.bahmnicore.service.BahmniOrderService; +import org.openmrs.Order; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_10.OrderResource1_10; + +@Resource(name = RestConstants.VERSION_1 + "/order", supportedClass = Order.class, supportedOpenmrsVersions = {"1.10.* - 2.*"}, order = 0) +public class BahmniOrderResource extends OrderResource1_10 { + + @Override + protected void delete(Order delegate, String reason, RequestContext context) throws ResponseException { + deleteChildOrder(delegate, context); + } + + private void deleteChildOrder(Order order, RequestContext context) { + Order nextOrder = Context.getService(BahmniOrderService.class).getChildOrder(order); + + if (nextOrder != null) + deleteChildOrder(nextOrder, context); + + super.delete(order, "Voided by User", context); + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetMemberSubResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetMemberSubResource.java new file mode 100644 index 0000000000..9051a5b8b9 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetMemberSubResource.java @@ -0,0 +1,138 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.openmrs.OrderSet; +import org.openmrs.OrderSetMember; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.SubResource; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; +import org.openmrs.module.webservices.rest.web.representation.RefRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingSubResource; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; + +import java.util.ArrayList; +import java.util.List; + +@SubResource(parent = BahmniOrderSetResource.class, path = "bahmniordersetmember", supportedClass = OrderSetMember.class, supportedOpenmrsVersions = { "1.12.* - 2.*"}) +public class BahmniOrderSetMemberSubResource extends DelegatingSubResource { + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + if (rep instanceof DefaultRepresentation) { + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("retired"); + description.addProperty("orderType", Representation.REF); + description.addProperty("orderTemplate"); + description.addProperty("concept", Representation.REF); + description.addSelfLink(); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + return description; + } else if (rep instanceof FullRepresentation) { + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("retired"); + description.addProperty("orderType", Representation.DEFAULT); + description.addProperty("orderTemplate"); + description.addProperty("concept", Representation.DEFAULT); + description.addProperty("auditInfo", findMethod("getAuditInfo")); + description.addSelfLink(); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + return description; + } else if (rep instanceof RefRepresentation) { + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("concept", Representation.REF); + description.addSelfLink(); + } + return null; + } + + @PropertyGetter("display") + public String getDisplayString(OrderSetMember orderSetMember) { + return orderSetMember.getDescription(); + } + + /** + * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getCreatableProperties() + */ + @Override + public DelegatingResourceDescription getCreatableProperties() { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("orderType"); + description.addProperty("orderTemplate"); + description.addProperty("concept"); + description.addProperty("retired"); + return description; + } + + /** + * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getUpdatableProperties() + */ + @Override + public DelegatingResourceDescription getUpdatableProperties() { + DelegatingResourceDescription creatableProperties = getCreatableProperties(); + return creatableProperties; + } + + @Override + public OrderSetMember getByUniqueId(String uniqueId) { + return Context.getOrderSetService().getOrderSetMemberByUuid(uniqueId); + } + + @Override + protected void delete(OrderSetMember orderSetMember, String reason, RequestContext context) throws ResponseException { + OrderSet orderSet = orderSetMember.getOrderSet(); + orderSet.retireOrderSetMember(orderSetMember); + Context.getOrderSetService().saveOrderSet(orderSet); + } + + @Override + public OrderSetMember newDelegate() { + return new OrderSetMember(); + } + + @Override + public OrderSetMember save(OrderSetMember delegate) { + OrderSet parent = delegate.getOrderSet(); + parent.addOrderSetMember(delegate); + Context.getOrderSetService().saveOrderSet(parent); + return delegate; + } + + @Override + public void purge(OrderSetMember orderSetMember, RequestContext context) throws ResponseException { + OrderSet orderSet = orderSetMember.getOrderSet(); + orderSet.removeOrderSetMember(orderSetMember); + Context.getOrderSetService().saveOrderSet(orderSet); + } + + @Override + public OrderSet getParent(OrderSetMember instance) { + return instance.getOrderSet(); + } + + @Override + public void setParent(OrderSetMember instance, OrderSet orderSet) { + instance.setOrderSet(orderSet); + } + + @Override + public PageableResult doGetAll(OrderSet parent, RequestContext context) throws ResponseException { + List orderSetMembers = new ArrayList(); + if (parent != null) { + for (OrderSetMember orderSetMember : parent.getOrderSetMembers()) { + orderSetMembers.add(orderSetMember); + } + } + return new NeedsPaging(orderSetMembers, context); + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetResource.java new file mode 100644 index 0000000000..433f7f4324 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetResource.java @@ -0,0 +1,119 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.openmrs.OrderSet; +import org.openmrs.OrderSetMember; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.PropertySetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; + +import java.util.List; + +@Resource(name = RestConstants.VERSION_1 + "/bahmniorderset", supportedClass = OrderSet.class, supportedOpenmrsVersions = { "1.12.* - 2.*"}) +public class BahmniOrderSetResource extends MetadataDelegatingCrudResource { + + @Override + public OrderSet getByUniqueId(String uniqueId) { + OrderSet orderSet = Context.getOrderSetService().getOrderSetByUuid(uniqueId); + orderSet.setOrderSetMembers(orderSet.getUnRetiredOrderSetMembers()); + return orderSet; + } + + @Override + public OrderSet newDelegate() { + return new OrderSet(); + } + + @Override + public OrderSet save(OrderSet orderSet) { + if(CollectionUtils.isNotEmpty(orderSet.getOrderSetMembers())){ + for(OrderSetMember orderSetMember : orderSet.getOrderSetMembers()) { + if (null != orderSetMember.getConcept() && StringUtils.isNotEmpty(orderSetMember.getConcept().getUuid())) { + orderSetMember.setConcept(Context.getConceptService().getConceptByUuid(orderSetMember.getConcept().getUuid())); + } + if(null != orderSetMember.getOrderType() && StringUtils.isNotEmpty(orderSetMember.getOrderType().getUuid())) { + orderSetMember.setOrderType(Context.getOrderService().getOrderTypeByUuid(orderSetMember.getOrderType().getUuid())); + } + } + } + return Context.getOrderSetService().saveOrderSet(orderSet); + } + + @PropertySetter("orderSetMembers") + public static void setOrderSetMembers(OrderSet instance, List orderSetMembers){ + instance.setOrderSetMembers(orderSetMembers); + } + + @PropertyGetter("orderSetMembers") + public static List getOrderSetMembers(OrderSet instance){ + return instance.getUnRetiredOrderSetMembers(); + } + + @Override + public void purge(OrderSet delegate, RequestContext context) throws ResponseException { + throw new ResourceDoesNotSupportOperationException(); + } + + /** + * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#doGetAll(org.openmrs.module.webservices.rest.web.RequestContext) + */ + @Override + protected NeedsPaging doGetAll(RequestContext context) { + List orderSets = Context.getOrderSetService().getOrderSets(context.getIncludeAll()); + for (OrderSet orderSet : orderSets) { + orderSet.setOrderSetMembers(orderSet.getUnRetiredOrderSetMembers()); + } + return new NeedsPaging(orderSets, context); + } + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + if (rep instanceof DefaultRepresentation) { + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("name"); + description.addProperty("description"); + description.addProperty("retired"); + description.addProperty("operator"); + description.addProperty("orderSetMembers", Representation.REF); + description.addSelfLink(); + description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); + return description; + } else if (rep instanceof FullRepresentation) { + description.addProperty("uuid"); + description.addProperty("display"); + description.addProperty("name"); + description.addProperty("description"); + description.addProperty("retired"); + description.addProperty("operator"); + description.addProperty("orderSetMembers", Representation.DEFAULT); + description.addProperty("auditInfo", findMethod("getAuditInfo")); + description.addSelfLink(); + return description; + } else { + return null; + } + } + + @Override + public DelegatingResourceDescription getCreatableProperties() { + DelegatingResourceDescription d = super.getCreatableProperties(); + d.addProperty("operator"); + d.addProperty("orderSetMembers"); + return d; + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResource.java new file mode 100644 index 0000000000..1312924874 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResource.java @@ -0,0 +1,167 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + + +import org.openmrs.PatientProgramAttribute; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.PatientState; +import org.openmrs.Program; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.ConversionUtil; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.PropertySetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.api.RestService; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.impl.AlreadyPaged; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingSubResource; +import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_10.ProgramEnrollmentResource1_10; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +@Resource(name = RestConstants.VERSION_1 + "/bahmniprogramenrollment", supportedClass = PatientProgram.class, supportedOpenmrsVersions = {"1.12.* - 2.*"}, order = 0) +public class BahmniProgramEnrollmentResource extends ProgramEnrollmentResource1_10 { + + @PropertySetter("attributes") + public static void setAttributes(PatientProgram instance, List attrs) { + for (PatientProgramAttribute attr : attrs) { + instance.addAttribute(attr); + } + } + + @PropertyGetter("attributes") + public static Collection getAttributes(PatientProgram instance) { + return instance.getActiveAttributes(); + } + + @PropertyGetter("states") + public static List getStates(PatientProgram instance) throws Exception { + List states = new ArrayList<>(); + for(PatientState state: instance.getStates()){ + if (!state.isVoided()) { + states.add(getPatientState(state)); + } + } + return states; + } + + private static SimpleObject getPatientState(PatientState patientState) throws Exception { + DelegatingSubResource patientStateResource = (DelegatingSubResource)Context.getService(RestService.class).getResourceBySupportedClass(PatientState.class); + + SimpleObject state = new SimpleObject(); + state.put("auditInfo", patientStateResource.getAuditInfo(patientState)); + state.put("uuid", patientState.getUuid()); + state.put("startDate", ConversionUtil.convertToRepresentation(patientState.getStartDate(), Representation.DEFAULT)); + state.put("endDate", ConversionUtil.convertToRepresentation(patientState.getEndDate(), Representation.DEFAULT)); + state.put("voided", patientState.getVoided()); + state.put("state", ConversionUtil.convertToRepresentation(patientState.getState(), Representation.REF)); + return state; + } + + @Override + public PatientProgram newDelegate() { + return new PatientProgram(); + } + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation rep) { + DelegatingResourceDescription parentRep = super.getRepresentationDescription(rep); + if (rep instanceof DefaultRepresentation) { + parentRep.addProperty("attributes", Representation.REF); + return parentRep; + } else if (rep instanceof FullRepresentation) { + parentRep.addProperty("states"); + parentRep.addProperty("attributes", Representation.DEFAULT); + return parentRep; + } else { + return null; + } + } + + @Override + public DelegatingResourceDescription getCreatableProperties() { + DelegatingResourceDescription delegatingResourceDescription = super.getCreatableProperties(); + delegatingResourceDescription.addProperty("attributes"); + return delegatingResourceDescription; + } + + @Override + public DelegatingResourceDescription getUpdatableProperties() { + DelegatingResourceDescription delegatingResourceDescription = super.getUpdatableProperties(); + delegatingResourceDescription.addProperty("attributes"); + delegatingResourceDescription.addProperty("voidReason"); + return delegatingResourceDescription; + } + + public PatientProgram getByUniqueId(String uniqueId) { + return Context.getService(BahmniProgramWorkflowService.class).getPatientProgramByUuid(uniqueId); + } + + protected void delete(PatientProgram delegate, String reason, RequestContext context) throws ResponseException { + if (!delegate.isVoided().booleanValue()) { + Context.getService(BahmniProgramWorkflowService.class).voidPatientProgram(delegate, reason); + } + } + + public void purge(PatientProgram delegate, RequestContext context) throws ResponseException { + Context.getService(BahmniProgramWorkflowService.class).purgePatientProgram(delegate); + } + + @Override + public List getPropertiesToExposeAsSubResources() { + return Arrays.asList("attributes"); + } + + public PatientProgram save(PatientProgram delegate) { + return Context.getService(BahmniProgramWorkflowService.class).savePatientProgram(delegate); + } + + protected PageableResult doSearch(RequestContext context) { + String patientUuid = context.getRequest().getParameter("patient"); + String patientProgramUuid = context.getRequest().getParameter("patientProgramUuid"); + if (patientProgramUuid != null) { + return searchByProgramUuid(context, patientProgramUuid); + } else if (patientUuid != null) { + return searchByPatientUuid(context, patientUuid); + } else { + return super.doSearch(context); + } + } + + private PageableResult searchByPatientUuid(RequestContext context, String patientUuid) { + PatientService patientService = Context.getPatientService(); + Patient patient = patientService.getPatientByUuid(patientUuid); + if (patient == null) { + return new EmptySearchResult(); + } else { + List patientPrograms = Context.getService(BahmniProgramWorkflowService.class).getPatientPrograms(patient, (Program) null, (Date) null, (Date) null, (Date) null, (Date) null, context.getIncludeAll()); + return new NeedsPaging(patientPrograms, context); + } + } + + private PageableResult searchByProgramUuid(RequestContext context, String patientProgramUuid) { + PatientProgram byUniqueId = getByUniqueId(patientProgramUuid); + if (byUniqueId == null) { + return new EmptySearchResult(); + } else { + return new AlreadyPaged<>(context, Collections.singletonList(byUniqueId), false); + } + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/EntityMappingResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/EntityMappingResource.java new file mode 100644 index 0000000000..592247c997 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/EntityMappingResource.java @@ -0,0 +1,76 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.bahmni.module.bahmnicore.contract.entityMapping.Entity; +import org.openmrs.Concept; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.RepHandler; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; +import org.openmrs.module.webservices.rest.web.representation.NamedRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.response.ConversionException; +import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; +import org.openmrs.module.webservices.rest.web.response.ResponseException; + +@Resource(name = RestConstants.VERSION_1 + "/entitymapping", supportedClass = Entity.class, supportedOpenmrsVersions = {"1.9.* - 2.*"}) +public class EntityMappingResource extends DelegatingCrudResource { + + @Override + public Entity getByUniqueId(String entity1Uuid) { + return null; + } + + @Override + protected void delete(Entity entity, String s, RequestContext requestContext) throws ResponseException { + throw new ResourceDoesNotSupportOperationException("deletion of entity mapping is not supported"); + } + + @Override + public Entity newDelegate() { + return new Entity(); + } + + @Override + public Entity save(Entity entity) { + throw new ResourceDoesNotSupportOperationException("Save of entity mapping is not supported"); + } + + @Override + public void purge(Entity entity, RequestContext requestContext) throws ResponseException { + throw new ResourceDoesNotSupportOperationException("Purge of entity mapping is not supported"); + } + + @RepHandler(DefaultRepresentation.class) + public SimpleObject asDefault(Entity delegate) throws ConversionException { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("entity", Representation.DEFAULT); + if (!delegate.getMappings().isEmpty() && delegate.getMappings().get(0) instanceof Concept) { + description.addProperty("mappings", new NamedRepresentation("bahmni")); + } else { + description.addProperty("mappings", Representation.DEFAULT); + } + return convertDelegateToRepresentation(delegate, description); + } + + + @Override + public DelegatingResourceDescription getRepresentationDescription(Representation representation) { + if (representation instanceof DefaultRepresentation) { + return null; + } else { + DelegatingResourceDescription description = new DelegatingResourceDescription(); + description.addProperty("entity", Representation.DEFAULT); + description.addProperty("mappings", Representation.DEFAULT); + return description; + } + } + + @Override + public Object retrieve(String uuid, RequestContext context) throws ResponseException { + throw new ResourceDoesNotSupportOperationException("Retrieve of entity mapping is not supported"); + } +} diff --git a/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/PersonAttributeTypeResource.java b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/PersonAttributeTypeResource.java new file mode 100644 index 0000000000..f0d3ef6e92 --- /dev/null +++ b/bahmnicore-omod/src/main/java/org/openmrs/module/bahmnicore/web/v1_0/resource/PersonAttributeTypeResource.java @@ -0,0 +1,29 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.openmrs.Concept; +import org.openmrs.PersonAttributeType; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.ConversionUtil; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; +import org.openmrs.module.webservices.rest.web.annotation.Resource; +import org.openmrs.module.webservices.rest.web.representation.NamedRepresentation; +import org.openmrs.module.webservices.rest.web.representation.Representation; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.response.ResponseException; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PersonAttributeTypeResource1_8; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_9.BaseAttributeTypeCrudResource1_9; +import org.openmrs.util.OpenmrsUtil; + +@Resource(name = RestConstants.VERSION_1 + "/personattributetype", supportedClass = PersonAttributeType.class, supportedOpenmrsVersions = {"1.12.* - 2.*"}, order = 0) +public class PersonAttributeTypeResource extends PersonAttributeTypeResource1_8 { + @PropertyGetter("concept") + public Object getConcept(PersonAttributeType delegate) { + if (OpenmrsUtil.nullSafeEquals(delegate.getFormat(), Concept.class.getCanonicalName())) { + Concept concept = Context.getConceptService().getConcept(delegate.getForeignKey()); + return ConversionUtil.convertToRepresentation(concept, new NamedRepresentation("bahmniFullAnswers")); + } + return null; + } +} diff --git a/bahmnicore-omod/src/main/resources/BahmniBMPatientListInWard.sql b/bahmnicore-omod/src/main/resources/BahmniBMPatientListInWard.sql new file mode 100644 index 0000000000..6f429cf71a --- /dev/null +++ b/bahmnicore-omod/src/main/resources/BahmniBMPatientListInWard.sql @@ -0,0 +1,135 @@ +DELETE FROM global_property where property = 'bedManagement.sqlGet.patientListForAdmissionLocation'; +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('bedManagement.sqlGet.patientListForAdmissionLocation', +'SELECT + b.bed_number AS "Bed", + concat(pn.given_name," ", ifnull(pn.family_name,"")) AS "Name", + pi.identifier AS "Id", + pv.gender AS "Gender", + TIMESTAMPDIFF(YEAR, pv.birthdate, CURDATE()) AS "Age", + admission_provider_name.given_name AS "Admission By", + cast(DATE_FORMAT(latestAdmissionEncounter.max_encounter_datetime, "%d %b %y %h:%i %p") AS CHAR) AS "Admission Time", + adtNotes.value_text AS "ADT Notes", + dispositionInfo.providerName AS "Disposition By", + cast(DATE_FORMAT(dispositionInfo.providerDate, "%d %b %y %h:%i %p") AS CHAR) AS "Disposition Time", + diagnosis.diagnosisConcept AS "Diagnosis", + diagnosis.certainty AS "Diagnosis Certainty", + diagnosis.diagnosisOrder AS "Diagnosis Order", + diagnosis.status AS "Diagnosis Status", + diagnosis.diagnosis_provider AS "Diagnosis Provider", + cast(DATE_FORMAT(diagnosis.diagnosis_datetime, "%d %b %y %h:%i %p") AS CHAR) AS "Diagnosis Datetime" +FROM bed_location_map blm + INNER JOIN bed b + ON blm.bed_id = b.bed_id AND b.status = "OCCUPIED" + INNER JOIN location l on blm.location_id = l.location_id and l.name = ${location_name} + INNER JOIN bed_patient_assignment_map bpam ON b.bed_id = bpam.bed_id AND date_stopped IS NULL + INNER JOIN person pv ON pv.person_id = bpam.patient_id + INNER JOIN person_name pn ON pn.person_id = pv.person_id + INNER JOIN patient_identifier pi ON pv.person_id = pi.patient_id + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + INNER JOIN ( + SELECT patient_id, max(encounter_datetime) AS max_encounter_datetime, + max(visit_id) as visit_id, max(encounter_id) AS encounter_id + FROM encounter INNER JOIN encounter_type ON encounter_type.encounter_type_id = encounter.encounter_type + WHERE encounter_type.name = "ADMISSION" + GROUP BY patient_id) latestAdmissionEncounter + ON pv.person_id = latestAdmissionEncounter.patient_id + LEFT OUTER JOIN obs adtNotes + ON adtNotes.encounter_id = latestAdmissionEncounter.encounter_id + AND adtNotes.voided = 0 + AND adtNotes.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = "Adt Notes" AND concept_name_type = "FULLY_SPECIFIED" AND locale = "en") + LEFT OUTER JOIN encounter_provider ep ON ep.encounter_id = latestAdmissionEncounter.encounter_id + LEFT OUTER JOIN provider admission_provider ON admission_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name admission_provider_name + ON admission_provider_name.person_id = admission_provider.person_id + LEFT OUTER JOIN ( + SELECT + bpam.patient_id AS person_id, + concept_name.name AS disposition, + latestDisposition.obs_datetime AS providerDate, + person_name.given_name AS providerName + FROM bed_patient_assignment_map bpam + INNER JOIN (SELECT person_id, max(obs_id) obs_id + FROM obs WHERE concept_id = (SELECT concept_id + FROM concept_name + WHERE name = "Disposition" AND concept_name_type = "FULLY_SPECIFIED" AND locale = "en") + GROUP BY person_id) + maxObsId ON maxObsId.person_id = bpam.patient_id + INNER JOIN obs latestDisposition + ON maxObsId.obs_id = latestDisposition.obs_id AND latestDisposition.voided = 0 + INNER JOIN concept_name ON latestDisposition.value_coded = concept_name.concept_id AND + concept_name_type = "FULLY_SPECIFIED" + LEFT OUTER JOIN encounter_provider ep ON latestDisposition.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider disp_provider ON disp_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = disp_provider.person_id + WHERE bpam.date_stopped IS NULL + ) dispositionInfo ON pv.person_id = dispositionInfo.person_id + LEFT OUTER JOIN ( + SELECT + diagnosis.person_id AS person_id, + diagnosis.obs_id AS obs_id, + diagnosis.obs_datetime AS diagnosis_datetime, + if(diagnosisConceptName.name IS NOT NULL, diagnosisConceptName.name, diagnosis.value_text) AS diagnosisConcept, + certaintyConceptName.name AS certainty, + diagnosisOrderConceptName.name AS diagnosisOrder, + diagnosisStatusConceptName.name AS status, + person_name.given_name AS diagnosis_provider + FROM bed_patient_assignment_map bpam + INNER JOIN visit latestVisit + ON latestVisit.patient_id = bpam.patient_id AND latestVisit.date_stopped IS NULL + AND bpam.date_stopped IS NULL + INNER JOIN encounter ON encounter.visit_id = latestVisit.visit_id + INNER JOIN obs diagnosis ON bpam.patient_id = diagnosis.person_id AND diagnosis.voided = 0 AND + diagnosis.encounter_id = encounter.encounter_id AND + diagnosis.concept_id IN ( + SELECT concept_id FROM concept_name + WHERE name IN ("Coded Diagnosis", "Non-Coded Diagnosis") + AND concept_name_type = "FULLY_SPECIFIED" ) + LEFT OUTER JOIN concept_name diagnosisConceptName + ON diagnosis.value_coded IS NOT NULL + AND diagnosis.value_coded = diagnosisConceptName.concept_id + AND diagnosisConceptName.concept_name_type = "FULLY_SPECIFIED" + AND diagnosisConceptName.locale ="en" + LEFT OUTER JOIN encounter_provider ep ON diagnosis.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider diagnosis_provider ON diagnosis_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = diagnosis_provider.person_id + INNER JOIN obs certainty + ON diagnosis.obs_group_id = certainty.obs_group_id AND certainty.voided = 0 + AND certainty.concept_id = ( + SELECT concept_id FROM concept_name + WHERE name = "Diagnosis Certainty" + AND concept_name_type = "FULLY_SPECIFIED" + AND locale = "en") + LEFT OUTER JOIN concept_name certaintyConceptName + ON certainty.value_coded IS NOT NULL + AND certainty.value_coded = certaintyConceptName.concept_id + AND certaintyConceptName.concept_name_type = "FULLY_SPECIFIED" + AND certaintyConceptName.locale = "en" + INNER JOIN obs diagnosisOrder + ON diagnosis.obs_group_id = diagnosisOrder.obs_group_id AND diagnosisOrder.voided = 0 + AND diagnosisOrder.concept_id = ( + SELECT concept_id FROM concept_name + WHERE name = "Diagnosis order" AND concept_name_type = "FULLY_SPECIFIED" and locale ="en") + LEFT OUTER JOIN concept_name diagnosisOrderConceptName + ON diagnosisOrder.value_coded IS NOT NULL + AND diagnosisOrder.value_coded = diagnosisOrderConceptName.concept_id + AND diagnosisOrderConceptName.concept_name_type = "FULLY_SPECIFIED" + AND diagnosisOrderConceptName.locale = "en" + LEFT JOIN obs diagnosisStatus + ON diagnosis.obs_group_id = diagnosisStatus.obs_group_id AND diagnosisStatus.voided = 0 + AND diagnosisStatus.concept_id = ( + SELECT concept_id FROM concept_name + WHERE name = "Bahmni Diagnosis Status" + AND concept_name_type = "FULLY_SPECIFIED" + AND locale = "en") + LEFT OUTER JOIN concept_name diagnosisStatusConceptName + ON diagnosisStatus.value_coded IS NOT NULL + AND diagnosisStatus.value_coded = diagnosisStatusConceptName.concept_id + AND diagnosisStatusConceptName.concept_name_type = "FULLY_SPECIFIED" + AND diagnosisStatusConceptName.locale = "en" +) diagnosis ON diagnosis.person_id = pv.person_id', +'Sql query to get admitted patients details in an Admission Location', +uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/ObsRelationship.hbm.xml b/bahmnicore-omod/src/main/resources/ObsRelationship.hbm.xml new file mode 100644 index 0000000000..95ce826b9e --- /dev/null +++ b/bahmnicore-omod/src/main/resources/ObsRelationship.hbm.xml @@ -0,0 +1,30 @@ + + + + + + obs_relationship_obs_relationship_id_seq + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/ObsRelationshipType.hbm.xml b/bahmnicore-omod/src/main/resources/ObsRelationshipType.hbm.xml new file mode 100644 index 0000000000..5ab0c1faca --- /dev/null +++ b/bahmnicore-omod/src/main/resources/ObsRelationshipType.hbm.xml @@ -0,0 +1,27 @@ + + + + + + obs_relationship_type_obs_relationship_type_id_seq + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_10__CreatingPatientIdentifierForBahmni.sql b/bahmnicore-omod/src/main/resources/V1_10__CreatingPatientIdentifierForBahmni.sql new file mode 100644 index 0000000000..c9fef607ca --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_10__CreatingPatientIdentifierForBahmni.sql @@ -0,0 +1,2 @@ +INSERT INTO patient_identifier_type (name, description, creator, date_created, required, uuid, location_behavior) + VALUES ('JSS', 'New patient identifier type created for use by the Bahmni Registration System', 1, curdate(), 1, uuid(), 'NOT_USED'); diff --git a/bahmnicore-omod/src/main/resources/V1_10__SetupRegistrationEncounterType.sql b/bahmnicore-omod/src/main/resources/V1_10__SetupRegistrationEncounterType.sql new file mode 100644 index 0000000000..998943c919 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_10__SetupRegistrationEncounterType.sql @@ -0,0 +1 @@ +INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('REG', 'Registration encounter', 1, curdate(), uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_11__CreateConceptSetForRegistrationConcepts.sql b/bahmnicore-omod/src/main/resources/V1_11__CreateConceptSetForRegistrationConcepts.sql new file mode 100644 index 0000000000..c19c7a00d7 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_11__CreateConceptSetForRegistrationConcepts.sql @@ -0,0 +1,6 @@ +-- This is a concept for concept-set +insert into concept (datatype_id, class_id, is_set, creator, date_created, changed_by, date_changed, uuid) + values (1, 10, 0, 1, now(), 1, now(), uuid()); +select max(concept_id) from concept into @registration_concepts_concept_id; +insert into concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (@registration_concepts_concept_id, 'REGISTRATION_CONCEPTS', 'en', 1, 1, now(), 'FULLY_SPECIFIED', uuid()); diff --git a/bahmnicore-omod/src/main/resources/V1_23__DeleteOpenMRSCorePersonAttributes.sql b/bahmnicore-omod/src/main/resources/V1_23__DeleteOpenMRSCorePersonAttributes.sql new file mode 100644 index 0000000000..21bdc1e1b4 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_23__DeleteOpenMRSCorePersonAttributes.sql @@ -0,0 +1,4 @@ +-- In OpenMRS Core liquibase-core-data.xml the ids are hard coded ( 1 to 7) +SET foreign_key_checks = 0; +delete from person_attribute_type where person_attribute_type_id >= 1 and person_attribute_type_id <= 7; +SET foreign_key_checks = 1; diff --git a/bahmnicore-omod/src/main/resources/V1_24__AddUniqueConstraintToPatientidentifier.sql b/bahmnicore-omod/src/main/resources/V1_24__AddUniqueConstraintToPatientidentifier.sql new file mode 100644 index 0000000000..77049428d1 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_24__AddUniqueConstraintToPatientidentifier.sql @@ -0,0 +1 @@ +ALTER TABLE patient_identifier ADD CONSTRAINT unique_patient_identifier UNIQUE (identifier); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_25__RegistrationConceptSetFix.sql b/bahmnicore-omod/src/main/resources/V1_25__RegistrationConceptSetFix.sql new file mode 100644 index 0000000000..27bc58bea6 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_25__RegistrationConceptSetFix.sql @@ -0,0 +1,3 @@ +select concept.concept_id from concept, concept_name where concept_name.concept_id = concept.concept_id and concept_name.name = 'REGISTRATION_CONCEPTS' into @concept_id; +update concept set is_set = 1 where concept_id = @concept_id; +delete from concept_set where concept_id = concept_set; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_29__AddConceptProc.sql b/bahmnicore-omod/src/main/resources/V1_29__AddConceptProc.sql new file mode 100644 index 0000000000..3e92579944 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_29__AddConceptProc.sql @@ -0,0 +1,36 @@ +CREATE PROCEDURE add_concept (INOUT new_concept_id INT, + INOUT concept_name_short_id INT, + INOUT concept_name_full_id INT, + concept_name VARCHAR(255), + concept_short_name VARCHAR(255), + data_type_name VARCHAR(255), + class_name VARCHAR(255), + is_set BOOLEAN) +BEGIN + DECLARE data_type_id INT; + DECLARE class_id INT; + DECLARE is_set_val TINYINT(1); + + CASE + WHEN is_set = TRUE THEN + SET is_set_val = '1'; + WHEN is_set = FALSE THEN + SET is_set_val = '0'; + END CASE; + + SELECT concept_datatype_id INTO data_type_id FROM concept_datatype WHERE name = data_type_name; + SELECT concept_class_id INTO class_id FROM concept_class WHERE name = class_name; + + INSERT INTO concept (datatype_id, class_id, is_set, creator, date_created, changed_by, date_changed, uuid) + values (data_type_id, class_id, is_set_val, 1, now(), 1, now(), uuid()); + SELECT MAX(concept_id) INTO new_concept_id FROM concept; + + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, concept_short_name, 'en', 0, 1, now(), 'SHORT', uuid()); + SELECT MAX(concept_name_id) INTO concept_name_short_id FROM concept_name; + + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, concept_name, 'en', 1, 1, now(), 'FULLY_SPECIFIED', uuid()); + SELECT MAX(concept_name_id) INTO concept_name_full_id FROM concept_name; +END; + diff --git a/bahmnicore-omod/src/main/resources/V1_30__AddConceptAnswerProc.sql b/bahmnicore-omod/src/main/resources/V1_30__AddConceptAnswerProc.sql new file mode 100644 index 0000000000..7e5914a6ed --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_30__AddConceptAnswerProc.sql @@ -0,0 +1,6 @@ +CREATE PROCEDURE add_concept_answer (concept_id INT, + answer_concept_id INT, + sort_weight DOUBLE) +BEGIN + INSERT INTO concept_answer (concept_id, answer_concept, answer_drug, date_created, creator, uuid, sort_weight) values (concept_id, answer_concept_id, null, now(), 1, uuid(), sort_weight); +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_37__SetValueAsConceptIdProc.sql b/bahmnicore-omod/src/main/resources/V1_37__SetValueAsConceptIdProc.sql new file mode 100644 index 0000000000..646ccd29a0 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_37__SetValueAsConceptIdProc.sql @@ -0,0 +1,28 @@ +CREATE PROCEDURE set_value_as_concept_id (person_attribute_type_name VARCHAR(255)) +BEGIN + DECLARE c_id INT; + DECLARE pa_id INT; + DECLARE c_name VARCHAR(255); + DECLARE val VARCHAR(255); + DECLARE done INT DEFAULT FALSE; + DECLARE cur1 CURSOR FOR SELECT person_attribute_id, value FROM person_attribute WHERE person_attribute_type_id IN + (SELECT person_attribute_type_id from person_attribute_type where name = person_attribute_type_name) and value != ''; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + CREATE TEMPORARY TABLE answer_concept_ids (id INT); + + INSERT INTO answer_concept_ids SELECT answer_concept FROM concept_answer + WHERE concept_id IN (SELECT BINARY foreign_key FROM person_attribute_type WHERE name = person_attribute_type_name); + + OPEN cur1; + REPEAT + FETCH cur1 INTO pa_id, val; + SELECT concept_id INTO c_id FROM concept_name + WHERE lower(name) = lower(val) AND concept_name_type = 'FULLY_SPECIFIED' + AND concept_id IN (SELECT id FROM answer_concept_ids); + UPDATE person_attribute set value = c_id where person_attribute_id = pa_id; + UNTIL done END REPEAT; + CLOSE cur1; + DROP TABLE answer_concept_ids; +END diff --git a/bahmnicore-omod/src/main/resources/V1_39__CreateLaboratoryPanelConcept.sql b/bahmnicore-omod/src/main/resources/V1_39__CreateLaboratoryPanelConcept.sql new file mode 100644 index 0000000000..76be399895 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_39__CreateLaboratoryPanelConcept.sql @@ -0,0 +1,5 @@ +INSERT INTO concept (datatype_id,class_id,is_set,creator,date_created,changed_by,date_changed,uuid) VALUES (4,8,true,1,{ts '2013-07-23 11:26:35'},1,{ts '2013-07-23 11:26:35'},uuid()); + +select max(concept_id) from concept into @laboratory_concept_id; + +insert into concept_name(concept_id, name, locale, locale_preferred,creator, date_created, concept_name_type, uuid) values (@laboratory_concept_id, 'Laboratory', 'en', true, 1, {ts '2013-07-23 11:26:35'}, 'FULLY_SPECIFIED', uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_41__AddingIndexToCityVillage-JssSpecific.sql b/bahmnicore-omod/src/main/resources/V1_41__AddingIndexToCityVillage-JssSpecific.sql new file mode 100644 index 0000000000..5f6f53fa0c --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_41__AddingIndexToCityVillage-JssSpecific.sql @@ -0,0 +1,2 @@ +-- JSS specific +CREATE INDEX person_address_city_village ON person_address (city_village); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_42__RemovingNotNullContraintOnOrderTypeId.sql b/bahmnicore-omod/src/main/resources/V1_42__RemovingNotNullContraintOnOrderTypeId.sql new file mode 100644 index 0000000000..688e2d5fb4 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_42__RemovingNotNullContraintOnOrderTypeId.sql @@ -0,0 +1 @@ +ALTER TABLE orders MODIFY COLUMN order_type_id int NULL; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_43__AddOPDConsultationEncounterType.sql b/bahmnicore-omod/src/main/resources/V1_43__AddOPDConsultationEncounterType.sql new file mode 100644 index 0000000000..f285773425 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_43__AddOPDConsultationEncounterType.sql @@ -0,0 +1 @@ +INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('OPD', 'OPD consultation encounter', 1, curdate(), uuid()); diff --git a/bahmnicore-omod/src/main/resources/V1_55__addLabAndRadiologyOrderTypes.sql b/bahmnicore-omod/src/main/resources/V1_55__addLabAndRadiologyOrderTypes.sql new file mode 100644 index 0000000000..3a101b3414 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_55__addLabAndRadiologyOrderTypes.sql @@ -0,0 +1,5 @@ +INSERT INTO order_type (`name`,`description`,`creator`,`date_created`,`retired`,`retired_by`,`date_retired`,`retire_reason`,`uuid`,`java_class_name`) +VALUES ('Lab Order','An order for laboratory tests',1,NOW(),0,NULL,NULL,NULL,UUID(),'org.openmrs.Order'); + +INSERT INTO order_type (`name`,`description`,`creator`,`date_created`,`retired`,`retired_by`,`date_retired`,`retire_reason`,`uuid`,`java_class_name`) +VALUES ('Radiology Order','An order for radiology tests',1,NOW(),0,NULL,NULL,NULL,UUID(),'org.openmrs.Order'); diff --git a/bahmnicore-omod/src/main/resources/V1_56__AddConceptDescriptionProc.sql b/bahmnicore-omod/src/main/resources/V1_56__AddConceptDescriptionProc.sql new file mode 100644 index 0000000000..a106cb59ea --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_56__AddConceptDescriptionProc.sql @@ -0,0 +1,5 @@ +CREATE PROCEDURE add_concept_description (concept_id INT, + description VARCHAR(250)) +BEGIN + INSERT INTO concept_description(uuid, concept_id, description, locale, creator, date_created) values(uuid(), concept_id, description, 'en', 1, now()); +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_57__addDrugDosageInstructionsAndDosageFrequecies.sql b/bahmnicore-omod/src/main/resources/V1_57__addDrugDosageInstructionsAndDosageFrequecies.sql new file mode 100644 index 0000000000..50929bcf99 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_57__addDrugDosageInstructionsAndDosageFrequecies.sql @@ -0,0 +1,37 @@ +set @concept_id = 0; +set @answer_concept_id = 0; +set @concept_name_short_id = 0; +set @concept_name_full_id = 0; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Dosage Frequency', 'dosagefrequency', 'Coded', 'Question', false); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'qD', 'qd', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 1); +call add_concept_description(@answer_concept_id, 'EVERY DAY'); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'BID', 'bid', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 2); +call add_concept_description(@answer_concept_id, 'TWICE A DAY'); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'TID', 'tid', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 3); +call add_concept_description(@answer_concept_id, 'THREE A DAY'); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'QID', 'qid', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 4); +call add_concept_description(@answer_concept_id, 'FOUR A DAY'); + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Dosage Instructions', 'dosage instructions', 'Coded', 'Question', false); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'AC', 'ac', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 1); +call add_concept_description(@answer_concept_id, 'BEFORE A MEAL'); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'PC', 'pc', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 2); +call add_concept_description(@answer_concept_id, 'AFTER A MEAL'); + +call add_concept(@answer_concept_id, @concept_name_short_id, @concept_name_full_id, 'HS', 'hs', 'Text', 'Misc', false); +call add_concept_answer(@concept_id, @answer_concept_id, 3); +call add_concept_description(@answer_concept_id, 'AT BEDTIME'); + diff --git a/bahmnicore-omod/src/main/resources/V1_58__AddConceptReferenceMapProc.sql b/bahmnicore-omod/src/main/resources/V1_58__AddConceptReferenceMapProc.sql new file mode 100644 index 0000000000..eb5b8c6aed --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_58__AddConceptReferenceMapProc.sql @@ -0,0 +1,18 @@ +CREATE PROCEDURE add_concept_reference_map (concept_id INT, + concept_source_id INT, + reference_term VARCHAR(255), + reference_type_id INT) +BEGIN + DECLARE reference_term_id INT; + + INSERT INTO concept_reference_term (concept_source_id,code,creator,date_created,uuid) + VALUES (concept_source_id,reference_term,1,now(),uuid()); + SELECT MAX(concept_reference_term_id) INTO reference_term_id FROM concept_reference_term; + + INSERT INTO concept_reference_map(concept_reference_term_id,concept_map_type_id,creator,date_created,concept_id,uuid) + VALUES(reference_term_id, reference_type_id, 1, now(), concept_id, uuid()); + +END; + + + diff --git a/bahmnicore-omod/src/main/resources/V1_59__AddConceptSetMembersProc.sql b/bahmnicore-omod/src/main/resources/V1_59__AddConceptSetMembersProc.sql new file mode 100644 index 0000000000..c263039d5c --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_59__AddConceptSetMembersProc.sql @@ -0,0 +1,9 @@ +CREATE PROCEDURE add_concept_set_members (set_concept_id INT, + member_concept_id INT,weight INT) +BEGIN + INSERT INTO concept_set (concept_id, concept_set,sort_weight,creator,date_created,uuid) + values (member_concept_id, set_concept_id,weight,1, now(),uuid()); +END; + + + diff --git a/bahmnicore-omod/src/main/resources/V1_60__AddDiagnosisConcepts.sql b/bahmnicore-omod/src/main/resources/V1_60__AddDiagnosisConcepts.sql new file mode 100644 index 0000000000..f912a6e403 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_60__AddDiagnosisConcepts.sql @@ -0,0 +1,55 @@ +set @concept_id = 0; +set @answer_concept_id = 0; +set @concept_name_short_id = 0; +set @concept_name_full_id = 0; +set @concept_source_id = 0; +set @concept_map_type_id = 0; + +SELECT concept_source_id INTO @concept_source_id FROM concept_reference_source where name = 'org.openmrs.module.emrapi'; +SELECT concept_map_type_id INTO @concept_map_type_id FROM concept_map_type where name = 'SAME-AS'; + + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Visit Diagnoses', 'Visit Diagnoses', 'N/A', 'ConvSet', true); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Diagnosis Concept Set',@concept_map_type_id); +set @set_concept_id = @concept_id; + + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Non-coded Diagnosis','Non-coded Diagnosis', 'Text', 'Question', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Non-Coded Diagnosis',@concept_map_type_id); +call add_concept_set_members (@set_concept_id,@concept_id,1); + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Coded Diagnosis','Coded Diagnosis', 'Coded', 'Question', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Coded Diagnosis',@concept_map_type_id); +call add_concept_set_members (@set_concept_id,@concept_id,1); + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Diagnosis Certainty','Diagnosis Certainty', 'Coded', 'Question', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Diagnosis Certainty',@concept_map_type_id); +call add_concept_set_members (@set_concept_id,@concept_id,1); +set @parent_concept_id = @concept_id; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Presumed','Presumed', 'N/A', 'Misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Presumed',@concept_map_type_id); +set @child1_concept_id = @concept_id; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Confirmed','Confirmed', 'N/A', 'Misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Confirmed',@concept_map_type_id); +set @child2_concept_id = @concept_id; + +call add_concept_answer (@parent_concept_id, @child1_concept_id, 1); +call add_concept_answer (@parent_concept_id, @child2_concept_id, 1); + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Diagnosis order','Diagnosis order', 'Coded', 'Question', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Diagnosis Order',@concept_map_type_id); +call add_concept_set_members (@set_concept_id,@concept_id,1); +set @parent_concept_id = @concept_id; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Secondary','Secondary', 'N/A', 'Misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Secondary',@concept_map_type_id); +set @child1_concept_id = @concept_id; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Primary','Primary', 'N/A', 'Misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Primary',@concept_map_type_id); +set @child2_concept_id = @concept_id; + +call add_concept_answer (@parent_concept_id, @child1_concept_id, 1); +call add_concept_answer (@parent_concept_id, @child2_concept_id, 1); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_61__CreatingGlobalPropertyForPatientIdentifierType.sql b/bahmnicore-omod/src/main/resources/V1_61__CreatingGlobalPropertyForPatientIdentifierType.sql new file mode 100644 index 0000000000..ec792027bf --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_61__CreatingGlobalPropertyForPatientIdentifierType.sql @@ -0,0 +1,2 @@ +select uuid from patient_identifier_type where name = 'Bahmni Id' into @uuid; +UPDATE global_property SET property_value = @uuid WHERE property='emr.primaryIdentifierType'; diff --git a/bahmnicore-omod/src/main/resources/V1_62__AddDispositionConcepts.sql b/bahmnicore-omod/src/main/resources/V1_62__AddDispositionConcepts.sql new file mode 100644 index 0000000000..bcccec742d --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_62__AddDispositionConcepts.sql @@ -0,0 +1,40 @@ +set @concept_id = 0; +set @answer_concept_id = 0; +set @concept_name_short_id = 0; +set @concept_name_full_id = 0; +set @concept_source_id = 0; +set @concept_map_type_id = 0; + +SELECT concept_source_id INTO @concept_source_id FROM concept_reference_source where name = 'org.openmrs.module.emrapi'; +SELECT concept_map_type_id INTO @concept_map_type_id FROM concept_map_type where name = 'SAME-AS'; + + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Admit Patient', 'Admit Patient', 'N/A', 'misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'ADMIT',@concept_map_type_id); +set @child1_concept_id = @concept_id; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Discharge Patient', 'Discharge Patient', 'N/A', 'misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'DISCHARGE',@concept_map_type_id); +set @child2_concept_id = @concept_id; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Transfer Patient', 'Transfer Patient', 'N/A', 'misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'TRANSFER',@concept_map_type_id); +set @child3_concept_id = @concept_id; + + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Disposition','Disposition', 'Coded', 'Question', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Disposition',@concept_map_type_id); +set @disposition_concept_id = @concept_id; + +call add_concept_answer (@disposition_concept_id, @child1_concept_id, 1); +call add_concept_answer (@disposition_concept_id, @child2_concept_id, 1); +call add_concept_answer (@disposition_concept_id, @child3_concept_id, 1); + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Disposition Set','Disposition Set', 'N/A', 'misc', true); +call add_concept_reference_map (@concept_id, @concept_source_id, 'Disposition Concept Set',@concept_map_type_id); +set @set_concept_id = @concept_id; +call add_concept_set_members (@set_concept_id,@disposition_concept_id,1); + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Disposition Note', 'Disposition Note', 'Text', 'misc', false); +call add_concept_reference_map (@concept_id, @concept_source_id, 'DispositionNote',@concept_map_type_id); +call add_concept_set_members (@set_concept_id,@concept_id,1); diff --git a/bahmnicore-omod/src/main/resources/V1_66__addConceptConsultationNote.sql b/bahmnicore-omod/src/main/resources/V1_66__addConceptConsultationNote.sql new file mode 100644 index 0000000000..93f366b74d --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_66__addConceptConsultationNote.sql @@ -0,0 +1,6 @@ +set @concept_id = 0; +set @concept_name_short_id = 0; +set @concept_name_full_id = 0; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Consultation Note', 'consultation note', 'Text', 'Misc', false); +call add_concept_description(@concept_id, 'Consultation Note'); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_67__AddConceptSetForAdmission.sql b/bahmnicore-omod/src/main/resources/V1_67__AddConceptSetForAdmission.sql new file mode 100644 index 0000000000..2b423c7351 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_67__AddConceptSetForAdmission.sql @@ -0,0 +1,5 @@ +set @concept_id = 0; +set @concept_name_short_id = 0; +set @concept_name_full_id = 0; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Admission', 'Admission', 'N/A', 'Misc', true); diff --git a/bahmnicore-omod/src/main/resources/V1_68__EncounterTypeForAdmission.sql b/bahmnicore-omod/src/main/resources/V1_68__EncounterTypeForAdmission.sql new file mode 100644 index 0000000000..f7ba5e4fc5 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_68__EncounterTypeForAdmission.sql @@ -0,0 +1 @@ +INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('ADMISSION', 'ADMISSION encounter', 1, curdate(), uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_69__AddConceptSetForDischarge.sql b/bahmnicore-omod/src/main/resources/V1_69__AddConceptSetForDischarge.sql new file mode 100644 index 0000000000..1f3c3edf1a --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_69__AddConceptSetForDischarge.sql @@ -0,0 +1,5 @@ +set @concept_id = 0; +set @concept_name_short_id = 0; +set @concept_name_full_id = 0; + +call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'DISCHARGE', 'DISCHARGE', 'N/A', 'Misc', true); diff --git a/bahmnicore-omod/src/main/resources/V1_70__EncounterTypeForDischarge.sql b/bahmnicore-omod/src/main/resources/V1_70__EncounterTypeForDischarge.sql new file mode 100644 index 0000000000..1e091cdbbc --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_70__EncounterTypeForDischarge.sql @@ -0,0 +1 @@ +INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('DISCHARGE', 'DISCHARGE encounter', 1, curdate(), uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_71__PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_71__PatientSearchSql.sql new file mode 100644 index 0000000000..02306f5f1c --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_71__PatientSearchSql.sql @@ -0,0 +1,167 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.activePatients', + 'emrapi.sqlSearch.patientsToAdmit', + 'emrapi.sqlSearch.admittedPatients', + 'emrapi.sqlSearch.patientsToDischarge', + 'emrapi.sqlSearch.patientsHasPendingOrders', + 'emrapi.sqlSearch.highRiskPatients', + 'emrapi.sqlSearch.additionalSearchHandler', + 'emrapi.sqlSearch.activePatientsByProvider' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatients', + 'select distinct + concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on p.person_id = v.patient_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of active patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToAdmit', + 'select distinct concat(pn.given_name,\' \', pn.family_name) as name, pi.identifier as identifier, concat("",p.uuid) as uuid, concat("",v.uuid) as activeVisitUuid from visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 AND v.voided = 0 join patient_identifier pi on v.patient_id = pi.patient_id join person p on v.patient_id = p.person_id join encounter e on v.visit_id = e.visit_id join obs o on e.encounter_id = o.encounter_id and o.voided = 0 join concept c on o.value_coded = c.concept_id join concept_name cn on c.concept_id = cn.concept_id where v.date_stopped is null and cn.name = \'Admit Patient\' and v.visit_id not in (select visit_id from encounter ie join encounter_type iet on iet.encounter_type_id = ie.encounter_type where iet.name = \'ADMISSION\')', + 'Sql query to get list of patients to be admitted', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToDischarge', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + FROM visit v + INNER JOIN person_name pn ON v.patient_id = pn.person_id and pn.voided is FALSE + INNER JOIN patient_identifier pi ON v.patient_id = pi.patient_id and pi.voided is FALSE + INNER JOIN person p ON v.patient_id = p.person_id + Inner Join (SELECT DISTINCT v.visit_id + FROM encounter en + INNER JOIN visit v ON v.visit_id = en.visit_id AND en.encounter_type = + (SELECT encounter_type_id + FROM encounter_type + WHERE name = "ADMISSION")) v1 on v1.visit_id = v.visit_id + INNER JOIN encounter e ON v.visit_id = e.visit_id + INNER JOIN obs o ON e.encounter_id = o.encounter_id + INNER JOIN concept_name cn ON o.value_coded = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND cn.voided is FALSE + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + LEFT OUTER JOIN encounter e1 ON e1.visit_id = v.visit_id AND e1.encounter_type = ( + SELECT encounter_type_id + FROM encounter_type + WHERE name = "DISCHARGE") AND e1.voided is FALSE + WHERE v.date_stopped IS NULL AND v.voided = 0 AND o.voided = 0 AND cn.name = "Discharge Patient" AND e1.encounter_id IS NULL', + 'Sql query to get list of patients to discharge', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsHasPendingOrders', + 'select distinct + concat(pn.given_name, " ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on p.person_id = v.patient_id + join orders on orders.patient_id = v.patient_id + join order_type on orders.order_type_id = order_type.order_type_id and order_type.name != "Lab Order" and order_type.name != "Drug Order" + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where v.date_stopped is null AND v.voided = 0 and order_id not in + (select obs.order_id + from obs + where person_id = pn.person_id and order_id = orders.order_id)', + 'Sql query to get list of patients who has pending orders', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.admittedPatients', + 'select distinct + concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on v.patient_id = p.person_id + join visit_attribute va on v.visit_id = va.visit_id and va.value_reference = "Admitted" + join visit_attribute_type vat on vat.visit_attribute_type_id = va.attribute_type_id and vat.name = "Admission Status" + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of admitted patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.highRiskPatients', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from person p + inner join person_name pn on pn.person_id = p.person_id + inner join patient_identifier pi ON pn.person_id = pi.patient_id + inner join visit v on v.patient_id = p.person_id and v.date_stopped IS NULL and v.voided=0 + inner join concept_name cn on cn.name = \'LAB_ABNORMAL\' AND cn.concept_name_type = \'FULLY_SPECIFIED\' + inner join obs o on o.voided=0 and o.value_coded=1 and o.person_id = p.person_id and o.concept_id = cn.concept_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where o.obs_group_id in (select obs_id from obs where voided=0 and concept_id IN (SELECT concept_id FROM concept_name cn WHERE cn.concept_name_type = \'FULLY_SPECIFIED\' AND ', + 'Sql query to get list of admitted patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.additionalSearchHandler', + ' cn.name = "${testName}"', + 'Sql query to get list of admitted patients', + uuid() +); + +insert into global_property (property,property_value,description,uuid) +values ('emrapi.sqlSearch.activePatientsByProvider', + 'select distinct + concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + pr.uuid=${provider_uuid} + order by en.encounter_datetime desc', + 'Sql query to get list of active patients by provider uuid', + uuid()) \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_72__AddProcToInsertNewAddressLevel.sql b/bahmnicore-omod/src/main/resources/V1_72__AddProcToInsertNewAddressLevel.sql new file mode 100644 index 0000000000..5a1887f6c4 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_72__AddProcToInsertNewAddressLevel.sql @@ -0,0 +1,42 @@ +CREATE PROCEDURE introduce_new_address_level(parent_field_name VARCHAR(160), new_field_name VARCHAR(160), new_field_address_field_name VARCHAR(160)) +introduce_new_address_level_proc: BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE parent_field_level_id INT; + DECLARE parent_field_entry_id INT; + DECLARE new_field_level_id INT; + DECLARE new_field_entry_id INT; + DECLARE number_children_fields_for_parent_field INT; + DECLARE parent_field_entries_cursor CURSOR FOR SELECT id from parent_field_ids; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + SELECT address_hierarchy_level_id INTO parent_field_level_id from address_hierarchy_level where name = parent_field_name; + INSERT INTO address_hierarchy_level(name, address_field, uuid, required) values(new_field_name, new_field_address_field_name, UUID(), false); + + select COUNT(*) INTO number_children_fields_for_parent_field from address_hierarchy_level where parent_level_id = parent_field_level_id; + + SELECT address_hierarchy_level_id INTO new_field_level_id from address_hierarchy_level where name = new_field_name; + UPDATE address_hierarchy_level set parent_level_id = new_field_level_id where parent_level_id = parent_field_level_id; + UPDATE address_hierarchy_level set parent_level_id = parent_field_level_id where name = new_field_name; + + -- If parent field was leaf node no address entry migration required + IF (number_children_fields_for_parent_field = 0)THEN + LEAVE introduce_new_address_level_proc; + END IF; + + -- Start address entry migration + CREATE TEMPORARY TABLE parent_field_ids(id INT); + INSERT INTO parent_field_ids SELECT address_hierarchy_entry_id from address_hierarchy_entry where level_id = parent_field_level_id; + + OPEN parent_field_entries_cursor; + read_loop: LOOP + FETCH parent_field_entries_cursor INTO parent_field_entry_id; + IF done THEN + LEAVE read_loop; + END IF; + INSERT INTO address_hierarchy_entry (name, level_id, parent_id, uuid) VALUES (NULL, new_field_level_id, parent_field_entry_id, UUID()); + SET new_field_entry_id = LAST_INSERT_ID(); + UPDATE address_hierarchy_entry SET parent_id = new_field_entry_id where parent_id = parent_field_entry_id and level_id != new_field_level_id; + END LOOP; + CLOSE parent_field_entries_cursor; + DROP TABLE parent_field_ids; +END; diff --git a/bahmnicore-omod/src/main/resources/V1_78__EncounterTypeForTransfer.sql b/bahmnicore-omod/src/main/resources/V1_78__EncounterTypeForTransfer.sql new file mode 100644 index 0000000000..e3c5df5805 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_78__EncounterTypeForTransfer.sql @@ -0,0 +1 @@ +INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('TRANSFER', 'TRANSFER encounter', 1, curdate(), uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_79__AddressTemplateWithAllFields.sql b/bahmnicore-omod/src/main/resources/V1_79__AddressTemplateWithAllFields.sql new file mode 100644 index 0000000000..e6e069f6ec --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_79__AddressTemplateWithAllFields.sql @@ -0,0 +1,40 @@ +update global_property +set property_value = ' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + address1 + address2 + cityVillage stateProvince country postalCode + latitude longitude + startDate endDate + + ' +where property = 'layout.address.format'; diff --git a/bahmnicore-omod/src/main/resources/V1_80__AddConceptNumericProc.sql b/bahmnicore-omod/src/main/resources/V1_80__AddConceptNumericProc.sql new file mode 100644 index 0000000000..92b1588f3a --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_80__AddConceptNumericProc.sql @@ -0,0 +1,8 @@ +CREATE PROCEDURE add_concept_numeric (concept_id INT, + low_normal DOUBLE, + hi_normal DOUBLE, + units VARCHAR(50)) +BEGIN + INSERT INTO concept_numeric (concept_id, low_normal, hi_normal, units) values (concept_id, low_normal, hi_normal, units); +END; + diff --git a/bahmnicore-omod/src/main/resources/V1_81__DeleteConcept.sql b/bahmnicore-omod/src/main/resources/V1_81__DeleteConcept.sql new file mode 100644 index 0000000000..339365ce7d --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_81__DeleteConcept.sql @@ -0,0 +1,11 @@ +CREATE PROCEDURE delete_concept (name_concept VARCHAR(255)) +BEGIN + DECLARE conceptId INT default 0; + + select concept_id INTO conceptId from concept_name where name = name_concept and locale_preferred = 1; + delete from concept_set where concept_set = conceptId; + delete from concept_name where concept_id = conceptId; + delete from concept_numeric where concept_id = conceptId; + delete from concept_answer where concept_id = conceptId; + delete from concept where concept_id = conceptId; +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_82__ChangeAddConceptProc.sql b/bahmnicore-omod/src/main/resources/V1_82__ChangeAddConceptProc.sql new file mode 100644 index 0000000000..a75f31e5af --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_82__ChangeAddConceptProc.sql @@ -0,0 +1,41 @@ +CREATE PROCEDURE add_concept (INOUT new_concept_id INT, + INOUT concept_name_short_id INT, + INOUT concept_name_full_id INT, + name_of_concept VARCHAR(255), + concept_short_name VARCHAR(255), + data_type_name VARCHAR(255), + class_name VARCHAR(255), + is_set BOOLEAN) +BEGIN + DECLARE data_type_id INT; + DECLARE class_id INT; + DECLARE is_set_val TINYINT(1); + + CASE + WHEN is_set = TRUE THEN + SET is_set_val = '1'; + WHEN is_set = FALSE THEN + SET is_set_val = '0'; + END CASE; + + SELECT count(distinct concept_id) into @concept_count from concept_name where name = name_of_concept; + IF @concept_count > 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Concept Already Exists'; + ELSE + SELECT concept_datatype_id INTO data_type_id FROM concept_datatype WHERE name = data_type_name; + SELECT concept_class_id INTO class_id FROM concept_class WHERE name = class_name; + + INSERT INTO concept (datatype_id, class_id, is_set, creator, date_created, changed_by, date_changed, uuid) + values (data_type_id, class_id, is_set_val, 1, now(), 1, now(), uuid()); + SELECT MAX(concept_id) INTO new_concept_id FROM concept; + + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, concept_short_name, 'en', 0, 1, now(), 'SHORT', uuid()); + SELECT MAX(concept_name_id) INTO concept_name_short_id FROM concept_name; + + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, name_of_concept, 'en', 1, 1, now(), 'FULLY_SPECIFIED', uuid()); + SELECT MAX(concept_name_id) INTO concept_name_full_id FROM concept_name; + END IF; +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_83__FixAddConceptProc.sql b/bahmnicore-omod/src/main/resources/V1_83__FixAddConceptProc.sql new file mode 100644 index 0000000000..2160bc91ec --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_83__FixAddConceptProc.sql @@ -0,0 +1,41 @@ +CREATE PROCEDURE add_concept (INOUT new_concept_id INT, + INOUT concept_name_short_id INT, + INOUT concept_name_full_id INT, + name_of_concept VARCHAR(255), + concept_short_name VARCHAR(255), + data_type_name VARCHAR(255), + class_name VARCHAR(255), + is_set BOOLEAN) +BEGIN + DECLARE data_type_id INT; + DECLARE class_id INT; + DECLARE is_set_val TINYINT(1); + + CASE + WHEN is_set = TRUE THEN + SET is_set_val = '1'; + WHEN is_set = FALSE THEN + SET is_set_val = '0'; + END CASE; + + SELECT count(distinct concept_id) into @concept_count from concept_name where name = name_of_concept and concept_name_type='FULLY_SPECIFIED'; + IF @concept_count > 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Concept Already Exists'; + ELSE + SELECT concept_datatype_id INTO data_type_id FROM concept_datatype WHERE name = data_type_name; + SELECT concept_class_id INTO class_id FROM concept_class WHERE name = class_name; + + INSERT INTO concept (datatype_id, class_id, is_set, creator, date_created, changed_by, date_changed, uuid) + values (data_type_id, class_id, is_set_val, 1, now(), 1, now(), uuid()); + SELECT MAX(concept_id) INTO new_concept_id FROM concept; + + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, concept_short_name, 'en', 0, 1, now(), 'SHORT', uuid()); + SELECT MAX(concept_name_id) INTO concept_name_short_id FROM concept_name; + + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, name_of_concept, 'en', 1, 1, now(), 'FULLY_SPECIFIED', uuid()); + SELECT MAX(concept_name_id) INTO concept_name_full_id FROM concept_name; + END IF; +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_84__FixAddConceptProc.sql b/bahmnicore-omod/src/main/resources/V1_84__FixAddConceptProc.sql new file mode 100644 index 0000000000..563665cc3b --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_84__FixAddConceptProc.sql @@ -0,0 +1,44 @@ +CREATE PROCEDURE add_concept (INOUT new_concept_id INT, + INOUT concept_name_short_id INT, + INOUT concept_name_full_id INT, + name_of_concept VARCHAR(255), + concept_short_name VARCHAR(255), + data_type_name VARCHAR(255), + class_name VARCHAR(255), + is_set BOOLEAN) +BEGIN + DECLARE data_type_id INT; + DECLARE class_id INT; + DECLARE is_set_val TINYINT(1); + + CASE + WHEN is_set = TRUE THEN + SET is_set_val = '1'; + WHEN is_set = FALSE THEN + SET is_set_val = '0'; + END CASE; + + SELECT count(distinct concept_id) into @concept_count from concept_name where name = name_of_concept and concept_name_type='FULLY_SPECIFIED'; + IF @concept_count > 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Concept Already Exists'; + ELSE + SELECT concept_datatype_id INTO data_type_id FROM concept_datatype WHERE name = data_type_name; + SELECT concept_class_id INTO class_id FROM concept_class WHERE name = class_name; + + SELECT uuid() into @uuid; + INSERT INTO concept (datatype_id, class_id, is_set, creator, date_created, changed_by, date_changed, uuid) + values (data_type_id, class_id, is_set_val, 1, now(), 1, now(), @uuid); + SELECT MAX(concept_id) INTO new_concept_id FROM concept; + + SELECT uuid() into @uuid; + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, concept_short_name, 'en', 0, 1, now(), 'SHORT', @uuid); + SELECT MAX(concept_name_id) INTO concept_name_short_id FROM concept_name; + + SELECT uuid() into @uuid; + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, name_of_concept, 'en', 1, 1, now(), 'FULLY_SPECIFIED', @uuid); + SELECT MAX(concept_name_id) INTO concept_name_full_id FROM concept_name; + END IF; +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_85__FixAddConceptProc.sql b/bahmnicore-omod/src/main/resources/V1_85__FixAddConceptProc.sql new file mode 100644 index 0000000000..563665cc3b --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_85__FixAddConceptProc.sql @@ -0,0 +1,44 @@ +CREATE PROCEDURE add_concept (INOUT new_concept_id INT, + INOUT concept_name_short_id INT, + INOUT concept_name_full_id INT, + name_of_concept VARCHAR(255), + concept_short_name VARCHAR(255), + data_type_name VARCHAR(255), + class_name VARCHAR(255), + is_set BOOLEAN) +BEGIN + DECLARE data_type_id INT; + DECLARE class_id INT; + DECLARE is_set_val TINYINT(1); + + CASE + WHEN is_set = TRUE THEN + SET is_set_val = '1'; + WHEN is_set = FALSE THEN + SET is_set_val = '0'; + END CASE; + + SELECT count(distinct concept_id) into @concept_count from concept_name where name = name_of_concept and concept_name_type='FULLY_SPECIFIED'; + IF @concept_count > 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Concept Already Exists'; + ELSE + SELECT concept_datatype_id INTO data_type_id FROM concept_datatype WHERE name = data_type_name; + SELECT concept_class_id INTO class_id FROM concept_class WHERE name = class_name; + + SELECT uuid() into @uuid; + INSERT INTO concept (datatype_id, class_id, is_set, creator, date_created, changed_by, date_changed, uuid) + values (data_type_id, class_id, is_set_val, 1, now(), 1, now(), @uuid); + SELECT MAX(concept_id) INTO new_concept_id FROM concept; + + SELECT uuid() into @uuid; + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, concept_short_name, 'en', 0, 1, now(), 'SHORT', @uuid); + SELECT MAX(concept_name_id) INTO concept_name_short_id FROM concept_name; + + SELECT uuid() into @uuid; + INSERT INTO concept_name (concept_id, name, locale, locale_preferred, creator, date_created, concept_name_type, uuid) + values (new_concept_id, name_of_concept, 'en', 1, 1, now(), 'FULLY_SPECIFIED', @uuid); + SELECT MAX(concept_name_id) INTO concept_name_full_id FROM concept_name; + END IF; +END; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_86__WardsListSql.sql b/bahmnicore-omod/src/main/resources/V1_86__WardsListSql.sql new file mode 100644 index 0000000000..ddb30fbdf9 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_86__WardsListSql.sql @@ -0,0 +1,155 @@ +DELETE FROM global_property where property = 'emrapi.sqlGet.wardsListDetails'; + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlGet.wardsListDetails', +"SELECT + b.bed_number AS 'Bed', + concat(pn.given_name, ' ', pn.family_name) AS 'Name', + pv.uuid AS 'Patient Uuid', + pi.identifier AS 'Id', + pv.gender AS 'Gender', + TIMESTAMPDIFF(YEAR, pv.birthdate, CURDATE()) AS 'Age', + pa.county_district AS 'District', + pa.city_village AS 'Village', + admission_provider_name.given_name AS 'Admission By', + cast(DATE_FORMAT(latestAdmissionEncounter.max_encounter_datetime, '%d %b %y %h:%i %p') AS CHAR) AS 'Admission Time', + diagnosis.diagnosisConcept AS 'Diagnosis', + diagnosis.certainty AS 'Diagnosis Certainty', + diagnosis.diagnosisOrder AS 'Diagnosis Order', + diagnosis.status AS 'Diagnosis Status', + diagnosis.diagnosis_provider AS 'Diagnosis Provider', + cast(DATE_FORMAT(diagnosis.diagnosis_datetime, '%d %b %y %h:%i %p') AS + CHAR) AS 'Diagnosis Datetime', + dispositionInfo.providerName AS 'Disposition By', + cast(DATE_FORMAT(dispositionInfo.providerDate, '%d %b %y %h:%i %p') AS CHAR) AS 'Disposition Time', + adtNotes.value_text AS 'ADT Notes', + v.uuid AS 'Visit Uuid' +FROM bed_location_map blm + INNER JOIN bed b + ON blm.bed_id = b.bed_id AND + b.status = 'OCCUPIED' AND + blm.location_id IN (SELECT child_location.location_id + FROM location child_location JOIN + location parent_location + ON parent_location.location_id = + child_location.parent_location + WHERE + parent_location.name = ${location_name}) + INNER JOIN bed_patient_assignment_map bpam ON b.bed_id = bpam.bed_id AND date_stopped IS NULL + INNER JOIN person pv ON pv.person_id = bpam.patient_id + INNER JOIN person_name pn ON pn.person_id = pv.person_id + INNER JOIN patient_identifier pi ON pv.person_id = pi.patient_id + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property='emr.primaryIdentifierType' and gp.property_value=pit.uuid + INNER JOIN person_address pa ON pa.person_id = pv.person_id + INNER JOIN (SELECT + patient_id, + max(encounter_datetime) AS max_encounter_datetime, + max(visit_id) as visit_id, + max(encounter_id) AS encounter_id + FROM encounter + INNER JOIN encounter_type ON encounter_type.encounter_type_id = encounter.encounter_type + WHERE encounter_type.name = 'ADMISSION' + GROUP BY patient_id) latestAdmissionEncounter ON pv.person_id = latestAdmissionEncounter.patient_id + INNER JOIN visit v ON latestAdmissionEncounter.visit_id = v.visit_id + LEFT OUTER JOIN obs adtNotes + ON adtNotes.encounter_id = latestAdmissionEncounter.encounter_id AND adtNotes.voided = 0 AND + adtNotes.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Adt Notes' AND concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN encounter_provider ep ON ep.encounter_id = latestAdmissionEncounter.encounter_id + LEFT OUTER JOIN provider admission_provider ON admission_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name admission_provider_name + ON admission_provider_name.person_id = admission_provider.person_id + LEFT OUTER JOIN ( + SELECT + bpam.patient_id AS person_id, + concept_name.name AS disposition, + latestDisposition.obs_datetime AS providerDate, + person_name.given_name AS providerName + FROM bed_patient_assignment_map bpam + INNER JOIN (SELECT + person_id, + max(obs_id) obs_id + FROM obs + WHERE concept_id = (SELECT concept_id + FROM concept_name + WHERE + name = 'Disposition' AND concept_name_type = 'FULLY_SPECIFIED') + GROUP BY person_id) maxObsId ON maxObsId.person_id = bpam.patient_id + INNER JOIN obs latestDisposition + ON maxObsId.obs_id = latestDisposition.obs_id AND latestDisposition.voided = 0 + INNER JOIN concept_name ON latestDisposition.value_coded = concept_name.concept_id AND + concept_name_type = 'FULLY_SPECIFIED' + LEFT OUTER JOIN encounter_provider ep ON latestDisposition.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider disp_provider ON disp_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = disp_provider.person_id + WHERE bpam.date_stopped IS NULL + ) dispositionInfo ON pv.person_id = dispositionInfo.person_id + LEFT OUTER JOIN ( + SELECT + diagnosis.person_id AS person_id, + diagnosis.obs_id AS obs_id, + diagnosis.obs_datetime AS diagnosis_datetime, + if(diagnosisConceptName.name IS NOT NULL, diagnosisConceptName.name, + diagnosis.value_text) AS diagnosisConcept, + certaintyConceptName.name AS certainty, + diagnosisOrderConceptName.name AS diagnosisOrder, + diagnosisStatusConceptName.name AS status, + person_name.given_name AS diagnosis_provider + FROM bed_patient_assignment_map bpam + INNER JOIN visit latestVisit + ON latestVisit.patient_id = bpam.patient_id AND latestVisit.date_stopped IS NULL AND + bpam.date_stopped IS NULL + INNER JOIN encounter ON encounter.visit_id = latestVisit.visit_id + INNER JOIN obs diagnosis ON bpam.patient_id = diagnosis.person_id AND diagnosis.voided = 0 AND + diagnosis.encounter_id = encounter.encounter_id AND + diagnosis.concept_id IN (SELECT concept_id + FROM concept_name + WHERE name IN + ('Coded Diagnosis', 'Non-Coded Diagnosis') + AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisConceptName + ON diagnosis.value_coded IS NOT NULL AND diagnosis.value_coded = diagnosisConceptName.concept_id + AND diagnosisConceptName.concept_name_type = 'FULLY_SPECIFIED' + LEFT OUTER JOIN encounter_provider ep ON diagnosis.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider diagnosis_provider ON diagnosis_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = diagnosis_provider.person_id + INNER JOIN obs certainty + ON diagnosis.obs_group_id = certainty.obs_group_id AND certainty.voided = 0 AND + certainty.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Diagnosis Certainty' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name certaintyConceptName + ON certainty.value_coded IS NOT NULL AND certainty.value_coded = certaintyConceptName.concept_id + AND certaintyConceptName.concept_name_type = 'FULLY_SPECIFIED' + INNER JOIN obs diagnosisOrder + ON diagnosis.obs_group_id = diagnosisOrder.obs_group_id AND diagnosisOrder.voided = 0 AND + diagnosisOrder.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Diagnosis order' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisOrderConceptName ON diagnosisOrder.value_coded IS NOT NULL + AND diagnosisOrder.value_coded = + diagnosisOrderConceptName.concept_id + AND + diagnosisOrderConceptName.concept_name_type + = 'FULLY_SPECIFIED' + LEFT JOIN obs diagnosisStatus + ON diagnosis.obs_group_id = diagnosisStatus.obs_group_id AND diagnosisStatus.voided = 0 AND + diagnosisStatus.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Bahmni Diagnosis Status' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisStatusConceptName ON diagnosisStatus.value_coded IS NOT NULL + AND diagnosisStatus.value_coded = + diagnosisStatusConceptName.concept_id + AND + diagnosisStatusConceptName.concept_name_type + = 'FULLY_SPECIFIED' + ) diagnosis ON diagnosis.person_id = pv.person_id", +'Sql query to get list of wards', +uuid() +); diff --git a/bahmnicore-omod/src/main/resources/V1_87_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_87_PatientSearchSql.sql new file mode 100644 index 0000000000..db363d23ba --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_87_PatientSearchSql.sql @@ -0,0 +1,24 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.activePatients' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatients', + 'select distinct + concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on p.person_id = v.patient_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) and va.voided = 0 + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of active patients', + uuid() +); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_88_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_88_PatientSearchSql.sql new file mode 100644 index 0000000000..d858643762 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_88_PatientSearchSql.sql @@ -0,0 +1,131 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.patientsToDischarge', + 'emrapi.sqlSearch.patientsHasPendingOrders', + 'emrapi.sqlSearch.admittedPatients', + 'emrapi.sqlSearch.highRiskPatients', + 'emrapi.sqlSearch.activePatientsByProvider' +); + + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToDischarge', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + FROM visit v + INNER JOIN person_name pn ON v.patient_id = pn.person_id and pn.voided is FALSE + INNER JOIN patient_identifier pi ON v.patient_id = pi.patient_id and pi.voided is FALSE + INNER JOIN person p ON v.patient_id = p.person_id + Inner Join (SELECT DISTINCT v.visit_id + FROM encounter en + INNER JOIN visit v ON v.visit_id = en.visit_id AND en.encounter_type = + (SELECT encounter_type_id + FROM encounter_type + WHERE name = "ADMISSION")) v1 on v1.visit_id = v.visit_id + INNER JOIN encounter e ON v.visit_id = e.visit_id + INNER JOIN obs o ON e.encounter_id = o.encounter_id + INNER JOIN concept_name cn ON o.value_coded = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND cn.voided is FALSE + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + LEFT OUTER JOIN encounter e1 ON e1.visit_id = v.visit_id AND e1.encounter_type = ( + SELECT encounter_type_id + FROM encounter_type + WHERE name = "DISCHARGE") AND e1.voided is FALSE + WHERE v.date_stopped IS NULL AND v.voided = 0 AND o.voided = 0 AND cn.name = "Discharge Patient" AND e1.encounter_id IS NULL', + 'Sql query to get list of patients to discharge', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsHasPendingOrders', + 'select distinct + concat(pn.given_name, " ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on p.person_id = v.patient_id + join orders on orders.patient_id = v.patient_id + join order_type on orders.order_type_id = order_type.order_type_id and order_type.name != "Lab Order" and order_type.name != "Drug Order" + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where v.date_stopped is null AND v.voided = 0 and order_id not in + (select obs.order_id + from obs + where person_id = pn.person_id and order_id = orders.order_id)', + 'Sql query to get list of patients who has pending orders', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.admittedPatients', + 'select distinct + concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on v.patient_id = p.person_id + join visit_attribute va on v.visit_id = va.visit_id and va.value_reference = "Admitted" and va.voided = 0 + join visit_attribute_type vat on vat.visit_attribute_type_id = va.attribute_type_id and vat.name = "Admission Status" + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of admitted patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.highRiskPatients', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from person p + inner join person_name pn on pn.person_id = p.person_id + inner join patient_identifier pi ON pn.person_id = pi.patient_id + inner join visit v on v.patient_id = p.person_id and v.date_stopped IS NULL and v.voided=0 + inner join concept_name cn on cn.name = \'LAB_ABNORMAL\' AND cn.concept_name_type = \'FULLY_SPECIFIED\' + inner join obs o on o.voided=0 and o.value_coded=1 and o.person_id = p.person_id and o.concept_id = cn.concept_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where o.obs_group_id in (select obs_id from obs where voided=0 and concept_id IN (SELECT concept_id FROM concept_name cn WHERE cn.concept_name_type = \'FULLY_SPECIFIED\' AND ', + 'Sql query to get list of admitted patients', + uuid() +); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('emrapi.sqlSearch.activePatientsByProvider',' + select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + pr.uuid=${provider_uuid} + order by en.encounter_datetime desc', + 'Sql query to get list of active patients by provider uuid', + uuid() +); diff --git a/bahmnicore-omod/src/main/resources/V1_89_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_89_PatientSearchSql.sql new file mode 100644 index 0000000000..54efdd62f5 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_89_PatientSearchSql.sql @@ -0,0 +1,28 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.patientsHasPendingOrders' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsHasPendingOrders', + 'select distinct + concat(pn.given_name, " ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on p.person_id = v.patient_id + join orders on orders.patient_id = v.patient_id + join order_type on orders.order_type_id = order_type.order_type_id and order_type.name != "Order" and order_type.name != "Drug Order" + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where v.date_stopped is null AND v.voided = 0 and order_id not in + (select obs.order_id + from obs + where person_id = pn.person_id and order_id = orders.order_id)', + 'Sql query to get list of patients who has pending orders', + uuid() +); diff --git a/bahmnicore-omod/src/main/resources/V1_90_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_90_PatientSearchSql.sql new file mode 100644 index 0000000000..ba7bef449a --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_90_PatientSearchSql.sql @@ -0,0 +1,40 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.highRiskPatients' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.highRiskPatients', + 'SELECT DISTINCT + concat(pn.given_name, '' '', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + FROM person p + INNER JOIN person_name pn ON pn.person_id = p.person_id + INNER JOIN patient_identifier pi ON pn.person_id = pi.patient_id + INNER JOIN visit v ON v.patient_id = p.person_id AND v.date_stopped IS NULL AND v.voided = 0 + INNER JOIN (SELECT max(obs_group_id) AS max_id, concept_id, person_id + FROM obs + WHERE voided = 0 AND concept_id IN + (SELECT concept_id + FROM concept_name cn + WHERE cn.concept_name_type = \'FULLY_SPECIFIED\' AND + cn.name IN (${testName})) + GROUP BY person_id, concept_id) AS tests ON tests.person_id = v.patient_id + INNER JOIN (SELECT obs_group_id, value_coded + FROM obs + WHERE voided = 0 AND concept_id IN + (SELECT concept_id + FROM concept_name cn + WHERE cn.concept_name_type = \'FULLY_SPECIFIED\' AND + cn.name = \'LAB_ABNORMAL\')) AS abnormal ON abnormal.obs_group_id = tests.max_id AND abnormal.value_coded =1 + + LEFT OUTER JOIN visit_attribute va ON va.visit_id = v.visit_id AND va.attribute_type_id = + (SELECT visit_attribute_type_id + FROM visit_attribute_type + WHERE NAME = "Admission Status")', + 'SQL QUERY TO get LIST of patients who has pending orders', + uuid() + ); diff --git a/bahmnicore-omod/src/main/resources/V1_91_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_91_PatientSearchSql.sql new file mode 100644 index 0000000000..6525a026b4 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_91_PatientSearchSql.sql @@ -0,0 +1,41 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.highRiskPatients' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.highRiskPatients', + 'SELECT DISTINCT + concat(pn.given_name, " ", pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") AS hasBeenAdmitted +FROM person p + INNER JOIN person_name pn ON pn.person_id = p.person_id + INNER JOIN patient_identifier pi ON pn.person_id = pi.patient_id + INNER JOIN visit v ON v.patient_id = p.person_id AND v.date_stopped IS NULL AND v.voided = 0 + INNER JOIN (SELECT + max(test_obs.obs_group_id) AS max_id, + test_obs.concept_id, + test_obs.person_id + FROM obs test_obs + INNER JOIN concept c ON c.concept_id = test_obs.concept_id AND test_obs.voided = 0 + INNER JOIN concept_name cn + ON c.concept_id = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND + cn.name IN (${testName}) + GROUP BY test_obs.person_id, test_obs.concept_id) AS tests ON tests.person_id = v.patient_id + INNER JOIN obs abnormal_obs + ON abnormal_obs.obs_group_id = tests.max_id AND abnormal_obs.value_coded = 1 AND abnormal_obs.voided = 0 + INNER JOIN concept abnormal_concept ON abnormal_concept.concept_id = abnormal_obs.concept_id + INNER JOIN concept_name abnormal_concept_name + ON abnormal_concept.concept_id = abnormal_concept_name.concept_id AND + abnormal_concept_name.concept_name_type = "FULLY_SPECIFIED" AND + abnormal_concept_name.name IN ("LAB_ABNORMAL") + LEFT OUTER JOIN visit_attribute va ON va.visit_id = v.visit_id AND va.attribute_type_id = + (SELECT visit_attribute_type_id + FROM visit_attribute_type + WHERE name = "Admission Status")', + 'SQL QUERY TO get LIST of patients who has pending orders', + uuid() +); diff --git a/bahmnicore-omod/src/main/resources/V1_92_PatientSearch.sql b/bahmnicore-omod/src/main/resources/V1_92_PatientSearch.sql new file mode 100644 index 0000000000..2f4e225fd8 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_92_PatientSearch.sql @@ -0,0 +1,31 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.activePatientsByLocation' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatientsByLocation', + 'select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + left outer join location loc on en.location_id = loc.location_id + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + loc.uuid=${location_uuid} + order by en.encounter_datetime desc', + 'SQL query to get list of active patients by location', + uuid() +); diff --git a/bahmnicore-omod/src/main/resources/V1_93_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_93_PatientSearchSql.sql new file mode 100644 index 0000000000..ac9ce277a2 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_93_PatientSearchSql.sql @@ -0,0 +1,132 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.activePatients', + 'emrapi.sqlSearch.activePatientsByProvider', + 'emrapi.sqlSearch.patientsToAdmit', + 'emrapi.sqlSearch.admittedPatients', + 'emrapi.sqlSearch.patientsToDischarge' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatients', + 'select distinct + concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on p.person_id = v.patient_id + join location l on l.uuid = ${visit_location_uuid} and v.location_id = l.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) and va.voided = 0 + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of active patients', + uuid() +); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('emrapi.sqlSearch.activePatientsByProvider',' + select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + join location l on l.uuid=${visit_location_uuid} and l.location_id = v.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + pr.uuid=${provider_uuid} + order by en.encounter_datetime desc', + 'Sql query to get list of active patients by provider uuid', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToAdmit', + 'select distinct concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 AND v.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on v.patient_id = p.person_id + join encounter e on v.visit_id = e.visit_id + join obs o on e.encounter_id = o.encounter_id and o.voided = 0 + join concept c on o.value_coded = c.concept_id + join concept_name cn on c.concept_id = cn.concept_id + join location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + where v.date_stopped is null and cn.name = \'Admit Patient\' and v.visit_id not in (select visit_id + from encounter ie join encounter_type iet + on iet.encounter_type_id = ie.encounter_type + where iet.name = \'ADMISSION\')', + 'Sql query to get list of patients to be admitted', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.admittedPatients', + 'select distinct + concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join person p on v.patient_id = p.person_id + join visit_attribute va on v.visit_id = va.visit_id and va.value_reference = "Admitted" and va.voided = 0 + join visit_attribute_type vat on vat.visit_attribute_type_id = va.attribute_type_id and vat.name = "Admission Status" + join location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of admitted patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToDischarge', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + FROM visit v + INNER JOIN person_name pn ON v.patient_id = pn.person_id and pn.voided is FALSE + INNER JOIN patient_identifier pi ON v.patient_id = pi.patient_id and pi.voided is FALSE + INNER JOIN person p ON v.patient_id = p.person_id + Inner Join (SELECT DISTINCT v.visit_id + FROM encounter en + INNER JOIN visit v ON v.visit_id = en.visit_id AND en.encounter_type = + (SELECT encounter_type_id + FROM encounter_type + WHERE name = "ADMISSION")) v1 on v1.visit_id = v.visit_id + INNER JOIN encounter e ON v.visit_id = e.visit_id + INNER JOIN obs o ON e.encounter_id = o.encounter_id + INNER JOIN concept_name cn ON o.value_coded = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND cn.voided is FALSE + JOIN location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + LEFT OUTER JOIN encounter e1 ON e1.visit_id = v.visit_id AND e1.encounter_type = ( + SELECT encounter_type_id + FROM encounter_type + WHERE name = "DISCHARGE") AND e1.voided is FALSE + WHERE v.date_stopped IS NULL AND v.voided = 0 AND o.voided = 0 AND cn.name = "Discharge Patient" AND e1.encounter_id IS NULL', + 'Sql query to get list of patients to discharge', + uuid() +); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_94_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_94_PatientSearchSql.sql new file mode 100644 index 0000000000..a037577217 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_94_PatientSearchSql.sql @@ -0,0 +1,242 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.activePatients', + 'emrapi.sqlSearch.activePatientsByProvider', + 'emrapi.sqlSearch.patientsToAdmit', + 'emrapi.sqlSearch.admittedPatients', + 'emrapi.sqlSearch.patientsToDischarge', + 'emrapi.sqlSearch.activePatientsByLocation', + 'emrapi.sqlSearch.highRiskPatients', + 'emrapi.sqlSearch.patientsHasPendingOrders' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatients', + 'select distinct + concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id + join location l on l.uuid = ${visit_location_uuid} and v.location_id = l.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) and va.voided = 0 + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of active patients', + uuid() +); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('emrapi.sqlSearch.activePatientsByProvider',' + select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + join location l on l.uuid=${visit_location_uuid} and l.location_id = v.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + pr.uuid=${provider_uuid} + order by en.encounter_datetime desc', + 'Sql query to get list of active patients by provider uuid', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToAdmit', + 'select distinct concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 AND v.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on v.patient_id = p.person_id + join encounter e on v.visit_id = e.visit_id + join obs o on e.encounter_id = o.encounter_id and o.voided = 0 + join concept c on o.value_coded = c.concept_id + join concept_name cn on c.concept_id = cn.concept_id + join location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + where v.date_stopped is null and cn.name = \'Admit Patient\' and v.visit_id not in (select visit_id + from encounter ie join encounter_type iet + on iet.encounter_type_id = ie.encounter_type + where iet.name = \'ADMISSION\')', + 'Sql query to get list of patients to be admitted', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.admittedPatients', + 'select distinct + concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on v.patient_id = p.person_id + join visit_attribute va on v.visit_id = va.visit_id and va.value_reference = "Admitted" and va.voided = 0 + join visit_attribute_type vat on vat.visit_attribute_type_id = va.attribute_type_id and vat.name = "Admission Status" + join location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of admitted patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToDischarge', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + FROM visit v + INNER JOIN person_name pn ON v.patient_id = pn.person_id and pn.voided is FALSE + INNER JOIN patient_identifier pi ON v.patient_id = pi.patient_id and pi.voided is FALSE + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + INNER JOIN person p ON v.patient_id = p.person_id + Inner Join (SELECT DISTINCT v.visit_id + FROM encounter en + INNER JOIN visit v ON v.visit_id = en.visit_id AND en.encounter_type = + (SELECT encounter_type_id + FROM encounter_type + WHERE name = "ADMISSION")) v1 on v1.visit_id = v.visit_id + INNER JOIN encounter e ON v.visit_id = e.visit_id + INNER JOIN obs o ON e.encounter_id = o.encounter_id + INNER JOIN concept_name cn ON o.value_coded = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND cn.voided is FALSE + JOIN location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + LEFT OUTER JOIN encounter e1 ON e1.visit_id = v.visit_id AND e1.encounter_type = ( + SELECT encounter_type_id + FROM encounter_type + WHERE name = "DISCHARGE") AND e1.voided is FALSE + WHERE v.date_stopped IS NULL AND v.voided = 0 AND o.voided = 0 AND cn.name = "Discharge Patient" AND e1.encounter_id IS NULL', + 'Sql query to get list of patients to discharge', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatientsByLocation', + 'select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + left outer join location loc on en.location_id = loc.location_id + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + loc.uuid=${location_uuid} + order by en.encounter_datetime desc', + 'SQL query to get list of active patients by location', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.highRiskPatients', + 'SELECT DISTINCT + concat(pn.given_name, " ", pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") AS hasBeenAdmitted +FROM person p + INNER JOIN person_name pn ON pn.person_id = p.person_id + INNER JOIN patient_identifier pi ON pn.person_id = pi.patient_id + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + INNER JOIN visit v ON v.patient_id = p.person_id AND v.date_stopped IS NULL AND v.voided = 0 + INNER JOIN (SELECT + max(test_obs.obs_group_id) AS max_id, + test_obs.concept_id, + test_obs.person_id + FROM obs test_obs + INNER JOIN concept c ON c.concept_id = test_obs.concept_id AND test_obs.voided = 0 + INNER JOIN concept_name cn + ON c.concept_id = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND + cn.name IN (${testName}) + GROUP BY test_obs.person_id, test_obs.concept_id) AS tests ON tests.person_id = v.patient_id + INNER JOIN obs abnormal_obs + ON abnormal_obs.obs_group_id = tests.max_id AND abnormal_obs.value_coded = 1 AND abnormal_obs.voided = 0 + INNER JOIN concept abnormal_concept ON abnormal_concept.concept_id = abnormal_obs.concept_id + INNER JOIN concept_name abnormal_concept_name + ON abnormal_concept.concept_id = abnormal_concept_name.concept_id AND + abnormal_concept_name.concept_name_type = "FULLY_SPECIFIED" AND + abnormal_concept_name.name IN ("LAB_ABNORMAL") + LEFT OUTER JOIN visit_attribute va ON va.visit_id = v.visit_id AND va.attribute_type_id = + (SELECT visit_attribute_type_id + FROM visit_attribute_type + WHERE name = "Admission Status")', + 'SQL QUERY TO get LIST of patients with high risk', + uuid() +); + + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsHasPendingOrders', + 'select distinct + concat(pn.given_name, " ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="emr.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id + join orders on orders.patient_id = v.patient_id + join order_type on orders.order_type_id = order_type.order_type_id and order_type.name != "Order" and order_type.name != "Drug Order" + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where v.date_stopped is null AND v.voided = 0 and order_id not in + (select obs.order_id + from obs + where person_id = pn.person_id and order_id = orders.order_id)', + 'Sql query to get list of patients who has pending orders', + uuid() +); + + diff --git a/bahmnicore-omod/src/main/resources/V1_95_WardsListSql.sql b/bahmnicore-omod/src/main/resources/V1_95_WardsListSql.sql new file mode 100644 index 0000000000..541086c251 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_95_WardsListSql.sql @@ -0,0 +1,155 @@ +DELETE FROM global_property where property = 'emrapi.sqlGet.wardsListDetails'; + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlGet.wardsListDetails', +"SELECT + b.bed_number AS 'Bed', + concat(pn.given_name, ' ', pn.family_name) AS 'Name', + pv.uuid AS 'Patient Uuid', + pi.identifier AS 'Id', + pv.gender AS 'Gender', + TIMESTAMPDIFF(YEAR, pv.birthdate, CURDATE()) AS 'Age', + pa.county_district AS 'District', + pa.city_village AS 'Village', + admission_provider_name.given_name AS 'Admission By', + cast(DATE_FORMAT(latestAdmissionEncounter.max_encounter_datetime, '%d %b %y %h:%i %p') AS CHAR) AS 'Admission Time', + diagnosis.diagnosisConcept AS 'Diagnosis', + diagnosis.certainty AS 'Diagnosis Certainty', + diagnosis.diagnosisOrder AS 'Diagnosis Order', + diagnosis.status AS 'Diagnosis Status', + diagnosis.diagnosis_provider AS 'Diagnosis Provider', + cast(DATE_FORMAT(diagnosis.diagnosis_datetime, '%d %b %y %h:%i %p') AS + CHAR) AS 'Diagnosis Datetime', + dispositionInfo.providerName AS 'Disposition By', + cast(DATE_FORMAT(dispositionInfo.providerDate, '%d %b %y %h:%i %p') AS CHAR) AS 'Disposition Time', + adtNotes.value_text AS 'ADT Notes', + v.uuid AS 'Visit Uuid' +FROM bed_location_map blm + INNER JOIN bed b + ON blm.bed_id = b.bed_id AND + b.status = 'OCCUPIED' AND + blm.location_id IN (SELECT child_location.location_id + FROM location child_location JOIN + location parent_location + ON parent_location.location_id = + child_location.parent_location + WHERE + parent_location.name = ${location_name}) + INNER JOIN bed_patient_assignment_map bpam ON b.bed_id = bpam.bed_id AND date_stopped IS NULL + INNER JOIN person pv ON pv.person_id = bpam.patient_id + INNER JOIN person_name pn ON pn.person_id = pv.person_id + INNER JOIN patient_identifier pi ON pv.person_id = pi.patient_id + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property='emr.primaryIdentifierType' and gp.property_value=pit.uuid + LEFT JOIN person_address pa ON pa.person_id = pv.person_id + INNER JOIN (SELECT + patient_id, + max(encounter_datetime) AS max_encounter_datetime, + max(visit_id) as visit_id, + max(encounter_id) AS encounter_id + FROM encounter + INNER JOIN encounter_type ON encounter_type.encounter_type_id = encounter.encounter_type + WHERE encounter_type.name = 'ADMISSION' + GROUP BY patient_id) latestAdmissionEncounter ON pv.person_id = latestAdmissionEncounter.patient_id + INNER JOIN visit v ON latestAdmissionEncounter.visit_id = v.visit_id + LEFT OUTER JOIN obs adtNotes + ON adtNotes.encounter_id = latestAdmissionEncounter.encounter_id AND adtNotes.voided = 0 AND + adtNotes.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Adt Notes' AND concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN encounter_provider ep ON ep.encounter_id = latestAdmissionEncounter.encounter_id + LEFT OUTER JOIN provider admission_provider ON admission_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name admission_provider_name + ON admission_provider_name.person_id = admission_provider.person_id + LEFT OUTER JOIN ( + SELECT + bpam.patient_id AS person_id, + concept_name.name AS disposition, + latestDisposition.obs_datetime AS providerDate, + person_name.given_name AS providerName + FROM bed_patient_assignment_map bpam + INNER JOIN (SELECT + person_id, + max(obs_id) obs_id + FROM obs + WHERE concept_id = (SELECT concept_id + FROM concept_name + WHERE + name = 'Disposition' AND concept_name_type = 'FULLY_SPECIFIED') + GROUP BY person_id) maxObsId ON maxObsId.person_id = bpam.patient_id + INNER JOIN obs latestDisposition + ON maxObsId.obs_id = latestDisposition.obs_id AND latestDisposition.voided = 0 + INNER JOIN concept_name ON latestDisposition.value_coded = concept_name.concept_id AND + concept_name_type = 'FULLY_SPECIFIED' + LEFT OUTER JOIN encounter_provider ep ON latestDisposition.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider disp_provider ON disp_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = disp_provider.person_id + WHERE bpam.date_stopped IS NULL + ) dispositionInfo ON pv.person_id = dispositionInfo.person_id + LEFT OUTER JOIN ( + SELECT + diagnosis.person_id AS person_id, + diagnosis.obs_id AS obs_id, + diagnosis.obs_datetime AS diagnosis_datetime, + if(diagnosisConceptName.name IS NOT NULL, diagnosisConceptName.name, + diagnosis.value_text) AS diagnosisConcept, + certaintyConceptName.name AS certainty, + diagnosisOrderConceptName.name AS diagnosisOrder, + diagnosisStatusConceptName.name AS status, + person_name.given_name AS diagnosis_provider + FROM bed_patient_assignment_map bpam + INNER JOIN visit latestVisit + ON latestVisit.patient_id = bpam.patient_id AND latestVisit.date_stopped IS NULL AND + bpam.date_stopped IS NULL + INNER JOIN encounter ON encounter.visit_id = latestVisit.visit_id + INNER JOIN obs diagnosis ON bpam.patient_id = diagnosis.person_id AND diagnosis.voided = 0 AND + diagnosis.encounter_id = encounter.encounter_id AND + diagnosis.concept_id IN (SELECT concept_id + FROM concept_name + WHERE name IN + ('Coded Diagnosis', 'Non-Coded Diagnosis') + AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisConceptName + ON diagnosis.value_coded IS NOT NULL AND diagnosis.value_coded = diagnosisConceptName.concept_id + AND diagnosisConceptName.concept_name_type = 'FULLY_SPECIFIED' + LEFT OUTER JOIN encounter_provider ep ON diagnosis.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider diagnosis_provider ON diagnosis_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = diagnosis_provider.person_id + INNER JOIN obs certainty + ON diagnosis.obs_group_id = certainty.obs_group_id AND certainty.voided = 0 AND + certainty.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Diagnosis Certainty' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name certaintyConceptName + ON certainty.value_coded IS NOT NULL AND certainty.value_coded = certaintyConceptName.concept_id + AND certaintyConceptName.concept_name_type = 'FULLY_SPECIFIED' + INNER JOIN obs diagnosisOrder + ON diagnosis.obs_group_id = diagnosisOrder.obs_group_id AND diagnosisOrder.voided = 0 AND + diagnosisOrder.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Diagnosis order' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisOrderConceptName ON diagnosisOrder.value_coded IS NOT NULL + AND diagnosisOrder.value_coded = + diagnosisOrderConceptName.concept_id + AND + diagnosisOrderConceptName.concept_name_type + = 'FULLY_SPECIFIED' + LEFT JOIN obs diagnosisStatus + ON diagnosis.obs_group_id = diagnosisStatus.obs_group_id AND diagnosisStatus.voided = 0 AND + diagnosisStatus.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Bahmni Diagnosis Status' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisStatusConceptName ON diagnosisStatus.value_coded IS NOT NULL + AND diagnosisStatus.value_coded = + diagnosisStatusConceptName.concept_id + AND + diagnosisStatusConceptName.concept_name_type + = 'FULLY_SPECIFIED' + ) diagnosis ON diagnosis.person_id = pv.person_id", +'Sql query to get list of wards', +uuid() +); diff --git a/bahmnicore-omod/src/main/resources/V1_96_NewRolesAndPrivileges.sql b/bahmnicore-omod/src/main/resources/V1_96_NewRolesAndPrivileges.sql new file mode 100644 index 0000000000..1e81677ea8 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_96_NewRolesAndPrivileges.sql @@ -0,0 +1,301 @@ +insert ignore into privilege values ('app:clinical:treatmentTab', 'View Treatment tab', UUID()); +insert ignore into privilege values ('app:clinical:ordersTab', 'View Orders tab', UUID()); +insert ignore into privilege values ('app:clinical:bacteriologyTab', 'View Bacteriology tab', UUID()); +insert ignore into privilege values ('app:implementer-interface', 'Will give access to implementer interface app', UUID()); +insert ignore into privilege values ('app:radiology-upload', 'Will give access to radiology app', UUID()); +insert ignore into privilege values ('app:patient-documents', 'Will give access to patient documents app', UUID()); + +# Create Bahmni-App-User-Login role +insert ignore into role values('Bahmni-App-User-Login', 'Will give ability to login to the application', UUID()); +insert ignore into role_privilege values('Bahmni-App-User-Login', 'Edit Users'); +insert ignore into role_privilege values('Bahmni-App-User-Login', 'Get Providers'); +insert ignore into role_privilege values('Bahmni-App-User-Login', 'Get Users'); + +# Create Registration-App-Read-Only role +insert ignore into role values('Registration-App-Read-Only', 'Will have read only access for Registration app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Registration-App-Read-Only'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'app:registration'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Concepts'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Encounters'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Patients'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get People'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Person Attribute Types'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Visit Types'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Visits'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'View Patients'); +insert ignore into role_privilege values('Registration-App-Read-Only', 'Get Observations'); + +# Create Registration-App role +insert ignore into role values('Registration-App', 'Will have full access for Registration app', UUID()); +insert ignore into role_role values('Registration-App-Read-Only', 'Registration-App'); +insert ignore into role_privilege values('Registration-App', 'Add Encounters'); +insert ignore into role_privilege values('Registration-App', 'Add Patients'); +insert ignore into role_privilege values('Registration-App', 'Add Visits'); +insert ignore into role_privilege values('Registration-App', 'Edit Encounters'); +insert ignore into role_privilege values('Registration-App', 'Edit Patients'); +insert ignore into role_privilege values('Registration-App', 'Edit Visits'); +insert ignore into role_privilege values('Registration-App', 'Get Encounter Roles'); +insert ignore into role_privilege values('Registration-App', 'Get Patient Identifiers'); +insert ignore into role_privilege values('Registration-App', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('Registration-App', 'Edit Patient Identifiers'); +insert ignore into role_privilege values('Registration-App', 'Edit Relationships'); +insert ignore into role_privilege values('Registration-App', 'Add Relationships'); + +# Create Programs-App role +insert ignore into role values('Programs-App', 'Will have full access for Programs app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Programs-App'); +insert ignore into role_privilege values('Programs-App', 'Add Patient Programs'); +insert ignore into role_privilege values('Programs-App', 'app:clinical'); +insert ignore into role_privilege values('Programs-App', 'app:clinical:locationpicker'); +insert ignore into role_privilege values('Programs-App', 'app:clinical:onbehalf'); +insert ignore into role_privilege values('Programs-App', 'app:clinical:retrospective'); +insert ignore into role_privilege values('Programs-App', 'Edit Patient Programs'); +insert ignore into role_privilege values('Programs-App', 'Get Patient Programs'); +insert ignore into role_privilege values('Programs-App', 'Get Patients'); +insert ignore into role_privilege values('Programs-App', 'Get People'); +insert ignore into role_privilege values('Programs-App', 'Get Programs'); +insert ignore into role_privilege values('Programs-App', 'Get Visits'); +insert ignore into role_privilege values('Programs-App', 'Manage Program Attribute Types'); +insert ignore into role_privilege values('Programs-App', 'Purge Program Attribute Types'); +insert ignore into role_privilege values('Programs-App', 'View Patient Programs'); +insert ignore into role_privilege values('Programs-App', 'View Program Attribute Types'); +insert ignore into role_privilege values('Programs-App', 'Get Concepts'); +insert ignore into role_privilege values('Programs-App', 'Get Visit Types'); + +# Create Reports-App role +insert ignore into role values('Reports-App', 'Will have full access for Reports app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Reports-App'); +insert ignore into role_privilege values('Reports-App', 'app:reports'); +insert ignore into role_privilege values('Reports-App', 'Get Concepts'); +insert ignore into role_privilege values('Reports-App', 'Get Visit Types'); + +# Create OrderFulfillment-App role +insert ignore into role values('OrderFulfillment-App', 'Will have full access for OrdersFulfillment app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'OrderFulfillment-App'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Add Encounters'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Add Visits'); +insert ignore into role_privilege values('OrderFulfillment-App', 'app:orders'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Edit Encounters'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Edit Visits'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Concepts'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Encounter Roles'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Encounters'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Orders'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Patients'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Visit Types'); +insert ignore into role_privilege values('OrderFulfillment-App', 'Get Visits'); + +# Create PatientDocuments-App role +insert ignore into role values('PatientDocuments-App', 'Will have full access for Patient Documents app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'PatientDocuments-App'); +insert ignore into role_privilege values('PatientDocuments-App', 'Add Visits'); +insert ignore into role_privilege values('PatientDocuments-App', 'app:patient-documents'); +insert ignore into role_privilege values('PatientDocuments-App', 'Edit Visits'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Concepts'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Encounter Roles'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Encounters'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Patients'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Visit Types'); +insert ignore into role_privilege values('PatientDocuments-App', 'Get Visits'); + +# Create Radiology-App role +insert ignore into role values('Radiology-App', 'Will have full access for Radiology app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Radiology-App'); +insert ignore into role_privilege values('Radiology-App', 'Add Visits'); +insert ignore into role_privilege values('Radiology-App', 'app:radiology-upload'); +insert ignore into role_privilege values('Radiology-App', 'Edit Visits'); +insert ignore into role_privilege values('Radiology-App', 'Get Encounter Roles'); +insert ignore into role_privilege values('Radiology-App', 'Get Encounters'); +insert ignore into role_privilege values('Radiology-App', 'Get Patients'); +insert ignore into role_privilege values('Radiology-App', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('Radiology-App', 'Get Visits'); +insert ignore into role_privilege values('Radiology-App', 'Get Visit Types'); +insert ignore into role_privilege values('Radiology-App', 'Get Concepts'); + +# Create InPatient-App-Read-Only role +insert ignore into role values('InPatient-App-Read-Only', 'Will have read only access for InPatient app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'InPatient-App-Read-Only'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'app:adt'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Admission Locations'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Beds'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Concepts'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Visit Types'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Observations'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Visits'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get People'); +insert ignore into role_privilege values('InPatient-App-Read-Only', 'Get Patients'); + +# Create Admin-App role +insert ignore into role values('Admin-App', 'Will have full access for Admin app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Admin-App'); +insert ignore into role_privilege values('Admin-App', 'Add Encounters'); +insert ignore into role_privilege values('Admin-App', 'Add Orders'); +insert ignore into role_privilege values('Admin-App', 'Add Patient Programs'); +insert ignore into role_privilege values('Admin-App', 'Add Patients'); +insert ignore into role_privilege values('Admin-App', 'Add Relationships'); +insert ignore into role_privilege values('Admin-App', 'Add Visits'); +insert ignore into role_privilege values('Admin-App', 'app:admin'); +insert ignore into role_privilege values('Admin-App', 'Manage Order Sets'); +insert ignore into role_privilege values('Admin-App', 'Edit Encounters'); +insert ignore into role_privilege values('Admin-App', 'Edit Orders'); +insert ignore into role_privilege values('Admin-App', 'Edit Patient Programs'); +insert ignore into role_privilege values('Admin-App', 'Edit Patients'); +insert ignore into role_privilege values('Admin-App', 'Edit Relationships'); +insert ignore into role_privilege values('Admin-App', 'Edit Visits'); +insert ignore into role_privilege values('Admin-App', 'Get Care Settings'); +insert ignore into role_privilege values('Admin-App', 'Get Concept Reference Terms'); +insert ignore into role_privilege values('Admin-App', 'Get Concepts'); +insert ignore into role_privilege values('Admin-App', 'Get Encounter Roles'); +insert ignore into role_privilege values('Admin-App', 'Get Encounters'); +insert ignore into role_privilege values('Admin-App', 'Get Observations'); +insert ignore into role_privilege values('Admin-App', 'Get Order Frequencies'); +insert ignore into role_privilege values('Admin-App', 'Get Order Sets'); +insert ignore into role_privilege values('Admin-App', 'Get Patient Programs'); +insert ignore into role_privilege values('Admin-App', 'Get Patients'); +insert ignore into role_privilege values('Admin-App', 'Get Programs'); +insert ignore into role_privilege values('Admin-App', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('Admin-App', 'Get Visit Types'); +insert ignore into role_privilege values('Admin-App', 'Get Visits'); +insert ignore into role_privilege values('Admin-App', 'Manage Concept Reference Terms'); +insert ignore into role_privilege values('Admin-App', 'Manage Concepts'); + +# Create InPatient-App role +insert ignore into role values('InPatient-App', 'Will have full access for InPatient app', UUID()); +insert ignore into role_role values('InPatient-App-Read-Only', 'InPatient-App'); +insert ignore into role_privilege values('InPatient-App', 'Add Encounters'); +insert ignore into role_privilege values('InPatient-App', 'Add Visits'); +insert ignore into role_privilege values('InPatient-App', 'Assign Beds'); +insert ignore into role_privilege values('InPatient-App', 'Edit Admission Locations'); +insert ignore into role_privilege values('InPatient-App', 'Edit Encounters'); +insert ignore into role_privilege values('InPatient-App', 'Edit Visits'); +insert ignore into role_privilege values('InPatient-App', 'Get Encounter Roles'); +insert ignore into role_privilege values('InPatient-App', 'Get Encounters'); +insert ignore into role_privilege values('InPatient-App', 'Get Observations'); +insert ignore into role_privilege values('InPatient-App', 'Get Patients'); +insert ignore into role_privilege values('InPatient-App', 'Get People'); +insert ignore into role_privilege values('InPatient-App', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('InPatient-App', 'Get Visits'); + +# Create Clinical-App-Common role +insert ignore into role values('Clinical-App-Common', 'Will have common privileges used by other Clinical roles, not be assigned User directly', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Clinical-App-Common'); +insert ignore into role_privilege values('Clinical-App-Common', 'app:clinical'); +insert ignore into role_privilege values('Clinical-App-Common', 'app:clinical:locationpicker'); +insert ignore into role_privilege values('Clinical-App-Common', 'app:clinical:onbehalf'); +insert ignore into role_privilege values('Clinical-App-Common', 'app:clinical:retrospective'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Admission Locations'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Beds'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Care Settings'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Concept Sources'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Concepts'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Encounters'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Observations'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Order Frequencies'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Order Types'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Orders'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Patient Programs'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Patients'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get People'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Privileges'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Visit Types'); +insert ignore into role_privilege values('Clinical-App-Common', 'Get Visits'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Concepts'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Encounters'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Observations'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Order Types'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Orders'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Patient Programs'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Patients'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Program Attribute Types'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Providers'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Users'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Visit Types'); +insert ignore into role_privilege values('Clinical-App-Common', 'View Visits'); +insert ignore into role_privilege values('Clinical-App-Common', 'app:clinical:history'); + +# Create Clinical-App-Read-Only role +insert ignore into role values('Clinical-App-Read-Only', 'Will have read only access to Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Read-Only'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:bacteriologyTab'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:consultationTab'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:diagnosisTab'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:dispositionTab'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:history'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:observationTab'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:ordersTab'); +insert ignore into role_privilege values('Clinical-App-Read-Only', 'app:clinical:treatmentTab'); + +# Create Clinical-App-Save role +insert ignore into role values('Clinical-App-Save', 'Will give ability to save in Clinical app', UUID()); +insert ignore into role_privilege values('Clinical-App-Save', 'Add Encounters'); +insert ignore into role_privilege values('Clinical-App-Save', 'Add Visits'); +insert ignore into role_privilege values('Clinical-App-Save', 'Edit Encounters'); +insert ignore into role_privilege values('Clinical-App-Save', 'Edit Visits'); +insert ignore into role_privilege values('Clinical-App-Save', 'Get Encounter Roles'); +insert ignore into role_privilege values('Clinical-App-Save', 'Get Visit Attribute Types'); +insert ignore into role_privilege values('Clinical-App-Save', 'Add Orders'); +insert ignore into role_privilege values('Clinical-App-Save', 'Edit Orders'); + +# Create Clinical-App-Diagnosis role +insert ignore into role values('Clinical-App-Diagnosis', 'Will have full access for Diagnosis tab in Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App-Diagnosis'); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Diagnosis'); +insert ignore into role_privilege values('Clinical-App-Diagnosis', 'app:clinical:diagnosisTab'); + +# Create Clinical-App-Disposition role +insert ignore into role values('Clinical-App-Disposition', 'Will have full access for Disposition tab in Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App-Disposition'); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Disposition'); +insert ignore into role_privilege values('Clinical-App-Disposition', 'app:clinical:dispositionTab'); + +# Create Clinical-App-Observations role +insert ignore into role values('Clinical-App-Observations', 'Will have full access for Observations tab in Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App-Observations'); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Observations'); +insert ignore into role_privilege values('Clinical-App-Observations', 'app:clinical:observationTab'); + +# Create Clinical-App-Treatment role +insert ignore into role values('Clinical-App-Treatment', 'Will have full access for Treatment tab in Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App-Treatment'); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Treatment'); +insert ignore into role_privilege values('Clinical-App-Treatment', 'app:clinical:treatmentTab'); + +# Create Clinical-App-Orders role +insert ignore into role values('Clinical-App-Orders', 'Will have full access for Orders tab in Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App-Orders'); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Orders'); +insert ignore into role_privilege values('Clinical-App-Orders', 'app:clinical:ordersTab'); + +# Create Clinical-App-Bacteriology role +insert ignore into role values('Clinical-App-Bacteriology', 'Will have full access for Bacteriology tab in Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App-Bacteriology'); +insert ignore into role_role values('Clinical-App-Common', 'Clinical-App-Bacteriology'); +insert ignore into role_privilege values('Clinical-App-Bacteriology', 'app:clinical:bacteriologyTab'); + +# Create Clinical-App role +insert ignore into role values('Clinical-App', 'Will have full access to Clinical app', UUID()); +insert ignore into role_role values('Clinical-App-Save', 'Clinical-App'); +insert ignore into role_role values('Clinical-App-Read-Only', 'Clinical-App'); + +# Create Implementer-Interface-App role +insert ignore into role values('Implementer-Interface-App', 'Will have full access to Implementer Interface app', UUID()); +insert ignore into role_role values('Bahmni-App-User-Login', 'Implementer-Interface-App'); +insert ignore into role_privilege values('Implementer-Interface-App', 'app:implementer-interface'); + +# Create Bahmni-App role +insert ignore into role values('Bahmni-App', 'Will have full access to Bahmni', UUID()); +insert ignore into role_role values('Registration-App', 'Bahmni-App'); +insert ignore into role_role values('Programs-App', 'Bahmni-App'); +insert ignore into role_role values('Reports-App', 'Bahmni-App'); +insert ignore into role_role values('OrderFulfillment-App', 'Bahmni-App'); +insert ignore into role_role values('PatientDocuments-App', 'Bahmni-App'); +insert ignore into role_role values('Radiology-App', 'Bahmni-App'); +insert ignore into role_role values('Implementer-Interface-App', 'Bahmni-App'); +insert ignore into role_role values('Admin-App', 'Bahmni-App'); +insert ignore into role_role values('InPatient-App', 'Bahmni-App'); +insert ignore into role_role values('Clinical-App', 'Bahmni-App'); +# Create SuperAdmin role +insert ignore into role values('SuperAdmin', 'Will give full acess to Bahmni and OpenMRS', UUID()); +insert ignore into role_privilege select 'SuperAdmin',privilege from privilege; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/V1_97_PatientSearchSql.sql b/bahmnicore-omod/src/main/resources/V1_97_PatientSearchSql.sql new file mode 100644 index 0000000000..0f78de3c66 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_97_PatientSearchSql.sql @@ -0,0 +1,242 @@ +DELETE FROM global_property +WHERE property IN ( + 'emrapi.sqlSearch.activePatients', + 'emrapi.sqlSearch.activePatientsByProvider', + 'emrapi.sqlSearch.patientsToAdmit', + 'emrapi.sqlSearch.admittedPatients', + 'emrapi.sqlSearch.patientsToDischarge', + 'emrapi.sqlSearch.activePatientsByLocation', + 'emrapi.sqlSearch.highRiskPatients', + 'emrapi.sqlSearch.patientsHasPendingOrders' +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatients', + 'select distinct + concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id + join location l on l.uuid = ${visit_location_uuid} and v.location_id = l.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) and va.voided = 0 + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of active patients', + uuid() +); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('emrapi.sqlSearch.activePatientsByProvider',' + select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + join location l on l.uuid=${visit_location_uuid} and l.location_id = v.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + pr.uuid=${provider_uuid} + order by en.encounter_datetime desc', + 'Sql query to get list of active patients by provider uuid', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToAdmit', + 'select distinct concat(pn.given_name,\' \', pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 AND v.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on v.patient_id = p.person_id + join encounter e on v.visit_id = e.visit_id + join obs o on e.encounter_id = o.encounter_id and o.voided = 0 + join concept c on o.value_coded = c.concept_id + join concept_name cn on c.concept_id = cn.concept_id + join location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + where v.date_stopped is null and cn.name = \'Admit Patient\' and v.visit_id not in (select visit_id + from encounter ie join encounter_type iet + on iet.encounter_type_id = ie.encounter_type + where iet.name = \'ADMISSION\')', + 'Sql query to get list of patients to be admitted', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.admittedPatients', + 'select distinct + concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on v.patient_id = p.person_id + join visit_attribute va on v.visit_id = va.visit_id and va.value_reference = "Admitted" and va.voided = 0 + join visit_attribute_type vat on vat.visit_attribute_type_id = va.attribute_type_id and vat.name = "Admission Status" + join location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + where v.date_stopped is null AND v.voided = 0', + 'Sql query to get list of admitted patients', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsToDischarge', + 'SELECT DISTINCT + concat(pn.given_name, \' \', pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + FROM visit v + INNER JOIN person_name pn ON v.patient_id = pn.person_id and pn.voided is FALSE + INNER JOIN patient_identifier pi ON v.patient_id = pi.patient_id and pi.voided is FALSE + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + INNER JOIN person p ON v.patient_id = p.person_id + Inner Join (SELECT DISTINCT v.visit_id + FROM encounter en + INNER JOIN visit v ON v.visit_id = en.visit_id AND en.encounter_type = + (SELECT encounter_type_id + FROM encounter_type + WHERE name = "ADMISSION")) v1 on v1.visit_id = v.visit_id + INNER JOIN encounter e ON v.visit_id = e.visit_id + INNER JOIN obs o ON e.encounter_id = o.encounter_id + INNER JOIN concept_name cn ON o.value_coded = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND cn.voided is FALSE + JOIN location l on l.uuid=${visit_location_uuid} and v.location_id = l.location_id + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + LEFT OUTER JOIN encounter e1 ON e1.visit_id = v.visit_id AND e1.encounter_type = ( + SELECT encounter_type_id + FROM encounter_type + WHERE name = "DISCHARGE") AND e1.voided is FALSE + WHERE v.date_stopped IS NULL AND v.voided = 0 AND o.voided = 0 AND cn.name = "Discharge Patient" AND e1.encounter_id IS NULL', + 'Sql query to get list of patients to discharge', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.activePatientsByLocation', + 'select distinct concat(pn.given_name," ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from + visit v join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 and v.voided=0 + join patient_identifier pi on v.patient_id = pi.patient_id and pi.voided=0 + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id and p.voided=0 + join encounter en on en.visit_id = v.visit_id and en.voided=0 + left outer join location loc on en.location_id = loc.location_id + join encounter_provider ep on ep.encounter_id = en.encounter_id and ep.voided=0 + join provider pr on ep.provider_id=pr.provider_id and pr.retired=0 + join person per on pr.person_id=per.person_id and per.voided=0 + left outer join visit_attribute va on va.visit_id = v.visit_id and va.attribute_type_id = ( + select visit_attribute_type_id from visit_attribute_type where name="Admission Status" + ) + where + v.date_stopped is null and + loc.uuid=${location_uuid} + order by en.encounter_datetime desc', + 'SQL query to get list of active patients by location', + uuid() +); + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.highRiskPatients', + 'SELECT DISTINCT + concat(pn.given_name, " ", pn.family_name) AS name, + pi.identifier AS identifier, + concat("", p.uuid) AS uuid, + concat("", v.uuid) AS activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") AS hasBeenAdmitted +FROM person p + INNER JOIN person_name pn ON pn.person_id = p.person_id + INNER JOIN patient_identifier pi ON pn.person_id = pi.patient_id + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + INNER JOIN visit v ON v.patient_id = p.person_id AND v.date_stopped IS NULL AND v.voided = 0 + INNER JOIN (SELECT + max(test_obs.obs_group_id) AS max_id, + test_obs.concept_id, + test_obs.person_id + FROM obs test_obs + INNER JOIN concept c ON c.concept_id = test_obs.concept_id AND test_obs.voided = 0 + INNER JOIN concept_name cn + ON c.concept_id = cn.concept_id AND cn.concept_name_type = "FULLY_SPECIFIED" AND + cn.name IN (${testName}) + GROUP BY test_obs.person_id, test_obs.concept_id) AS tests ON tests.person_id = v.patient_id + INNER JOIN obs abnormal_obs + ON abnormal_obs.obs_group_id = tests.max_id AND abnormal_obs.value_coded = 1 AND abnormal_obs.voided = 0 + INNER JOIN concept abnormal_concept ON abnormal_concept.concept_id = abnormal_obs.concept_id + INNER JOIN concept_name abnormal_concept_name + ON abnormal_concept.concept_id = abnormal_concept_name.concept_id AND + abnormal_concept_name.concept_name_type = "FULLY_SPECIFIED" AND + abnormal_concept_name.name IN ("LAB_ABNORMAL") + LEFT OUTER JOIN visit_attribute va ON va.visit_id = v.visit_id AND va.attribute_type_id = + (SELECT visit_attribute_type_id + FROM visit_attribute_type + WHERE name = "Admission Status")', + 'SQL QUERY TO get LIST of patients with high risk', + uuid() +); + + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlSearch.patientsHasPendingOrders', + 'select distinct + concat(pn.given_name, " ", pn.family_name) as name, + pi.identifier as identifier, + concat("",p.uuid) as uuid, + concat("",v.uuid) as activeVisitUuid, + IF(va.value_reference = "Admitted", "true", "false") as hasBeenAdmitted + from visit v + join person_name pn on v.patient_id = pn.person_id and pn.voided = 0 + join patient_identifier pi on v.patient_id = pi.patient_id + join patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + join global_property gp on gp.property="bahmni.primaryIdentifierType" and gp.property_value=pit.uuid + join person p on p.person_id = v.patient_id + join orders on orders.patient_id = v.patient_id + join order_type on orders.order_type_id = order_type.order_type_id and order_type.name != "Order" and order_type.name != "Drug Order" + left outer join visit_attribute va on va.visit_id = v.visit_id and va.voided = 0 and va.attribute_type_id = + (select visit_attribute_type_id from visit_attribute_type where name="Admission Status") + where v.date_stopped is null AND v.voided = 0 and order_id not in + (select obs.order_id + from obs + where person_id = pn.person_id and order_id = orders.order_id)', + 'Sql query to get list of patients who has pending orders', + uuid() +); + + diff --git a/bahmnicore-omod/src/main/resources/V1_98_WardsListSql.sql b/bahmnicore-omod/src/main/resources/V1_98_WardsListSql.sql new file mode 100644 index 0000000000..2b1e05ad18 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/V1_98_WardsListSql.sql @@ -0,0 +1,155 @@ +DELETE FROM global_property where property = 'emrapi.sqlGet.wardsListDetails'; + +INSERT INTO global_property (`property`, `property_value`, `description`, `uuid`) +VALUES ('emrapi.sqlGet.wardsListDetails', +"SELECT + b.bed_number AS 'Bed', + concat(pn.given_name, ' ', pn.family_name) AS 'Name', + pv.uuid AS 'Patient Uuid', + pi.identifier AS 'Id', + pv.gender AS 'Gender', + TIMESTAMPDIFF(YEAR, pv.birthdate, CURDATE()) AS 'Age', + pa.county_district AS 'District', + pa.city_village AS 'Village', + admission_provider_name.given_name AS 'Admission By', + cast(DATE_FORMAT(latestAdmissionEncounter.max_encounter_datetime, '%d %b %y %h:%i %p') AS CHAR) AS 'Admission Time', + diagnosis.diagnosisConcept AS 'Diagnosis', + diagnosis.certainty AS 'Diagnosis Certainty', + diagnosis.diagnosisOrder AS 'Diagnosis Order', + diagnosis.status AS 'Diagnosis Status', + diagnosis.diagnosis_provider AS 'Diagnosis Provider', + cast(DATE_FORMAT(diagnosis.diagnosis_datetime, '%d %b %y %h:%i %p') AS + CHAR) AS 'Diagnosis Datetime', + dispositionInfo.providerName AS 'Disposition By', + cast(DATE_FORMAT(dispositionInfo.providerDate, '%d %b %y %h:%i %p') AS CHAR) AS 'Disposition Time', + adtNotes.value_text AS 'ADT Notes', + v.uuid AS 'Visit Uuid' +FROM bed_location_map blm + INNER JOIN bed b + ON blm.bed_id = b.bed_id AND + b.status = 'OCCUPIED' AND + blm.location_id IN (SELECT child_location.location_id + FROM location child_location JOIN + location parent_location + ON parent_location.location_id = + child_location.parent_location + WHERE + parent_location.name = ${location_name}) + INNER JOIN bed_patient_assignment_map bpam ON b.bed_id = bpam.bed_id AND date_stopped IS NULL + INNER JOIN person pv ON pv.person_id = bpam.patient_id + INNER JOIN person_name pn ON pn.person_id = pv.person_id + INNER JOIN patient_identifier pi ON pv.person_id = pi.patient_id + INNER JOIN patient_identifier_type pit on pi.identifier_type = pit.patient_identifier_type_id + INNER JOIN global_property gp on gp.property='bahmni.primaryIdentifierType' and gp.property_value=pit.uuid + LEFT JOIN person_address pa ON pa.person_id = pv.person_id + INNER JOIN (SELECT + patient_id, + max(encounter_datetime) AS max_encounter_datetime, + max(visit_id) as visit_id, + max(encounter_id) AS encounter_id + FROM encounter + INNER JOIN encounter_type ON encounter_type.encounter_type_id = encounter.encounter_type + WHERE encounter_type.name = 'ADMISSION' + GROUP BY patient_id) latestAdmissionEncounter ON pv.person_id = latestAdmissionEncounter.patient_id + INNER JOIN visit v ON latestAdmissionEncounter.visit_id = v.visit_id + LEFT OUTER JOIN obs adtNotes + ON adtNotes.encounter_id = latestAdmissionEncounter.encounter_id AND adtNotes.voided = 0 AND + adtNotes.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Adt Notes' AND concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN encounter_provider ep ON ep.encounter_id = latestAdmissionEncounter.encounter_id + LEFT OUTER JOIN provider admission_provider ON admission_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name admission_provider_name + ON admission_provider_name.person_id = admission_provider.person_id + LEFT OUTER JOIN ( + SELECT + bpam.patient_id AS person_id, + concept_name.name AS disposition, + latestDisposition.obs_datetime AS providerDate, + person_name.given_name AS providerName + FROM bed_patient_assignment_map bpam + INNER JOIN (SELECT + person_id, + max(obs_id) obs_id + FROM obs + WHERE concept_id = (SELECT concept_id + FROM concept_name + WHERE + name = 'Disposition' AND concept_name_type = 'FULLY_SPECIFIED') + GROUP BY person_id) maxObsId ON maxObsId.person_id = bpam.patient_id + INNER JOIN obs latestDisposition + ON maxObsId.obs_id = latestDisposition.obs_id AND latestDisposition.voided = 0 + INNER JOIN concept_name ON latestDisposition.value_coded = concept_name.concept_id AND + concept_name_type = 'FULLY_SPECIFIED' + LEFT OUTER JOIN encounter_provider ep ON latestDisposition.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider disp_provider ON disp_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = disp_provider.person_id + WHERE bpam.date_stopped IS NULL + ) dispositionInfo ON pv.person_id = dispositionInfo.person_id + LEFT OUTER JOIN ( + SELECT + diagnosis.person_id AS person_id, + diagnosis.obs_id AS obs_id, + diagnosis.obs_datetime AS diagnosis_datetime, + if(diagnosisConceptName.name IS NOT NULL, diagnosisConceptName.name, + diagnosis.value_text) AS diagnosisConcept, + certaintyConceptName.name AS certainty, + diagnosisOrderConceptName.name AS diagnosisOrder, + diagnosisStatusConceptName.name AS status, + person_name.given_name AS diagnosis_provider + FROM bed_patient_assignment_map bpam + INNER JOIN visit latestVisit + ON latestVisit.patient_id = bpam.patient_id AND latestVisit.date_stopped IS NULL AND + bpam.date_stopped IS NULL + INNER JOIN encounter ON encounter.visit_id = latestVisit.visit_id + INNER JOIN obs diagnosis ON bpam.patient_id = diagnosis.person_id AND diagnosis.voided = 0 AND + diagnosis.encounter_id = encounter.encounter_id AND + diagnosis.concept_id IN (SELECT concept_id + FROM concept_name + WHERE name IN + ('Coded Diagnosis', 'Non-Coded Diagnosis') + AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisConceptName + ON diagnosis.value_coded IS NOT NULL AND diagnosis.value_coded = diagnosisConceptName.concept_id + AND diagnosisConceptName.concept_name_type = 'FULLY_SPECIFIED' + LEFT OUTER JOIN encounter_provider ep ON diagnosis.encounter_id = ep.encounter_id + LEFT OUTER JOIN provider diagnosis_provider ON diagnosis_provider.provider_id = ep.provider_id + LEFT OUTER JOIN person_name ON person_name.person_id = diagnosis_provider.person_id + INNER JOIN obs certainty + ON diagnosis.obs_group_id = certainty.obs_group_id AND certainty.voided = 0 AND + certainty.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Diagnosis Certainty' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name certaintyConceptName + ON certainty.value_coded IS NOT NULL AND certainty.value_coded = certaintyConceptName.concept_id + AND certaintyConceptName.concept_name_type = 'FULLY_SPECIFIED' + INNER JOIN obs diagnosisOrder + ON diagnosis.obs_group_id = diagnosisOrder.obs_group_id AND diagnosisOrder.voided = 0 AND + diagnosisOrder.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Diagnosis order' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisOrderConceptName ON diagnosisOrder.value_coded IS NOT NULL + AND diagnosisOrder.value_coded = + diagnosisOrderConceptName.concept_id + AND + diagnosisOrderConceptName.concept_name_type + = 'FULLY_SPECIFIED' + LEFT JOIN obs diagnosisStatus + ON diagnosis.obs_group_id = diagnosisStatus.obs_group_id AND diagnosisStatus.voided = 0 AND + diagnosisStatus.concept_id = (SELECT concept_id + FROM concept_name + WHERE name = 'Bahmni Diagnosis Status' AND + concept_name_type = 'FULLY_SPECIFIED') + LEFT OUTER JOIN concept_name diagnosisStatusConceptName ON diagnosisStatus.value_coded IS NOT NULL + AND diagnosisStatus.value_coded = + diagnosisStatusConceptName.concept_id + AND + diagnosisStatusConceptName.concept_name_type + = 'FULLY_SPECIFIED' + ) diagnosis ON diagnosis.person_id = pv.person_id", +'Sql query to get list of wards', +uuid() +); diff --git a/bahmnicore-omod/src/main/resources/addAtomfeedMigrations.xml b/bahmnicore-omod/src/main/resources/addAtomfeedMigrations.xml new file mode 100644 index 0000000000..5f50c7dc62 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/addAtomfeedMigrations.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Creating column tags for failed_events table. This is same as atom spec feed.entry.categories. + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/config.xml b/bahmnicore-omod/src/main/resources/config.xml new file mode 100644 index 0000000000..0111d342a4 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/config.xml @@ -0,0 +1,211 @@ + + + + + + + @MODULE_ID@ + @MODULE_NAME@ + @MODULE_VERSION@ + @MODULE_PACKAGE@ + Bahmni + + Provides core Bahmni EMR services + + @MODULE_PACKAGE@.Activator + + https://example.com/modules/download/bahmnicore/update.rdf + + + ${openMRSRuntimeVersion} + + org.openmrs.module.webservices.rest + org.openmrs.module.idgen + org.openmrs.module.idgen.webservices + org.openmrs.module.emrapi + org.ict4h.openmrs.openmrs-atomfeed + org.bahmni.module.reference-data + org.openmrs.module.addresshierarchy + org.openmrs.module.uiframework + org.openmrs.module.bacteriology + org.openmrs.module.bedmanagement + org.openmrs.module.rulesengine + org.openmrs.module.episodes + org.openmrs.module.auditlog + org.bahmni.module.bahmnicommons + org.bahmni.module.communication + + + + + + + + Add Patient Lists + Ability to create patient lists + + + Delete Patient Lists + Ability to delete patient lists + + + Edit Patient Lists + Ability to edit patient lists + + + View Patient Lists + Ability to view patient lists + + + + Add Drug Groups + Ability to create Drug Groups + + + Delete Drug Groups + Ability to delete Drug Groups + + + Edit Drug Groups + Ability to edit Drug Groups + + + View Drug Groups + Ability to view Drug Groups + + + + Add Drug Info + Ability to create Drug Info + + + Delete Drug Info + Ability to delete Drug Info + + + Edit Drug Info + Ability to edit Drug Info + + + View Drug Info + Ability to view Drug Info + + + Delete Patient Document + Ability to delete any patient document + + + app:lab-lite + Will give access to Lab Lite app + + + + org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService + org.openmrs.module.bahmniemrapi.encountertransaction.advisor.BahmniEncounterServiceAdvisor + + + + + + + + + CacheHeaders + org.bahmni.module.bahmnicore.web.filter.CacheHeadersFilter + + + LocaleFilter + org.bahmni.module.bahmnicore.web.filter.LocaleFilter + + + shallowEtagHeaderFilter + /ws/rest/v1/concept + + + CacheHeaders + /ws/rest/v1/concept + + + LocaleFilter + /ws/rest/v1/concept + + + ObsRelationship.hbm.xml + ObsRelationshipType.hbm.xml + LocationEncounterTypeMap.hbm.xml + BahmniConfig.hbm.xml + EntityMapping.hbm.xml + EntityMappingType.hbm.xml + Notes.hbm.xml + NoteType.hbm.xml + + + + + en + messages.properties + + + bahmni.relationshipTypeMap + + Relationship Type Map format Eg:{ "patient": ["Sibling", "Parent"],"provider": ["Doctor"]}.If no value is specified default is patient relationship. + + + + bahmni.enableAuditLog + true + Enable or disable audit log + + + + bahmni.primaryIdentifierType + + Primary identifier type for looking up patients + + + + bahmni.extraPatientIdentifierTypes + + A list of UUIDs indicating extra Patient Identifier Types that should be displayed + + + + bahmni.lookupExternalTerminologyServer + false + Property used to determine whether external terminology server being used or not + + + + bahmni.enableEmailPrescriptionOption + false + Boolean to enable sending email with prescription details + + + + bahmni.executeGroovyObsValueCalculator + true + Enable or disable Groovy script execution for obs value calculation on encounter save + + + + bahmni.diagnosisSetForNewDiagnosisConcepts + + UUID of set member of diagnosis set of sets. New Diagnosis concepts from terminology server will be added to this set + + + + sms.enableRegistrationSMSAlert + false + Boolean to enable sending sms when patient registers + + + + + org.openmrs.api.PatientService + org.bahmni.module.bahmnicore.events.advice.PatientAdvice + + + org.openmrs.api.EncounterService + org.bahmni.module.bahmnicore.events.advice.EncounterAdvice + + diff --git a/bahmnicore-omod/src/main/resources/dispositionConfig.json b/bahmnicore-omod/src/main/resources/dispositionConfig.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/dispositionConfig.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/liquibase.xml b/bahmnicore-omod/src/main/resources/liquibase.xml new file mode 100644 index 0000000000..682fff9f75 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/liquibase.xml @@ -0,0 +1,4682 @@ + + + + + + + + + + + + SELECT COUNT(*) FROM concept_reference_source where name = 'org.openmrs.module.emrapi'; + + + rel3 + + + + + + + + + + + + + + rel2 + + + + rel2 + + + + rel2 + + + + + + select count(*) from information_schema.routines WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_NAME = 'add_concept'; + + + rel2 + + + + rel2 + + + + rel2 + + + + rel2 + + + + rel2 + + + + rel2 + + + + rel2 + + + + rel2 + + + + 3:9596557aceeccee17eb9a9af5df316af + rel3 + + + + rel3 + + + + 3:248b34d9ff8955c24cfceffb8396e01c + rel3 + + + + rel3 + + + + + + select count(*) from information_schema.routines WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_NAME = 'add_concept_set_members'; + + + rel3 + + + + 3:a15a57cb8324e3e099775d7838880b71 + rel3 + + + + 3:03c23be81ba7cebf6fec9df46bec239c + rel3 + + + + 3:14d62b7a1d949387b19aeeb385c17408 + rel3 + + + + 3:89336c228d0063f50b24e7cc288793e5 + rel3 + + + + rel3 + + + + 3:321fb0b2fbc8c0add1dac2fac4824068 + rel3 + + + + rel3 + + + + rel3 + + + + rel3 + + + name='JSS' + + + + rel3 + + + + 3:9265b4028eba323f1fe9752430c96b92 + 3:8303f4f9d1ac7eb2de6c4d2b2466d873 + rel3 + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.primaryIdentifierType'; + + + Introducing 'emr.primaryIdentifierType' GlobalProperty + + INSERT INTO global_property (property, uuid, description) values ('emr.primaryIdentifierType', UUID(), 'Primary identifier type for looking up patients, generating barcodes, etc'); + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.primaryIdentifierType' + + + rel3 + + + + 3:7e9c42924c89c509275adda048d3f6a0 + Add investigations meta data + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Lab Departments', 'Lab departments', 'N/A', 'ConvSet', true); + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Other Investigations', 'Other Investigations', 'N/A', 'ConvSet', true); + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Other Investigations Categories', 'Other Investigations Categories', 'N/A', 'ConvSet', true); + + + + + Add concept Adt Notes + + insert into concept (retired, short_name, description, datatype_id, class_id, is_set, creator, date_created, + changed_by, date_changed, uuid) + values (0, 'Adt Notes', 'Adt Notes', + (select concept_datatype_id from concept_datatype where name = 'Text'), + (select concept_class_id from concept_class where name = 'Misc'), + 0, 1, now(), 1, now(), uuid()); + + + + + Add concept-name Adt Notes + + insert into concept_name (concept_id, name, locale, locale_preferred, creator, date_created, + concept_name_type, voided, uuid) + values ((select concept_id from concept where short_name='Adt Notes'), + 'Adt Notes', 'en', 1, 1, now(), 'FULLY_SPECIFIED', 0, uuid()); + + + + + + SELECT COUNT(*) FROM global_property where property = 'bahmni.encountersession.duration' + + + Add encounter session duration + + insert into global_property (`property`, `property_value`, `description`, `uuid`) + values ('bahmni.encountersession.duration', + '60', + 'Encountersession duration in minutes', + uuid() + ); + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.encounterMatcher' + + + Add custom encounter session matcher + + insert into global_property (`property`, `property_value`, `description`, `uuid`) + values ('emr.encounterMatcher', + 'org.bahmni.module.bahmnicore.matcher.EncounterSessionMatcher', + 'custom encounter session matcher', + uuid() + ); + + + + Add concept Document + + insert into concept (retired, short_name, description, datatype_id, class_id, is_set, creator, date_created, + changed_by, date_changed, uuid) + values (0, 'Document', 'Document', + (select concept_datatype_id from concept_datatype where name = 'Text'), + (select concept_class_id from concept_class where name = 'Misc'), + 0, 1, now(), 1, now(), uuid()); + + + + + Add concept-name Document + + insert into concept_name (concept_id, name, locale, locale_preferred, creator, date_created, + concept_name_type, voided, uuid) + values ((select concept_id from concept where short_name='Document'), + 'Document', 'en', 1, 1, now(), 'FULLY_SPECIFIED', 0, uuid()); + + + + + Add Encounter Type Radiology + + insert into encounter_type (name, description, creator, date_created, uuid) + VALUES ('RADIOLOGY', 'RADIOLOGY encounter', 1, curdate(), uuid()); + + + + + + select count(*) from privilege where privilege = 'app:clinical' + + + + + + + + + + + select count(*) from privilege where privilege = 'app:radiologyOrders' + + + + + + + + + + + select count(*) from privilege where privilege = 'app:documents' + + + + + + + + + Add new encounter type for investigation + + INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('INVESTIGATION', 'Investigation encounter', 1, curdate(), uuid()); + + + + Add job for processing reference data + + INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval,start_on_startup, started, created_by, date_created, uuid) + VALUES ('Reference Data Task', 'org.bahmni.module.referncedatafeedclient.task.ReferenceDataFeedTask', now(),'MM/dd/yyyy HH:mm:ss', 60, 1, 0, 1, curdate(), uuid()); + + + + Add job for processing failed reference data + + INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval,start_on_startup, started, created_by, date_created, uuid) + VALUES ('Reference Data Failed Event Task', 'org.bahmni.module.referncedatafeedclient.task.ReferenceDataFailedEventTask', now(),'MM/dd/yyyy HH:mm:ss', 60, 1, 0, 1, curdate(), uuid()); + + + + Update class name of reference data feed task and failed event task. + + UPDATE scheduler_task_config SET schedulable_class = 'org.bahmni.module.referencedatafeedclient.task.ReferenceDataFeedTask' WHERE name = 'Reference Data Task'; + UPDATE scheduler_task_config SET schedulable_class = 'org.bahmni.module.referencedatafeedclient.task.ReferenceDataFailedEventTask' WHERE name = 'Reference Data Failed Event Task'; + + + + + select count(*) from encounter_type where name = 'LAB_RESULT' + + Add new encounter type for Lab Result + + INSERT INTO encounter_type (name, description, creator, date_created, uuid) VALUES ('LAB_RESULT', 'Lab Result encounter', 1, curdate(), uuid()); + + + + 3:190851ded03e41d8b33b47c3cf720866 + + select count(*) from concept_name where name = 'LAB_RESULTS_CONCEPT_SET' + + + Add concept set for Lab results + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + set @answer_concept_id = 0; + call add_concept(@concept_id, @concept_name_short_id, + @concept_name_full_id,'LABRESULTS_CONCEPT','LABRESULTS_CONCEPT', 'N/A', 'Finding', true); + + set @labresults_concept_id = @concept_id; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'LAB_RESULT','LAB_RESULT', + 'Text', 'Finding', false); + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'LAB_NOTES','LAB_NOTES', 'Text', + 'Finding', false); + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'LAB_MINNORMAL','LAB_MINNORMAL', + 'Numeric', 'Finding', false); + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'LAB_MAXNORMAL','LAB_MAXNORMAL', + 'Numeric', 'Finding', false); + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'LAB_ABNORMAL','LAB_ABNORMAL', + 'Boolean', 'Finding', false); + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + + + + select count(*) from visit_type where name = 'LAB_RESULTS_IN_ABSENTEE' + + Add new visit type LAB_RESULTS_IN_ABSENTEE + + INSERT INTO visit_type (name, description, creator, uuid, date_created) VALUES ('LAB_RESULTS_IN_ABSENTEE', 'Visit for which results come when patient is not present', 1, uuid(), curdate()); + + + + + select count(*) from privilege where privilege = 'app:document-upload' + + + + + + + + + + select count(*) from privilege where privilege = 'app:adt' + + + + + + + + + + select count(*) from visit_type where name = 'DRUG_ORDER' + + Creating new visit type DRUG_ORDER + + INSERT INTO visit_type (name, description, creator, uuid, date_created) VALUES ('DRUG_ORDER', 'Placeholder visit for orders created when no visit is open', 1, uuid(), curdate()); + + + + + deleting visit types DRUG_ORDER and LAB_RESULTS_IN_ABSENTEE + + DELETE from visit_type where name in ('DRUG_ORDER','LAB_RESULTS_IN_ABSENTEE'); + + + + + select count(*) from global_property where property = 'emr.primaryIdentifierType' + + Add global property for emr primary identifier type + + INSERT INTO global_property (property, uuid, description) values ('emr.primaryIdentifierType', UUID(), 'Primary identifier type for looking up patients, generating barcodes, etc') ON DUPLICATE KEY UPDATE description = 'Primary identifier type for looking up patients, generating barcodes, etc'; + + + + + select count(*) from patient_identifier_type where name = 'Bahmni Id' + + set global property value for emr primary identifier type + + update global_property set property_value = (select uuid from patient_identifier_type where name = 'Bahmni Id') where property = 'emr.primaryIdentifierType'; + + + + + + + select count(*) from concept_name cn inner join concept c on cn.concept_id = c.concept_id where cn.name = 'REFERRED_OUT' + and cn.concept_name_type = 'FULLY_SPECIFIED' and c.class_id = (SELECT concept_class_id FROM concept_class WHERE name = 'Misc'); + + + Add new concept to mark referred out tests + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @labresults_concept_id = 0; + + set @answer_concept_id = 0; + call add_concept(@concept_id, @concept_name_short_id, + @concept_name_full_id,'REFERRED_OUT','REFERRED_OUT', 'N/A', 'Misc', true); + select @labresults_concept_id := concept_id, min(concept_id) from concept_name where name = 'LABRESULTS_CONCEPT' GROUP BY concept_id; + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + + + + Add concept Lab Order Notes + + insert into concept (retired, short_name, description, datatype_id, class_id, is_set, creator, date_created, + changed_by, date_changed, uuid) + values (0, 'Lab Order Notes', 'Lab Order Notes', + (select concept_datatype_id from concept_datatype where name = 'Text'), + (select concept_class_id from concept_class where name = 'Misc'), + 0, 1, now(), 1, now(), uuid()); + + + + Add concept-name Lab Order Notes + + insert into concept_name (concept_id, name, locale, locale_preferred, creator, date_created, + concept_name_type, voided, uuid) + values ((select concept_id from concept where short_name='Document'), + 'Lab Order Notes', 'en', 1, 1, now(), 'FULLY_SPECIFIED', 0, uuid()); + + + + Delete concept Lab Order Notes + + DELETE from concept where short_name = 'Lab Order Notes'; + DELETE from concept_name where name = 'Lab Order Notes'; + + + + 3:176087fd78dcbd1639ceded0a350687b + Add new concept to lab order notes + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + set @answer_concept_id = 0; + call add_concept(@concept_id, @concept_name_short_id, + @concept_name_full_id,'Lab Order Notes','Lab Order Notes', 'Text', 'Misc', false); + set @set_concept_id = @concept_id; + + + + Add new concept for test and panel + + insert into concept(datatype_id, class_id, is_set, creator, date_created, uuid) values(4, 10, true, 1, now(), uuid()); + + select max(concept_id) from concept into @laboratory_concept_id; + + insert into concept_name(concept_id, name, locale, locale_preferred,creator, date_created, concept_name_type, uuid) values (@laboratory_concept_id, 'All_Tests_and_Panels', 'en', true, 1, now(), 'FULLY_SPECIFIED', uuid()); + insert into concept_name(concept_id, name, locale, locale_preferred,creator, date_created, concept_name_type, uuid) values (@laboratory_concept_id, 'A_T_and_P', 'en', false, 1, now(), 'SHORT', uuid()); + + + + Add new concept for observation group (XCompoundObservation) + + insert into concept(datatype_id, class_id, is_set, creator, date_created, uuid) values(4, 10, true, 1, now(), uuid()); + + select max(concept_id) from concept into @compound_observation_id; + + insert into concept_name(concept_id, name, locale, locale_preferred,creator, date_created, concept_name_type, uuid) values (@compound_observation_id, 'XCompoundObservation', 'en', true, 1, now(), 'FULLY_SPECIFIED', uuid()); + + insert into concept(datatype_id, class_id, is_set, creator, date_created, uuid) values(4, 10, true, 1, now(), uuid()); + select max(concept_id) from concept into @abnormal_id; + + insert into concept_name(concept_id, name, locale, locale_preferred,creator, date_created, concept_name_type, uuid) values (@abnormal_id, 'IS_ABNORMAL', 'en', true, 1, now(), 'FULLY_SPECIFIED', uuid()); + + call add_concept_set_members (@compound_observation_id, @abnormal_id,1); + + + + + Add new concept for observation group (XCompoundObservation) + + update concept set datatype_id = (select concept_datatype_id from concept_datatype where name = 'Boolean'), class_id = (select concept_class_id from concept_class where name = 'Finding'), is_set = 0 where concept_id = (select concept_id from concept_name where name = 'IS_ABNORMAL' and concept_name_type='FULLY_SPECIFIED'); + + + + 3:a56d649cadef2d0f667a04e1c1bf0db2 + Add new concept for Ruled Out Diagnosis + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Ruled Out Diagnosis', 'Ruled Out Diagnosis', 'N/A', 'Misc', true); + + + + + + SELECT COUNT(*) FROM person_attribute_type where name = 'givenNameLocal'; + + + adding givenNameLocal person attribute type + + INSERT INTO person_attribute_type (name, description, format, searchable, creator, date_created, retired, sort_weight, uuid) VALUES ('givenNameLocal', 'givenNameLocal', 'java.lang.String', '0', 1, now(), 0, 3, uuid()); + + + + + + SELECT COUNT(*) FROM person_attribute_type where name = 'familyNameLocal'; + + + adding familyNameLocal person attribute type + + INSERT INTO person_attribute_type (name, description, format, searchable, creator, date_created, retired, sort_weight, uuid) VALUES ('familyNameLocal', 'familyNameLocal', 'java.lang.String', '0', 1, now(), 0, 3, uuid()); + + + + + + SELECT COUNT(*) FROM person_attribute_type where name = 'middleNameLocal'; + + + adding middleNameLocal person attribute type + + INSERT INTO person_attribute_type (name, description, format, searchable, creator, date_created, retired, sort_weight, uuid) VALUES ('middleNameLocal', 'middleNameLocal', 'java.lang.String', '0', 1, now(), 0, 3, uuid()); + + + + + + SELECT COUNT(*) FROM encounter_type where name = 'Patient Document'; + + + add encounter type for patient document upload + + + + + + + + + + 3:3d0122b224fea11193b83de519fe6bf1 + Adding diagnosis meta data concepts + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Bahmni Diagnosis Status', 'Bahmni Diagnosis Status', 'Coded', 'Misc', true); + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Bahmni Initial Diagnosis', 'Bahmni Initial Diagnosis', 'Text', 'Misc', true); + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Bahmni Diagnosis Revised', 'Bahmni Diagnosis Revised', 'Boolean', 'Misc', true); + + + + 3:bfc6b2f1fa801727c5496ff02c3cf9f3 + Adding Lab Manager Notes Concept + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Lab Manager Notes', 'Lab Manager Notes', 'N/A', 'Misc', false); + + + + Adding Lab Manager Notes Provider + + set @puuid = uuid(); + + insert into person(birthdate_estimated, dead, creator, date_created, uuid) + values(0, 0, 1, now(), @puuid); + + insert into users(system_id, creator, date_created, person_id, uuid, username) + values ('Lab Manager', 1, now(),(select person_id from person where uuid = @puuid) , uuid(), 'Lab Manager'); + + insert into provider (person_id, identifier, creator, date_created, uuid, name) values ((select person_id from person where uuid = @puuid), 'LABMANAGER', 1, now(), uuid(), 'Lab Manager'); + + + 3:78af611c62a4dad7866a56f48d08d84e + Adding Accession Uuid Concept + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Accession Uuid', 'Accession Uuid', 'N/A', 'Misc', false); + + + + + + SELECT COUNT(*) FROM encounter_type where name = 'VALIDATION NOTES'; + + + Add Encounter Type Validation Notes + + insert into encounter_type (name, description, creator, date_created, uuid) + VALUES ('VALIDATION NOTES', 'Validation Notes encounter', 1, curdate(), uuid()); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Concept Attribute'; + + + add concept class Concept Attribute + + + + + + + + + + + + + SELECT COUNT(*) != 0 FROM concept WHERE datatype_id = 1 AND concept_id NOT IN (SELECT concept_id FROM concept_numeric); + + + add concept numeric feild to all numeric concepts + + INSERT INTO concept_numeric (concept_id) (SELECT concept_id FROM concept WHERE + datatype_id = (SELECT concept_datatype_id FROM concept_datatype WHERE name = 'Numeric') + AND concept_id NOT IN (SELECT concept_id FROM concept_numeric)); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Abnormal'; + + + add concept class Abnormal + + + + + + + + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Duration'; + + + add concept class Duration + + + + + + + + + + + add concept numeric proc + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Concept Details'; + + + add concept class Concept Details + + + + + + + + + + + 3:0cc74f1871cb1efa7199f4f4ea562a07 + delete Concept Proc + + + + 3:32a6fc34947fd6ad55898c0d3e600ac2 + 3:95dbc7a307cda404901615be33a3c95d + Configure EMR API admit and discharge encounter type + + INSERT INTO global_property(property, property_value, description, uuid) + VALUES('emr.admissionEncounterType', (Select uuid from encounter_type where name = 'ADMISSION'), 'UUID of the encounter type for admitting a patient', 'c4b94bb1-97a8-4252-bec3-c8b17d72b4b5') + ON DUPLICATE KEY UPDATE property_value = (Select uuid from encounter_type where name = 'ADMISSION'); + + INSERT INTO global_property(property, property_value, description, uuid) + VALUES('emr.exitFromInpatientEncounterType', (Select uuid from encounter_type where name = 'DISCHARGE'), 'UUID of the encounter type for exiting a patient from inpatient care', 'fdb6b9ea-db33-44cb-b946-cc9e02baf50f') + ON DUPLICATE KEY UPDATE property_value = (Select uuid from encounter_type where name = 'DISCHARGE'); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Duration'; + + + add concept class Duration + + + + + + + + + + + 3:61f1718716d2347542975e019859c062 + Fix delete_concept + DROP PROCEDURE IF EXISTS delete_concept; + + + + + + 3:d0b49ca7745107877d6019920536f0de + add adt notes data concept set + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + select concept_id INTO @adt_notes_id from concept_name where name='Adt Notes' and locale_preferred = 1; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Adt Notes Data', 'Adt Notes Data', 'N/A', 'Concept Details', true); + set @adt_notes_data_id = @concept_id; + call add_concept_set_members(@adt_notes_data_id, @adt_notes_id, 0); + + + + remove adt notes data concept set + + call delete_concept('Adt Notes Data'); + + + + 3:23ca21a6b0be660b4b3fad3505f1b161 + Fix delete_concept. deleting concept set membership for the concept to be deleted. + DROP PROCEDURE IF EXISTS delete_concept; + + + + + + + Change sort weight for Admit Patients. + + update concept_answer set sort_weight=10 where answer_concept=(select concept_id from concept_name where name='Admit Patient' limit 1); + + + + + Change sort weight for Discharge Patients. + + update concept_answer set sort_weight=100 where answer_concept=(select concept_id from concept_name where name='Discharge Patient' limit 1); + + + + + Change sort weight for Transfer Patients. + + update concept_answer set sort_weight=200 where answer_concept=(select concept_id from concept_name where name='Transfer Patient' limit 1); + + + + 3:955279b9326084c5c0ad3f2df90295e0 + 3:752289f5803016fad52abe864a8278c5 + Update webservices.rest.maxResultsAbsolute to 1000 + + INSERT INTO global_property(property, property_value, description, uuid) + VALUES('webservices.rest.maxResultsAbsolute', 1000, 'The absolute results limit. If the client requests a larger number of results, then will get an error', '829347ef-1e0d-4368-8681-56f9544a0adc') + ON DUPLICATE KEY UPDATE property_value = 1000; + + + + Add global property bahmni.cacheHeadersFilter.expiresDuration + + INSERT INTO global_property(`property`, `property_value`, `description`, `uuid`) + VALUES ('bahmni.cacheHeadersFilter.expiresDuration', '0', 'Expires duration in minutes', '672dc790-e0b6-11e3-8b68-0800200c9a66') + ON DUPLICATE KEY UPDATE property_value = '0'; + + + + Add person name for lab and billing system users + + set @uuid = ''; + select uuid() into @uuid; + insert into person_name (preferred, person_id,given_name, family_name, creator,uuid, date_created) + select true, person_id, 'Lab', 'System', 1, @uuid, now() from users where username = 'Lab System'; + + select uuid() into @uuid; + insert into person_name (preferred, person_id,given_name, family_name, creator,uuid, date_created) + select true, person_id, 'Billing', 'System', 1, @uuid, now() from users where username = 'Billing System'; + + + + + + SELECT COUNT(*) FROM privilege where privilege = 'Get Order Frequencies'; + + + New privileges added + + set @uuid = ''; + select uuid() into @uuid; + INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Get Order Frequencies','Able to get Order Frequencies',@uuid); + + + + + + SELECT COUNT(*) FROM privilege where privilege = 'Manage Order Frequencies'; + + + New privileges added + + set @uuid = ''; + select uuid() into @uuid; + INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Order Frequencies','Able to add/edit/retire Order Frequencies',@uuid); + + + + + + SELECT COUNT(*) FROM privilege where privilege = 'Get Care Settings'; + + + New privileges added + + set @uuid = ''; + select uuid() into @uuid; + INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Get Care Settings','Able to get Care Settings',@uuid); + + + + Global property pointing to the new encounter provider only session matcher + + insert into global_property + (`property`, + `property_value`, + `description`, + `uuid`) + values + ('emr.encounterProviderMatcher', + 'org.bahmni.module.bahmnicore.matcher.EncounterProviderSessionMatcher', + 'Encountersession matcher which considers only encounter type and provider', + uuid()); + + + + Set dosing type and dosing instructions + + update drug_order + inner join drug on drug_order.drug_inventory_id = drug.drug_id + inner join concept_name on drug.dosage_form = concept_name.concept_id and + concept_name.concept_name_type = 'FULLY_SPECIFIED' + set drug_order.dosing_instructions = concat(drug_order.dose, ' ', concept_name.name), + drug_order.dosing_type = 'FREE_TEXT'; + + + + add concept class Image + + + + + + + + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Computed'; + + + add concept class Computed + + + + + + + + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.encounterMatcher' + + + Update custom encounter session matcher + + update global_property set property_value='org.openmrs.module.bahmniemrapi.encountertransaction.matcher.EncounterSessionMatcher' where property='emr.encounterMatcher' ; + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.encounterProviderMatcher' + + + Update custom encounter session matcher + + update global_property set property_value='org.openmrs.module.bahmniemrapi.encountertransaction.matcher.EncounterProviderSessionMatcher' where property='emr.encounterProviderMatcher'; + + + + 3:1c02bbb4699963a7c83ea542f2ea9236 + Set quantity for drug orders without this data + + UPDATE drug_order + JOIN orders on drug_order.order_id = orders.order_id + SET quantity = (datediff(auto_expire_date, date_activated) * dose) + WHERE quantity IS NULL; + + + + Set num_refills for drug orders without this data + + UPDATE drug_order + SET num_refills = 0 + WHERE num_refills IS NULL; + + + + 3:67ea9e924f423254cfd3658b87c38eed + Adding concepts and concept set related to dosing units + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @concept_set_uuid=''; + set @uuid = ''; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Dosing Units', 'dosing units', 'N/A', 'ConvSet', true); + set @set_concept_id = @concept_id; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Capsule', 'capsule', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Tablet', 'tablet', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Teaspoon', 'teaspoon', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Tablespoon', 'tablespoon', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Drop', 'drop', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'ml', 'ml', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'mg', 'mg', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + select c.uuid from concept_name cn inner join concept c on cn.concept_id = c.concept_id where cn.name = 'Dosing Units' and cn.concept_name_type = 'FULLY_SPECIFIED' into @concept_set_uuid; + select uuid() into @uuid; + + insert into global_property + (`property`, + `property_value`, + `description`, + `uuid`) + values + ('order.drugDosingUnitsConceptUuid', + @concept_set_uuid, + 'Global property pointing to dosing units concept set', + @uuid) + ON DUPLICATE KEY UPDATE + `property_value`=@concept_set_uuid; + + + + 3:e9299d5f6a6555c2d7ab498f5a515f80 + Add drug routes and set global property + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @uuid = ''; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Drug Routes', 'drug routes', 'N/A', 'ConvSet', true); + set @set_concept_id = @concept_id; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Intramuscular', 'IM', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Intravenous', 'IV', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Per Os', 'PO', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Per Vaginal', 'PV', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Sub Cutaneous', 'SC', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Per Rectum', 'PR', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Sub Lingual', 'SL', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Percutaneous Endoscopic Gastrostomy', 'PEG', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Nasogastric', 'NG', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + select c.uuid from concept_name cn inner join concept c on cn.concept_id = c.concept_id where cn.name = 'Drug Routes' and cn.concept_name_type = 'FULLY_SPECIFIED' into @concept_set_uuid; + select uuid() into @uuid; + + insert into global_property + (`property`, + `property_value`, + `description`, + `uuid`) + values + ('order.drugRoutesConceptUuid', + @concept_set_uuid, + 'Global property pointing to drug routes concept set', + @uuid) + ON DUPLICATE KEY UPDATE + `property_value`=@concept_set_uuid; + + + + + + select count(*) from global_property where property = 'order.durationUnitsConceptUuid' and property_value IS NULL; + + + Adding duration unit concepts and setting up associated global property. CIEL dataset should create the actual members. this is replacement of changeset bahmni-core-201906101318 + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Duration Units', 'duration units', 'Coded', 'ConvSet', true); + + update concept set uuid = '1732AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where concept_id=@concept_id; + + insert into global_property + (`property`, + `property_value`, + `description`, + `uuid`) + values + ('order.durationUnitsConceptUuid', + '1732AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + 'Global property pointing to duration units concept set', + @uuid) + ON DUPLICATE KEY UPDATE `property_value`='1732AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + + + + 3:0eca0d167cd6e8ae3738ef2dadb1f2b6 + + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @uuid = 0; + set @now = now(); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Once a day', 'OD', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Twice a day', 'BD', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 2, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Thrice a day', 'TDS', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 3, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Four times a day', 'QDS', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 4, 1, @now, @uuid); + + + + 3:b281314578771f23d480ae45d66e38ea + + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Dosing Instructions', 'Dosing Instructions', 'N/A', 'ConvSet', true); + set @set_concept_id = @concept_id; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Before meals', 'ac', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Empty stomach', '', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,2); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'After meals', 'pc', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,3); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'In the morning', 'cm', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,4); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'In the evening', '', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,5); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'At bedtime', 'hs', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,6); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Immediately', 'STAT', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,7); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'As directed', '', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id,@concept_id,8); + + select c.uuid from concept_name cn inner join concept c on cn.concept_id = c.concept_id where cn.name = 'Dosing Instructions' and cn.concept_name_type = 'FULLY_SPECIFIED' into @concept_set_uuid; + select uuid() into @uuid; + + insert into global_property + (`property`, + `property_value`, + `description`, + `uuid`) + values + ('order.dosingInstructionsConceptUuid', + @concept_set_uuid, + 'Global property pointing to duration units concept set', + @uuid) + ON DUPLICATE KEY UPDATE + `property_value`=@concept_set_uuid; + + + + 3:106fe9b9c492f9d9c0f93d65dd1aa516 + Adding all templates concept set of sets + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'All Observation Templates', 'All Observation templates', 'N/A', 'ConvSet', true); + set @set_concept_id = @concept_id; + + + + Update Dosing type from ENUM to Class Name + + update drug_order set dosing_type='org.openmrs.FreeTextDosingInstructions' where dosing_type='FREE_TEXT'; + update drug_order set dosing_type='org.openmrs.SimpleDosingInstructions' where dosing_type='SIMPLE'; + + + + + + + Introducing import status table + + CREATE TABLE import_status ( + id INT AUTO_INCREMENT NOT NULL, + original_file_name VARCHAR(500) NOT NULL, + saved_file_name VARCHAR(500) NOT NULL, + error_file_name VARCHAR(500) NULL, + type VARCHAR(25) NOT NULL, + status VARCHAR(25) NOT NULL, + successful_records NUMERIC(6) NULL, + failed_records NUMERIC(6) NULL, + stage_name VARCHAR(10) NULL, + stack_trace TEXT NULL, + uploaded_by VARCHAR(20) NOT NULL, + start_time TIMESTAMP NULL DEFAULT NULL, + end_time TIMESTAMP NULL DEFAULT NULL, + CONSTRAINT import_status_pk PRIMARY KEY (id)); + + + + + + SELECT COUNT(*) FROM global_property where property = 'uploaded.files.directory' + + + Add directory for imported files + + insert into global_property (`property`, `property_value`, `description`, `uuid`) + values ('uploaded.files.directory', '/home/bahmni/uploaded-files/mrs/', 'Directory where files uploaded to Bahmni are stored', uuid()); + + + + + Introducing Obs relationship type and obs relationship tables + + + CREATE TABLE obs_relationship_type( + obs_relationship_type_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, + name VARCHAR(50) NOT NULL, + description VARCHAR(255), + uuid CHAR(38) NOT NULL, + creator INT NOT NULL, + date_created DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, + retired TINYINT DEFAULT 0 NOT NULL, + date_retired DATETIME, + retired_by INT, + retire_reason VARCHAR(255), + date_changed DATETIME, + changed_by INT, + FOREIGN KEY (creator) REFERENCES users (user_id), + FOREIGN KEY (changed_by) REFERENCES users (user_id), + FOREIGN KEY (retired_by) REFERENCES users (user_id) + ); + CREATE UNIQUE INDEX uuid ON obs_relationship_type (uuid); + + CREATE TABLE obs_relationship( + obs_relationship_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, + obs_relationship_type_id INT NOT NULL, + source_obs_id INT NOT NULL, + target_obs_id INT NOT NULL, + uuid CHAR(38) NOT NULL, + date_created DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, + creator INT NOT NULL, + FOREIGN KEY (obs_relationship_type_id) REFERENCES obs_relationship_type (obs_relationship_type_id), + FOREIGN KEY (source_obs_id) REFERENCES obs (obs_id), + FOREIGN KEY (target_obs_id) REFERENCES obs (obs_id), + FOREIGN KEY (creator) REFERENCES person (person_id) + ); + CREATE UNIQUE INDEX uuid ON obs_relationship (uuid); + + + + + + select count(*) from privilege where privilege = 'app:admin' + + + + + + + + + + + + SELECT COUNT(*) FROM concept_class where name = 'URL'; + + + add concept class URL + + + + + + + + + + + + + select count(*) from concept_name cn inner join concept c on cn.concept_id = c.concept_id where cn.name = 'LAB_REPORT' + and cn.concept_name_type = 'FULLY_SPECIFIED' and c.datatype_id = (SELECT concept_datatype_id FROM concept_datatype WHERE name = 'TEXT') + and c.class_id = (SELECT concept_class_id FROM concept_class WHERE name = 'URL'); + + + Add new concept LAB REPORT for uploaded file + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @labresults_concept_id = 0; + + set @answer_concept_id = 0; + call add_concept(@concept_id, @concept_name_short_id, + @concept_name_full_id,'LAB_REPORT','LAB_REPORT', 'Text', 'URL', true); + select @labresults_concept_id := concept_id, min(concept_id) from concept_name where name = 'LABRESULTS_CONCEPT' GROUP BY concept_id; + set @set_concept_id = @concept_id; + call add_concept_set_members (@labresults_concept_id,@set_concept_id,1); + + + + Removing global property for encounter provider matcher + + delete from global_property where property='emr.encounterProviderMatcher'; + + + + + rel2 + + DROP PROCEDURE IF EXISTS add_concept; + + + + + + Adding tablet and capsule concepts to dosing units + + set @tablet_concept_id = 0; + set @capsule_concept_id = 0; + set @concept_set_id=0; + + select concept_id from concept_name where name = 'Dosing Units' and concept_name_type = 'FULLY_SPECIFIED' into @set_concept_id; + select concept_id from concept_name where name = 'Tablet' and concept_name_type = 'FULLY_SPECIFIED' into @tablet_concept_id; + select concept_id from concept_name where name = 'Capsule' and concept_name_type = 'FULLY_SPECIFIED' into @capsule_concept_id; + + call add_concept_set_members (@set_concept_id,@tablet_concept_id,1); + + call add_concept_set_members (@set_concept_id,@capsule_concept_id,1); + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3:443fc5590784d91c87f4551ca782b7f1 + + + select count(*) from concept_name where name = 'Impression'; + + + Add Impression concept + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Impression', 'Impression', 'Text', 'Misc', false); + + + + + Adding obs relationship type : qualified-by + + + INSERT INTO obs_relationship_type (name, description, uuid, creator) + VALUES ('qualified-by', 'target is qualified by source', 'dbde17aa-3d7e-11e4-8782-164230d1df67', 1); + + + + + Fix the new add_concept procedure + + DROP PROCEDURE IF EXISTS add_concept; + + + + + Rename OPD encounter type to Consultation + + + + name = 'OPD' + + + + Update hl7_code for concept reference source 'ISO 8601 Duration' + + update concept_reference_source set hl7_code = 'SCT' where name='ISO 8601 Duration'; + + + + Update code for concept reference term 'Second(s)' + + update concept_reference_term set code='257997001' where name='Second(s)'; + + + + Update code for concept reference term 'Minute(s)' + + update concept_reference_term set code='258701004' where name='Minute(s)'; + + + + Update code for concept reference term 'Hour(s)' + + update concept_reference_term set code='258702006' where name='Hour(s)'; + + + + Update code for concept reference term 'Day(s)' + + update concept_reference_term set code='258703001' where name='Day(s)'; + + + + Update code for concept reference term 'Week(s)' + + update concept_reference_term set code='258705008' where name='Week(s)'; + + + + Update code for concept reference term 'Month(s)' + + update concept_reference_term set code='258706009' where name='Month(s)'; + + + + Update code for concept reference term 'Year(s)' + + update concept_reference_term set code='258707000' where name='Year(s)'; + + + + Update code for concept reference term 'Time(s)' + + update concept_reference_term set code='252109000' where name='Time(s)'; + + + + Update name for concept reference source 'ISO 8601 Duration' + + update concept_reference_source set name='SNOMED', description='SNOMED Duration Source' where name='ISO 8601 Duration'; + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Sample'; + + + Add concept class for lab samples + + set @uuid = ''; + set @date = ''; + select uuid() into @uuid; + select curdate() into @date; + select @uuid; + insert into concept_class (name, description, creator, date_created, retired, uuid) + values ('Sample', 'Lab Samples Concept Class', 1, @date, 0, @uuid); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Department'; + + + Add concept class for lab samples + + set @uuid = ''; + set @date = ''; + select uuid() into @uuid; + select curdate() into @date; + select @uuid; + insert into concept_class (name, description, creator, date_created, retired, uuid) + values ('Department', 'Lab Departments Concept Class', 1, @date, 0, @uuid); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Sample'; + + + Migrate sample concepts to concept class sample + + UPDATE concept SET class_id = (SELECT concept_class_id FROM concept_class WHERE name = 'Sample') WHERE concept_id IN (SELECT concept_id FROM concept_set WHERE concept_set = (SELECT distinct concept_id FROM concept_name WHERE name = 'Laboratory')); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Department'; + + + Migrate department concepts to concept class department + + UPDATE concept SET class_id = (SELECT concept_class_id FROM concept_class WHERE name = 'Department') WHERE concept_id IN (SELECT concept_id FROM concept_set WHERE concept_set = (SELECT distinct concept_id FROM concept_name WHERE name = 'Lab Departments')); + + + + + + SELECT count(*) FROM concept_name where name='Laboratory' and concept_name_type='FULLY_SPECIFIED'; + + + Rename Laboratory concept to Lab Samples + + update concept_name set name='Lab Samples' where name='Laboratory' and concept_name_type='FULLY_SPECIFIED'; + + + + 3:59227f59b0dc69aedb429642ea0c528a + Adding All Disease Templates Concept Set + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'All Disease Templates', 'All Disease Templates', 'N/A', 'ConvSet', true); + + + + 3:4d2eac86ae2e3719506593f3446ce962 + Adding concepts and concept set related to dosing units + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + select concept_id into @set_concept_id from concept_name where name = 'Dosing Units' and concept_name_type = 'FULLY_SPECIFIED'; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'IU', '', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Unit(s)', 'unit(s)', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + + + 3:8b1b389e659dd0b96682abd8769b64c5 + Adding order frequencies + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @uuid = 0; + set @now = now(); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every Hour', 'QH', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 24, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 2 hours', 'Q2H', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 12, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 3 hours', 'Q3H', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 8, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 4 hours', 'Q4H', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 6, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 6 hours', 'Q6H', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 4, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 8 hours', 'Q8H', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 3, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 12 hours', 'Q12H', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 2, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'On alternate days', 'A/D', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1/2, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Once a week', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1/7, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Twice a week', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 2/7, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Thrice a week', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 3/7, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 2 weeks', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1/14, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Every 3 weeks', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1/21, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Once a month', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1/30, 1, @now, @uuid); + + + + 3:e16e8fe4446e38963a84a7a9681b9c54 + Add drug routes and delete Percutaneous Endoscopic Gastrostomy + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @uuid = ''; + + select concept_id into @set_concept_id from concept_name where name = 'Drug Routes' and concept_name_type = 'FULLY_SPECIFIED'; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Intradermal', 'ID', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Intraperitoneal', 'IP', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Intrathecal', 'IT', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Intraosseous', 'IO', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call delete_concept('Percutaneous Endoscopic Gastrostomy'); + + + + Removing update of Duration Units concept member name. Replacement of changeset bahmni-core-201409291704. Also only checking for dosing unit Oral + + UPDATE concept_name SET name='Oral' where name='Per Os' and concept_name_type='FULLY_SPECIFIED'; + + + + Changing sort order for dose units + + select concept_id into @dosing_units_concept_id from concept_name where name = 'Dosing Units' and concept_name_type = 'FULLY_SPECIFIED'; + + UPDATE concept_set, concept_name SET concept_set.sort_weight = 1 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'Tablet(s)' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 2 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'Capsule(s)' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 3 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'ml' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 4 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'mg' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 5 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'IU' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 6 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'Drop' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 7 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'Tablespoon' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 8 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'Teaspoon' and concept_set.concept_set = @dosing_units_concept_id; + UPDATE concept_set, concept_name SET concept_set.sort_weight = 9 where concept_set.concept_id = concept_name.concept_id and concept_name.name = 'Unit(s)' and concept_set.concept_set = @dosing_units_concept_id; + + + + Add index for orders date_activated + + CREATE INDEX bahmni_orders_date_activated ON orders(date_activated); + + + + + select count(*) from global_property where property = 'encounter.feed.publish.url' + + Updating GP encounter feed publish url to publish BahmniEncounterTransaction + + + property='encounter.feed.publish.url' + + + + Remove class name of reference data feed task and failed event task. + + delete from scheduler_task_config WHERE name = 'Reference Data Task'; + delete from scheduler_task_config WHERE name = 'Reference Data Failed Event Task'; + + + + + + select count(*) from privilege where privilege='app:clinical:history' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('app:clinical:history', 'Bahmni observation history view and edit', @uuid); + + + + + select count(*) from privilege where privilege='app:clinical:diagnosisTab' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('app:clinical:diagnosisTab', 'View and Edit Diagnosis tab', @uuid); + + + + + select count(*) from privilege where privilege='app:clinical:dispositionTab' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('app:clinical:dispositionTab', 'View Disposition tab', @uuid); + + + + + select count(*) from privilege where privilege='app:clinical:observationTab' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('app:clinical:observationTab', 'View Observation tab', @uuid); + + + + + select count(*) from privilege where privilege='app:clinical:consultationTab' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('app:clinical:consultationTab', 'View Consultation tab', @uuid); + + + + + + select count(*) from privilege where privilege='View Providers' + + Workaround for adding missing View Providers privlege + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('View Providers', 'Able to view Provider', @uuid); + + + + + + select count(*) from privilege where privilege='View Visit Types' + + Workaround for adding missing View Providers privlege + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('View Visit Types', 'Able to view Visit Types', @uuid); + + + + + + select count(*) from privilege where privilege='View Visits' + + Workaround for adding missing View Providers privlege + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('View Visits', 'Able to view Visits', @uuid); + + + + + + select count(*) from privilege where privilege='View Visit Attribute Types' + + Workaround for adding missing View Visit Attribute Types privlege + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('View Visit Attribute Types', 'Able to view Visit Attribute Types', @uuid); + + + + + + + SELECT count(*) FROM concept_name where name='Lab Samples' and concept_name_type='FULLY_SPECIFIED'; + + + Rename Laboratory concept to Lab Samples + + UPDATE concept + SET class_id = (SELECT + concept_class_id + FROM concept_class + WHERE uuid = '8d492594-c2cc-11de-8d13-0010c6dffd0f') + WHERE concept_id = (SELECT + concept_id + FROM concept_name + WHERE name = 'Lab Samples' AND concept_name_type = 'FULLY_SPECIFIED'); + + + + Set global property default_locale to en + + INSERT INTO global_property(`property`, `property_value`, `description`, `uuid`) + VALUES ('default_locale', 'en', 'Specifies the default locale. You can specify both the language code(ISO-639) and the country code(ISO-3166), e.g. \'en_GB\' or just country: e.g. \'en\'', 'ffc74409-b8e1-48e7-a318-8810a2f452da') + ON DUPLICATE KEY UPDATE property_value = 'en'; + + + + 3:6188bf0917228defa2c058eb141f90df + Fix the new add_concept procedure + + DROP PROCEDURE IF EXISTS add_concept; + + + + + 3:9d7ca5167308aeea04c82a867098154e + + + SELECT count(*) FROM concept_name where name='Tablet' and concept_name_type='FULLY_SPECIFIED'; + + + Adding new concept for Tablet as drug form + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Tablet', 'tablet', 'N/A', 'Misc', false); + + + + 3:5db567592d0dfe203c5a3a6a159c7c61 + + + SELECT count(*) FROM concept_name where name='Capsule' and concept_name_type='FULLY_SPECIFIED'; + + + Adding new concept for Capsule as drug form + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Capsule', 'capsule', 'N/A', 'Misc', false); + + + + Update drug table to use the new drug forms created + + select distinct concept_id from concept_name where name = 'Tablet(s)' and concept_name_type = 'FULLY_SPECIFIED' into @tablets_concept_id; + select distinct concept_id from concept_name where name = 'Tablet' and concept_name_type = 'FULLY_SPECIFIED' into @tablet_concept_id; + + update drug set dosage_form = @tablet_concept_id where dosage_form = @tablets_concept_id; + + select distinct concept_id from concept_name where name = 'Capsule(s)' and concept_name_type = 'FULLY_SPECIFIED' into @capsules_concept_id; + select distinct concept_id from concept_name where name = 'Capsule' and concept_name_type = 'FULLY_SPECIFIED' into @capsule_concept_id; + + update drug set dosage_form = @capsule_concept_id where dosage_form = @capsules_concept_id; + + + + Ensure drug orders are always in units + + select distinct concept_id from concept_name where name = 'Unit(s)' and concept_name_type = 'FULLY_SPECIFIED' into @units_concept_id; + + update drug_order set quantity_units = @units_concept_id; + + + + Make sure doseUnits and dosingInstructions for reverse synced drug orders are sane + + update drug_order set dose = null where dose_units is null; + + update drug_order set dosing_instructions = replace(dosing_instructions, 'Tablet', 'Tablet(s)') where dosing_instructions not like '%Tablet(s)%'; + + update drug_order set dosing_instructions = replace(dosing_instructions, 'Capsule', 'Capsule(s)') where dosing_instructions not like '%Capsule(s)%'; + + + + + + SELECT COUNT(*) FROM concept_class where name = 'LabTest'; + + + Add concept class LabTest + + set @uuid = ''; + set @date = ''; + select uuid() into @uuid; + select curdate() into @date; + select @uuid; + insert into concept_class (name, description, creator, date_created, retired, uuid) + values ('LabTest', 'Lab Tests', 1, @date, 0, @uuid); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Radiology'; + + + Add concept class Radiology + + set @uuid = ''; + set @date = ''; + select uuid() into @uuid; + select curdate() into @date; + select @uuid; + insert into concept_class (name, description, creator, date_created, retired, uuid) + values ('Radiology', 'Radiology Orders', 1, @date, 0, @uuid); + + + + + select count(*) from chunking_history; + + Default chunking history entry if doesn't exist. + + + + + + + 3:809bb2af1d4d95755dcf48f62c3a1840 + Add drug routes Topical, Nasal, Inhalation + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + select concept_id into @set_concept_id from concept_name where name = 'Drug Routes' and concept_name_type = 'FULLY_SPECIFIED'; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Topical', 'TOPIC', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Nasal', 'NASAL', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Inhalation', 'RESPIR', 'N/A', 'Misc', false); + call add_concept_set_members (@set_concept_id, @concept_id, 1); + + + + Fix the new add_concept procedure + + DROP PROCEDURE IF EXISTS add_concept; + + + + + Fix concepts created in liquibase without uuid + + select concept_id into @concept_id from concept_name where name = 'Tablet' and concept_name_type = 'FULLY_SPECIFIED'; + SELECT uuid() into @uuid; + UPDATE concept set uuid = @uuid where concept_id = @concept_id; + + select concept_id into @concept_id from concept_name where name = 'Capsule' and concept_name_type = 'FULLY_SPECIFIED'; + SELECT uuid() into @uuid; + UPDATE concept set uuid = @uuid where concept_id = @concept_id; + + select concept_id into @concept_id from concept_name where name = 'Topical' and concept_name_type = 'FULLY_SPECIFIED'; + SELECT uuid() into @uuid; + UPDATE concept set uuid = @uuid where concept_id = @concept_id; + + select concept_id into @concept_id from concept_name where name = 'Nasal' and concept_name_type = 'FULLY_SPECIFIED'; + SELECT uuid() into @uuid; + UPDATE concept set uuid = @uuid where concept_id = @concept_id; + + select concept_id into @concept_id from concept_name where name = 'Inhalation' and concept_name_type = 'FULLY_SPECIFIED'; + SELECT uuid() into @uuid; + UPDATE concept set uuid = @uuid where concept_id = @concept_id; + + + + 3:d1ca4fa7639c189ed9602242e4f2bd0e + + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @uuid = 0; + set @now = now(); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Five times a day', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 5, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Four days a week', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 4/7, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Five days a week', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 5/7, 1, @now, @uuid); + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Six days a week', '', 'N/A', 'Frequency', false); + select uuid() into @uuid; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 6/7, 1, @now, @uuid); + + + + Adding Immediately as Order Frequency + + set @concept_id = 0; + set @uuid = 0; + set @now = now(); + select concept_id from concept_name where name='Immediately' and concept_name_type='FULLY_SPECIFIED' into @concept_id; + insert into order_frequency(concept_id, frequency_per_day, creator, date_created, uuid) values(@concept_id, 1, 1, @now, @uuid); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Computed/Editable'; + + + Add concept class Computed/Editable + + set @uuid = ''; + set @date = ''; + select uuid() into @uuid; + select curdate() into @date; + select @uuid; + insert into concept_class (name, description, creator, date_created, retired, uuid) + values ('Computed/Editable', 'Computed/Editable', 1, @date, 0, @uuid); + + + + 3:ff3f26723a22f34131d082f64923f708 + + + select count(*) from concept_name where name='Admission' and concept_name_type='FULLY_SPECIFIED'; + + + Adding Admission Decision concept reference term and mapping for close visit task + + set @concept_id = 0; + set @concept_map_type_id = 0; + set @concept_reference_term_id = 0; + + set @uuid = 0; + set @emr_source_id = 0; + set @current_date = 0; + + select uuid() into @uuid; + select now() into @current_date; + select concept_source_id from concept_reference_source where name='org.openmrs.module.emrapi' into @emr_source_id; + + insert into concept_reference_term(concept_source_id, name, code, description, creator, date_created, uuid) + values(@emr_source_id, 'Admission Decision', 'Admission Decision', '', 1, @current_date, @uuid); + + select concept_reference_term_id from concept_reference_term where name='Admission Decision' into @concept_reference_term_id; + select concept_map_type_id from concept_map_type where name='SAME-AS' into @concept_map_type_id; + select concept_id from concept_name where name='Admission' and concept_name_type='FULLY_SPECIFIED' into @concept_id; + + select uuid() into @uuid; + insert into concept_reference_map (concept_reference_term_id, concept_map_type_id, concept_id, date_created, creator, uuid) values ( + @concept_reference_term_id , @concept_map_type_id, @concept_id, @current_date, 1, @uuid); + + + + 3:8dab05861bd023ac8ce19d56224d6576 + 3:ba27b100100f1dc0f5d2d0afdf9d29e9 + Adding Deny Admission concept reference term and mapping for close visit task + + set @concept_id = 0; + set @concept_map_type_id = 0; + set @concept_reference_term_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + set @uuid = 0; + set @emr_source_id = 0; + set @current_date = 0; + + select uuid() into @uuid; + select now() into @current_date; + select concept_source_id from concept_reference_source where name='org.openmrs.module.emrapi' into @emr_source_id; + + insert into concept_reference_term(concept_source_id, name, code, description, creator, date_created, uuid) + values(@emr_source_id, 'Deny Admission', 'Deny Admission', 'Deny Admission', 1, @current_date, @uuid); + + select concept_reference_term_id from concept_reference_term where name='Deny Admission' into @concept_reference_term_id; + select concept_map_type_id from concept_map_type where name='SAME-AS' into @concept_map_type_id; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Deny Admission','Deny Admission', 'N/A', 'Misc', false); + + select uuid() into @uuid; + insert into concept_reference_map (concept_reference_term_id, concept_map_type_id, concept_id, date_created, creator, uuid) values ( + @concept_reference_term_id , @concept_map_type_id, @concept_id, @current_date, 1, @uuid); + + + + + + SELECT COUNT(*) FROM global_property where property = 'encounterModifier.groovy.allowCaching' + + + Set global property allow_groovy_caching to true + + INSERT INTO global_property(`property`, `property_value`, `description`, `uuid`) + VALUES ('encounterModifier.groovy.allowCaching', 'true', 'Allow Groovy Caching', 'e16605a1-266a-47cb-8385-d07742646640'); + + + + + + SELECT COUNT(*) FROM location_tag where name='Login Location'; + + + Add Login Location Tag if not already added. + + set @current_date = 0; + select now() into @current_date; + + INSERT INTO location_tag (name, description, creator, date_created, uuid) VALUES + ('Login Location', + 'When a user logs in and chooses a session location, they may only choose one with this tag', + 1, + @current_date, + 'b8bbf83e-645f-451f-8efe-a0db56f09676'); + + + + 3:f9ed5a94595e1affa2778dce8f39f6a8 + + + SELECT COUNT(*) FROM concept_name where name='Order Attributes' and concept_name_type='FULLY_SPECIFIED' and voided=0; + + + Adding Order Attributes concept set + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id,'Order Attributes','Order Attributes', 'N/A', 'Misc', true); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Case Intake'; + + + add concept class Case Intake + + + + + + + + + + + + select count(*) from privilege where privilege = 'app:clinical:retrospective' + + + + + + + + + 3:83d50d47fd5091b289483c66a54e3ac9 + + select count(*) from concept_name where name = 'Undo Discharge' and concept_name_type='FULLY_SPECIFIED' + + Adding Undo Discharge disposition + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @concept_source_id = 0; + set @concept_map_type_id = 0; + set @disposition_concept_id = 0; + + SELECT concept_source_id INTO @concept_source_id FROM concept_reference_source where name = 'org.openmrs.module.emrapi'; + SELECT concept_id INTO @disposition_concept_id FROM concept_name where name = 'Disposition' and concept_name_type='FULLY_SPECIFIED'; + SELECT concept_map_type_id INTO @concept_map_type_id FROM concept_map_type where name = 'SAME-AS'; + + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Undo Discharge', 'Undo Discharge', 'N/A', 'misc', false); + call add_concept_reference_map (@concept_id, @concept_source_id, 'UNDO_DISCHARGE',@concept_map_type_id); + set @child1_concept_id = @concept_id; + + call add_concept_answer(@disposition_concept_id, @child1_concept_id, 3); + + + + Sql file for getting all wards, beds and related patients info + + + + Adding privilege for dispensing drug orders. + + + + + + + + 3:9dc0f97f859e8d26392fb7dbb48e980d + Adding dispensed drug order attribute + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @set_concept_id = 0; + + select concept_id from concept_name where name = 'Order Attributes' and concept_name_type = 'FULLY_SPECIFIED' into @set_concept_id; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Dispensed', 'D', 'Boolean', 'Misc', false); + + call add_concept_set_members(@set_concept_id,@concept_id,1); + + + + Chaning colume type of property_value in user_property to text + + alter table user_property modify property_value text + + + + Adding privilege for bi-directional navigation between registration and consultation. + + + + + + + + Creating Visit Status as visit attribute + + INSERT INTO visit_attribute_type (name, datatype, creator, date_created, uuid, min_occurs) + VALUES ('Visit Status', 'org.openmrs.customdatatype.datatype.FreeTextDatatype', 1, now(), uuid(), 0); + + + + Adding Close Visit Privilege + + + + + + + + + select count(*) from privilege where privilege = 'app:orders' + + + + + + + + + + select count(*) from privilege where privilege = 'app:clinical:deleteDiagnosis' + + + + + + + + + Creating Admission Status as visit attribute + + INSERT INTO visit_attribute_type (name, datatype, creator, date_created, uuid, min_occurs) + VALUES ('Admission Status', 'org.openmrs.customdatatype.datatype.FreeTextDatatype', 1, now(), uuid(), 0); + + + + Adding privilege for provider. + + + + + + + + Associating LabSet and LabTest concept classes to Lab Order order type + + set @order_type_id = ''; + set @lab_set = ''; + set @lab_test = ''; + + select order_type_id into @order_type_id from order_type where name = 'Lab Order'; + select concept_class_id into @lab_set from concept_class where name = 'LabSet'; + select concept_class_id into @lab_test from concept_class where name = 'LabTest'; + insert into order_type_class_map(order_type_id, concept_class_id) values(@order_type_id,@lab_set); + insert into order_type_class_map(order_type_id, concept_class_id) values(@order_type_id,@lab_test); + + + + + 3:24754f616857125b862150154fb85150 + + + select count(*) from concept_name where name='All Orderables' and concept_name_type='FULLY_SPECIFIED'; + + + Adding 'All Orderables' concept set and associating Lab Samples to it. + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'All Orderables', 'All Orderables', 'N/A', 'ConvSet', true); + + select concept_id into @labsamples_concept_id from concept_name where name = 'Lab Samples' and concept_name_type = 'FULLY_SPECIFIED'; + call add_concept_set_members (@concept_id,@labsamples_concept_id,1); + + + + + + select count(*) from concept_name where name='Lab Orders' and concept_name_type='SHORT' and voided=0; + + + Adding a display name for Lab Samples concept on UI + + select concept_id into @labsamples_concept_id from concept_name where name like 'Lab Samples' and concept_name_type = 'FULLY_SPECIFIED'; + + insert into concept_name (concept_id, name, locale, locale_preferred, creator, date_created,concept_name_type, voided, uuid) values (@labsamples_concept_id,'Lab Orders', 'en', 0, 1, now(), 'SHORT', 0, uuid()); + + + + 3:b92570973c3eb23083225d3dd889d0f9 + Adding gender values and codes used across MRS + + select uuid() into @uuid; + INSERT INTO global_property(property, property_value, description, uuid) + VALUES('mrs.genders', '{"M":"Male", "F":"Female","O":"Other"}', 'List of gender and gender codes used across MRS', @uuid); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Changing short name for Lab Samples concept on UI + + select concept_id into @labsamples_concept_id from concept_name where name like 'Lab Samples' and concept_name_type = 'FULLY_SPECIFIED'; + + update concept_name set name = 'Laboratory' where concept_id = @labsamples_concept_id and concept_name_type = 'SHORT'; + + + + + Changing description for LabSet concept class to Panels + + update concept_class set description = 'Panels' where name = 'LabSet'; + + + + + + SELECT COUNT(*) FROM global_property where property = 'bahmni.encounterType.default' + + + Global property for default encounter type. + + insert into global_property (`property`, `property_value`, `description`, `uuid`) + values ('bahmni.encounterType.default', + 'Consultation', + 'Default Encounter Type', + uuid() + ); + + + + + Getting rid of the revese sync schedulers for Drug. + + delete from scheduler_task_config where name='OpenERP Feed Task'; + delete from scheduler_task_config where name='OpenERP Failed Feed Task'; + + + + + Cleaning up relationships types for the relationships. + + SET FOREIGN_KEY_CHECKS = 0; + truncate relationship_type; + SET FOREIGN_KEY_CHECKS = 1; + + + + + rel3 + + + + + rel3 + + + + + Moving to order from test_order + + UPDATE `order_type` SET `java_class_name` = 'org.openmrs.Order' WHERE name ='Lab Order'; + UPDATE `order_type` SET `java_class_name` = 'org.openmrs.Order' WHERE name ='Radiology Order'; + UPDATE `order_type` SET `name` = 'Order' WHERE name ='Lab Order'; + DELETE FROM `test_order`; + + + + + + Updating sql to use order instead of lab order as order type name + + + + + Associating LabSet and LabTest concept classes to Order order type + + set @order_type_id = ''; + set @lab_set = ''; + set @lab_test = ''; + + delete from order_type_class_map; + select order_type_id into @order_type_id from order_type where name = 'Order'; + select concept_class_id into @lab_set from concept_class where name = 'LabSet'; + select concept_class_id into @lab_test from concept_class where name = 'LabTest'; + insert into order_type_class_map(order_type_id, concept_class_id) values(@order_type_id,@lab_set); + insert into order_type_class_map(order_type_id, concept_class_id) values(@order_type_id,@lab_test); + + + + + + + SELECT COUNT(*) FROM person_attribute_type where name = 'Telephone Number'; + + + Adding Telephone Number person attribute type + + INSERT INTO person_attribute_type (name, description, format, searchable, creator, date_created, retired, sort_weight, uuid) VALUES ('Telephone Number', 'Telephone Number', 'java.lang.String', '0', 1, now(), 0, 3, uuid()); + + + + + + + SELECT COUNT(*) FROM person_attribute_type where name = 'Unknown patient'; + + + Adding Unknown patient person attribute type + + INSERT INTO person_attribute_type (name, description, format, searchable, creator, date_created, retired, sort_weight, uuid) VALUES ('Unknown patient', 'Unknown Patient', 'java.lang.String', '0', 1, now(), 0, 3, uuid()); + + + + + Updating high risk patient sql to consider latest test value + + + + + Optimised the high risk patient sql to consider latest test value + + + + + Changing the OrderType name for lab order from Order to Lab Order + + UPDATE `order_type` SET `name` = 'Lab Order' WHERE name ='Order'; + + + + Adding global property for Reason for death + + insert into global_property + (`property`, + `property_value`, + `description`, + `uuid`) + values + ('concept.reasonForDeath', + '', + 'Concept id of the REASON FOR DEATH Concept Set', + uuid()) + ON DUPLICATE KEY UPDATE + `property_value`=@concept_set_uuid; + + + + Updating column stage_name of import_status table + + ALTER TABLE import_status MODIFY stage_name varchar(30); + + + + Deleting bahmnicore.relationshipTypeMap from global property + + delete ignore from global_property where property='bahmnicore.relationshipTypeMap'; + + + + + + Entity mapping table + + + + + + + + + + + + + + + + + + + + + Inserting Program Obstemplate Mapping type + + + + + + + + + + + Introducing constraint unique key to name column in the entity_mapping_type table + + + + + Inserting Program EncounterType Mapping + + + + + + + + + + + + + SELECT count(*) FROM person_attribute_type WHERE name = 'Telephone Number' + + + SELECT count(*) FROM person_attribute JOIN person_attribute_type ON person_attribute.person_attribute_type_id = person_attribute_type.person_attribute_type_id where name = 'Telephone Number' + + + Deleting Telephone Number person attribute type + + DELETE FROM person_attribute_type WHERE name = 'Telephone Number'; + + + + + + + SELECT count(*) FROM person_attribute_type WHERE name = 'Unknown patient' + + + SELECT count(*) FROM person_attribute JOIN person_attribute_type ON person_attribute.person_attribute_type_id = person_attribute_type.person_attribute_type_id where name = 'Unknown patient' + + + Deleting Unknown patient person attribute type + + DELETE FROM person_attribute_type WHERE name = 'Unknown patient'; + + + + + + set @concept_source_id = 0; + set @concept_reference_term_id = 0; + set @set_concept_id = 0; + set @bahmni_initial_diagnosis_concept_id = 0; + set @bahmni_diagnosis_revised_concept_id = 0; + set @bahmni_diagnosis_status_concept_id = 0; + + select concept_source_id into @concept_source_id from concept_reference_source where name = "org.openmrs.module.emrapi"; + + select concept_reference_term_id into @concept_reference_term_id from concept_reference_term where code = 'Diagnosis Concept Set' and concept_source_id = @concept_source_id; + + select concept_id into @set_concept_id from concept_reference_map where concept_reference_term_id = @concept_reference_term_id; + + select concept_id into @bahmni_initial_diagnosis_concept_id from concept_name where name = 'Bahmni Initial Diagnosis' and concept_name_type='FULLY_SPECIFIED' ; + + select concept_id into @bahmni_diagnosis_revised_concept_id from concept_name where name = 'Bahmni Diagnosis Revised' and concept_name_type='FULLY_SPECIFIED'; + + select concept_id into @bahmni_diagnosis_status_concept_id from concept_name where name = 'Bahmni Diagnosis Status' and concept_name_type='FULLY_SPECIFIED'; + + call add_concept_set_members (@set_concept_id,@bahmni_initial_diagnosis_concept_id,1); + call add_concept_set_members (@set_concept_id,@bahmni_diagnosis_revised_concept_id,1); + call add_concept_set_members (@set_concept_id,@bahmni_diagnosis_status_concept_id,1); + + + + + + + + SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'event_records' AND INDEX_NAME = 'event_records_category_idx' + + + Add index to the category column in event_records table for performance (if it is not already present) + + + + + + + + select count(*) from privilege where privilege = 'app:registration' + + + + + + + + + + Add emrgency app role + + INSERT INTO privilege(privilege, description, uuid) VALUES('app:emergency', 'bahmni emergency app access privilege', uuid()) ON DUPLICATE KEY UPDATE privilege = 'app:emergency'; + + + + + Add relationship between orderType and conceptClass + + insert into order_type_class_map values((select order_type_id from order_type where name='Drug Order'), (select concept_class_id from concept_class where name='Drug')); + + + + + SQL query to get list of active patients by location + + + + + Remove the SQL query to get list of active patients by location + + DELETE FROM global_property WHERE property IN ('emrapi.sqlSearch.activePatientsByLocation'); + + + + + rel2 + + + + + rel2 + + + + + rel3 + + + + + rel3 + update patient_identifier_type set name = 'Bahmni Id' where name = 'JSS' + + + + + + select count(*) from concept where concept_id in (select concept_id from concept_name where name='DrugOther' and concept_name_type='FULLY_SPECIFIED') + + + Adding 'DrugOther' concept. + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'DrugOther', 'DrugOther', 'N/A', 'Misc', false); + + + + + + + SELECT COUNT(*) FROM global_property where property = 'drugOrder.drugOther' + + + Add drug other global property + + insert into global_property (property, property_value, description, uuid) + values ('drugOrder.drugOther', '', 'Specifies the uuid of the concept which represents drug other non coded', uuid()); + + + + + + select count(*) from global_property where property='drugOrder.drugOther' + + Setting 'DrugOther' concept uuid as value for 'drugOrder.drugOther' globalProperty. + + select uuid into @uuid from concept where concept_id in (select concept_id from concept_name where name='DrugOther' and concept_name_type='FULLY_SPECIFIED'); + UPDATE global_property set property_value = @uuid where property='drugOrder.drugOther'; + + + + + + select count(*) from global_property where property='concept.reasonForDeath' + + Changing description for reason for death global property + + UPDATE global_property set description='Fully Specified name of the Concept Set created as Reasons for death' where property='concept.reasonForDeath'; + + + + + select count(*) from privilege where privilege='app:reports' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('app:reports', 'View Reports', @uuid); + + + + Adding new loginLocationToVisitTypeMapping in entityMappingType table + + insert into entity_mapping_type(name ,uuid ,entity1_type , entity2_type , date_created) values('loginlocation_visittype', uuid() , 'org.openmrs.Location' , 'org.openmrs.VisitType' , '2015-11-25 18:54:23.0'); + + + + + select count(*) from concept_name where name in ('Stopped Order Reason','Refused To Take') and concept_name_type='FULLY_SPECIFIED' + + Adding Stopped Order Reason and answers + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @stopped_order_reason_concept_id = 0; + + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Stopped Order Reason', 'Stopped Order Reason', 'Coded', 'Question', false); + + select concept_id into @stopped_order_reason_concept_id from concept_name where name = 'Stopped Order Reason' and concept_name_type = 'FULLY_SPECIFIED'; + + set @concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + set @refused_to_take_concept_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Refused To Take', 'Refused To Take', 'N/A', 'Misc', false); + select concept_id into @refused_to_take_concept_id from concept_name where name = 'Refused To Take' and concept_name_type = 'FULLY_SPECIFIED'; + call add_concept_answer(@stopped_order_reason_concept_id, @refused_to_take_concept_id, 1); + + + + + select count(*) from concept_reference_source where name='Abbreviation' + + Insert concept reference source for Abbreviation + + set @uuid = 0; + select uuid() into @uuid; + + insert into concept_reference_source (name, description, hl7_code, creator, date_created, uuid) + values('Abbreviation', 'Custom dictionary for storing abbreviation of concepts', null, 1, now(), @uuid); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Unknown'; + + + add concept class Unknown + + + + + + + + + + + + + select count(*) from entity_mapping_type where name='location_encountertype' + + Add entity mapping type for location_encountertype + + insert into entity_mapping_type (name, uuid, entity1_type, entity2_type, date_created) + values ('location_encountertype', uuid(), "org.openmrs.Location", "org.openmrs.EncounterType", now()); + + + + + + + + + + Creating program_attribute_type table + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.encounterMatcher' + and property_value = 'org.openmrs.module.bahmniemrapi.encountertransaction.matcher.EncounterSessionMatcher' + + + Update custom encounter session matcher + + update global_property set property_value='org.bahmni.module.bahmnicore.matcher.EncounterSessionMatcher' where property='emr.encounterMatcher' ; + + + + + + select count(*) from privilege where privilege = 'Manage Program Attribute Types' + + + + + + + + + + + select count(*) from privilege where privilege = 'View Program Attribute Types' + + + + + + + + + + + select count(*) from privilege where privilege = 'Purge Program Attribute Types' + + + + + + + + + + + + SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS + WHERE table_schema='openmrs' AND table_name='bed_patient_assignment_map' AND + column_name='date_stopped'; + + + Add index on date_stopped column for bed_patient_assignment_map table + + + + + + + + + SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS + WHERE table_schema='openmrs' AND table_name='visit' AND + column_name='date_stopped'; + + + Add index on date_stopped column for visit table + + + + + + + SQL query to get list of active patients by location + + + + + + + SELECT count(*) FROM privilege WHERE privilege='app:clinical:locationpicker'; + + + Creating Location Picker Privilege + + INSERT INTO privilege (privilege, description, uuid) VALUES ('app:clinical:locationpicker', 'View Location Picker option', uuid()); + + + + + + + SELECT count(*) FROM privilege WHERE privilege='app:clinical:onbehalf'; + + + Creating On Behalf Of Privilege + + INSERT INTO privilege (privilege, description, uuid) VALUES ('app:clinical:onbehalf', 'View On behalf of option', uuid()); + + + + + + + SELECT COUNT(*) FROM location_tag where name='Visit Location'; + + + Add Visit Location Tag if not already added. + + set @current_date = 0; + select now() into @current_date; + + INSERT INTO location_tag (name, description, creator, date_created, uuid) VALUES + ('Visit Location', + 'Visit Location', + 1, + @current_date, + uuid()); + + + + + + SELECT COUNT(*) FROM visit where location_id is null; + + + Visits should not have location null. Please refer to release notes 0.83 + + + + update the search query to consider visit location + + + + + + + SELECT count(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME='patient_identifier' AND CONSTRAINT_NAME='unique_patient_identifier'; + + + Drop unique constraint on identifier column in patient_identifier table + + ALTER TABLE patient_identifier DROP INDEX unique_patient_identifier; + + + + + + select count(*) from patient_identifier_type where name = 'Bahmni Id'; + + + Renaming Bahmni Id to Patient Identifer in patient_identifier_type table + + update patient_identifier_type set name = 'Patient Identifier' where name = 'Bahmni Id' + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Video'; + + + Add Concept Class Video + + + + + + + + + + + update the search query to consider multiple identifiers + + + + Update the wards list sql to use left join for patient address + + + + + + select count(*) from concept_name where name='Cured Diagnosis' AND concept_name_type = 'FULLY_SPECIFIED'; + + + Add new concept for Cured Diagnosis + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Cured Diagnosis', 'Cured Diagnosis', 'N/A', 'Misc', true); + + + + 3:14239025d1eeb1a927e6ab5e0bb85e08 + New roles and privileges for bahmni + + + + + + select count(*) from users where system_id='superman' or username='superman'; + + + Adding superman user + + SET @puuid = uuid(); + INSERT INTO person(gender, birthdate_estimated, dead, creator, date_created, uuid) VALUES('M', 0, 0, 1, now(), @puuid); + SELECT person_id INTO @person_id from person where uuid = @puuid; + INSERT INTO person_name(person_id, preferred, given_name, family_name, creator, date_created, uuid) VALUES(@person_id, 1, 'Super', 'Man', 1, now(), @puuid); + INSERT INTO users(system_id, creator, date_created, person_id, uuid, username, password, salt) VALUES ('superman', 1, now(),@person_id, uuid(), 'superman', 'e28e3ae84c66bfba6b2c50a406567f3e34fea1d76b17c006931571fe5d940f6c6b81e49cf8ea5e0adfca19fe3beb68d8ad79f7c3812e92b8d502a9afcf2029b2', '1c9d7e94aeeb7a2459ef45ed200b2944582e0e7088d75f9b57a3644861ea766c20a269b3fe2eadaff1bc445ecfbd9bd3c0c550dfd813de48d39423cd3d1a8b10'); + INSERT INTO provider (person_id, identifier, creator, date_created, uuid, name) VALUES (@person_id, 'superman', 1, now(), uuid(), 'superman'); + + + + + + select count(*) from users where system_id = 'admin' or system_id = 'superman' + + + Map users to new roles + + set @id = NULL; + select user_id from users where system_id='admin' into @id; + INSERT IGNORE INTO `user_role` VALUES (@id,'Provider'),(@id,'System Developer'); + + select user_id from users where system_id='superman' into @id; + INSERT IGNORE INTO `user_role` VALUES (@id,'Provider'),(@id,'System Developer'), (@id, 'SuperAdmin'); + + + + + + select count(*) from role where role = 'Reports-App'; + + + Map 'reports-user' user to new roles + + select user_id from users where username = 'reports-user' into @id; + INSERT IGNORE INTO `user_role` VALUES (@id, 'Reports-App'); + + + + + + select count(*) from users where username = 'automation' + + + Assign role to automation user + + set @id = NULL; + select user_id from users where username='automation' into @id; + INSERT INTO `user_role` VALUES (@id, 'SuperAdmin'); + + + + + Change data type of REFERRED_OUT concept to boolean + + UPDATE concept + SET datatype_id = + (SELECT concept_datatype_id + FROM concept_datatype + WHERE name = 'Boolean') + WHERE concept_id IN (SELECT concept_id + FROM concept_name + WHERE name = 'REFERRED_OUT'); + + + + + + select count(*) from role where role = 'Bahmni-App-User-Login' + + + Add correct description for internal roles + + update role set description = 'Will give ability to login to the application and used internally, should not be assigned to user directly.' where role = 'Bahmni-App-User-Login'; + update role set description = 'Will have save privileges used by other Clinical roles and used internally, should not be assigned to user directly.' where role = 'Clinical-App-Save'; + update role set description = 'Will have common privileges used by other Clinical roles and used internally, should not be assigned to user directly.' where role = 'Clinical-App-Common'; + update role set description = 'Role if assigned disables two factor authentication for that user and used internally, should not be assigned to user directly.' where role = 'bypass2FA'; + + + + + + + select count(*) from role where role in ('Clinical-App','Programs-App') + + + Add Clinical-app role as sub role to Programs-app role + + insert into role_role values('Clinical-App', 'Programs-App'); + + + + + Updating Referred out obs to have value coded as true + + UPDATE obs + SET value_coded = (SELECT concept_id + FROM concept_name + WHERE name = 'True' AND concept_name_type = 'FULLY_SPECIFIED') + WHERE concept_id IN (SELECT concept_id + FROM concept_name + WHERE name = 'REFERRED_OUT' AND concept_name_type = 'FULLY_SPECIFIED') AND value_coded IS NULL; + + + + + Add privileges to roles Clinical-App-Common(Get Order Sets), Registration-App(Delete Visits) + + INSERT IGNORE INTO role_privilege (role, privilege) SELECT * FROM (SELECT 'Clinical-App-Common', 'Get Order Sets') AS tmp WHERE EXISTS ( SELECT role FROM role WHERE role = 'Clinical-App-Common' ); + INSERT IGNORE INTO role_privilege (role, privilege) SELECT * FROM (SELECT 'Registration-App', 'Delete Visits') AS tmp WHERE EXISTS ( SELECT role FROM role WHERE role = 'Registration-App' ); + + + + + Add 'Get Concept Sources' privilege to all roles containing 'Get Concepts' + privilege + + + INSERT INTO role_privilege ( + SELECT DISTINCT + role, + 'Get Concept Sources' + FROM + ( SELECT DISTINCT role + FROM role_privilege + WHERE privilege IN ('Get Concepts')) tmp + WHERE (role, 'Get Concept Sources') NOT IN ( SELECT * + FROM role_privilege)); + + + + + Add 'Add Encounters' privilege to all roles containing 'Add Visits' or 'Edit Visits' + privilege + + + INSERT INTO role_privilege ( + SELECT DISTINCT + role, + 'Add Encounters' + FROM + ( SELECT DISTINCT role + FROM role_privilege + WHERE privilege IN ('Add Visits','Edit Visits')) tmp + WHERE (role, 'Add Encounters') NOT IN ( SELECT * + FROM role_privilege)); + + + + + Add 'Edit Encounters' privilege to all roles containing 'Add Visits'or 'Edit Visits' + privilege + + + INSERT INTO role_privilege ( + SELECT DISTINCT + role, + 'Edit Encounters' + FROM + ( SELECT DISTINCT role + FROM role_privilege + WHERE privilege IN ('Add Visits','Edit Visits')) tmp + WHERE (role, 'Edit Encounters') NOT IN ( SELECT * + FROM role_privilege)); + + + + + Add 'Get Observations' privilege to all roles containing 'Add Encounters' and 'Edit Encounters' + privilege + + + INSERT INTO role_privilege ( + SELECT DISTINCT + role, + 'Get Observations' + FROM + ( SELECT DISTINCT role + FROM role_privilege + WHERE privilege IN ('Add Encounters', 'Edit Encounters')) tmp + WHERE (role, 'Get Observations') NOT IN ( SELECT * + FROM role_privilege)); + + + + + Add 'Add Observations' privilege to all roles containing 'Add Encounters' and 'Edit Encounters' + privilege + + + INSERT INTO role_privilege ( + SELECT DISTINCT + role, + 'Add Observations' + FROM + ( SELECT DISTINCT role + FROM role_privilege + WHERE privilege IN ('Add Encounters', 'Edit Encounters')) tmp + WHERE (role, 'Add Observations') NOT IN ( SELECT * + FROM role_privilege)); + + + + + Add 'Edit Observations' privilege to all roles containing 'Add Encounters' and 'Edit Encounters' + privilege + + + INSERT INTO role_privilege ( + SELECT DISTINCT + role, + 'Edit Observations' + FROM + ( SELECT DISTINCT role + FROM role_privilege + WHERE privilege IN ('Add Encounters', 'Edit Encounters')) tmp + WHERE (role, 'Edit Observations') NOT IN ( SELECT * + FROM role_privilege)); + + + + Delete empty diagnosis status obs + + set @diagnosis_status_concept_id = 0; + select concept_id from concept_name where concept_name_type='FULLY_SPECIFIED' and name='Bahmni Diagnosis Status' into @diagnosis_status_concept_id; + update obs o1 join obs o2 on o1.previous_version = o2.obs_id and o2.concept_id = @diagnosis_status_concept_id and o2.value_coded is null set o1.previous_version = null; + delete from obs where concept_id = @diagnosis_status_concept_id and value_coded is null; + + + + + + + select count(*) from role_privilege where role = 'Clinical-App' and privilege = 'app:clinical:deleteDiagnosis' + + + Add delete diagnosis privilege to Clinical App role + + insert into role_privilege values('Clinical-App', 'app:clinical:deleteDiagnosis'); + + + + + Update log level of org.openmrs.api to WARN + + update global_property set property_value='org.openmrs.api:warn' where property = 'log.level' and property_value like '%org.openmrs.api%'; + + + + + Switch boolean concepts/observations to be stored as coded + + + + + + + + SELECT COUNT(*) FROM global_property WHERE property = 'concept.true' and property_value is not null; + + + + Set value coded for referred out concepts + + UPDATE obs + SET value_coded = (SELECT property_value + FROM global_property where property = 'concept.true') + WHERE concept_id IN (SELECT concept_id + FROM concept_name + WHERE name = 'REFERRED_OUT' AND concept_name_type = 'FULLY_SPECIFIED') AND value_coded IS NULL; + + + + + + + select count(*) from role where role = 'HubConnect'; + + + Create HubConnect Role with location and provider privileges + + insert into role(role, description, uuid) values( 'HubConnect', 'Will have privileges required to sync resources from parent Bahmni server to child Bahmni server', uuid()); + insert into role_privilege(role, privilege) values ('HubConnect', 'Get Locations'); + insert into role_privilege(role, privilege) values ('HubConnect', 'Get Location Attribute Types'); + + + + + + + + + Update the foreign key constrain on obs_relationship, Consider user_id(users) for foreign key reference instead of person_id(person) + + ALTER TABLE obs_relationship + DROP FOREIGN KEY obs_relationship_ibfk_4; + + ALTER TABLE obs_relationship + ADD CONSTRAINT obs_relationship_ibfk_4 + FOREIGN KEY (creator) + REFERENCES users(user_id); + + + + + + select count(*) from patient_identifier_type where name = 'Bahmni Id' + + set global property value for bahmni primary identifier type + + update global_property set property_value = (select uuid from patient_identifier_type where name = 'Bahmni Id') where property = 'bahmni.primaryIdentifierType'; + + + + + update the search query to use bahmni.primaryIdentifierType global property instead of emr.primaryIdentifierType + + + + + Update the wards list sql to use bahmni.primaryIdentifierType global property instead of emr.primaryIdentifierType + + + + + + + SELECT count(property) FROM global_property WHERE property='emr.primaryIdentifierType'; + + + SELECT count(property) FROM global_property WHERE property='bahmni.primaryIdentifierType'; + + + update global property key 'emr.primaryIdentifierType' to 'bahmni.primaryIdentifierType' + + UPDATE global_property SET property='bahmni.primaryIdentifierType' where property='emr.primaryIdentifierType'; + + + + + + + SELECT count(property) FROM global_property where property='emr.extraPatientIdentifierTypes'; + + + update global property key 'emr.extraPatientIdentifierTypes' to 'bahmni.extraPatientIdentifierTypes' + + update global_property set property='bahmni.extraPatientIdentifierTypes' where property='emr.extraPatientIdentifierTypes'; + + + + + + + + + + + + CREATE TABLE audit_log ( + audit_log_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY , + user_id INT(11) NOT NULL, + patient_id INT(11), + event_type VARCHAR(100) NOT NULL, + message LONGBLOB NOT NULL, + date_created DATETIME NOT NULL, + uuid VARCHAR(38) NOT NULL UNIQUE, + + FOREIGN KEY fk_patient_id(patient_id) REFERENCES patient(patient_id), + FOREIGN KEY fk_user_id(user_id) REFERENCES users(user_id) + ); + + + + + + 3:2b48153e296e929a8c7fe8bd519654ec + + + SELECT COUNT(*) FROM concept where concept_id in (select concept_id from concept_name where + name = 'Non-Coded Condition' AND concept_name_type = 'FULLY_SPECIFIED' AND voided = FALSE) + and retired = FALSE; + + + Add new concept for Non-Coded Condition + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Non-Coded Condition', + 'Non-Coded Condition', 'Text', 'Question', false); + + update global_property set property_value = (select uuid from concept where concept_id = @concept_id) + where property = 'conditionList.nonCodedUuid'; + + + + + + + select count(*) from global_property where property_value='en, es, fr, it, pt'; + + + Renaming 'pt' to 'pt_BR' for locale.allowed.list property in global_property table + + update global_property set property_value='en, es, fr, it, pt_BR' where property_value='en, es, fr, it, pt'; + + + + + + select count(*) from privilege where privilege='Edit conditions' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('Edit conditions', 'Privilege to add or edit conditions', @uuid); + + + + + + select count(*) from privilege where privilege='Get conditions' + + + set @uuid = ''; + select uuid() into @uuid; + insert into privilege(privilege, description, uuid) values('Get conditions', 'Privilege to view conditions', @uuid); + + + + + + SELECT count(privilege) FROM role_privilege WHERE privilege = 'Edit conditions' and role = 'Clinical-App-Save' + + Add privileges to roles Clinical-App-Save(Edit Conditions) + + INSERT IGNORE INTO role_privilege (role, privilege) SELECT * FROM (SELECT 'Clinical-App-Save', 'Edit conditions') AS tmp WHERE EXISTS ( SELECT role FROM role WHERE role = 'Clinical-App-Save' ); + + + + + + SELECT count(privilege) FROM role_privilege WHERE privilege = 'Get conditions' and role = 'Clinical-App-Read-Only' + + Add privileges to roles Clinical-App-Read-Only(Get conditions) + + INSERT IGNORE INTO role_privilege (role, privilege) SELECT * FROM (SELECT 'Clinical-App-Read-Only', 'Get conditions') AS tmp WHERE EXISTS ( SELECT role FROM role WHERE role = 'Clinical-App-Read-Only' ); + + + + + + SELECT count(privilege) FROM role_privilege WHERE privilege = 'Get Forms' and role = 'Clinical-App-Read-Only' + + Add privileges to roles Clinical-App-Read-Only(Get Forms) + + INSERT IGNORE INTO role_privilege (role, privilege) SELECT * FROM (SELECT 'Clinical-App-Read-Only', 'Get Forms') AS tmp WHERE EXISTS ( SELECT role FROM role WHERE role = 'Clinical-App-Read-Only' ); + + + + + 3:a735e6b93635ffb2bc7e6a01a24407c3 + + + SELECT COUNT(*) FROM concept where concept_id in (select concept_id from concept_name where + name = 'Follow-up Condition' AND concept_name_type = 'FULLY_SPECIFIED' AND voided = FALSE) and + retired = FALSE; + + + Add new concept for Follow-up Condition + + set @concept_id = 0; + set @answer_concept_id = 0; + set @concept_name_short_id = 0; + set @concept_name_full_id = 0; + + call add_concept(@concept_id, @concept_name_short_id, @concept_name_full_id, 'Follow-up Condition', + 'Follow-up Condition', 'Text', 'Misc', false); + + + + + Update global property to handle null for family name + + UPDATE global_property + SET property_value = REPLACE(property_value, "pn.family_name", "ifnull(pn.family_name,'')") + WHERE global_property.property_value LIKE '%pn.family_name%'; + + + + + + select count(*) from privilege where privilege='app:appointments' + + Adding privilege for Appointments Module + + INSERT INTO privilege (privilege, description, uuid) VALUES ('app:appointments', 'Able to view Appointments module', uuid()); + + + + + + select count(*) from privilege where privilege='app:appointments:manageAppointmentsTab' + + Adding privilege for managing appointments in appointments Module + + INSERT INTO privilege (privilege, description, uuid) VALUES ('app:appointments:manageAppointmentsTab', 'Able to manage appointments in appointments module', uuid()); + + + + + + select count(*) from privilege where privilege='app:appointments:adminTab' + + Adding privilege for managing services in appointments Module + + INSERT INTO privilege (privilege, description, uuid) VALUES ('app:appointments:adminTab', 'Able to manage services in appointments module', uuid()); + + + + + + + SELECT count(*) FROM role WHERE role = 'Appointments:ReadOnly'; + + + Creating new role Appointments: ReadOnly for Appointments module + + INSERT INTO role(role, description, uuid) VALUES ("Appointments:ReadOnly", "Ability to view appointments in appointments module", uuid()); + + + + + + SELECT count(*) FROM role WHERE role = 'Appointments:ManageAppointments'; + + + Creating new role Appointments: Manage for Appointments module + + INSERT INTO role(role, description, uuid) VALUES ("Appointments:ManageAppointments", "Ability to manage appointments in appointments module", uuid()); + + + + + + SELECT count(*) FROM role WHERE role = 'Appointments:FullAccess'; + + + Creating new role for Full Access to Appointments module + + INSERT INTO role(role, description, uuid) VALUES ("Appointments:FullAccess", "Ability to manage appointments and services in appointments module", uuid()); + + + + + + + SELECT count(*) FROM privilege WHERE privilege = "app:appointments"; + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:ReadOnly" AND privilege = "app:appointments"; + + + Adding app:appointments privilege to Appointments: ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:ReadOnly", "app:appointments"); + + + + + + SELECT count(*) FROM privilege WHERE privilege = "View Appointments"; + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:ReadOnly" AND privilege="View Appointments"; + + + Adding View Appointments privilege to Appointments: ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:ReadOnly", "View Appointments"); + + + + + + SELECT count(*) FROM privilege WHERE privilege = "View Appointment Services"; + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:ReadOnly" AND privilege ="View Appointment Services"; + + + Adding all the privileges to Appointments: ReadOnly + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:ReadOnly", "View Appointment Services"); + + + + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT COUNT(*) FROM role_privilege WHERE role = 'Appointments:ReadOnly' AND privilege = 'Get Locations'; + + + adding Get Locations privilege to Appointments:ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ('Appointments:ReadOnly', 'Get Locations'); + + + + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT COUNT(*) FROM role_privilege WHERE role = 'Appointments:ReadOnly' AND privilege = 'Get Patients'; + + + adding Get Patients privilege to Appointments:ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ('Appointments:ReadOnly', 'Get Patients'); + + + + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT COUNT(*) FROM role_privilege WHERE role = 'Appointments:ReadOnly' AND privilege = 'Get Patient Identifiers'; + + + adding Get Patient Identifiers privilege to Appointments:ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ('Appointments:ReadOnly', 'Get Patient Identifiers'); + + + + + + SELECT count(*) FROM role WHERE role = "Appointments:ReadOnly"; + + + SELECT COUNT(*) FROM role_privilege WHERE role = 'Appointments:ReadOnly' AND privilege = 'Get Providers'; + + + adding Get Providers privilege to Appointments:ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ('Appointments:ReadOnly', 'Get Providers'); + + + + + + + + SELECT count(*) FROM privilege WHERE privilege = "app:appointments:manageAppointmentsTab"; + + + SELECT count(*) FROM role WHERE role = "Appointments:ManageAppointments"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:ManageAppointments" AND privilege = "app:appointments:manageAppointmentsTab"; + + + Adding app:appointments:manageAppointmentsTab privilege to Appointments:ManageAppointments role + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:ManageAppointments", "app:appointments:manageAppointmentsTab"); + + + + + + SELECT count(*) FROM privilege WHERE privilege = "Manage Appointments"; + + + SELECT count(*) FROM role WHERE role = "Appointments:ManageAppointments"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:ManageAppointments" AND privilege = "Manage Appointments"; + + + Adding Manage Appointments privilege to Appointments:ManageAppointments role + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:ManageAppointments", "Manage Appointments"); + + + + + + + SELECT count(*) FROM privilege WHERE privilege = "app:appointments:adminTab"; + + + SELECT count(*) FROM role WHERE role = "Appointments:FullAccess"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:FullAccess" AND privilege = "app:appointments:adminTab"; + + + Adding app:appointments:adminTab privilege to Appointments:FullAccess + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:FullAccess", "app:appointments:adminTab"); + + + + + + SELECT count(*) FROM privilege WHERE privilege = "Manage Appointment Services"; + + + SELECT count(*) FROM role WHERE role = "Appointments:FullAccess"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:FullAccess" AND privilege = "Manage Appointment Services"; + + + Adding Manage Appointment Services privilege to Appointments:FullAccess + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:FullAccess", "Manage Appointment Services"); + + + + + + + SELECT COUNT(*) FROM role_role WHERE child_role = 'Appointments:ManageAppointments' AND parent_role = 'Appointments:ReadOnly'; + + + adding Appointments:ReadOnly as parent role for Appointments:ManageAppointments role to inherit all privileges from Appointments:ReadOnly + + INSERT INTO role_role(child_role, parent_role) VALUES ('Appointments:ManageAppointments', 'Appointments:ReadOnly'); + + + + + + SELECT COUNT(*) FROM role_role WHERE child_role = 'Appointments:FullAccess' AND parent_role = 'Appointments:ManageAppointments'; + + + adding Appointments:ManageAppointments as parent role for Appointments:FullAccess role to inherit all privileges from Appointments:ManageAppointments + + INSERT INTO role_role(child_role, parent_role) VALUES ('Appointments:FullAccess', 'Appointments:ManageAppointments'); + + + + + + SELECT count(*) FROM role where role = "OT: FullAccess"; + + + Creating a role for OT: FullAccess + + INSERT INTO role(role, description, uuid) VALUES ("OT: FullAccess", "Ability to access and modify OT schedules", uuid()); + + + + + + SELECT count(*) FROM role where role = "OT: ReadOnly"; + + + Creating a role for OT- ReadOnly + + INSERT INTO role(role, description, uuid) VALUES ("OT: ReadOnly", "Ability to access and modify OT schedules", uuid()); + + + + + + SELECT count(*) FROM privilege where privilege = "app:ot"; + + + Creating a privilege for viewing the OT module + + INSERT INTO privilege(privilege, description, uuid) VALUES ("app:ot", "Ability to view OT module", uuid()); + + + + + + SELECT count(*) FROM privilege where privilege = "app:ot:write"; + + + Creating a privilege for viewing the OT module + + INSERT INTO privilege(privilege, description, uuid) VALUES ("app:ot:write", "Ability to view new surgical block and other buttons to edit on OT module", uuid()); + + + + + + SELECT count(*) FROM privilege WHERE privilege = "Manage OT Schedules"; + + + SELECT count(*) FROM role_privilege WHERE role = "OT: FullAccess" AND privilege = "Manage OT Schedules"; + + + Adding Manage OT Schedules privilege to OT: FullAccess role + + INSERT INTO role_privilege(role, privilege) VALUES ("OT: FullAccess", "Manage OT Schedules"); + INSERT INTO role_privilege(role, privilege) VALUES ("OT: FullAccess", "View OT Schedules"); + INSERT INTO role_privilege(role, privilege) VALUES ("OT: FullAccess", "app:ot"); + INSERT INTO role_privilege(role, privilege) VALUES ("OT: FullAccess", "app:ot:write"); + + + + + + SELECT count(*) FROM privilege WHERE privilege = "View OT Schedules"; + + + SELECT count(*) FROM role_privilege WHERE role = "OT: ReadOnly" AND privilege = "View OT Schedules"; + + + Adding view OT Schedules privilege to OT: ReadOnly role + + INSERT INTO role_privilege(role, privilege) VALUES ("OT: ReadOnly", "View OT Schedules"); + INSERT INTO role_privilege(role, privilege) VALUES ("OT: ReadOnly", "app:ot"); + + + + + + + + + + Creating view concept + + SELECT concept.concept_id, concept_full_name.name AS concept_full_name, concept_short_name.name + AS concept_short_name, concept_class.name AS concept_class_name,concept_datatype.name + AS concept_datatype_name,concept.retired,concept_description.description,concept.date_created + AS date_created FROM concept LEFT OUTER JOIN concept_name AS concept_full_name + ON concept_full_name.concept_id = concept.concept_id AND concept_full_name.concept_name_type = + 'FULLY_SPECIFIED' + AND concept_full_name.locale = 'en' AND concept_full_name.voided = 0 + LEFT OUTER JOIN concept_name AS concept_short_name ON concept_short_name.concept_id = concept.concept_id + AND concept_short_name.concept_name_type = 'SHORT'AND concept_short_name.locale = 'en' AND + concept_short_name.voided = 0 + LEFT OUTER JOIN concept_class ON concept_class.concept_class_id = concept.class_id + LEFT OUTER JOIN concept_datatype ON concept_datatype.concept_datatype_id = concept.datatype_id + LEFT OUTER JOIN concept_description ON concept_description.concept_id = concept.concept_id; + + + + + + + SELECT count(*) FROM concept_view WHERE concept_full_name = 'Bahmni Initial Diagnosis'; + + + SELECT count(*) FROM concept WHERE is_set= TRUE AND concept_id = (SELECT concept_id FROM concept_view + WHERE concept_full_name = 'Bahmni Initial Diagnosis'); + + + SELECT count(*) FROM concept_set WHERE concept_set = (SELECT concept_id FROM concept_view + WHERE concept_full_name = 'Bahmni Initial Diagnosis'); + + + Updating 'Bahmni Initial Diagnosis' concept to non-set concept + + SET @concept_id=0; + SELECT concept_id FROM concept_view WHERE concept_full_name = 'Bahmni Initial Diagnosis' INTO @concept_id; + UPDATE concept SET is_set = FALSE WHERE concept_id = @concept_id; + + + + + + SELECT count(*) FROM concept_view WHERE concept_full_name = 'Bahmni Diagnosis Status'; + + + SELECT count(*) FROM concept WHERE is_set= TRUE AND concept_id = (SELECT concept_id FROM concept_view + WHERE concept_full_name = 'Bahmni Diagnosis Status'); + + + SELECT count(*) FROM concept_set WHERE concept_set = (SELECT concept_id FROM concept_view + WHERE concept_full_name = 'Bahmni Diagnosis Status'); + + + Updating 'Bahmni Diagnosis Status' concept to non-set concept + + SET @concept_id=0; + SELECT concept_id FROM concept_view WHERE concept_full_name = 'Bahmni Diagnosis Status' INTO @concept_id; + UPDATE concept SET is_set = FALSE WHERE concept_id = @concept_id; + + + + + + SELECT count(*) FROM concept_view WHERE concept_full_name = 'Bahmni Diagnosis Revised'; + + + SELECT count(*) FROM concept WHERE is_set= TRUE AND concept_id = (SELECT concept_id FROM concept_view + WHERE concept_full_name = 'Bahmni Diagnosis Revised'); + + + SELECT count(*) FROM concept_set WHERE concept_set = (SELECT concept_id FROM concept_view + WHERE concept_full_name = 'Bahmni Diagnosis Revised'); + + + Updating 'Bahmni Diagnosis Revised' concept to non-set concept + + SET @concept_id=0; + SELECT concept_id FROM concept_view WHERE concept_full_name = 'Bahmni Diagnosis Revised' INTO @concept_id; + UPDATE concept SET is_set = FALSE WHERE concept_id = @concept_id; + + + + Override SQL query for Get Patient Details in Ward + + + + + + select count(*) from scheduler_task_config where schedulable_class= "org.openmrs.module.emrapi.adt.CloseStaleVisitsTask" and name = "Close Stale Visits Task"; + + Add Bahmni preferred EMR API scheduler which closes stale visits + + + + + + + + + + + + + + + + + select count(*) from scheduler_task_config where schedulable_class= "org.openmrs.module.atomfeed.scheduler.tasks.EventPublisherTask" and name = "OpenMRS event publisher task"; + + + adding OpenMRS event publisher task scheduler + + + + + + + + + + + + + + + + + select count(*) from role_privilege where role = 'Anonymous' and privilege = 'Get Locations'; + + + Assign the 'Get Locations' previlege to the Anonymous user + + INSERT INTO role_privilege (role, privilege) VALUES ('Anonymous', 'Get Locations'); + + + + + + SELECT COUNT(*) FROM global_property where property = 'bahmni.admin.csv.upload.dateFormat' + + + Add default date format for all CSV imports + + insert into global_property (`property`, `property_value`, `description`, `uuid`) + values ('bahmni.admin.csv.upload.dateFormat', 'yyyy-M-d', 'Default date format for all CSV imports', uuid()); + + + + + + + Rename Column Precise To AllowDecimal in ConceptNumeric Table + + ALTER TABLE concept_numeric CHANGE precise allow_decimal tinyint(1); + + + + Make allow decimal checkbox checked for all numeric concept + + UPDATE concept_numeric SET allow_decimal = 1 WHERE allow_decimal = 0 + + + + + + SELECT COUNT(*) != 0 FROM concept WHERE datatype_id = 1 AND concept_id NOT IN (SELECT concept_id FROM concept_numeric); + + + add concept numeric row to all numeric concepts + + INSERT INTO concept_numeric (concept_id,allow_decimal) (SELECT concept_id,0 FROM concept WHERE + datatype_id = (SELECT concept_datatype_id FROM concept_datatype WHERE name = 'Numeric') + AND concept_id NOT IN (SELECT concept_id FROM concept_numeric)); + + + + + + + SELECT count(*) FROM provider_attribute_type where name="practitioner_type"; + + + Adding provider attribute type of practitioner_type + + INSERT INTO provider_attribute_type (name, description, datatype, preferred_handler,handler_config, min_occurs, creator, date_created, + retired, uuid) + VALUES ("practitioner_type","list of practitioners", + "org.openmrs.customdatatype.datatype.SpecifiedTextOptionsDatatype","org.openmrs.web.attribute.handler.SpecifiedTextOptionsDropdownHandler",",Doctor", 0, 1, NOW(), 0, UUID()); + + + + + + SELECT COUNT(*) from patient_identifier_type where name='Patient Identifier'; + + + SELECT COUNT(*) from metadatamapping_metadata_term_mapping WHERE code="emr.primaryIdentifierType"; + + + Updating metadata_uuid in metadatamapping_metadata_term_mapping with primaryIdentifier uuid to remove exceptions in landing page of Lab Entry + + set @metadata_uuid = null; + SELECT uuid INTO @metadata_uuid FROM patient_identifier_type WHERE name = "Patient Identifier"; + UPDATE metadatamapping_metadata_term_mapping SET metadata_uuid=@metadata_uuid WHERE code="emr.primaryIdentifierType"; + + + + + + + + select count(c.concept_id) from concept c + INNER join concept_name cn + on cn.concept_id=c.concept_id and cn.name='Visit Diagnoses' and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' and c.version is null; + + + + select count(rmap.concept_id) from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Visit Diagnoses' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + + Update version for the 'Visit Diagnoses' concept because Bahmni concept can be uniquely recognised and doens’t clash with CIEL, or other concepts + + SET @concept_id = 0; + + select rmap.concept_id into @concept_id from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Visit Diagnoses' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + UPDATE concept set version = 'BAHMNI-CORE-1.0' where concept_id = @concept_id and version is null ; + + + + + + + select count(c.concept_id) from concept c + INNER join + concept_name cn + on cn.concept_id=c.concept_id and cn.name='Coded Diagnosis' and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' and c.version is null; + + + + select count(rmap.concept_id) from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Coded Diagnosis' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + + Update version for the 'Coded Diagnosis' concept because Bahmni concept can be uniquely recognised and doens’t clash with CIEL, or other concepts + + SET @concept_id = 0; + + select rmap.concept_id into @concept_id from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Coded Diagnosis' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + UPDATE concept set version='BAHMNI-CORE-1.0' where concept_id=@concept_id and version is null ; + + + + + + + select count(c.concept_id) from concept c + INNER join + concept_name cn + on cn.concept_id=c.concept_id and cn.name='Non-coded Diagnosis' and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' and c.version is null; + + + + select count(rmap.concept_id) from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Non-coded Diagnosis' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + + Update version for the 'Non-Coded Diagnosis' concept because Bahmni concept can be uniquely recognised and doens’t clash with CIEL, or other concepts + + SET @concept_id = 0; + + select rmap.concept_id into @concept_id from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Non-coded Diagnosis' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + UPDATE concept set version='BAHMNI-CORE-1.0' where concept_id=@concept_id and version is null ; + + + + + + + select count(c.concept_id) from concept c + INNER join + concept_name cn + on cn.concept_id=c.concept_id and cn.name='Diagnosis Certainty' and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' and c.version is null; + + + + select count(rmap.concept_id) from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Diagnosis Certainty' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + + Update version for the 'Diagnosis Certainty' concept because Bahmni concept can be uniquely recognised and doens’t clash with CIEL, or other concepts + + SET @concept_id = 0; + + select rmap.concept_id into @concept_id from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Diagnosis Certainty' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + UPDATE concept set version='BAHMNI-CORE-1.0' where concept_id=@concept_id and version is null ; + + + + + + + select count(c.concept_id) from concept c + INNER join + concept_name cn + on cn.concept_id=c.concept_id and cn.name='Diagnosis order' and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' and c.version is null; + + + + select count(rmap.concept_id) from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Diagnosis order' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + + Update version for the 'Diagnosis order' concept because Bahmni concept can be uniquely recognised and doens’t clash with CIEL, or other concepts + + SET @concept_id = 0; + + select rmap.concept_id into @concept_id from concept_reference_map rmap + INNER JOIN concept_name cn on cn.concept_id = rmap.concept_id and cn.name='Diagnosis order' + and cn.concept_name_type='FULLY_SPECIFIED' and cn.voided=0 and cn.locale = 'en' group by rmap.concept_id having count(*) = 1; + + UPDATE concept set version='BAHMNI-CORE-1.0' where concept_id=@concept_id and version is null ; + + + + + + select count(*) from global_property where property='emrapi.useLegacyDiagnosisService' and property_value='FALSE'; + + + set 'emrapi.useLegacyDiagnosisService' to true to use legacy diagnosis service + + UPDATE global_property set property_value='TRUE' where property='emrapi.useLegacyDiagnosisService'; + + + + + + SELECT count(property) FROM global_property WHERE property='emr.primaryIdentifierType' AND property='bahmni.primaryIdentifierType'; + + + Remove global property with value 'emr.primaryIdentifierType' to avoid duplications + + DELETE FROM global_property WHERE property='emr.primaryIdentifierType'; + + + + + + SELECT count(property) FROM global_property WHERE property='bahmni.primaryIdentifierType'; + + + Update gobal property with Patient Identifier uuid + + SELECT uuid INTO @uuid FROM patient_identifier_type WHERE name='Patient Identifier'; + UPDATE global_property SET property_value=@uuid WHERE property='bahmni.primaryIdentifierType'; + + + + + + + SELECT count(*) FROM privilege WHERE privilege = "Create Teleconsultation"; + + + SELECT count(*) FROM role_privilege WHERE role = "Appointments:ManageAppointments" and privilege = "Create Teleconsultation"; + + + Adding Create Teleconsultation privilege to Appointments:ManageAppointments role + + INSERT INTO role_privilege(role, privilege) VALUES ("Appointments:ManageAppointments", "Create Teleconsultation"); + + + + + + select count(*) from order_type where name='Lab Order'; + + + select count(*) from concept_class where name='Test'; + + + select count(*) from order_type_class_map where order_type_id=(select order_type_id from order_type where name = 'Lab Order') and concept_class_id=(select concept_class_id from concept_class where name = 'Test'); + + + Associating Test concept classes to Lab Order order type + + set @order_type_id = ''; + set @test_class = ''; + + select order_type_id into @order_type_id from order_type where name = 'Lab Order'; + select concept_class_id into @test_class from concept_class where name = 'Test'; + + insert into order_type_class_map(order_type_id, concept_class_id) values(@order_type_id,@test_class); + + + + + + SELECT COUNT(*) FROM concept_class where name = 'Radiology/Imaging Procedure'; + + + Add concept class for Radiology/Imaging Procedure + + insert into concept_class (name, description, creator, date_created, retired, uuid) + values ('Radiology/Imaging Procedure', 'Radiology Orders', 1, NOW(), 0, 'c6664c16-16b4-4bf4-91da-93f2ac88a0eb'); + + + + + + select count(*) from order_type where name='Radiology Order'; + + + select count(*) from concept_class where name='Radiology/Imaging Procedure'; + + + select count(*) from order_type_class_map where order_type_id=(select order_type_id from order_type where name = 'Radiology Order') and concept_class_id=(select concept_class_id from concept_class where name = 'Radiology/Imaging Procedure'); + + + Associating Radiology/Imaging Procedure concept class to Radiology Order order type + + set @radiology_order_type_id = ''; + set @radiology_imaging = ''; + + select order_type_id into @radiology_order_type_id from order_type where name = 'Radiology Order'; + select concept_class_id into @radiology_imaging from concept_class where name = 'Radiology/Imaging Procedure'; + + insert into order_type_class_map(order_type_id, concept_class_id) values(@radiology_order_type_id,@radiology_imaging); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select count(*) from note_type where name = 'OT module'; + + + Adding note type + + insert into note_type (name, description, uuid) values ('OT module', 'OT module', uuid()); + + + + + + + SELECT count(*) FROM provider_attribute_type where name="Login Locations"; + + + Adding provider attribute type - Login Locations + + INSERT INTO provider_attribute_type (name, description, datatype, min_occurs, creator, date_created, retired, uuid) + VALUES ("Login Locations","Specific locations for providers to login", "org.openmrs.customdatatype.datatype.LocationDatatype", 0, 1, NOW(), 0, UUID()); + + + + + + + SELECT COUNT(*) FROM program_attribute_type where name = 'Stage' AND datatype = + 'org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype'; + + + Update datatype of patient stage program attribute type + + UPDATE program_attribute_type SET datatype = 'org.openmrs.customdatatype.datatype.ConceptDatatype' WHERE + name = 'Stage' AND datatype = 'org.bahmni.module.bahmnicore.customdatatype.datatype.CodedConceptDatatype'; + + + + diff --git a/bahmnicore-omod/src/main/resources/messages.properties b/bahmnicore-omod/src/main/resources/messages.properties new file mode 100644 index 0000000000..cd2616a57a --- /dev/null +++ b/bahmnicore-omod/src/main/resources/messages.properties @@ -0,0 +1 @@ +@MODULE_ID@.title=Bahmni Core \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_07__AddOnStartupRolesPrivileges.sql b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_07__AddOnStartupRolesPrivileges.sql new file mode 100644 index 0000000000..dfd8c25a36 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_07__AddOnStartupRolesPrivileges.sql @@ -0,0 +1,52 @@ +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add Allergies','Add allergies',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add HL7 Inbound Archive','Able to add an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add HL7 Inbound Exception','Able to add an HL7 error item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add HL7 Inbound Queue','Able to add an HL7 Queue item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add HL7 Source','Able to add an HL7 Source',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add Problems','Add problems',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Add Visits','Able to add visits',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Configure Visits','Able to choose encounter visit handler and enable/disable encounter visits',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Delete HL7 Inbound Archive','Able to delete/retire an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Delete HL7 Inbound Exception','Able to delete an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Delete HL7 Inbound Queue','Able to delete an HL7 Queue item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Delete Visits','Able to delete visits',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Edit Allergies','Able to edit allergies',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Edit Problems','Able to edit problems',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Edit Visits','Able to edit visits',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Address Hierarchy','Able to add/edit/delete address hierarchies',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Address Templates','Able to add/edit/delete address templates',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Concept Map Types','Able to add/edit/retire concept map types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Concept Name tags','Able to add/edit/delete concept name tags',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Concept Reference Terms','Able to add/edit/retire reference terms',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Concept Stop Words','Able to view/add/remove the concept stop words',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Encounter Roles','Able to add/edit/retire encounter roles',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage HL7 Messages','Able to add/edit/delete HL7 messages',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Implementation Id','Able to view/add/edit the implementation id for the system',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Location Attribute Types','Able to add/edit/retire location attribute types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Location Tags','Able to add/edit/delete location tags',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Providers','Able to edit Provider',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Rule Definitions','Allows creation and editing of user-defined rules',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Tokens','Allows registering and removal of tokens',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Visit Attribute Types','Able to add/edit/retire visit attribute types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Manage Visit Types','Able to add/edit/delete visit types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Patient Dashboard - View Visits Section','Able to view the \'Visits\' tab on the patient dashboard',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Remove Allergies','Remove allergies',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Remove Problems','Remove problems',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Update HL7 Inbound Archive','Able to update an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Update HL7 Inbound Exception','Able to update an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Update HL7 Inbound Queue','Able to update an HL7 Queue item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('Update HL7 Source','Able to update an HL7 Source',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Concept Map Types','Able to view concept map types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Concept Reference Terms','Able to view concept reference terms',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Database Changes','Able to view database changes from the admin screen',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Encounter Roles','Able to view encounter roles',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View HL7 Inbound Archive','Able to view an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View HL7 Inbound Exception','Able to view an HL7 archive item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View HL7 Inbound Queue','Able to view an HL7 Queue item',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View HL7 Source','Able to view an HL7 Source',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Location Attribute Types','Able to view location attribute types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Providers','Able to view Provider',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Rule Definitions','Allows viewing of user-defined rules. (This privilege is not necessary to run rules under normal usage.)',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Visit Attribute Types','Able to view visit attribute types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Visit Types','Able to view visit types',uuid()); +INSERT INTO `privilege` (`privilege`,`description`,`uuid`) VALUES ('View Visits','Able to view visits',uuid()); diff --git a/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_08__AddressHierarchy.sql b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_08__AddressHierarchy.sql new file mode 100644 index 0000000000..158360eae0 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_08__AddressHierarchy.sql @@ -0,0 +1,128 @@ +CREATE TABLE IF NOT EXISTS address_hierarchy_type +( + location_attribute_type_id int(11) NOT NULL auto_increment, + name varchar(160) NOT NULL, + PRIMARY KEY (location_attribute_type_id) +); + +CREATE TABLE IF NOT EXISTS address_hierarchy +( + location_attribute_type_value_id int(11) NOT NULL auto_increment, + name varchar(160) NOT NULL, + type_id int(11) NOT NULL, + parent_location_attribute_type_value_id int(11), + PRIMARY KEY (`location_attribute_type_value_id`), + KEY `parent_location_id` (`parent_location_attribute_type_value_id`), + KEY `location_type_id` (`type_id`), + CONSTRAINT `parent_location_id` FOREIGN KEY (`parent_location_attribute_type_value_id`) REFERENCES `address_hierarchy` (`location_attribute_type_value_id`), + CONSTRAINT `location_type_id` FOREIGN KEY (`type_id`) REFERENCES `address_hierarchy_type` (`location_attribute_type_id`) +); + +ALTER TABLE address_hierarchy ADD COLUMN user_generated_id varchar(11); +ALTER TABLE address_hierarchy DROP FOREIGN KEY location_type_id; +ALTER TABLE address_hierarchy DROP KEY location_type_id; +ALTER TABLE address_hierarchy DROP FOREIGN KEY parent_location_id; +ALTER TABLE address_hierarchy DROP KEY parent_location_id; + +ALTER TABLE address_hierarchy CHANGE COLUMN location_attribute_type_value_id `address_hierarchy_id` int(11) NOT NULL auto_increment; +ALTER TABLE address_hierarchy CHANGE COLUMN parent_location_attribute_type_value_id `parent_id` int(11); + +ALTER TABLE address_hierarchy ADD KEY `parent_location_id` (`parent_id`); +ALTER TABLE address_hierarchy ADD CONSTRAINT `parent_location_id` FOREIGN KEY (`parent_id`) REFERENCES `address_hierarchy` (`address_hierarchy_id`); +ALTER TABLE address_hierarchy ADD KEY `location_type_id` (`type_id`); +ALTER TABLE address_hierarchy ADD CONSTRAINT `location_type_id` FOREIGN KEY (`type_id`) REFERENCES `address_hierarchy_type` (`location_attribute_type_id`); + +ALTER TABLE address_hierarchy_type ADD COLUMN `parent_type_id` int(11) default NULL; +ALTER TABLE address_hierarchy_type ADD COLUMN `child_type_id` int(11) default NULL; + +DROP TABLE IF EXISTS unstructured_address; +ALTER TABLE address_hierarchy add column latitude double, add column longitude double, add column elevation double; + +create index name_ah on address_hierarchy(name); + +ALTER TABLE address_hierarchy DROP FOREIGN KEY location_type_id; +ALTER TABLE address_hierarchy_type CHANGE COLUMN `location_attribute_type_id` `address_hierarchy_type_id` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE address_hierarchy_type ADD COLUMN `address_field` varchar(50) NOT NULL; + +ALTER TABLE address_hierarchy +ADD COLUMN `uuid` char(38) +NOT NULL; + +ALTER TABLE address_hierarchy_type +ADD COLUMN `uuid` char(38) +NOT NULL; + +UPDATE address_hierarchy SET uuid = UUID(); +UPDATE address_hierarchy_type SET uuid = UUID(); + +ALTER TABLE address_hierarchy_type DROP COLUMN child_type_id; + +ALTER TABLE address_hierarchy RENAME address_hierarchy_entry; + +ALTER TABLE address_hierarchy_entry DROP FOREIGN KEY parent_location_id; +ALTER TABLE address_hierarchy_entry CHANGE COLUMN `address_hierarchy_id` `address_hierarchy_entry_id` int(11) NOT NULL AUTO_INCREMENT; + +ALTER TABLE address_hierarchy_type RENAME address_hierarchy_level; + +ALTER TABLE address_hierarchy_level CHANGE COLUMN `address_hierarchy_type_id` `address_hierarchy_level_id` int(11) NOT NULL AUTO_INCREMENT; +ALTER TABLE address_hierarchy_level CHANGE COLUMN `parent_type_id` `parent_level_id` int(11); + +ALTER TABLE address_hierarchy_entry CHANGE COLUMN `type_id` `level_id` int(11); + +ALTER TABLE address_hierarchy_level CHANGE COLUMN `name` `name` varchar(160); + +ALTER TABLE address_hierarchy_level CHANGE COLUMN `address_field` `address_field` varchar(50); + +ALTER TABLE address_hierarchy_level ADD COLUMN `required` tinyint(1) NOT NULL default '0'; + +ALTER TABLE address_hierarchy_entry CHANGE COLUMN `level_id` `level_id` int(11) NOT NULL; + +ALTER TABLE address_hierarchy_level ADD INDEX address_field_unique (address_field); +ALTER TABLE address_hierarchy_level ADD UNIQUE parent_level_id_unique (parent_level_id); + +DROP INDEX parent_location_id ON address_hierarchy_entry; +DROP INDEX location_type_id ON address_hierarchy_entry; +DROP INDEX name_ah ON address_hierarchy_entry; +ALTER TABLE address_hierarchy_entry ADD INDEX parent_name (parent_id,name(20)); +ALTER TABLE address_hierarchy_entry ADD INDEX level_name (level_id,name(20)); + +ALTER TABLE address_hierarchy_entry ADD CONSTRAINT parent_to_parent FOREIGN KEY (parent_id) REFERENCES address_hierarchy_entry (address_hierarchy_entry_id); +ALTER TABLE address_hierarchy_entry ADD CONSTRAINT level_to_level FOREIGN KEY (level_id) REFERENCES address_hierarchy_level (address_hierarchy_level_id); +ALTER TABLE address_hierarchy_level ADD CONSTRAINT parent_level FOREIGN KEY (parent_level_id) REFERENCES address_hierarchy_level (address_hierarchy_level_id); + +ALTER TABLE address_hierarchy_entry DROP FOREIGN KEY parent_to_parent; +ALTER TABLE address_hierarchy_entry ADD CONSTRAINT `parent-to-parent` FOREIGN KEY (`parent_id`) REFERENCES `address_hierarchy_entry` (`address_hierarchy_entry_id`) ON DELETE CASCADE; + +CREATE TABLE IF NOT EXISTS address_hierarchy_address_to_entry_map +( + address_to_entry_map_id int(11) NOT NULL auto_increment, + address_id int(11) NOT NULL, + entry_id int(11) NOT NULL, + uuid char(38) NOT NULL, + PRIMARY KEY (address_to_entry_map_id), + CONSTRAINT address_id_to_person_address_table FOREIGN KEY person_address_index (address_id) REFERENCES person_address (person_address_id), + CONSTRAINT entry_id_to_address_hierarchy_table FOREIGN KEY address_hierarchy_index (entry_id) REFERENCES address_hierarchy_entry (address_hierarchy_entry_id) +); + +-- Insert global properties +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.addressToEntryMapUpdaterLastStartTime', NULL, 'The module uses this field to store when the AddressToEntryMapUpdater task was last started; DO NOT MODIFY', uuid()); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.allowFreetext', 'true', 'Valid values: true/false. When overriding the address portlet, allow the entry of free text for address fields associated with the address hierarchy by providing an "Other" option', uuid()); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.database_version', '2.8.0', 'DO NOT MODIFY. Current database version number for the addresshierarchy module.', uuid()); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.enableOverrideOfAddressPortlet', 'true', 'Valid values: true/false. When enabled, the existing "edit" component of the address portlet is overridden by the new functionality provided by the address hierarchy module', uuid()); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.initializeAddressHierarchyCacheOnStartup', 'true', 'Sets whether to initialize the address hierarchy in-memory cache (which is used to speed up address hierarchy searches. Generally, you want to set this to "true", though developers may want to set it to false during development to speed module start-up.', uuid()); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.mandatory', 'false', 'true/false whether or not the addresshierarchy module MUST start when openmrs starts. This is used to make sure that mission critical modules are always running if openmrs is running.', uuid()); + +insert into global_property (`property`, `property_value`, `description`, `uuid`) +values ('addresshierarchy.soundexProcessor', NULL, 'If the Name Phonetics module is installed, this defines the name of a soundex algorithm used by the getPossibleFullAddresses service method.', uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_09__Idgen.sql b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_09__Idgen.sql new file mode 100644 index 0000000000..dd8b4a08c7 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_09__Idgen.sql @@ -0,0 +1,111 @@ +CREATE TABLE `idgen_identifier_source` ( + `id` int(11) NOT NULL auto_increment, + `uuid` char(38) NOT NULL, + `name` varchar(255) NOT NULL, + `description` varchar(1000), + `identifier_type` int(11) NOT NULL default '0', + `creator` int(11) NOT NULL default '0', + `date_created` datetime NOT NULL default '0000-00-00 00:00:00', + `changed_by` int(11) default NULL, + `date_changed` datetime default NULL, + `retired` tinyint(1) NOT NULL default 0, + `retired_by` int(11) default NULL, + `date_retired` datetime default NULL, + `retire_reason` varchar(255) default NULL, + PRIMARY KEY (`id`), + KEY `id for idgen_identifier_source` (`id`), + KEY `identifier_type for idgen_identifier_source` (`identifier_type`), + KEY `creator for idgen_identifier_source` (`creator`), + KEY `changed_by for idgen_identifier_source` (`changed_by`), + KEY `retired_by for idgen_identifier_source` (`retired_by`), + CONSTRAINT `identifier_type for idgen_identifier_source` FOREIGN KEY (`identifier_type`) REFERENCES `patient_identifier_type` (`patient_identifier_type_id`), + CONSTRAINT `creator for idgen_identifier_source` FOREIGN KEY (`creator`) REFERENCES `users` (`user_id`), + CONSTRAINT `changed_by for idgen_identifier_source` FOREIGN KEY (`changed_by`) REFERENCES `users` (`user_id`), + CONSTRAINT `retired_by for idgen_identifier_source` FOREIGN KEY (`retired_by`) REFERENCES `users` (`user_id`) +); + +CREATE TABLE `idgen_seq_id_gen` ( + `id` int(11) NOT NULL, + `next_sequence_value` int(11) NOT NULL default -1, + `base_character_set` varchar(255) NOT NULL, + `first_identifier_base` varchar(50) NOT NULL, + `prefix` varchar(20), + `suffix` varchar(20), + `length` int(11), + PRIMARY KEY (`id`), + CONSTRAINT `id for idgen_seq_id_gen` FOREIGN KEY (`id`) REFERENCES `idgen_identifier_source` (`id`) +); + +CREATE TABLE `idgen_remote_source` ( + `id` int(11) NOT NULL, + `url` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `id for idgen_remote_source` FOREIGN KEY (`id`) REFERENCES `idgen_identifier_source` (`id`) +); + +CREATE TABLE `idgen_id_pool` ( + `id` int(11) NOT NULL, + `source` int(11), + `batch_size` int(11), + `min_pool_size` int(11), + `sequential` tinyint(1) NOT NULL default 0, + PRIMARY KEY (`id`), + KEY `source for idgen_id_pool` (`source`), + CONSTRAINT `id for idgen_id_pool` FOREIGN KEY (`id`) REFERENCES `idgen_identifier_source` (`id`), + CONSTRAINT `source for idgen_id_pool` FOREIGN KEY (`source`) REFERENCES `idgen_identifier_source` (`id`) +); + +CREATE TABLE `idgen_pooled_identifier` ( + `id` int(11) NOT NULL auto_increment, + `uuid` char(38) NOT NULL, + `pool_id` int(11) NOT NULL, + `identifier` varchar(50) NOT NULL, + `date_used` datetime, + `comment` varchar(255), + PRIMARY KEY (`id`), + CONSTRAINT `pool_id for idgen_pooled_identifier` FOREIGN KEY (`pool_id`) REFERENCES `idgen_id_pool` (`id`) +); + +CREATE TABLE `idgen_auto_generation_option` ( + `id` int(11) NOT NULL auto_increment, + `identifier_type` int(11) unique NOT NULL, + `source` int(11) NOT NULL, + `manual_entry_enabled` tinyint(1) NOT NULL default 1, + `automatic_generation_enabled` tinyint(1) NOT NULL default 1, + PRIMARY KEY (`id`), + CONSTRAINT `identifier_type for idgen_auto_generation_option` FOREIGN KEY (`identifier_type`) REFERENCES `patient_identifier_type` (`patient_identifier_type_id`), + CONSTRAINT `source for idgen_auto_generation_option` FOREIGN KEY (`source`) REFERENCES `idgen_identifier_source` (`id`) +); + +CREATE TABLE `idgen_log_entry` ( + `id` int(11) NOT NULL auto_increment, + `source` int(11) NOT NULL, + `identifier` varchar(50) NOT NULL, + `date_generated` datetime NOT NULL default '0000-00-00 00:00:00', + `generated_by` int(11) NOT NULL, + `comment` varchar(255) default NULL, + PRIMARY KEY (`id`), + KEY `id for idgen_log` (`id`), + KEY `source for idgen_log` (`source`), + KEY `generated_by for idgen_log` (`generated_by`), + CONSTRAINT `source for idgen_log` FOREIGN KEY (`source`) REFERENCES `idgen_identifier_source` (`id`), + CONSTRAINT `generated_by for idgen_log` FOREIGN KEY (`generated_by`) REFERENCES `users` (`user_id`) +); + +CREATE TABLE `idgen_reserved_identifier` ( + `id` int(11) NOT NULL auto_increment, + `source` int(11) NOT NULL, + `identifier` varchar(50) NOT NULL, + PRIMARY KEY (`id`), + KEY `id for idgen_reserved_identifier` (`id`), + KEY `source for idgen_reserved_identifier` (`source`), + CONSTRAINT `source for idgen_reserved_identifier` FOREIGN KEY (`source`) REFERENCES `idgen_identifier_source` (`id`) +); + +ALTER TABLE `idgen_id_pool` ADD COLUMN `refill_with_scheduled_task` tinyint(1) NOT NULL default 1; + +ALTER TABLE `idgen_remote_source` ADD COLUMN `user` varchar(50) ; +ALTER TABLE `idgen_remote_source` ADD COLUMN `password` varchar(20) ; + +insert into global_property (`property`, `property_value`, `description`, `uuid`) values ('idgen.database_version', '2.4.1', +'DO NOT MODIFY. Current database version number for the idgen module.', uuid()); \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_73__RemoveNotNullConstraintOnAddressEntryName.sql b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_73__RemoveNotNullConstraintOnAddressEntryName.sql new file mode 100644 index 0000000000..448c8b7a18 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/V1_73__RemoveNotNullConstraintOnAddressEntryName.sql @@ -0,0 +1 @@ +ALTER TABLE address_hierarchy_entry MODIFY name varchar(160) NULL; \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/migrations/dependent-modules/liquibase.xml b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/liquibase.xml new file mode 100644 index 0000000000..c025d060ed --- /dev/null +++ b/bahmnicore-omod/src/main/resources/migrations/dependent-modules/liquibase.xml @@ -0,0 +1,91 @@ + + + + + + + rel2 + + + + + rel2 + + + + + rel2 + + + + + rel3 + + + + + + + SELECT COUNT(*) FROM global_property where property = 'emr.primaryIdentifierType' + + + rel3 + + + + + + + + + + + + + + + IDGEN - add column for user in idgen + + ALTER TABLE `idgen_remote_source` ADD COLUMN `user` varchar(50) ; + + + + + + + + IDGEN - add column for password in idgen + + ALTER TABLE `idgen_remote_source` ADD COLUMN `user` varchar(50) ; + ALTER TABLE `idgen_remote_source` ADD COLUMN `password` varchar(20) ; + + + + + + + + + IDGEN - modify seq table to add min length and max length instead of length + + ALTER TABLE `idgen_seq_id_gen` CHANGE COLUMN `length` `min_length` int(11); + ALTER TABLE `idgen_seq_id_gen` ADD COLUMN `max_length` int(11); + UPDATE `idgen_seq_id_gen` SET `max_length` = `min_length`; + + + + Update version for above change + + + property='idgen.database_version' + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/main/resources/webModuleApplicationContext.xml b/bahmnicore-omod/src/main/resources/webModuleApplicationContext.xml new file mode 100644 index 0000000000..32cc5af196 --- /dev/null +++ b/bahmnicore-omod/src/main/resources/webModuleApplicationContext.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/BahmniVisitControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/BahmniVisitControllerTest.java new file mode 100644 index 0000000000..f94d885230 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/BahmniVisitControllerTest.java @@ -0,0 +1,41 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import org.bahmni.module.bahmnicore.web.v1_0.controller.BahmniVisitController; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class BahmniVisitControllerTest { + @Mock + private VisitService visitService; + @Mock + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + @InjectMocks + private BahmniVisitController bahmniVisitController; + + @Test + public void shouldCloseExistingVisitAndCreateANewEncounter() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + Visit visit = new Visit(); + when(visitService.getVisitByUuid("visitUuid")).thenReturn(visit); + + bahmniVisitController.endVisitAndCreateNewEncounter("visitUuid", bahmniEncounterTransaction); + + verify(visitService, times(1)).getVisitByUuid("visitUuid"); + verify(visitService, times(1)).endVisit(visit, null); + verify(bahmniEncounterTransactionService, times(1)).save(bahmniEncounterTransaction); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/BaseIntegrationTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/BaseIntegrationTest.java new file mode 100644 index 0000000000..e04b2f6790 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/BaseIntegrationTest.java @@ -0,0 +1,7 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import org.bahmni.test.web.controller.BaseWebControllerTest; + +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BaseIntegrationTest extends BaseWebControllerTest { +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java new file mode 100644 index 0000000000..1cd47ee7b9 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/LocaleResolverTest.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.web.v1_0; + +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.openmrs.util.LocaleUtility; + +import java.util.Locale; + +public class LocaleResolverTest { + + @Test + public void shouldReturnDefaultLocaleIfNull() { + Locale locale = identifyLocale(null); + assertEquals(LocaleUtility.getDefaultLocale(), locale); + } + + @Test + public void shouldReturnDefaultLocaleIfEmpty() { + Locale locale = identifyLocale(""); + assertEquals(LocaleUtility.getDefaultLocale(), locale); + } + + @Test + public void shouldReturnParsedLocaleIfValid() { + Locale locale = identifyLocale("en_US"); + assertEquals(new Locale("en", "US"), locale); + } + + @Test(expected = AssertionError.class) + public void shouldThrowExceptionIfInvalidLocale() { + identifyLocale("invalid"); + fail("Should have thrown exception"); + } + +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyControllerIT.java new file mode 100644 index 0000000000..63fd1dbc9a --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyControllerIT.java @@ -0,0 +1,44 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class BahmniAddressHierarchyControllerIT extends BaseIntegrationTest { + + @Autowired + BahmniAddressHierarchyController bahmniAddressHierarchyController; + + @Before + public void setUp() throws Exception { + executeDataSet("addressHierarchy.xml"); + } + + @Test + public void shouldGetAddressHierarchyByUuid() throws Exception { + BahmniAddressHierarchyEntry bahmniAddressHierarchyEntries = bahmniAddressHierarchyController.get("22e41146-e162-11df-9195-001e378eb67f"); + assertNotNull(bahmniAddressHierarchyEntries); + assertEquals("United States", bahmniAddressHierarchyEntries.getName()); + assertEquals("Country", bahmniAddressHierarchyEntries.getAddressHierarchyLevel().getName()); + } + + + @Test + public void shouldGetAddressHierarchyEntriesByUuidIncludingParent() throws Exception { + List addressHierarchyEntries = bahmniAddressHierarchyController.getAddressHierarchyEntriesByUuid(Arrays.asList("22e41146-e134-11df-9195-001e378eb67f","22e41146-e162-11df-9195-001e378eb67f")); + assertNotNull(addressHierarchyEntries); + assertEquals("United States", addressHierarchyEntries.get(0).getName()); + assertEquals("Country", addressHierarchyEntries.get(0).getAddressHierarchyLevel().getName()); + assertEquals("New York", addressHierarchyEntries.get(1).getName()); + assertEquals("State", addressHierarchyEntries.get(1).getAddressHierarchyLevel().getName()); + assertEquals((Integer) 1, addressHierarchyEntries.get(1).getParentId()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyControllerTest.java new file mode 100644 index 0000000000..520dca29ce --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniAddressHierarchyControllerTest.java @@ -0,0 +1,56 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.model.BahmniAddressHierarchyEntry; +import org.bahmni.module.bahmnicore.service.BahmniAddressHierarchyService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniAddressHierarchyControllerTest { + @Mock + BahmniAddressHierarchyService bahmniAddressHierarchyService; + + private BahmniAddressHierarchyController bahmniAddressHierarchyController; + + @Before + public void setUp() throws Exception { + initMocks(this); + bahmniAddressHierarchyController = new BahmniAddressHierarchyController(bahmniAddressHierarchyService); + } + + @Test + public void shouldGetAddressHierarchyEntryByUuid() throws Exception { + List addressHierarchyEntries = new ArrayList<>(); + BahmniAddressHierarchyEntry addressHierarchyEntry = new BahmniAddressHierarchyEntry(); + addressHierarchyEntry.setName("test"); + addressHierarchyEntries.add(addressHierarchyEntry); + when(bahmniAddressHierarchyService.getAddressHierarchyEntriesByUuid(Arrays.asList("uuid"))).thenReturn(addressHierarchyEntries); + BahmniAddressHierarchyEntry hierarchyEntry = bahmniAddressHierarchyController.get("uuid"); + + verify(bahmniAddressHierarchyService, times(1)).getAddressHierarchyEntriesByUuid(Arrays.asList("uuid")); + assertNotNull(hierarchyEntry); + assertEquals("test", addressHierarchyEntries.get(0).getName()); + } + + @Test + public void shouldReturnNullIfUuidIsNull() throws Exception { + BahmniAddressHierarchyEntry hierarchyEntry = bahmniAddressHierarchyController.get(null); + + verify(bahmniAddressHierarchyService, never()).getAddressHierarchyEntriesByUuid(Arrays.asList(anyString())); + assertNull(hierarchyEntry); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java new file mode 100644 index 0000000000..56bf23e3f4 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConceptSearchControllerTest.java @@ -0,0 +1,92 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniDiagnosisService; +import org.bahmni.module.bahmnicore.service.TsConceptSearchService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.concept.EmrConceptService; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BahmniConceptSearchControllerTest { + + @Mock + private BahmniDiagnosisService bahmniDiagnosisService; + + @Mock + private EmrConceptService emrService; + + @Mock + private TsConceptSearchService tsConceptSearchService; + + @Mock + private AdministrationService administrationService; + + @InjectMocks + private BahmniConceptSearchController bahmniConceptSearchController; + + String searchTerm = "Malaria"; + int searchLimit = 20; + String locale = LocaleUtility.getDefaultLocale().toString(); + List locales = Collections.singletonList(LocaleUtility.getDefaultLocale()); + + @Before + public void setUp() throws Exception { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(administrationService.getAllowedLocales()).thenReturn(locales); + } + + @Test + public void shouldSearchDiagnosisByNameFromDiagnosisSetOfSetsWhenNoExternalTerminologyServerUsed() throws Exception { + String malariaConceptUuid = "uuid1"; + SimpleObject MalariaObject = new SimpleObject(); + MalariaObject.add("conceptName", searchTerm); + MalariaObject.add("conceptUuid", malariaConceptUuid); + MalariaObject.add("matchedName", searchTerm); + + when(tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale)).thenReturn(Collections.singletonList(MalariaObject)); + + List searchResults = (List< SimpleObject >) bahmniConceptSearchController.search(searchTerm, searchLimit, locale); + + assertNotNull(searchResults); + assertEquals(searchResults.size(), 1); + assertEquals(searchResults.get(0).get("conceptName"), searchTerm); + assertEquals(searchResults.get(0).get("conceptUuid"), malariaConceptUuid); + } + + @Test + public void shouldSearchDiagnosisByNameFromExternalTerminologyServerAndShouldReturnEmptyList() throws Exception { + when(tsConceptSearchService.getConcepts(searchTerm, searchLimit, locale)).thenReturn(new ArrayList<>()); + + List searchResults = (List< SimpleObject >) bahmniConceptSearchController.search(searchTerm, searchLimit, locale); + assertNotNull(searchResults); + assertEquals(searchResults.size(), 0); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConfigControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConfigControllerIT.java new file mode 100644 index 0000000000..5f67b9e48b --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniConfigControllerIT.java @@ -0,0 +1,74 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.admin.config.model.BahmniConfig; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.codehaus.jackson.type.TypeReference; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertNotNull; +import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.assertTrue; + + +public class BahmniConfigControllerIT extends BaseIntegrationTest { + @Before + public void setUp() throws Exception { + executeDataSet("configDataSetup.xml"); + } + + @Test + public void deserializationToJsonOfConfig() throws Exception { + HashMap headers = new HashMap<>(); + BahmniConfig bahmniConfig = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/config", headers, new Parameter("appName", "clinical"), new Parameter("configName", "app.json"))), new TypeReference() { + }); + assertEquals("app.json", bahmniConfig.getConfigName()); + assertEquals("clinical", bahmniConfig.getAppName()); + } + + @Test + public void getConfigByPath() throws Exception { + String bahmniConfig = handle(newGetRequest("/rest/v1/bahmnicore/config/clinical/app.json")).getContentAsString(); + assertFalse(bahmniConfig.isEmpty()); + assertTrue(bahmniConfig.contains("bahmni.registration")); + } + + @Test + public void strippedDownJsonOfAllConfigsUnderAnApp() throws Exception { + HashMap headers = new HashMap<>(); + List bahmniConfigs = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/config/all", headers, new Parameter("appName", "clinical"))), new TypeReference>() { + }); + assertEquals(2, bahmniConfigs.size()); + assertNull(bahmniConfigs.get(0).getConfig()); + assertNull(bahmniConfigs.get(1).getConfig()); + } + + @Test + public void createNewConfig() throws Exception { + BahmniConfig bahmniConfig = new BahmniConfig(); + bahmniConfig.setConfig("New Config"); + bahmniConfig.setAppName("registration"); + bahmniConfig.setConfigName("app.json"); + BahmniConfig savedConfig = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/config", bahmniConfig)), BahmniConfig.class); + BahmniConfig getConfig = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/config", new Parameter("appName", "registration"), new Parameter("configName", "app.json"))), BahmniConfig.class); + assertEquals(savedConfig, getConfig); + assertNotNull(getConfig.getDateCreated()); + assertEquals("New Config", getConfig.getConfig()); + } + + @Test + public void updateExistingConfig() throws Exception { + BahmniConfig getConfig = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/config", new Parameter("appName", "clinical"), new Parameter("configName", "app.json"))), BahmniConfig.class); + getConfig.setConfig("Updated Config"); + BahmniConfig savedConfig = deserialize(handle(newPutRequest("/rest/v1/bahmnicore/config", getConfig)), BahmniConfig.class); + getConfig = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/config", new Parameter("appName", "clinical"), new Parameter("configName", "app.json"))), BahmniConfig.class); + assertEquals(savedConfig, getConfig); + assertNotNull(getConfig.getDateCreated()); + assertEquals("Updated Config", getConfig.getConfig()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDischargeControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDischargeControllerTest.java new file mode 100644 index 0000000000..d820dff4f7 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDischargeControllerTest.java @@ -0,0 +1,68 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.openmrs.api.OpenmrsService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.bedmanagement.service.BedManagementService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BahmniDischargeControllerTest { + @Mock + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + @Mock + private PatientService patientService; + @Mock + private BedManagementService bedManagementService; + + @InjectMocks + private BahmniDischargeController bahmniDischargeController; + + @Before + public void setUp() throws Exception { + initMocks(this); + + PowerMockito.mockStatic(Context.class); + when(Context.getPatientService()).thenReturn(patientService); + List services = new ArrayList<>(); + services.add(bedManagementService); + when(Context.getModuleOpenmrsServices(BedManagementService.class.getName())).thenReturn(services); + } + + @Test + public void shouldDischargeAndUnassignBedOfPatient() throws Exception { + String patientUuid = "patientUuid"; + Patient patient = new Patient(); + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setPatientUuid(patientUuid); + when(patientService.getPatientByUuid(patientUuid)).thenReturn(patient); + when(bahmniEncounterTransactionService.save(bahmniEncounterTransaction)).thenReturn(bahmniEncounterTransaction); + + BahmniEncounterTransaction encounterTransaction = bahmniDischargeController.discharge(bahmniEncounterTransaction); + + verify(bedManagementService, times(1)).unAssignPatientFromBed(patient); + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(bahmniEncounterTransactionService, times(1)).save(bahmniEncounterTransaction); + assertEquals(encounterTransaction, bahmniEncounterTransaction); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDispositionControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDispositionControllerIT.java new file mode 100644 index 0000000000..ab41ef63bd --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDispositionControllerIT.java @@ -0,0 +1,44 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.disposition.contract.BahmniDisposition; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class BahmniDispositionControllerIT extends BaseIntegrationTest { + + @Autowired + private BahmniDispositionController bahmniDispositionController; + + @Before + public void setUp() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionsForVisit.xml"); + } + + @Test + public void shouldRetrieveEmptyDispositionsByInvalidVisitUuid(){ + List dispositions = bahmniDispositionController.getDispositionByVisitUuid("INVALID"); + assertEquals(dispositions.size(),0); + } + + @Test + public void shouldRetrieveDispositionForVisitUuid(){ + List dispositions = bahmniDispositionController.getDispositionByVisitUuid("adf4fb41-a41a-4ad6-12f5-2f59889acf5a"); + assertEquals(dispositions.size(),1); + assertEquals("Absconding", dispositions.get(0).getConceptName()); + } + + @Test + public void shouldRetrieveDispositionByPatient(){ + List dispositions = bahmniDispositionController.getDispositionByPatientUuid("1a246ed5-3c11-11de-a0ba-001ed98eb67a", 3); + assertEquals(dispositions.size(),1); + assertEquals("Absconding", dispositions.get(0).getConceptName()); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java new file mode 100644 index 0000000000..be74f6f69b --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerIT.java @@ -0,0 +1,246 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.matchers.JUnitMatchers.hasItems; + +public class BahmniDrugOrderControllerIT extends BaseIntegrationTest { + + @Autowired + private BahmniDrugOrderController bahmniDrugOrderController; + + @Autowired + private BahmniDrugOrderService bahmniDrugOrderService; + + @Before + public void setUp() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("drugOrdersForVisits.xml"); + } + + @Test + public void shouldReturnDrugOrdersWithoutJavaAssistOrderProxy() throws Exception{ + executeDataSet("activeOrderTests.xml"); + List drugOrders = bahmniDrugOrderService.getActiveDrugOrders("c475abf0-59d7-4bfe-8d73-57604a17e519"); + for(Order order: drugOrders){ + //This issue happened in Possible when the Order that is returned is a javassist proxy instead of a DrugOrder and it returned a ClassCastException + if(!(order instanceof DrugOrder)){ + fail("The Order ["+order+"] is not an instance of drugOrder"); + } + } + assertEquals(3, drugOrders.size()); + } + + @Test + public void shouldReturnVisitWisePrescribedAndOtherActiveOrdersInOrderOfStartDate() throws Exception { + executeDataSet("prescribedAndActiveDrugOrdersForVisits.xml"); + Map> drugOrders = bahmniDrugOrderController.getVisitWisePrescribedAndOtherActiveOrders("1a246ed5-3c11-11de-a0ba-001ed98eb67a", 1, true, new ArrayList(), null, null, false); + assertEquals(2, drugOrders.keySet().size()); + + assertEquals(1, drugOrders.get("visitDrugOrders").size()); + assertEquals("92c1bdef-72d4-49d9-8a1f-804892f44acf", drugOrders.get("visitDrugOrders").iterator().next().getUuid()); + + assertEquals(1, drugOrders.get("Other Active DrugOrders").size()); + assertEquals("92c1bdef-72d4-77d9-8a1f-80411ac77abe", drugOrders.get("Other Active DrugOrders").iterator().next().getUuid()); + + } + + @Test + public void shouldReturnVisitWiseEffectiveDrugOrdersInADateRange() throws Exception { + executeDataSet("prescribedAndActiveDrugOrdersForVisits.xml"); + + Map> drugOrders = bahmniDrugOrderController.getVisitWisePrescribedAndOtherActiveOrders("1a246ed5-3c11-11de-a0ba-001ed98eb67a", 5, false, new ArrayList(), "2005-09-22T18:30:00.000", "2015-01-05T18:30:00.000", true); + Iterator drugOrderIterator = drugOrders.get("visitDrugOrders").iterator(); + + assertEquals(3, drugOrders.get("visitDrugOrders").size()); + assertEquals("2015-01-03 08:00:00.0", drugOrderIterator.next().getScheduledDate().toString()); + assertEquals("2015-01-03 00:00:00.0", drugOrderIterator.next().getScheduledDate().toString()); + assertEquals("2005-09-23 00:00:00.0", drugOrderIterator.next().getScheduledDate().toString()); + } + + @Test + public void shouldReturnVisitWisePrescribedAndOtherActiveOrdersByVisitUuid() throws Exception { + executeDataSet("prescribedAndActiveDrugOrdersForVisits.xml"); + Map> drugOrders = bahmniDrugOrderController.getVisitWisePrescribedAndOtherActiveOrders("1a246ed5-3c11-11de-a0ba-001ed98eb67a", 1, true, Arrays.asList("c809162f-dc55-4814-be3f-33d23c8abc1d"),null, null, false); + assertEquals(2, drugOrders.keySet().size()); + + assertEquals(1, drugOrders.get("visitDrugOrders").size()); + assertEquals("92c1bdef-72d4-49d9-8a1f-804892f44acf", drugOrders.get("visitDrugOrders").iterator().next().getUuid()); + + assertEquals(1, drugOrders.get("Other Active DrugOrders").size()); + assertEquals("92c1bdef-72d4-77d9-8a1f-80411ac77abe", drugOrders.get("Other Active DrugOrders").iterator().next().getUuid()); + } + + @Test + public void shouldReturnVisitWisePrescribedWithoutOtherActiveOrdersInOrderOfStartDate() throws Exception { + executeDataSet("prescribedAndActiveDrugOrdersForVisits.xml"); + Map> drugOrders = bahmniDrugOrderController.getVisitWisePrescribedAndOtherActiveOrders("1a246ed5-3c11-11de-a0ba-001ed98eb67a", 2, true, new ArrayList(), null, null, false); + assertEquals(2, drugOrders.keySet().size()); + + assertEquals(5, drugOrders.get("visitDrugOrders").size()); + Iterator drugOrderIterator = drugOrders.get("visitDrugOrders").iterator(); + assertEquals("92c1bdef-72d4-77d9-8a1f-80411ac77abe", drugOrderIterator.next().getUuid()); + assertEquals("92c1bdef-72d4-77d9-8a1f-80411ac66abe", drugOrderIterator.next().getUuid()); + assertEquals("92c1bdef-72d4-88d9-8a1f-804892f66abf", drugOrderIterator.next().getUuid()); + assertEquals("92c1bdef-72d4-49d9-8a1f-804892f44acf", drugOrderIterator.next().getUuid()); + assertEquals("92c1bdef-72d4-77d9-8a1f-804892f66aba", drugOrderIterator.next().getUuid()); + + assertEquals(0, drugOrders.get("Other Active DrugOrders").size()); + + drugOrders = bahmniDrugOrderController.getVisitWisePrescribedAndOtherActiveOrders("1a246ed5-3c11-11de-a0ba-001ed98eb67a", 2, false, new ArrayList(), null, null, false); + assertEquals(1, drugOrders.keySet().size()); + assertNull(drugOrders.get("Other Active DrugOrders")); + + } + + @Test + public void shouldReturnDrugOrdersForSpecifiedNumberOfVisits() throws Exception { + executeDataSet("drugOrdersForVisits.xml"); + List prescribedDrugOrders = bahmniDrugOrderController.getPrescribedDrugOrders("86526ed5-3c11-11de-a0ba-001ed98eb67a", true, 2, null, null); + assertEquals(5, prescribedDrugOrders.size()); + + BahmniDrugOrder drugOrder1 = prescribedDrugOrders.get(0); + assertEquals("d798916f-210d-4c4e-8978-467d1a969f31", drugOrder1.getVisit().getUuid()); + EncounterTransaction.DosingInstructions dosingInstructions1 = drugOrder1.getDosingInstructions(); + assertEquals("{\"dose\": \"1.5\", \"doseUnits\": \"Tablet\"}", dosingInstructions1.getAdministrationInstructions()); + assertEquals(15, drugOrder1.getDuration(), 0); + assertEquals("Triomune-30", drugOrder1.getDrug().getName()); + assertEquals("2011-10-24 00:00:00.0", drugOrder1.getEffectiveStartDate().toString()); + assertEquals("2011-11-08 00:00:00.0", drugOrder1.getEffectiveStopDate().toString()); + + BahmniDrugOrder drugOrder2 = prescribedDrugOrders.get(1); + assertEquals("d798916f-210d-4c4e-8978-467d1a969f31", drugOrder2.getVisit().getUuid()); + EncounterTransaction.DosingInstructions dosingInstructions2 = drugOrder2.getDosingInstructions(); + assertEquals(4.5, dosingInstructions2.getDose(), 0); + assertEquals("Before meals", drugOrder2.getInstructions()); + assertEquals("Take while sleeping", drugOrder2.getCommentToFulfiller()); + assertEquals("1/day x 7 days/week", dosingInstructions2.getFrequency()); + assertEquals("UNKNOWN", dosingInstructions2.getRoute()); + assertEquals(6, drugOrder2.getDuration(), 0); + assertEquals("Paracetamol 250 mg", drugOrder2.getDrug().getName()); + assertEquals("2011-10-22 00:00:00.0", drugOrder2.getEffectiveStartDate().toString()); + assertEquals("2011-10-30 00:00:00.0", drugOrder2.getEffectiveStopDate().toString()); + + BahmniDrugOrder drugOrder3 = prescribedDrugOrders.get(2); + assertEquals("adf4fb41-a41a-4ad6-8835-2f59889acf5a", drugOrder3.getVisit().getUuid()); + EncounterTransaction.DosingInstructions dosingInstructions3 = drugOrder3.getDosingInstructions(); + assertEquals("{\"dose\": \"5.0\", \"doseUnits\": \"Tablet\"}", dosingInstructions3.getAdministrationInstructions()); + assertEquals("tab (s)", drugOrder3.getDrug().getForm()); + assertEquals(6, drugOrder3.getDuration(), 0); + assertEquals("Triomune-30", drugOrder3.getDrug().getName()); + assertEquals("2005-09-23 08:00:00.0", drugOrder3.getEffectiveStartDate().toString()); + assertEquals("2005-09-30 00:00:00.0", drugOrder3.getEffectiveStopDate().toString()); + assertEquals(1, drugOrder3.getOrderAttributes().size()); + assertEquals("dispensed", drugOrder3.getOrderAttributes().get(0).getName()); + assertEquals("true", drugOrder3.getOrderAttributes().get(0).getValue()); + assertEquals("be48cdcb-6666-47e3-9f2e-2635032f3a9a", drugOrder3.getOrderAttributes().get(0).getObsUuid()); + assertNotNull(drugOrder3.getOrderAttributes().get(0).getEncounterUuid()); + + BahmniDrugOrder drugOrder4 = prescribedDrugOrders.get(3); + assertEquals("adf4fb41-a41a-4ad6-8835-2f59889acf5a", drugOrder4.getVisit().getUuid()); + EncounterTransaction.DosingInstructions dosingInstructions4 = drugOrder4.getDosingInstructions(); + assertEquals("{\"dose\": \"2.5\", \"doseUnits\": \"Tablet\"}", dosingInstructions4.getAdministrationInstructions()); + assertEquals(6, drugOrder4.getDuration(), 0); + assertEquals("Triomune-40", drugOrder4.getDrug().getName()); + assertEquals("2005-09-23 00:00:00.0", drugOrder4.getEffectiveStartDate().toString()); + assertEquals("2005-09-29 00:00:00.0", drugOrder4.getEffectiveStopDate().toString()); + + BahmniDrugOrder drugOrder5 = prescribedDrugOrders.get(4); + assertEquals("d798916f-210d-4c4e-8978-467d1a969f31", drugOrder5.getVisit().getUuid()); + assertEquals("FreeTextDrug", drugOrder5.getDrugNonCoded()); + EncounterTransaction.DosingInstructions dosingInstructions5 = drugOrder5.getDosingInstructions(); + assertEquals("{\"dose\": \"1.5\", \"doseUnits\": \"Tablet\"}", dosingInstructions5.getAdministrationInstructions()); + assertEquals(15, drugOrder5.getDuration(), 0); + assertEquals(null, drugOrder5.getDrug()); + assertEquals("2005-09-23 00:00:00.0", drugOrder5.getEffectiveStartDate().toString()); + assertEquals("2005-09-23 00:00:00.0", drugOrder5.getEffectiveStopDate().toString()); + } + + @Test + public void shouldReturnAllDrugOrdersForGivenConceptSet() throws Exception { + executeDataSet("allDrugOrdersForConcepts.xml"); + List allDrugOrders = bahmniDrugOrderController.getDrugOrderDetails("1a246ed5-3c11-3456-wenh-001ed98eb612", null, "All TB Drugs", null, null); + assertEquals(5, allDrugOrders.size()); + assertThat(getOrderUuids(allDrugOrders), hasItems("6d0ae116-ewrg-4629-9850-f15205e63ab0", "6d0ae116-5r45-4629-9850-f15205e63ab0", "6d0ae116-707a-4629-iop6-f15205e63ab0", + "6d0ae116-707a-4629-wenm-f15205e63ab0", "6d0ae116-ewrg-4629-9850-f15205e6bgop")); + } + + @Test + public void shouldReturnActiveDrugOrdersForGivenConceptSet() throws Exception { + executeDataSet("allDrugOrdersForConcepts.xml"); + List activeDrugOrders = bahmniDrugOrderController.getDrugOrderDetails("1a246ed5-3c11-3456-wenh-001ed98eb612", true, "All TB Drugs", null, null); + assertEquals(1, activeDrugOrders.size()); + assertThat(getOrderUuids(activeDrugOrders), hasItems("6d0ae116-ewrg-4629-9850-f15205e6bgop")); + } + + @Test + public void shouldReturnInactiveDrugOrdersForGivenConceptSet() throws Exception { + executeDataSet("allDrugOrdersForConcepts.xml"); + List inactiveDrugOrders = bahmniDrugOrderController.getDrugOrderDetails("1a246ed5-3c11-3456-wenh-001ed98eb612", false, "All TB Drugs", null, null); + assertEquals(4, inactiveDrugOrders.size()); + assertThat(getOrderUuids(inactiveDrugOrders), hasItems("6d0ae116-ewrg-4629-9850-f15205e63ab0", "6d0ae116-5r45-4629-9850-f15205e63ab0", "6d0ae116-707a-4629-iop6-f15205e63ab0", + "6d0ae116-707a-4629-wenm-f15205e63ab0")); + } + + @Test + public void shouldReturnAllDrugOrderExceptForGivenConceptSet() throws Exception{ + executeDataSet("allDrugOrdersForConcepts.xml"); + List allDrugOrders = bahmniDrugOrderController.getDrugOrderDetails("1a246ed5-3c11-3456-wenh-001ed98eb612", null, null, "All TB Drugs", null); + assertEquals(2, allDrugOrders.size()); + assertEquals("6d0ae116-ewrg-4629-9850-f15205e6bgoq", allDrugOrders.get(0).getUuid()); + assertEquals("6d0ae116-ewrg-4629-9850-f15205e6bgoh", allDrugOrders.get(1).getUuid()); + } + + @Test + public void shouldReturnActiveDrugOrderExceptForGivenConceptSet() throws Exception{ + executeDataSet("allDrugOrdersForConcepts.xml"); + List activeDrugOrders = bahmniDrugOrderController.getDrugOrderDetails("1a246ed5-3c11-3456-wenh-001ed98eb612", true, null, "All TB Drugs", null); + assertEquals(1, activeDrugOrders.size()); + assertEquals("6d0ae116-ewrg-4629-9850-f15205e6bgoq", activeDrugOrders.get(0).getUuid()); + } + + @Test + public void shouldReturnInactiveDrugOrderExceptForGivenConceptSet() throws Exception{ + executeDataSet("allDrugOrdersForConcepts.xml"); + List inactiveDrugOrders = bahmniDrugOrderController.getDrugOrderDetails("1a246ed5-3c11-3456-wenh-001ed98eb612", false, null, "All TB Drugs", null); + assertEquals(1, inactiveDrugOrders.size()); + assertEquals("6d0ae116-ewrg-4629-9850-f15205e6bgoh", inactiveDrugOrders.get(0).getUuid()); + } + + @Test + public void shouldReturnDrugOrderByOrderId() throws Exception { + executeDataSet("prescribedAndActiveDrugOrdersForVisits.xml"); + BahmniDrugOrder drugOrder = bahmniDrugOrderController.getDrugOrderByOrderId("6d0ae116-707a-4629-9850-f15205e63ab0"); + assertEquals("6d0ae116-707a-4629-9850-f15205e63ab0", drugOrder.getUuid()); + } + + private List getOrderUuids(List bahmniDrugOrders) { + ArrayList orderUuids = new ArrayList<>(); + for (BahmniDrugOrder drugOrder : bahmniDrugOrders) { + orderUuids.add(drugOrder.getUuid()); + } + return orderUuids; + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerTest.java new file mode 100644 index 0000000000..9ba211900f --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniDrugOrderControllerTest.java @@ -0,0 +1,47 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.api.ConceptService; + +import java.util.Set; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(MockitoJUnitRunner.class) +public class BahmniDrugOrderControllerTest { + + @Mock + ConceptService conceptService; + @Mock + BahmniDrugOrderService bahmniDrugOrderService; + + @InjectMocks + BahmniDrugOrderController bahmniDrugOrderController; + + @Before + public void setUp() throws Exception { + initMocks(this); + } + + @Test + public void shouldReturnNullIfConceptNotFound() throws Exception { + String drugConceptSetName = "All TB Drugs"; + when(conceptService.getConceptByName(drugConceptSetName)).thenReturn(null); + Set drugConcepts = bahmniDrugOrderController.getDrugConcepts(drugConceptSetName); + assertNull(drugConcepts); + } + + @Test + public void shouldReturnNullIfDrugConceptNameIsNull() { + Set drugConcepts = bahmniDrugOrderController.getDrugConcepts(null); + assertNull(drugConcepts); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerIT.java new file mode 100644 index 0000000000..f547bc0a37 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerIT.java @@ -0,0 +1,193 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.Location; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder; +import org.openmrs.module.bahmniemrapi.builder.ETConceptBuilder; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosis; +import org.openmrs.module.bahmniemrapi.diagnosis.contract.BahmniDiagnosisRequest; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.diagnosis.Diagnosis; +import org.openmrs.module.emrapi.encounter.EmrEncounterService; +import org.openmrs.module.emrapi.encounter.EmrEncounterServiceImpl; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.module.emrapi.encounter.postprocessor.EncounterTransactionHandler; +import org.openmrs.obs.ComplexData; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.*; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@Ignore +public class BahmniEncounterControllerIT extends BaseIntegrationTest { + + @Autowired + private VisitService visitService; + @Autowired + private BahmniEncounterController bahmniEncounterController; + + @Before + public void setUp() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("setup.xml"); + } + + @Test + public void shouldSaveNewEncounterWithLocationComplexObsHandler() throws Exception { + BahmniEncounterTransaction bahmniEncounterTransaction = bahmniEncounterTransaction(); + Concept weight = Context.getConceptService().getConceptByName("Weight"); + //EncounterTransaction.Concept weightConcept = new ETConceptBuilder().withName("Weight").withUuid("5d2d4cb7-955b-4837-80f7-0ebb94044444").withSet(false).withClass("Finding").build(); + EncounterTransaction.Concept locationConcept = new ETConceptBuilder().withName("Location Name").withUuid("edd25bd1-56ef-4382-afda-4e15a33ad33a").withSet(false).withClass("Finding").build(); + + System.out.println(weight.getDatatype()); + bahmniEncounterTransaction.setObservations(new ArrayList() {{ + //this.add(new org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder().withConcept(weightConcept).withValue("71").withObsDateTime(new Date()).build()); + this.add(new org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder().withConcept(locationConcept).withValue("12").withObsDateTime(new Date()).build()); + }}); + BahmniEncounterTransaction encounterTransaction = bahmniEncounterController.update(bahmniEncounterTransaction); + Collection bahmniObservations = encounterTransaction.getObservations(); + Assert.assertEquals(1, bahmniObservations.size()); + BahmniObservation observation = bahmniObservations.iterator().next(); + Serializable obsData = observation.getComplexData(); + Assert.assertEquals(HashMap.class, obsData.getClass()); + Assert.assertEquals("Location", ((Map)obsData).get("dataType")); + + Object locationData = ((Map) obsData).get("data"); + Assert.assertEquals(HashMap.class, locationData.getClass()); + + Assert.assertEquals("LAB", ((Map)locationData).get("name")); + Assert.assertEquals(Integer.valueOf("12"), ((Map)locationData).get("id")); + + } + + @Test + @Ignore + public void shouldSaveNewDiagnosisWithinTheSameEncounterSession() throws Exception { + BahmniEncounterTransaction bahmniEncounterTransaction = bahmniEncounterTransaction(); + final String comments = "High fever and symptoms indicate Malaria"; + bahmniEncounterTransaction.setBahmniDiagnoses(new ArrayList() { + { + this.add(new BahmniDiagnosisRequest() {{ + this.setCertainty(Diagnosis.Certainty.CONFIRMED.name()); + this.setOrder(Diagnosis.Order.PRIMARY.name()); + this.setCodedAnswer(new EncounterTransaction.Concept("d102c80f-1yz9-4da3-bb88-8122ce8868dh")); + this.setDiagnosisStatusConcept(new EncounterTransaction.Concept(null, "Ruled Out")); + this.setComments(comments); + }}); + } + }); + + BahmniEncounterTransaction encounterTransaction = bahmniEncounterController.update(bahmniEncounterTransaction); + assertEquals("1e5d5d48-6b78-11e0-93c3-18a905e044dc", encounterTransaction.getVisitUuid()); + assertEquals(1, encounterTransaction.getBahmniDiagnoses().size()); + final BahmniDiagnosis bahmniDiagnosisAfterFirstSave = encounterTransaction.getBahmniDiagnoses().get(0); + assertDiagnosis(bahmniDiagnosisAfterFirstSave, Diagnosis.Certainty.CONFIRMED, Diagnosis.Order.PRIMARY, "Ruled Out", false, comments); + assertDiagnosis(bahmniDiagnosisAfterFirstSave.getFirstDiagnosis(), Diagnosis.Certainty.CONFIRMED, Diagnosis.Order.PRIMARY, "Ruled Out", false, comments); + + bahmniEncounterTransaction.setBahmniDiagnoses(new ArrayList() { + { + this.add(new BahmniDiagnosisRequest() {{ + this.setCertainty(Diagnosis.Certainty.PRESUMED.name()); + this.setOrder(Diagnosis.Order.SECONDARY.name()); + this.setCodedAnswer(new EncounterTransaction.Concept("d102c80f-1yz9-4da3-bb88-8122ce8868dh")); + this.setExistingObs(bahmniDiagnosisAfterFirstSave.getExistingObs()); + this.setFirstDiagnosis(bahmniDiagnosisAfterFirstSave); + }}); + } + }); + encounterTransaction = bahmniEncounterController.update(bahmniEncounterTransaction); + final BahmniDiagnosis bahmniDiagnosisAfterSecondSave = encounterTransaction.getBahmniDiagnoses().get(0); + assertDiagnosis(bahmniDiagnosisAfterSecondSave, Diagnosis.Certainty.PRESUMED, Diagnosis.Order.SECONDARY, null, false, null); + assertDiagnosis(bahmniDiagnosisAfterSecondSave.getFirstDiagnosis(), Diagnosis.Certainty.PRESUMED, Diagnosis.Order.SECONDARY, null, false, null); + Context.flushSession(); + closeVisit(encounterTransaction.getVisitUuid()); + } + + @Test + @Ignore + public void shouldUpdateDiagnosisFromAnotherVisit() throws Exception { + BahmniEncounterTransaction encounterTransactionForFirstVisit = bahmniEncounterTransaction(); + encounterTransactionForFirstVisit.setBahmniDiagnoses(new ArrayList() { + { + this.add(new BahmniDiagnosisRequest() {{ + this.setCertainty(Diagnosis.Certainty.PRESUMED.name()); + this.setOrder(Diagnosis.Order.SECONDARY.name()); + this.setCodedAnswer(new EncounterTransaction.Concept("d102c80f-1yz9-4da3-bb88-8122ce8868dh")); + }}); + } + }); + BahmniEncounterTransaction firstEncounterTransaction = bahmniEncounterController.update(encounterTransactionForFirstVisit); + closeVisit(firstEncounterTransaction.getVisitUuid()); + + final BahmniDiagnosis bahmniDiagnosisAfterFirstSave = firstEncounterTransaction.getBahmniDiagnoses().get(0); + assertDiagnosis(bahmniDiagnosisAfterFirstSave, Diagnosis.Certainty.PRESUMED, Diagnosis.Order.SECONDARY, null, false, null); + + BahmniEncounterTransaction encounterTransactionForSecondVisit = bahmniEncounterTransaction(); + encounterTransactionForSecondVisit.setBahmniDiagnoses(new ArrayList() { + { + this.add(new BahmniDiagnosisRequest() {{ + this.setCertainty(Diagnosis.Certainty.CONFIRMED.name()); + this.setOrder(Diagnosis.Order.PRIMARY.name()); + this.setCodedAnswer(new EncounterTransaction.Concept("d102c80f-1yz9-4da3-bb88-8122ce8868dh")); + this.setDiagnosisStatusConcept(new EncounterTransaction.Concept(null, "Ruled Out")); + this.setExistingObs(null); + this.setPreviousObs(bahmniDiagnosisAfterFirstSave.getExistingObs()); + this.setFirstDiagnosis(bahmniDiagnosisAfterFirstSave); + }}); + } + }); + BahmniEncounterTransaction secondEncounterTransaction = bahmniEncounterController.update(encounterTransactionForSecondVisit); + assertThat(firstEncounterTransaction.getEncounterUuid(), is(not(equalTo(secondEncounterTransaction.getEncounterUuid())))); + + final BahmniDiagnosis bahmniDiagnosisAfterSecondSave = secondEncounterTransaction.getBahmniDiagnoses().get(0); + assertThat(bahmniDiagnosisAfterFirstSave.getExistingObs(), is(not(equalTo(bahmniDiagnosisAfterSecondSave.getExistingObs())))); + assertDiagnosis(bahmniDiagnosisAfterSecondSave, Diagnosis.Certainty.CONFIRMED, Diagnosis.Order.PRIMARY, "Ruled Out", false, null); + assertDiagnosis(bahmniDiagnosisAfterSecondSave.getFirstDiagnosis(), Diagnosis.Certainty.PRESUMED, Diagnosis.Order.SECONDARY, null, true, null); + BahmniEncounterTransaction bahmniEncounterTransaction = bahmniEncounterController.get(firstEncounterTransaction.getEncounterUuid()); + assertTrue(bahmniEncounterTransaction.getBahmniDiagnoses().get(0).isRevised()); + + Context.flushSession(); + } + + private void closeVisit(String visitUuid) { + Visit visit = visitService.getVisitByUuid(visitUuid); + visit.setStopDatetime(new Date()); + visitService.saveVisit(visit); + } + + private void assertDiagnosis(BahmniDiagnosis bahmniDiagnosis, Diagnosis.Certainty certainty, Diagnosis.Order order, String status, boolean isRevised, String comments) { + assertEquals(certainty.name(), bahmniDiagnosis.getCertainty()); + assertEquals(order.name(), bahmniDiagnosis.getOrder()); + if (status != null) { + assertEquals(status, bahmniDiagnosis.getDiagnosisStatusConcept().getName()); + } + assertEquals(isRevised, bahmniDiagnosis.isRevised()); + assertEquals(comments, bahmniDiagnosis.getComments()); + } + + private BahmniEncounterTransaction bahmniEncounterTransaction() { + BahmniEncounterTransaction bahmniEncounterTransaction = new BahmniEncounterTransaction(); + bahmniEncounterTransaction.setPatientUuid("a76e8d23-0c38-408c-b2a8-ea5540f01b51"); + bahmniEncounterTransaction.setVisitTypeUuid("b45ca846-c79a-11e2-b0c0-8e397087571c"); + bahmniEncounterTransaction.setEncounterTypeUuid("2b377dba-62c3-4e53-91ef-b51c68899890"); + return bahmniEncounterTransaction; + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java new file mode 100644 index 0000000000..22412cc755 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniEncounterControllerTest.java @@ -0,0 +1,114 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.web.v1_0.VisitClosedException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Encounter; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderEntryException; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterSearchParameters; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.BahmniEncounterTransactionMapper; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.BahmniEncounterTransactionService; +import org.openmrs.module.emrapi.encounter.EmrEncounterService; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.when; + +public class BahmniEncounterControllerTest { + @Mock + private EmrEncounterService emrEncounterService; + @Mock + private BahmniEncounterTransactionMapper bahmniEncounterTransactionMapper; + @Mock + private BahmniEncounterTransactionService bahmniEncounterTransactionService; + + @Mock + private EncounterService encounterService; + private BahmniEncounterController bahmniEncounterController; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void returnsMultipleEncounterTransactionsIfExists() throws Exception { + EncounterTransaction et1 = new EncounterTransaction(); + et1.setEncounterUuid("et1"); + + BahmniEncounterSearchParameters encounterSearchParameters = new BahmniEncounterSearchParameters(); + encounterSearchParameters.setIncludeAll(false); + + when(bahmniEncounterTransactionService.find(encounterSearchParameters)).thenReturn(et1); + when(bahmniEncounterTransactionMapper.map(et1, false)).thenReturn(new BahmniEncounterTransaction(et1)); + + bahmniEncounterController = new BahmniEncounterController(null, emrEncounterService, null, bahmniEncounterTransactionService, bahmniEncounterTransactionMapper); + + BahmniEncounterTransaction bahmniEncounterTransaction = bahmniEncounterController.find(encounterSearchParameters); + + assertEquals(et1.getEncounterUuid(), bahmniEncounterTransaction.getEncounterUuid()); + } + + @Test + public void shouldReturnEmptyEncounterTransactionIfThereAreNoEncountersExists() throws Exception { + BahmniEncounterSearchParameters encounterSearchParameters = new BahmniEncounterSearchParameters(); + encounterSearchParameters.setIncludeAll(false); + + when(emrEncounterService.find(encounterSearchParameters)).thenReturn(null); + when(bahmniEncounterTransactionMapper.map(any(EncounterTransaction.class), anyBoolean())).thenReturn(new BahmniEncounterTransaction(new EncounterTransaction())); + + bahmniEncounterController = new BahmniEncounterController(null, emrEncounterService, null, bahmniEncounterTransactionService, bahmniEncounterTransactionMapper); + BahmniEncounterTransaction bahmniEncounterTransactions = bahmniEncounterController.find(encounterSearchParameters); + + assertNull(bahmniEncounterTransactions.getEncounterUuid()); + } + + @Test(expected=VisitClosedException.class) + public void shouldThrowVisitClosedExceptionIfEncounterVisitIsClosed() throws Exception{ + DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Visit visit = new Visit(); + visit.setId(123); + visit.setStopDatetime(format.parse("2016-03-08 12:46:46")); + + Encounter encounter = new Encounter(); + encounter.setId(321); + encounter.setUuid("410491d2-b617-42ad-bf0f-de2fc9b42998"); + encounter.setVisit(visit); + + bahmniEncounterController = new BahmniEncounterController(encounterService, emrEncounterService, null, bahmniEncounterTransactionService, bahmniEncounterTransactionMapper); + + when(encounterService.getEncounterByUuid("410491d2-b617-42ad-bf0f-de2fc9b42998")).thenReturn(encounter); + + bahmniEncounterController.delete("410491d2-b617-42ad-bf0f-de2fc9b42998","Undo Discharge"); + } + @Test + public void shouldThrowBadRequestStatusCodeForOrderEntryException() throws Exception{ + bahmniEncounterController = new BahmniEncounterController(encounterService, emrEncounterService, null, bahmniEncounterTransactionService, bahmniEncounterTransactionMapper); + + OrderEntryException mockException = new OrderEntryException("Order.cannot.have.more.than.one"); + + ResponseEntity response = bahmniEncounterController.handleOrderEntryException(mockException); + + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + + Map responseBody = (Map) response.getBody(); + Map errorBody = (Map) responseBody.get("error"); + + assertEquals("[Order.cannot.have.more.than.one]", errorBody.get("message")); + } + +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsControllerIT.java new file mode 100644 index 0000000000..42fa79be10 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsControllerIT.java @@ -0,0 +1,110 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.model.Provider; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; +import static org.junit.Assert.assertEquals; + +public class BahmniFormDetailsControllerIT extends BaseIntegrationTest { + + @Autowired + private BahmniFormDetailsController bahmniFormDetailsController; + + private Provider superUser = new Provider(); + private Provider bruno = new Provider(); + + @Before + public void setUp() throws Exception { + executeDataSet("formBuilderObs.xml"); + + superUser.setProviderName("Super User"); + superUser.setUuid("1010d442-e134-11de-babe-001e378eb67e"); + + bruno.setProviderName("Bruno Otterbourg"); + bruno.setUuid("c1d8f5c2-e131-11de-babe-001e378eb67e"); + } + + @Test + public void shouldReturnFormDetailsUsingPatientUuidForFormTypeOfV2() { + Collection formDetailsCollection = bahmniFormDetailsController + .getFormDetails("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", "v2", -1, null, null); + + assertEquals(2, formDetailsCollection.size()); + Iterator formDetailsIterator = formDetailsCollection.iterator(); + verifyBloodSampleFormDetails(formDetailsIterator.next()); + verifyVitalFormDetails(formDetailsIterator.next()); + } + + @Test + public void shouldReturnFormDetailsUsingPatientUuidAndNumberOfNumberOfVisitsForFormTypeOfV2() { + Collection formDetailsCollection = bahmniFormDetailsController + .getFormDetails("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", "v2", 2, null, null); + + assertEquals(1, formDetailsCollection.size()); + verifyBloodSampleFormDetails(formDetailsCollection.iterator().next()); + } + + @Test + public void shouldReturnFormDetailsUsingPatientUuidAndVisitUuidForFormTypeOfV2() { + Collection formDetailsCollection = bahmniFormDetailsController + .getFormDetails("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", "v2", -1, "1e5d5d48-6b78-11e0-93c3-18a905e044dc", null); + + assertEquals(1, formDetailsCollection.size()); + verifyVitalFormDetails(formDetailsCollection.iterator().next()); + } + + @Test + public void shouldReturnFormDetailsUsingPatientUuidAndPatientProgramUuidForFormTypeOfV2() { + Collection formDetailsCollection = bahmniFormDetailsController + .getFormDetails("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", "v2", -1, null, "b75462a0-4c92-451e-b8bc-e98b38b76534"); + + assertEquals(1, formDetailsCollection.size()); + verifyVitalFormDetails(formDetailsCollection.iterator().next()); + } + + @Test + public void shouldReturnFormDetailsUsingPatientUuidPatientProgramUuidAndVisitUuidForFormTypeOfV2() { + Collection formDetailsCollection = bahmniFormDetailsController + .getFormDetails("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", "v2", -1, "1e5d5d48-6b78-11e0-93c3-18a905e044dc", "b75462a0-4c92-451e-b8bc-e98b38b76534"); + + assertEquals(1, formDetailsCollection.size()); + verifyVitalFormDetails(formDetailsCollection.iterator().next()); + } + + private void verifyBloodSampleFormDetails(FormDetails bloodSampleFormDetails) { + assertEquals("v2", bloodSampleFormDetails.getFormType()); + assertEquals("BloodSample", bloodSampleFormDetails.getFormName()); + assertEquals(2, bloodSampleFormDetails.getFormVersion()); + assertEquals("fcf11e2c-e59c-11e8-9f32-f2801f1b9fd1", bloodSampleFormDetails.getEncounterUuid()); + assertEquals("2018-11-08 00:10:00.0", bloodSampleFormDetails.getEncounterDateTime().toString()); + assertEquals("4e663d66-6b78-11e0-93c3-18a905e044dc", bloodSampleFormDetails.getVisitUuid()); + assertEquals("2005-01-01 00:00:00.0", bloodSampleFormDetails.getVisitStartDateTime().toString()); + + assertEquals(1, bloodSampleFormDetails.getProviders().size()); + assertEquals(superUser, bloodSampleFormDetails.getProviders().iterator().next()); + } + + private void verifyVitalFormDetails(FormDetails vitalsFormDetails) { + assertEquals("v2", vitalsFormDetails.getFormType()); + assertEquals("Vitals", vitalsFormDetails.getFormName()); + assertEquals(1, vitalsFormDetails.getFormVersion()); + assertEquals("66f59ecc-e59a-11e8-9f32-f2801f1b9fd1", vitalsFormDetails.getEncounterUuid()); + assertEquals("2018-11-08 00:00:00.0", vitalsFormDetails.getEncounterDateTime().toString()); + assertEquals("1e5d5d48-6b78-11e0-93c3-18a905e044dc", vitalsFormDetails.getVisitUuid()); + assertEquals("2005-01-01 00:00:00.0", vitalsFormDetails.getVisitStartDateTime().toString()); + + assertEquals(2, vitalsFormDetails.getProviders().size()); + containsInAnyOrder(Arrays.asList(superUser, bruno), vitalsFormDetails.getProviders()); + } + + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsControllerTest.java new file mode 100644 index 0000000000..388ae84047 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniFormDetailsControllerTest.java @@ -0,0 +1,63 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.forms2.contract.FormDetails; +import org.bahmni.module.bahmnicore.forms2.contract.FormType; +import org.bahmni.module.bahmnicore.forms2.service.BahmniFormDetailsService; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +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 BahmniFormDetailsControllerTest { + + private BahmniFormDetailsController bahmniFormDetailsController; + + private BahmniFormDetailsService bahmniFormDetailsService = mock(BahmniFormDetailsService.class); + + private String patientUuid = "provider-uuid"; + private String formType = "v2"; + private String visitUuid = "visitUuid"; + private String patientProgramUuid = "patientProgramUuid"; + + @Before + public void setUp() { + bahmniFormDetailsController = new BahmniFormDetailsController(bahmniFormDetailsService); + } + + @Test + public void shouldReturnCollectionOfFormDetailsGivenPatienUuidFormTypeAndNumberOfVisits() { + FormDetails formDetails = mock(FormDetails.class); + when(bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, -1)) + .thenReturn(Collections.singletonList(formDetails)); + + Collection actualFormDetails = bahmniFormDetailsController.getFormDetails(patientUuid, formType, -1, null, null); + + assertFormDetails(formDetails, actualFormDetails); + verify(bahmniFormDetailsService, times(1)).getFormDetails(patientUuid, FormType.FORMS2, -1); + } + + private void assertFormDetails(FormDetails formDetails, Collection actualFormDetails) { + assertEquals(1, actualFormDetails.size()); + assertEquals(formDetails, actualFormDetails.iterator().next()); + } + + @Test + public void shouldReturnCollectionOfFormDetailsGivenPatientUuidFormTypeVisitUuidAndPatientProgramUuid() { + FormDetails formDetails = mock(FormDetails.class); + + when(bahmniFormDetailsService.getFormDetails(patientUuid, FormType.FORMS2, visitUuid, patientProgramUuid)) + .thenReturn(Collections.singletonList(formDetails)); + + Collection actualFormDetails = bahmniFormDetailsController.getFormDetails(patientUuid, formType, -1, visitUuid, patientProgramUuid); + + assertFormDetails(formDetails, actualFormDetails); + verify(bahmniFormDetailsService, times(1)).getFormDetails(patientUuid, FormType.FORMS2, visitUuid, patientProgramUuid); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniLabOrderResultControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniLabOrderResultControllerIT.java new file mode 100644 index 0000000000..1b53d55f12 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniLabOrderResultControllerIT.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResults; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@Ignore +public class BahmniLabOrderResultControllerIT extends BaseIntegrationTest { + + + private String LAB_ORDER_URL = "/rest/v1/bahmnicore/labOrderResults"; + private String PERSON_UUID = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + + @Before + public void setUp() throws Exception { + executeDataSet("diagnosisMetaData.xml"); + executeDataSet("dispositionMetaData.xml"); + executeDataSet("labOrderTestData.xml"); + } + + @Test + //todo: add more good assert statements + public void shouldFindLabOrderResultsForMultipleVisitUuids() throws Exception { + MockHttpServletRequest mockHttpServletRequest = newGetRequest(LAB_ORDER_URL, + new Parameter("visitUuids", "ad41ef34-a41a-4ad6-8835-2f59099acf5a"), + new Parameter("visitUuids", "9d705396-0c0c-11e4-bb80-f18addb6f9bb")); + MockHttpServletResponse response = handle(mockHttpServletRequest); + LabOrderResults labOrderResults = deserialize(response, LabOrderResults.class); + } + + @Test + //todo: add more good assert statements + public void shouldReturnSpecifiedVisitsWhenQueried() throws Exception { + MockHttpServletRequest mockHttpServletRequest = newGetRequest(LAB_ORDER_URL, + new Parameter("patientUuid", PERSON_UUID), + new Parameter("numberOfVisits", "1")); + MockHttpServletResponse response = handle(mockHttpServletRequest); + LabOrderResults labOrderResults = deserialize(response, LabOrderResults.class); + assertNotNull(labOrderResults); + assertEquals(labOrderResults.getResults().size(), 1); + assertEquals(labOrderResults.getResults().get(0).getTestName(),"PS for Malaria"); + } + + @Test + public void shouldReturnForAllVisitsIfNoneSpecified() throws Exception { + MockHttpServletRequest mockHttpServletRequest = newGetRequest(LAB_ORDER_URL, + new Parameter("patientUuid", PERSON_UUID)); + MockHttpServletResponse response = handle(mockHttpServletRequest); + LabOrderResults labOrderResults = deserialize(response, LabOrderResults.class); + assertNotNull(labOrderResults); + assertEquals(labOrderResults.getResults().size(), 6); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniLabOrderResultControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniLabOrderResultControllerTest.java new file mode 100644 index 0000000000..812249b1f9 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniLabOrderResultControllerTest.java @@ -0,0 +1,55 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.dao.OrderDao; +import org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls.BahmniLabOrderResultController; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Patient; +import org.openmrs.Visit; +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 java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class BahmniLabOrderResultControllerTest { + + @Mock + private OrderDao orderDao; + @Mock + private LabOrderResultsService labOrderResultsService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void shouldDelegateRetrievingLabOrderResultsToOrderDao() { + BahmniLabOrderResultController controller = new BahmniLabOrderResultController(null, orderDao, labOrderResultsService); + Patient patient = new Patient(); + Visit visit = new Visit(); + visit.setPatient(patient); + List expectedVisits = Arrays.asList(visit); + + when(orderDao.getVisitsForUUids(new String[]{"visitUuid1", "visitUuid2"})).thenReturn(expectedVisits); + LabOrderResults expectedLabOrderResults = new LabOrderResults(new ArrayList()); + when(labOrderResultsService.getAll(patient, expectedVisits, Integer.MAX_VALUE)).thenReturn(expectedLabOrderResults); + + LabOrderResults actualLabOrderResults = controller.getForVisitUuids(new String[]{"visitUuid1", "visitUuid2"}); + + assertThat(actualLabOrderResults, is(equalTo(expectedLabOrderResults))); + verify(orderDao).getVisitsForUUids(new String[]{"visitUuid1", "visitUuid2"}); + verify(labOrderResultsService).getAll(patient,expectedVisits, Integer.MAX_VALUE); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java new file mode 100644 index 0000000000..3bf0c24cee --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java @@ -0,0 +1,177 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls.BahmniObservationsController; +import org.bahmni.test.builder.VisitBuilder; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +public class BahmniObservationsControllerTest { + + @Mock + private BahmniObsService bahmniObsService; + @Mock + private ConceptService conceptService; + @Mock + private VisitService visitService; + @Mock + private BahmniExtensions bahmniExtensions; + + private Visit visit; + private Concept concept; + private BahmniObservationsController bahmniObservationsController; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + visit = new VisitBuilder().build(); + concept = new Concept(); + bahmniObservationsController = new BahmniObservationsController(bahmniObsService, conceptService, visitService, bahmniExtensions); + when(visitService.getVisitByUuid("visitId")).thenReturn(visit); + when(conceptService.getConceptByName("Weight")).thenReturn(concept); + } + + @Test + public void returnLatestObservations() throws Exception { + BahmniObservation latestObs = new BahmniObservation(); + latestObs.setUuid("initialId"); + when(bahmniObsService.getLatestObsByVisit(visit, Arrays.asList(concept), null, true)).thenReturn(Arrays.asList(latestObs)); + + Collection bahmniObservations = bahmniObservationsController.get("visitId", "latest", Arrays.asList("Weight"), null, true); + + verify(bahmniObsService, never()).getInitialObsByVisit(visit, Arrays.asList(concept), null, false); + assertEquals(1, bahmniObservations.size()); + } + + @Test + public void returnInitialObservation() throws Exception { + EncounterTransaction.Concept cpt = new EncounterTransaction.Concept(); + cpt.setShortName("Concept1"); + + BahmniObservation initialObs = new BahmniObservation(); + initialObs.setUuid("initialId"); + initialObs.setConcept(cpt); + + when(bahmniObsService.getInitialObsByVisit(visit, Arrays.asList(this.concept), null, true)).thenReturn(Arrays.asList(initialObs)); + + Collection bahmniObservations = bahmniObservationsController.get("visitId", "initial", Arrays.asList("Weight"), null, true); + + assertEquals(1, bahmniObservations.size()); + } + + @Test + public void returnAllObservations() throws Exception { + BahmniObservation obs = new BahmniObservation(); + List conceptNames = Arrays.asList("Weight"); + ArrayList obsIgnoreList = new ArrayList<>(); + when(bahmniObsService.getObservationForVisit("visitId", conceptNames, obsIgnoreList, true, null)).thenReturn(Arrays.asList(obs)); + + Collection bahmniObservations = bahmniObservationsController.get("visitId", null, conceptNames, null, true); + + verify(bahmniObsService, never()).getLatestObsByVisit(visit, Arrays.asList(concept), null, false); + verify(bahmniObsService, never()).getInitialObsByVisit(visit, Arrays.asList(concept), null, false); + verify(bahmniObsService, times(1)).getObservationForVisit("visitId", conceptNames, obsIgnoreList, true, null); + + assertEquals(1, bahmniObservations.size()); + } + + @Test + public void shouldMakeACallToGetObsForEncounterAndConceptsSpecified() throws Exception { + ArrayList conceptNames = new ArrayList<>(); + String encounterUuid = "encounterUuid"; + String obsUuid = "ObsUuid"; + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(new BahmniObservationBuilder().withUuid(obsUuid).build()); + when(bahmniObsService.getObservationsForEncounter(encounterUuid, conceptNames)).thenReturn(bahmniObservations); + + Collection actualResult = bahmniObservationsController.get(encounterUuid, conceptNames); + + verify(bahmniObsService, times(1)).getObservationsForEncounter(encounterUuid, conceptNames); + assertEquals(1, actualResult.size()); + assertEquals(obsUuid, actualResult.iterator().next().getUuid()); + } + + @Test + public void shouldGetObsForPatientProgramWhenPatientProgramUuidIsSpecified() throws Exception { + String patientProgramUuid = "patientProgramUuid"; + List conceptNames = Arrays.asList("Weight"); + when(bahmniExtensions.getExtension("observationsAdder","CurrentMonthOfTreatment.groovy")).thenReturn(null); + + bahmniObservationsController.get(patientProgramUuid, conceptNames, null, null); + + verify(bahmniObsService, times(1)).getObservationsForPatientProgram(patientProgramUuid, conceptNames, null); + } + + @Test + public void shouldNotGetObsForPatientProgramWhenPatientProgramUuidIsSpecified() throws Exception { + List conceptNames = new ArrayList(); + String patientProgramUuid = null; + when(bahmniExtensions.getExtension("observationsAdder","CurrentMonthOfTreatment.groovy")).thenReturn(null); + + bahmniObservationsController.get(patientProgramUuid, null, null, null); + + verify(bahmniObsService, times(0)).getObservationsForPatientProgram(patientProgramUuid, conceptNames, null); + } + + @Test + public void shouldGetLatestObsForPatientProgramWhenPatientProgramUuidAndScopeLatestIsSpecified() throws Exception { + List conceptNames = new ArrayList(); + List ignoreObsList = new ArrayList<>(); + String patientProgramUuid = "patientProgramUuid"; + String scope = "latest"; + + bahmniObservationsController.get(patientProgramUuid, conceptNames, scope, ignoreObsList); + + verify(bahmniObsService, times(1)).getLatestObservationsForPatientProgram(patientProgramUuid, conceptNames, ignoreObsList); + } + + @Test + public void shouldGetInitialObsForPatientProgramWhenPatientProgramUuidAndScopeLatestIsSpecified() throws Exception { + List conceptNames = new ArrayList(); + List ignoreObsList = new ArrayList(); + String patientProgramUuid = "patientProgramUuid"; + String scope = "initial"; + when(bahmniExtensions.getExtension("observationsAdder","CurrentMonthOfTreatment.groovy")).thenReturn(null); + + bahmniObservationsController.get(patientProgramUuid, conceptNames, scope, ignoreObsList); + + verify(bahmniObsService, times(1)).getInitialObservationsForPatientProgram(patientProgramUuid, conceptNames, ignoreObsList); + } + + @Test + public void shouldGetBahmniObservationWithTheGivenObservationUuid() throws Exception { + String observationUuid = "observationUuid"; + BahmniObservation expectedBahmniObservation = new BahmniObservation(); + when(bahmniObsService.getBahmniObservationByUuid(observationUuid)).thenReturn(expectedBahmniObservation); + + BahmniObservation actualBahmniObservation = bahmniObservationsController.get(observationUuid, ""); + + verify(bahmniObsService, times(1)).getBahmniObservationByUuid("observationUuid"); + assertNotNull("BahmniObservation should not be null", actualBahmniObservation); + assertEquals(expectedBahmniObservation, actualBahmniObservation); + } + +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java new file mode 100644 index 0000000000..2ceca1e3a9 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniOrderControllerTest.java @@ -0,0 +1,98 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniOrderService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.Patient; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.order.contract.BahmniOrder; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +public class BahmniOrderControllerTest { + + @Mock + private BahmniOrderService bahmniOrderService; + + @Mock + private ConceptService conceptService; + + private Patient patient; + private Concept concept; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + concept = new Concept(); + patient = new Patient(); + patient.setUuid("patientUuid"); + when(conceptService.getConceptByName("Weight")).thenReturn(concept); + } + + @Test + public void shouldReturnBahmniOrdersForOrderType() throws Exception { + BahmniObservation obs = new BahmniObservation(); + BahmniOrder bahmniOrder = new BahmniOrder(); + obs.setUuid("initialId"); + bahmniOrder.setBahmniObservations(Arrays.asList(obs)); + List locationUuids = new ArrayList<>(); + locationUuids.add("LocationUuid"); + + when(bahmniOrderService.ordersForOrderType("patientUuid", Arrays.asList(concept), null, null, "OrderTypeUuid", true, locationUuids)).thenReturn(Arrays.asList(bahmniOrder)); + + BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService); + List bahmniOrders = bahmniOrderController.get("patientUuid", Arrays.asList("Weight"),"OrderTypeUuid", null, null, null, null, true, locationUuids); + + verify(bahmniOrderService, never()).ordersForOrderUuid("patientUuid", Arrays.asList(concept), null, "someUuid"); + verify(bahmniOrderService, never()).ordersForVisit("visitUuid", "orderTypeUuid", Arrays.asList("Weight"), Arrays.asList(concept)); + verify(bahmniOrderService, times(1)).ordersForOrderType("patientUuid", Arrays.asList(concept),null, null, "OrderTypeUuid", true, locationUuids); + assertEquals(1, bahmniOrders.size()); + } + + @Test + public void shouldReturnBahmniOrdersForOrderUuid() throws Exception { + BahmniObservation obs = new BahmniObservation(); + BahmniOrder bahmniOrder = new BahmniOrder(); + obs.setUuid("initialId"); + bahmniOrder.setBahmniObservations(Arrays.asList(obs)); + + when(bahmniOrderService.ordersForOrderUuid("patientUuid", Arrays.asList(this.concept), null, "OrderUuid")).thenReturn(Arrays.asList(bahmniOrder)); + BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService); + List bahmniOrders = bahmniOrderController.get("patientUuid", Arrays.asList("Weight"), null, null, "OrderUuid", 0, null, true, null); + + verify(bahmniOrderService, never()).ordersForOrderType("patientUuid", Arrays.asList(concept), null, null, "someUuid", true, null); + verify(bahmniOrderService, never()).ordersForVisit("visitUuid", "orderTypeUuid", Arrays.asList("Weight"), Arrays.asList(concept)); + assertEquals(1, bahmniOrders.size()); + } + + @Test + public void shouldReturnBahmniOrdersForVisit() throws Exception { + BahmniObservation obs = new BahmniObservation(); + BahmniOrder bahmniOrder = new BahmniOrder(); + obs.setUuid("initialId"); + bahmniOrder.setBahmniObservations(Arrays.asList(obs)); + + when(bahmniOrderService.ordersForVisit("visitUuid", "orderTypeUuid", Arrays.asList("Weight"), Arrays.asList(concept))).thenReturn(Arrays.asList(bahmniOrder)); + BahmniOrderController bahmniOrderController = new BahmniOrderController(conceptService, bahmniOrderService); + List bahmniOrders = bahmniOrderController.get("patientUuid", Arrays.asList("Weight"), "orderTypeUuid", "visitUuid", null, null, Arrays.asList("Weight"), false, null); + + verify(bahmniOrderService, never()).ordersForOrderType("patientUuid", Arrays.asList(concept), null, null, "someUuid", true, null); + verify(bahmniOrderService, never()).ordersForOrderUuid("patientUuid", Arrays.asList(concept), null, "someUuid"); + verify(bahmniOrderService, atLeastOnce()).ordersForVisit("visitUuid", "orderTypeUuid", Arrays.asList("Weight"), Arrays.asList(concept)); + assertEquals(1, bahmniOrders.size()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientImageControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientImageControllerTest.java new file mode 100644 index 0000000000..a77c58d0a8 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientImageControllerTest.java @@ -0,0 +1,68 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.PatientDocumentService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BahmniPatientImageControllerTest { + + private BahmniPatientImageController bahmniPatientImageController; + + @Mock + private PatientDocumentService patientDocumentService; + + @Mock + private UserContext userContext; + + @Before + public void setUp() throws IOException { + PowerMockito.mockStatic(Context.class); + PowerMockito.when(Context.getUserContext()).thenReturn(userContext); + bahmniPatientImageController = new BahmniPatientImageController(patientDocumentService); + } + + @Test + public void shouldRespondWithFileNotFoundStatusCodeIfTheImageIsNotFound() throws Exception { + Mockito.when(userContext.isAuthenticated()).thenReturn(true); + when(patientDocumentService.retriveImage(anyString())).thenReturn(new ResponseEntity(new Object(), HttpStatus.OK)); + String patientUuid = "patientUuid"; + + ResponseEntity responseEntity = bahmniPatientImageController.getImage(patientUuid); + + verify(patientDocumentService).retriveImage(patientUuid); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + public void shouldRespondWithNotAuthorizeStatusCodeIfTheImageIsNotFound() throws Exception { + Mockito.when(userContext.isAuthenticated()).thenReturn(false); + when(patientDocumentService.retriveImage(anyString())).thenReturn(new ResponseEntity(new Object(), HttpStatus.OK)); + String patientUuid = "patientUuid"; + + ResponseEntity responseEntity = bahmniPatientImageController.getImage(patientUuid); + + verify(patientDocumentService, never()).retriveImage(patientUuid); + assertEquals(HttpStatus.UNAUTHORIZED, responseEntity.getStatusCode()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceIT.java new file mode 100644 index 0000000000..c727789db0 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceIT.java @@ -0,0 +1,180 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.io.FileUtils; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.hibernate.exception.DataException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.openmrs.module.emrapi.patient.EmrPatientProfileService; +import org.openmrs.module.emrapi.patient.PatientProfile; +import org.openmrs.module.idgen.contract.IdentifierSource; +import org.openmrs.module.idgen.webservices.services.IdentifierSourceServiceWrapper; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +public class BahmniPatientProfileResourceIT extends BaseIntegrationTest { + + @Autowired + private EmrPatientProfileService emrPatientProfileService; + + private BahmniPatientProfileResource bahmniPatientProfileResource; + private SimpleObject propertiesToCreate; + private ClassLoader classLoader; + + @Mock + private IdentifierSourceServiceWrapper identifierSourceServiceWrapper; + + @Mock + private IdentifierSource identifierSource; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + executeDataSet("createPatientMetadata.xml"); + bahmniPatientProfileResource = new BahmniPatientProfileResource(emrPatientProfileService, identifierSourceServiceWrapper); + when(identifierSourceServiceWrapper.getSequenceValueUsingIdentifierSourceUuid("dead-cafe")).thenReturn("300010"); + when(identifierSourceServiceWrapper.generateIdentifierUsingIdentifierSourceUuid("dead-cafe", "")).thenReturn("BAH300010"); + classLoader = getClass().getClassLoader(); + File file = new File(classLoader.getResource("patient.json").getFile()); + String jsonString = FileUtils.readFileToString(file); + propertiesToCreate = SimpleObject.parseJson(jsonString); + } + + @Test + public void shouldReturnHttpPreconditionFailedStatusAndJumpSizeIfIdentifierIsPassedInTheRequestAndTheirIsAJump() throws Exception { + LinkedHashMap identifierProperties = (LinkedHashMap) ((ArrayList) ((LinkedHashMap) propertiesToCreate.get("patient")).get("identifiers")).get(0); + String identifier = String.valueOf(identifierProperties.get("identifierPrefix")).concat("300020"); + identifierProperties.put("identifier", identifier); + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + assertEquals(412, response.getStatusCode().value()); + assertEquals("[{\"sizeOfJump\":10,\"identifierType\":\"81433852-3f10-11e4-adec-0800271c1b75\"}]", response.getBody().toString()); + verify(identifierSourceServiceWrapper,never()).saveSequenceValueUsingIdentifierSourceUuid(anyLong(), anyString()); + } + + @Test + public void shouldCreatePatientWhenUserAcceptsTheJump() throws Exception { + LinkedHashMap identifierProperties = (LinkedHashMap) ((ArrayList) ((LinkedHashMap) propertiesToCreate.get("patient")).get("identifiers")).get(0); + String identifier = String.valueOf(identifierProperties.get("identifierPrefix")).concat("300020"); + identifierProperties.put("identifier", identifier); + ResponseEntity response = bahmniPatientProfileResource.create(true, propertiesToCreate); + assertEquals(200, response.getStatusCode().value()); + } + + @Test + public void shouldCreatePatientWhenIdentifierIsPassedAndJumpIsZero() throws Exception { + LinkedHashMap identifierProperties = (LinkedHashMap) ((ArrayList) ((LinkedHashMap) propertiesToCreate.get("patient")).get("identifiers")).get(0); + String identifier = String.valueOf(identifierProperties.get("identifierPrefix")).concat("300010"); + identifierProperties.put("identifier", identifier); + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + assertEquals(200, response.getStatusCode().value()); + } + + @Test + public void shouldCreatePatient() throws Exception { + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + assertEquals(200, response.getStatusCode().value()); + } + + @Test + public void shouldCreatePatientWhenIdentifierPrefixIsNotPresentAndIdentifierIsManuallyEntered() throws Exception { + HashMap patient = propertiesToCreate.get("patient"); + List> identifiers = (List>) patient.get("identifiers"); + identifiers.get(0).put("identifier", "identifier"); + identifiers.get(0).put("identifierPrefix", ""); + + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + + assertEquals(200, response.getStatusCode().value()); + } + + @Test + public void shouldCreatePatientWhenIdentifierPrefixIsBlankAndNoIdentifierIsEntered() throws Exception { + when(identifierSourceServiceWrapper.getAllIdentifierSources()).thenReturn(Arrays.asList(identifierSource)); + when(identifierSource.getName()).thenReturn("identifierName"); + when(identifierSourceServiceWrapper.generateIdentifier("identifierName", "")).thenReturn("300010"); + HashMap patient = propertiesToCreate.get("patient"); + List> identifiers = (ArrayList>) patient.get("identifiers"); + identifiers.get(0).put("identifierPrefix", ""); + + + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + + assertEquals(200, response.getStatusCode().value()); + } + + @Test + public void shouldReturnBadRequestForInvalidJson() throws Exception { + LinkedHashMap person = ((LinkedHashMap)((LinkedHashMap)propertiesToCreate.get("patient")).get("person")); + person.remove("names"); + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + assertEquals(400, response.getStatusCode().value()); + } + + @Test + public void shouldUpdatePatient() throws Exception { + File file = new File(classLoader.getResource("updatePatient.json").getFile()); + String jsonString = FileUtils.readFileToString(file); + propertiesToCreate = SimpleObject.parseJson(jsonString); + String uuid = "592b29e1-b3f5-423e-83cb-0d2c9b80867f"; + ResponseEntity response = bahmniPatientProfileResource.update(uuid, propertiesToCreate); + assertEquals(200, response.getStatusCode().value()); + final Patient patient = ((PatientProfile) response.getBody()).getPatient(); + SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss yyyy"); + assertEquals("Wed Mar 07 12:00:00 1984", formatter.format(patient.getBirthdate())); + assertEquals(2, patient.getIdentifiers().size()); + assertEquals("ABC123DEF", patient.getActiveIdentifiers().get(1).getIdentifier()); + } + + @Test + public void shouldReturnBadRequestForLongPatientName() throws Exception { + File file = new File(classLoader.getResource("updatePatient.json").getFile()); + String jsonString = FileUtils.readFileToString(file); + propertiesToCreate = SimpleObject.parseJson(jsonString); + LinkedHashMap name = (LinkedHashMap) ((ArrayList) ((LinkedHashMap) ((LinkedHashMap) propertiesToCreate.get("patient")).get("person")).get("names")).get(0); + name.put("givenName", "LongStringLongStringLongStringLongStringLongStringLongString"); + String uuid = "592b29e1-b3f5-423e-83cb-0d2c9b80867f"; + ResponseEntity response = bahmniPatientProfileResource.update(uuid, propertiesToCreate); + assertEquals(400, response.getStatusCode().value()); + } + + @Test + public void shouldReturnBadRequestForLongNumericPatientIdentifier() throws Exception { + LinkedHashMap identifier = (LinkedHashMap) ((ArrayList) ((LinkedHashMap) propertiesToCreate.get("patient")).get("identifiers")).get(0); + identifier.put("identifier", "BAH12345678912345678"); + when(identifierSourceServiceWrapper.saveSequenceValueUsingIdentifierSourceUuid(12345678912345679L, "dead-cafe")).thenThrow(DataException.class); + ResponseEntity response = bahmniPatientProfileResource.create(true, propertiesToCreate); + assertThat(response.getStatusCode().value(), is(400)); + assertThat(response.getBody().toString(), is("{\"error\":{\"message\":\"Entered numeric patient identifier is too large\"}}")); + } + + @Test + public void shouldCreatePatientWithMultipleIdentifiers() throws Exception { + ResponseEntity response = bahmniPatientProfileResource.create(false, propertiesToCreate); + assertEquals(200, response.getStatusCode().value()); + assertEquals(2, ((PatientProfile)response.getBody()).getPatient().getIdentifiers().size()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java new file mode 100644 index 0000000000..3370598943 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniPatientProfileResourceTest.java @@ -0,0 +1,166 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.Person; +import org.openmrs.Relationship; +import org.openmrs.api.APIAuthenticationException; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.PersonService; +import org.openmrs.api.context.Context; +import org.openmrs.messagesource.MessageSourceService; +import org.openmrs.module.emrapi.patient.EmrPatientProfileService; +import org.openmrs.module.emrapi.patient.PatientProfile; +import org.openmrs.module.idgen.webservices.services.IdentifierSourceServiceWrapper; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.api.RestService; +import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs1_8.PatientResource1_8; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.ResponseEntity; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.spy; +import static org.powermock.api.mockito.PowerMockito.doThrow; + +// TODO: 13/09/16 This is wrong way of writing test. We should mock the external dependency in resource but we ended up mocking all internal dependencies. For eg: MessageSourceService +@PrepareForTest({Context.class, BahmniPatientProfileResource.class}) +@RunWith(PowerMockRunner.class) +public class BahmniPatientProfileResourceTest { + + @Mock + private EmrPatientProfileService emrPatientProfileService; + + @Mock + private RestService restService; + + @Mock + PatientResource1_8 patientResource1_8; + + @Mock + private AdministrationService administrationService; + + @Mock + private PatientService patientService; + + @Mock + private PersonService personService; + @Mock + private MessageSourceService messageSourceService; + + @Mock + private IdentifierSourceServiceWrapper identifierSourceServiceWrapper; + + private BahmniPatientProfileResource bahmniPatientProfileResource; + private SimpleObject propertiesToCreate; + + @Before + public void setUp() throws IOException { + MockitoAnnotations.initMocks(this); + ClassLoader classLoader = getClass().getClassLoader(); + File file = new File(classLoader.getResource("patient.json").getFile()); + String jsonString = FileUtils.readFileToString(file); + propertiesToCreate = new SimpleObject().parseJson(jsonString); + Patient patient = new Patient(); + patient.setGender("M"); + mockStatic(Context.class); + PowerMockito.when(Context.getService(RestService.class)).thenReturn(restService); + PowerMockito.when(Context.getPersonService()).thenReturn(personService); + PowerMockito.when(Context.getMessageSourceService()).thenReturn(messageSourceService); + PowerMockito.when(restService.getResourceBySupportedClass(Patient.class)).thenReturn(patientResource1_8); + PowerMockito.when(patientResource1_8.getPatient(any(SimpleObject.class))).thenReturn(patient); + PowerMockito.when(patientResource1_8.getPatientForUpdate(anyString(), any(SimpleObject.class))).thenReturn(patient); + } + + @Test + public void createPatient() throws Exception { + bahmniPatientProfileResource = new BahmniPatientProfileResource(emrPatientProfileService, identifierSourceServiceWrapper); + BahmniPatientProfileResource bahmniPatientProfileResourceSpy = spy(this.bahmniPatientProfileResource); + PatientProfile delegate = mock(PatientProfile.class); + when(identifierSourceServiceWrapper.generateIdentifierUsingIdentifierSourceUuid("dead-cafe", "")).thenReturn("BAH300010"); + doReturn(delegate).when(bahmniPatientProfileResourceSpy, "mapForCreatePatient", propertiesToCreate); + when(emrPatientProfileService.save(delegate)).thenReturn(delegate); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(Context.getPatientService()).thenReturn(patientService); + Patient patient = mock(Patient.class); + when(patient.getUuid()).thenReturn("patientUuid"); + when(delegate.getPatient()).thenReturn(patient); + PatientIdentifier patientIdentifier = mock(PatientIdentifier.class); + Set patientIdentifiers = new HashSet<>(); + patientIdentifiers.add(patientIdentifier); + when(patient.getIdentifiers()).thenReturn(patientIdentifiers); + doNothing().when(bahmniPatientProfileResourceSpy).setConvertedProperties(any(PatientProfile.class), any(SimpleObject.class), any(DelegatingResourceDescription.class), any(Boolean.class)); + Person person = new Person(); + person.setUuid("personUuid"); + when(personService.getPersonByUuid("patientUuid")).thenReturn(person); + List relationships = Arrays.asList(); + when(personService.getRelationshipsByPerson(person)).thenReturn(relationships); + + ResponseEntity response = bahmniPatientProfileResourceSpy.create(false, propertiesToCreate); + + Assert.assertEquals(200, response.getStatusCode().value()); + verify(identifierSourceServiceWrapper, times(1)).generateIdentifierUsingIdentifierSourceUuid("dead-cafe", ""); + verify(personService, times(1)).getPersonByUuid("patientUuid"); + verify(delegate, times(1)).setRelationships(relationships); + } + + @Test + public void updatePatient() throws Exception { + bahmniPatientProfileResource = new BahmniPatientProfileResource(emrPatientProfileService, identifierSourceServiceWrapper); + BahmniPatientProfileResource spy = spy(bahmniPatientProfileResource); + PatientProfile delegate = mock(PatientProfile.class); + doReturn(delegate).when(spy, "mapForUpdatePatient", anyString(), any(SimpleObject.class)); + when(emrPatientProfileService.save(delegate)).thenReturn(delegate); + doNothing().when(spy).setConvertedProperties(any(PatientProfile.class), any(SimpleObject.class), any(DelegatingResourceDescription.class), any(Boolean.class)); + Person person = new Person(); + person.setUuid("personUuid"); + when(personService.getPersonByUuid("patientUuid")).thenReturn(person); + List relationships = Collections.emptyList(); + when(personService.getRelationshipsByPerson(person)).thenReturn(relationships); + Patient patient = mock(Patient.class); + when(patient.getUuid()).thenReturn("patientUuid"); + when(delegate.getPatient()).thenReturn(patient); + + ResponseEntity response = spy.update("someUuid", propertiesToCreate); + + Assert.assertEquals(200, response.getStatusCode().value()); + verify(personService, times(1)).getPersonByUuid("patientUuid"); + verify(delegate, times(2)).setRelationships(relationships); + } + + @Test + public void shouldThrowExceptionWhenPatientIsNotHavingProperPrivilege() throws Exception { + bahmniPatientProfileResource = new BahmniPatientProfileResource(emrPatientProfileService, identifierSourceServiceWrapper); + BahmniPatientProfileResource spy = spy(bahmniPatientProfileResource); + doThrow(new APIAuthenticationException()).when(spy, "mapForUpdatePatient", anyString(), any(SimpleObject.class)); + + ResponseEntity response = spy.update("someUuid", propertiesToCreate); + Assert.assertEquals(403,response.getStatusCode().value()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniTrendsControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniTrendsControllerTest.java new file mode 100644 index 0000000000..56eeb5d465 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniTrendsControllerTest.java @@ -0,0 +1,70 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Obs; +import org.openmrs.Person; +import org.openmrs.api.AdministrationService; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniTrendsControllerTest { + @Mock + BahmniObsService bahmniObsService; + @Mock + AdministrationService administrationService ; + + @Before + public void setup() { + initMocks(this); + } + + @Test + @Ignore + public void shouldGetObsForPersonAndMap() { + ArrayList obs = new ArrayList<>(); + Person person = new Person(1); + + Concept concept = new Concept(1); + concept.addName(new ConceptName("concept", Locale.ENGLISH)); + obs.add(new Obs(person, concept, new Date(), null)); + + when(bahmniObsService.getObsForPerson("foo")).thenReturn(obs); + + BahmniTrendsController controller = new BahmniTrendsController(bahmniObsService); + verify(bahmniObsService).getObsForPerson("foo"); + + } + + @Test + @Ignore + public void shouldGetNumericalConceptForPersonAndMap() { + ArrayList concepts = new ArrayList<>(); + + Concept concept1 = new Concept(1); + concept1.addName(new ConceptName("concept1", Locale.ENGLISH)); + + Concept concept2 = new Concept(2); + concept2.addName(new ConceptName("concept2", Locale.ENGLISH)); + + concepts.add(concept1); + concepts.add(concept2); + + when(bahmniObsService.getNumericConceptsForPerson("foo")).thenReturn(concepts); + + BahmniTrendsController controller = new BahmniTrendsController(bahmniObsService); + verify(bahmniObsService).getObsForPerson("foo"); + + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitControllerIT.java new file mode 100644 index 0000000000..49f6dd1e7e --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitControllerIT.java @@ -0,0 +1,71 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.contract.visit.VisitSummary; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class BahmniVisitControllerIT extends BaseIntegrationTest { + + @Autowired + private BahmniVisitController bahmniVisitController; + + @Before + public void setUp() throws Exception { + executeDataSet("visitInfo.xml"); + } + + @Test + public void shouldGetVisitSummary() { + VisitSummary visitSummary = bahmniVisitController.getVisitInfo("1e5d5d48-6b78-11e0-933c-18a905e044cd"); + + assertNotNull(visitSummary); + assertEquals("1e5d5d48-6b78-11e0-933c-18a905e044cd", visitSummary.getUuid()); + assertEquals("2005-01-01 00:00:00.0", visitSummary.getStartDateTime().toString()); + assertEquals("2005-01-05 00:00:00.0", visitSummary.getStopDateTime().toString()); + } + + @Test + public void shouldNotGetVisitSummaryOfVoidedVisit() { + VisitSummary visitSummary = bahmniVisitController.getVisitInfo("e1428fea-6b78-11e0-93c3-18a905e044dc"); + + assertNull(visitSummary); + } + + @Test + public void shouldGetAdmissionDetailsAndDischargeDetailsIfVisitStatusIsIPD() throws Exception { + VisitSummary visitSummary = bahmniVisitController.getVisitInfo("1e5d5d48-6b78-11e0-933c-18a905e044cd"); + + assertNotNull(visitSummary); + assertNotNull(visitSummary.getAdmissionDetails()); + assertEquals("bb0af6767-707a-4629-9850-f15206e63ab0", visitSummary.getAdmissionDetails().getUuid()); + assertEquals("2005-01-01 00:00:00.0", visitSummary.getAdmissionDetails().getDate().toString()); + + assertNotNull(visitSummary.getDischargeDetails()); + assertEquals("bb0af6767-707a-4629-9850-f15206e63a0b", visitSummary.getDischargeDetails().getUuid()); + assertEquals("2005-01-04 00:00:00.0", visitSummary.getDischargeDetails().getDate().toString()); + } + + @Test + public void shouldNotGetAdmissionDetailsOrDischargeDetailsIfTheVisitStatusIsOPD() throws Exception { + VisitSummary visitSummary = bahmniVisitController.getVisitInfo("1e5d5d48-6b78-11e0-988c-18a905e044cd"); + + assertNotNull(visitSummary); + assertNull(visitSummary.getAdmissionDetails()); + assertNull(visitSummary.getDischargeDetails()); + } + + @Test + public void shouldNotGetAdmissionDetailsOrDischargeDetailsIfTheVisitStatusIsEmergency() throws Exception { + VisitSummary visitSummary = bahmniVisitController.getVisitInfo("1e5d5d48-6b78-11e0-988c-18a905e033cd"); + + assertNotNull(visitSummary); + assertNull(visitSummary.getAdmissionDetails()); + assertNull(visitSummary.getDischargeDetails()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitLocationControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitLocationControllerIT.java new file mode 100644 index 0000000000..e032c049f4 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniVisitLocationControllerIT.java @@ -0,0 +1,57 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.bahmni.module.bahmnicommons.api.visitlocation.VisitLocationNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class BahmniVisitLocationControllerIT extends BaseIntegrationTest { + + @Autowired + private BahmniVisitLocationController bahmniVisitLocationController; + + @Before + public void setUp() throws Exception { + executeDataSet("locationData.xml"); + } + + @Test + public void shouldGetImmediateParentLocationIdIfItIsTaggedToVisitLocation() throws Exception { + String locationUuid = bahmniVisitLocationController.getVisitLocationInfo("c36006e5-9fbb-4f20-866b-0ece245615a1").get("uuid"); + assertEquals("e36006e5-9fbb-4f20-866b-0ece24561525", locationUuid); + } + + @Test + public void shouldTraverseTillItGetsParentLocationIdWhichIsTaggedToVisitLocation() throws Exception { + String locationUuid= bahmniVisitLocationController.getVisitLocationInfo("e36023e5-9fwb-4f20-866b-0ece24561525").get("uuid"); + assertEquals("e36006e5-9fbb-4f20-866b-0ece24561525", locationUuid); + } + + @Test(expected = VisitLocationNotFoundException.class) + public void shouldThrowExceptionIfNoLocationTaggedUntilRoot() throws Exception { + bahmniVisitLocationController.getVisitLocationInfo("l36023e5-9fhb-4f20-866b-0ece24561525"); + } + + @Test + public void shouldGetRootParentLocationIdWithVisitLocationTag() throws Exception { + String locationUuid = bahmniVisitLocationController.getFacilityVisitLocationInfo("g36006e5-9fbb-4f20-866b-0ece24561530").get("uuid"); + assertEquals("g36006e5-9fbb-4f20-866b-0ece24561528", locationUuid); + } + + @Test + public void shouldReturnPassedLocationIfParentLocationHasNotVisitLocationTag() throws Exception { + String locationUuid = bahmniVisitLocationController.getFacilityVisitLocationInfo("g36006e5-9fbb-4f20-866b-0ece24561527").get("uuid"); + assertEquals("g36006e5-9fbb-4f20-866b-0ece24561527", locationUuid); + } + + @Test + public void shouldReturnNullIfLocationHasNotVisitLocationTagTillRoot() throws Exception { + String locationUuid = bahmniVisitLocationController.getFacilityVisitLocationInfo("g36006e5-9fbb-4f20-866b-0ece24561531").get("uuid"); + assertNull(locationUuid); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DiseaseTemplateControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DiseaseTemplateControllerIT.java new file mode 100644 index 0000000000..dda66d4d03 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DiseaseTemplateControllerIT.java @@ -0,0 +1,82 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.contract.diseasetemplate.DiseaseTemplate; +import org.bahmni.module.bahmnicore.contract.diseasetemplate.ObservationTemplate; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.codehaus.jackson.type.TypeReference; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class DiseaseTemplateControllerIT extends BaseIntegrationTest { + + @Autowired + DiseaseTemplateController diseaseTemplateController; + + + @Before + public void setUp() throws Exception { + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + executeDataSet("obsTestData.xml"); + } + + @Test + public void shouldReturnObsForAllDiseaseTemplatesWithIntakeAndProgressFromTheLatestVisit() throws Exception { + String dataJson = "{\n" + + " \"diseaseTemplateConfigList\" : [{" + + "\"templateName\": \"Breast Cancer\"" + "}],\n" + + " \"patientUuid\": \"86526ed5-3c11-11de-a0ba-001e378eb67a\"\n" + + "}"; + List diseaseTemplates = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/diseaseTemplates", dataJson)), new TypeReference>() {}); + assertNotNull(diseaseTemplates); + assertEquals(1, diseaseTemplates.size()); + DiseaseTemplate breastCancer = diseaseTemplates.get(0); + assertEquals(2, breastCancer.getObservationTemplates().size()); + ObservationTemplate breastCancerIntake = breastCancer.getObservationTemplates().get(0); + assertEquals(2, breastCancerIntake.getBahmniObservations().size()); + assertEquals("Breast Cancer Intake", breastCancerIntake.getConcept().getName()); + assertEquals("BC_intake_concept_uuid", breastCancerIntake.getConcept().getUuid()); + } + + @Test + public void getShouldReturnEmptyObservationTemplatesForIncorrectTemplateName() throws Exception { + String dataJson = "{\n" + + " \"diseaseTemplateConfigList\" : [{" + + "\"templateName\": \"Does not exist\"" + "}],\n" + + " \"patientUuid\": \"86526ed5-3c11-11de-a0ba-001e378eb67a\"\n" + + "}"; + List diseaseTemplates = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/diseaseTemplates", dataJson)), new TypeReference>() {}); + assertEquals(1, diseaseTemplates.size()); + assertEquals(0, diseaseTemplates.get(0).getObservationTemplates().size()); + } + + @Test + public void getDiseaseTemplate_shouldReturnEmptyObservationTemplatesForIncorrectTemplateName() throws Exception { + String dataJson = "{\n" + + " \"diseaseTemplateConfigList\" : [{" + + "\"templateName\": \"Non Existing Concept\"" + "}],\n" + + " \"patientUuid\": \"86526ed5-3c11-11de-a0ba-001e378eb67a\"\n" + + "}"; + DiseaseTemplate diseaseTemplate = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/diseaseTemplate", dataJson)), new TypeReference() {}); + assertEquals(0, diseaseTemplate.getObservationTemplates().size()); + } + + @Test + public void getDiseaseTemplate_shouldReturnObsForADiseaseTemplateWithIntakeAndProgressAcrossAllVisits() throws Exception { + String dataJson = "{\n" + + " \"diseaseTemplateConfigList\" : [{" + + "\"templateName\": \"Breast Cancer\"" + "}],\n" + + " \"patientUuid\": \"86526ed5-3c11-11de-a0ba-001e378eb67a\"\n" + + "}"; + DiseaseTemplate diseaseTemplates = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/diseaseTemplate", dataJson)), new TypeReference() {}); + assertNotNull(diseaseTemplates); + assertEquals("Breast Cancer", diseaseTemplates.getConcept().getName()); + assertEquals(4, diseaseTemplates.getObservationTemplates().size()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DoseCalculatorControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DoseCalculatorControllerTest.java new file mode 100644 index 0000000000..10d8e44799 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/DoseCalculatorControllerTest.java @@ -0,0 +1,41 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.module.rulesengine.domain.DosageRequest; +import org.openmrs.module.rulesengine.domain.Dose; +import org.openmrs.module.rulesengine.engine.RulesEngine; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class DoseCalculatorControllerTest { + + @InjectMocks + DoseCalculatorController doseCalculatorController; + + @Mock + RulesEngine rulesEngine; + + @Test + public void shouldParseTheJsonDoseRequestAndReturnsConvertedDoseObject() throws Exception { + Dose testDose = new Dose("testdrug", 150, Dose.DoseUnit.mg); + when(rulesEngine.calculateDose(any(DosageRequest.class))).thenReturn(testDose); + String dosageRequest="{ \"patientUuid\": \"id\", " + + "\"drugName\": \"testDrug\", \"baseDose\": 5.0, \"doseUnit\": \"mg/kg\", \"orderSetName\": \"testOrderSet\"," + + "\"dosingRule\": \"testrule\"}"; + Dose dose = doseCalculatorController.calculateDose(dosageRequest); + assertNotNull(dose); + assertEquals(150,dose.getValue(),1); + assertEquals("testdrug",dose.getDrugName()); + verify(rulesEngine, times(1)).calculateDose(any(DosageRequest.class)); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/GlobalPropertySearchControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/GlobalPropertySearchControllerTest.java new file mode 100644 index 0000000000..96354e10ae --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/GlobalPropertySearchControllerTest.java @@ -0,0 +1,65 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.GlobalProperty; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.context.Context; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.ResponseEntity; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class GlobalPropertySearchControllerTest { + + @Mock + private AdministrationService administrationService; + + @InjectMocks + private GlobalPropertySearchController globalPropertySearchController; + + private List globalPropertyList = new ArrayList(); + + + @Test + public void shouldReturnPasswordRelatedPolicies() throws Exception { + GlobalProperty passwordMinLength = new GlobalProperty("security.passwordMinLength","8"); + GlobalProperty globalProperty = new GlobalProperty("gender","F, M"); + GlobalProperty passwordCantMatchUserName = new GlobalProperty("security.passwordShouldNotMatchUserName","true"); + + globalPropertyList.add(passwordMinLength); + globalPropertyList.add(globalProperty); + globalPropertyList.add(passwordCantMatchUserName); + + when(administrationService.getAllGlobalProperties()).thenReturn(globalPropertyList); + + ResponseEntity> passwordPolicies = globalPropertySearchController.getPasswordPolicies(); + + assertEquals(2, passwordPolicies.getBody().size()); + assertEquals("8", passwordPolicies.getBody().get("security.passwordMinLength")); + assertEquals("true", passwordPolicies.getBody().get("security.passwordShouldNotMatchUserName")); + } + + @Test + public void shouldReturnEmptyListIfPasswordPoliciesAreNotThere() throws Exception { + GlobalProperty globalProperty = new GlobalProperty("gender","F, M"); + globalPropertyList.add(globalProperty); + + when(administrationService.getAllGlobalProperties()).thenReturn(globalPropertyList); + + ResponseEntity> passwordPolicies = globalPropertySearchController.getPasswordPolicies(); + + assertEquals(0, passwordPolicies.getBody().size()); + + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/ObsRelationshipControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/ObsRelationshipControllerIT.java new file mode 100644 index 0000000000..3d7c7dd4ed --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/ObsRelationshipControllerIT.java @@ -0,0 +1,38 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@Ignore +public class ObsRelationshipControllerIT extends BaseIntegrationTest { + + @Autowired + private ObsRelationshipController obsRelationshipController; + + @Before + public void setUp() throws Exception { + executeDataSet("obsRelationshipDataset.xml"); + } + + @Test @Ignore + public void shouldReturnAllSourceObsByGivenTargetObsUuid(){ + List bahmniObservations = obsRelationshipController.find("39fb7f47-e80a-4056-9285-bd798be13c63"); + + assertEquals(2, bahmniObservations.size()); + assertEquals("be48cdcb-6a76-47e3-9f2e-2635032f3a9a", bahmniObservations.get(0).getUuid()); + assertEquals("39fb7f47-e80a-4056-9285-bd798be13c63", bahmniObservations.get(0).getTargetObsRelation().getTargetObs().getUuid()); + assertEquals("qualified-by", bahmniObservations.get(0).getTargetObsRelation().getRelationshipType()); + + assertEquals("f6ec1267-8eac-415f-a3f0-e47be2c8bb67", bahmniObservations.get(1).getUuid()); + assertEquals("39fb7f47-e80a-4056-9285-bd798be13c63", bahmniObservations.get(1).getTargetObsRelation().getTargetObs().getUuid()); + assertEquals("qualified-by", bahmniObservations.get(1).getTargetObsRelation().getRelationshipType()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerIT.java new file mode 100644 index 0000000000..20ff455c6a --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerIT.java @@ -0,0 +1,386 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.Encounter; +import org.openmrs.EncounterProvider; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentResponse; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.web.bind.MissingServletRequestParameterException; + +import java.io.File; +import java.util.ArrayList; +import java.util.Date; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class VisitDocumentControllerIT extends BaseIntegrationTest { + + public static final String TMP_DOCUMENT_IMAGES = "/tmp/document_images"; + private final String image = "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; + @Autowired + private VisitService visitService; + public static final String IMAGE_CONCEPT_UUID = "e060cf44-3d3d-11e3-bf2b-0800271c1b75"; + + @Before + public void setUp() throws Exception { + FileUtils.deleteDirectory(new File(TMP_DOCUMENT_IMAGES)); + System.setProperty("bahmnicore.documents.baseDirectory", TMP_DOCUMENT_IMAGES); + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + } + + @Test + public void shouldUploadDocumentsForNewVisit() throws Exception { + executeDataSet("uploadDocuments.xml"); + String patientUUID = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + String encounterTypeUUID = "759799ab-c9a5-435e-b671-77773ada74e4"; + String visitTypeUUID = "b45ca846-c79a-11e2-b0c0-8e397087571c"; + String testUUID = "e340cf44-3d3d-11e3-bf2b-0800271c1b75"; + String imageConceptUuid = "e060cf44-3d3d-11e3-bf2b-0800271c1b75"; + String locationUuid = "l3602jn5-9fhb-4f20-866b-0ece24561525"; + + String json = "{" + + "\"patientUuid\":\"" + patientUUID + "\"," + + "\"visitTypeUuid\":\"" + visitTypeUUID + "\"," + + "\"visitStartDate\":\"2015-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2015-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + encounterTypeUUID + "\"," + + "\"locationUuid\":\"" + locationUuid + "\"," + + "\"encounterDateTime\":\"2015-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + testUUID + "\", \"image\": \"" + image + "\", \"format\": \".jpeg\"}]" + + "}"; + + + VisitDocumentResponse visitDocumentResponse = deserialize(handle( + newPostRequest("/rest/v1/bahmnicore/visitDocument", json)), VisitDocumentResponse.class); + Context.flushSession(); + Context.clearSession(); + + Visit visit = visitService.getVisitByUuid(visitDocumentResponse.getVisitUuid()); + assertNotNull(visit); + assertEquals(1, visit.getEncounters().size()); + assertEquals(visit.getLocation().getUuid(), "l38923e5-9fhb-4f20-866b-0ece24561525"); + Encounter encounter = new ArrayList<>(visit.getEncounters()).get(0); + assertEquals(2, encounter.getAllObs().size()); + assertEquals(1, encounter.getEncounterProviders().size()); + EncounterProvider encounterProvider = encounter.getEncounterProviders().iterator().next(); + assertEquals("Jane Doe", encounterProvider.getProvider().getName()); + assertEquals("Unknown", encounterProvider.getEncounterRole().getName()); + Obs parentObs = new ArrayList<>(encounter.getObsAtTopLevel(false)).get(0); + assertEquals(1, parentObs.getGroupMembers().size()); + assertObservationWithImage(parentObs, testUUID, imageConceptUuid); + } + + + + @Test + public void shouldUploadDocumentsForExistingVisit() throws Exception { + executeDataSet("uploadDocuments.xml"); + Patient patient = Context.getPatientService().getPatientByUuid("75e04d42-3ca8-11e3-bf2b-0800271c1b75"); + Visit visit = createVisitForDate(patient, null, new Date(), true); + String locationUuid = "l3602jn5-9fhb-4f20-866b-0ece24561525"; + + String json = "{" + + "\"patientUuid\":\"" + "75e04d42-3ca8-11e3-bf2b-0800271c1b75" + "\"," + + "\"visitTypeUuid\":\"" + "b45ca846-c79a-11e2-b0c0-8e397087571c" + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + "759799ab-c9a5-435e-b671-77773ada74e4" + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"locationUuid\":\"" + locationUuid + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + "e340cf44-3d3d-11e3-bf2b-0800271c1b75" + "\", \"image\": \"" + image + "\", \"format\": \".jpeg\"}]" + + "}"; + + + VisitDocumentResponse visitDocumentResponse = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", json)), VisitDocumentResponse.class); + Visit existingVisit = visitService.getVisitByUuid(visitDocumentResponse.getVisitUuid()); + + assertEquals(visit.getUuid(), existingVisit.getUuid()); + assertEquals(1, existingVisit.getEncounters().size()); + Encounter encounter = new ArrayList<>(existingVisit.getEncounters()).get(0); + assertEquals(1, encounter.getAllObs().size()); + assertEquals(1, encounter.getEncounterProviders().size()); + EncounterProvider encounterProvider = encounter.getEncounterProviders().iterator().next(); + assertEquals("Jane Doe", encounterProvider.getProvider().getName()); + assertEquals("Unknown", encounterProvider.getEncounterRole().getName()); + Obs parentObs = new ArrayList<>(encounter.getAllObs()).get(0); + assertEquals(1, parentObs.getGroupMembers().size()); + assertObservationWithImage(parentObs, "e340cf44-3d3d-11e3-bf2b-0800271c1b75", IMAGE_CONCEPT_UUID); + } + + @Test + @Ignore + public void shouldDoMultipleUploadsToSameTest() throws Exception { + executeDataSet("uploadDocuments.xml"); + Patient patient = Context.getPatientService().getPatientByUuid("75e04d42-3ca8-11e3-bf2b-0800271c1b75"); + Visit visit = createVisitForDate(patient, null, new Date(), true); + + String firstRequest = "{" + + "\"patientUuid\":\"" + "75e04d42-3ca8-11e3-bf2b-0800271c1b75" + "\"," + + "\"visitTypeUuid\":\"" + "b45ca846-c79a-11e2-b0c0-8e397087571c" + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + "759799ab-c9a5-435e-b671-77773ada74e4" + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + "e340cf44-3d3d-11e3-bf2b-0800271c1b75" + "\", \"image\": \"" + image + "\", \"format\": \".jpeg\"}]" + + "}"; + + + deserialize(handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", firstRequest)), VisitDocumentResponse.class); + + String secondRequest = "{" + + "\"patientUuid\":\"" + "75e04d42-3ca8-11e3-bf2b-0800271c1b75" + "\"," + + "\"visitTypeUuid\":\"" + "b45ca846-c79a-11e2-b0c0-8e397087571c" + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + "759799ab-c9a5-435e-b671-77773ada74e4" + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + "e340cf44-3d3d-11e3-bf2b-0800271c1b75" + "\", \"image\": \"" + image + "\", \"format\": \".png\"}]" + + "}"; + + VisitDocumentResponse visitDocumentResponse = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", secondRequest)), VisitDocumentResponse.class); + Visit existingVisit = visitService.getVisitByUuid(visitDocumentResponse.getVisitUuid()); + + assertEquals(visit.getUuid(), existingVisit.getUuid()); + assertEquals(1, existingVisit.getEncounters().size()); + Encounter encounter = new ArrayList<>(existingVisit.getEncounters()).get(0); + assertEquals(1, encounter.getEncounterProviders().size()); + assertEquals(2, encounter.getAllObs().size()); + Obs parentObs1 = new ArrayList<>(encounter.getAllObs()).get(0); + Obs parentObs2 = new ArrayList<>(encounter.getAllObs()).get(1); + assertEquals(1, parentObs1.getGroupMembers().size()); + assertEquals(1, parentObs1.getGroupMembers().size()); + + String imageUrl = parentObs1.getGroupMembers().iterator().next().getValueText(); + assertTrue(imageUrl.contains("jpeg") || imageUrl.contains("png")); + imageUrl = parentObs2.getGroupMembers().iterator().next().getValueText(); + assertTrue(imageUrl.contains("jpeg") || imageUrl.contains("png")); + } + + @Test + public void shouldDeleteDocumentsForExistingVisit() throws Exception { + executeDataSet("uploadDocuments.xml"); + String patientUUID = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + String encounterTypeUUID = "759799ab-c9a5-435e-b671-77773ada74e4"; + String visitTypeUUID = "b45ca846-c79a-11e2-b0c0-8e397087571c"; + String testUUID = "e340cf44-3d3d-11e3-bf2b-0800271c1b75"; + String locationUuid = "l3602jn5-9fhb-4f20-866b-0ece24561525"; + + Patient patient = Context.getPatientService().getPatientByUuid(patientUUID); + Visit visit = createVisitForDate(patient, null, new Date(), true); + + String addDocumentJSON = "{" + + "\"patientUuid\":\"" + patientUUID + "\"," + + "\"visitTypeUuid\":\"" + visitTypeUUID + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + encounterTypeUUID + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"locationUuid\":\"" + locationUuid + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + testUUID + "\", \"image\": \"" + image + "\", \"format\": \".jpeg\"}]" + + "}"; + + VisitDocumentResponse documentAddedResponse = deserialize( + handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", addDocumentJSON)), + VisitDocumentResponse.class); + Visit addedVisit = visitService.getVisitByUuid(documentAddedResponse.getVisitUuid()); + String obsUuid = addedVisit.getEncounters().iterator().next().getAllObs().iterator().next().getUuid(); + + String deleteDocumentJSON = "{" + + "\"patientUuid\":\"" + patientUUID + "\"," + + "\"visitTypeUuid\":\"" + visitTypeUUID + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + encounterTypeUUID + "\"," + + "\"locationUuid\":\"" + locationUuid + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + testUUID + "\", \"image\": \"" + image + "\", \"format\": \".jpeg\", \"voided\" : true, \"obsUuid\" : \""+obsUuid+"\"}]" + + "}"; + + VisitDocumentResponse response = deserialize( + handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", deleteDocumentJSON)), + VisitDocumentResponse.class); + Visit updatedVisit = visitService.getVisitByUuid(response.getVisitUuid()); + + assertEquals(1, updatedVisit.getEncounters().size()); + Encounter encounter = new ArrayList<>(updatedVisit.getEncounters()).get(0); + assertEquals(2, encounter.getAllObs(true).size()); + assertEquals(true, encounter.getAllObs(true).iterator().next().getVoided()); + } + + @Test + public void shouldUpdateTestAssociatedToExisitingDocument() throws Exception { + executeDataSet("uploadDocuments.xml"); + String patientUUID = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + String encounterTypeUUID = "759799ab-c9a5-435e-b671-77773ada74e4"; + String visitTypeUUID = "b45ca846-c79a-11e2-b0c0-8e397087571c"; + String testUUID = "e340cf44-3d3d-11e3-bf2b-0800271c1b75"; + String otherTestUUID = "07a90a4b-0fca-42ff-8988-f5b519be06ab"; + String locationUuid = "l3602jn5-9fhb-4f20-866b-0ece24561525"; + + Patient patient = Context.getPatientService().getPatientByUuid(patientUUID); + Visit visit = createVisitForDate(patient, null, new Date(), true); + + String addDocumentJSON = "{" + + "\"patientUuid\":\"" + patientUUID + "\"," + + "\"visitTypeUuid\":\"" + visitTypeUUID + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + encounterTypeUUID + "\"," + + "\"locationUuid\":\"" + locationUuid + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + testUUID + "\", \"image\": \"" + image + "\", \"format\": \".jpeg\"}]" + + "}"; + + VisitDocumentResponse documentAddedResponse = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", addDocumentJSON)), VisitDocumentResponse.class); + Visit addedVisit = visitService.getVisitByUuid(documentAddedResponse.getVisitUuid()); + String obsUuid = addedVisit.getEncounters().iterator().next().getAllObs().iterator().next().getUuid(); + + String updateTestInDocumentJSON = "{" + + "\"patientUuid\":\"" + patientUUID + "\"," + + "\"visitTypeUuid\":\"" + visitTypeUUID + "\"," + + "\"visitStartDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"visitEndDate\":\"2019-12-31T18:30:00.000Z\"," + + "\"encounterTypeUuid\":\"" + encounterTypeUUID + "\"," + + "\"locationUuid\":\"" + locationUuid + "\"," + + "\"visitUuid\":\"" + visit.getUuid() + "\"," + + "\"encounterDateTime\":\"2019-12-31T18:30:00.000Z\"," + + "\"providerUuid\":\"331c6bf8-7846-11e3-a96a-0800271c1b75\"," + + "\"documents\": [{\"testUuid\": \"" + otherTestUUID + "\", \"image\": \"" + "/x/y/1-1-1-1.jpg" + "\", \"format\": \".jpeg\", \"obsUuid\" : \""+obsUuid+"\"}]" + + "}"; + + VisitDocumentResponse response = deserialize(handle(newPostRequest("/rest/v1/bahmnicore/visitDocument", updateTestInDocumentJSON)), VisitDocumentResponse.class); + Visit updatedVisit = visitService.getVisitByUuid(response.getVisitUuid()); + + assertEquals(1, updatedVisit.getEncounters().size()); + Encounter encounter = new ArrayList<>(updatedVisit.getEncounters()).get(0); + assertEquals(1, encounter.getAllObs().size()); + + Obs parentObs = new ArrayList<>(encounter.getAllObs()).get(0); + assertEquals(otherTestUUID, parentObs.getConcept().getUuid()); + assertEquals(1, parentObs.getGroupMembers(true).size()); + } + + @Test + public void shouldDeleteGivenPatientDocumentFromFileSystem() throws Exception { + File file = new File(TMP_DOCUMENT_IMAGES + "/testFileName.png"); + File thumbnailFile = new File(TMP_DOCUMENT_IMAGES + "/testFileName_thumbnail.png"); + file.getParentFile().mkdirs(); + file.createNewFile(); + thumbnailFile.createNewFile(); + + OpenmrsUtil.setApplicationDataDirectory(TMP_DOCUMENT_IMAGES); + FileUtils.writeStringToFile(new File(TMP_DOCUMENT_IMAGES + "/bahmnicore.properties"), + "bahmnicore.documents.baseDirectory=" + TMP_DOCUMENT_IMAGES); + BahmniCoreProperties.load(); + + MockHttpServletResponse response = handle(newDeleteRequest("/rest/v1/bahmnicore/visitDocument", + new Parameter("filename", "testFileName.png"))); + assertFalse(file.exists()); + assertFalse(thumbnailFile.exists()); + } + + @Test + public void shouldNotDeleteGivenPatientDocumentFromFileSystemIfFilenameIsEmpty() throws Exception { + executeDataSet("userRolesAndPrivileges.xml"); + File file = new File(TMP_DOCUMENT_IMAGES + "/testFileName.png"); + File thumbnailFile = new File(TMP_DOCUMENT_IMAGES + "/testFileName_thumbnail.png"); + file.getParentFile().mkdirs(); + file.createNewFile(); + thumbnailFile.createNewFile(); + + OpenmrsUtil.setApplicationDataDirectory(TMP_DOCUMENT_IMAGES); + FileUtils.writeStringToFile(new File(TMP_DOCUMENT_IMAGES + "/bahmnicore.properties"), + "bahmnicore.documents.baseDirectory=" + TMP_DOCUMENT_IMAGES); + BahmniCoreProperties.load(); + Context.authenticate("manage-user", "P@ssw0rd"); + MockHttpServletResponse response = handle(newDeleteRequest("/rest/v1/bahmnicore/visitDocument", + new Parameter("filename", ""))); + assertEquals(400, response.getStatus()); + assertEquals("{\"error\":{\"message\":\"[Required String parameter 'filename' is empty]\"}}", response.getContentAsString()); + assertTrue(file.exists()); + assertTrue(thumbnailFile.exists()); + assertTrue(new File(TMP_DOCUMENT_IMAGES).exists()); + } + + @Test + public void shouldNotDeleteGivenPatientDocumentFromFileSystemIfFilenameIsNull() throws Exception { + File file = new File(TMP_DOCUMENT_IMAGES + "/testFileName.png"); + File thumbnailFile = new File(TMP_DOCUMENT_IMAGES + "/testFileName_thumbnail.png"); + file.getParentFile().mkdirs(); + file.createNewFile(); + thumbnailFile.createNewFile(); + + OpenmrsUtil.setApplicationDataDirectory(TMP_DOCUMENT_IMAGES); + FileUtils.writeStringToFile(new File(TMP_DOCUMENT_IMAGES + "/bahmnicore.properties"), + "bahmnicore.documents.baseDirectory=" + TMP_DOCUMENT_IMAGES); + BahmniCoreProperties.load(); + + try{ + MockHttpServletResponse response = handle(newDeleteRequest("/rest/v1/bahmnicore/visitDocument", + new Parameter("filename", null))); + fail(); + } catch (MissingServletRequestParameterException exception){ + assertEquals("Required String parameter 'filename' is not present",exception.getMessage()); + assertTrue(file.exists()); + assertTrue(thumbnailFile.exists()); + assertTrue(new File(TMP_DOCUMENT_IMAGES).exists()); + } + } + + private Visit createVisitForDate(Patient patient, Encounter encounter, Date orderDate, boolean isActive) { + VisitType opdVisitType = visitService.getVisitType(1); + Visit visit = new Visit(patient, opdVisitType, orderDate); + if (encounter != null) + visit.addEncounter(encounter); + if (!isActive) + visit.setStopDatetime(DateUtils.addDays(orderDate, 1)); + return visitService.saveVisit(visit); + } + + + private Obs assertObservationWithImage(Obs parentObs, String testUUID, String documentUUID) { + Obs expectedObservation = null; + assertEquals(parentObs.getConcept().getUuid(), testUUID); + assertTrue(parentObs.getGroupMembers().size() > 0); + for (Obs memberObs : parentObs.getGroupMembers()) { + if (documentUUID.equals(memberObs.getConcept().getUuid())) { + expectedObservation = memberObs; + break; + } + } + assertTrue(expectedObservation != null); + return expectedObservation; + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java new file mode 100644 index 0000000000..e0ed25b547 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/VisitDocumentControllerTest.java @@ -0,0 +1,262 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.model.Document; +import org.bahmni.module.bahmnicore.security.PrivilegeConstants; +import org.bahmni.module.bahmnicore.service.PatientDocumentService; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.EnvironmentVariables; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Encounter; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.document.contract.VisitDocumentRequest; +import org.openmrs.module.bahmniemrapi.document.service.VisitDocumentService; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import java.util.Base64; +import java.util.HashMap; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class VisitDocumentControllerTest { + @InjectMocks + VisitDocumentController visitDocumentController; + @Mock + PatientService patientService; + @Mock + AdministrationService administrationService; + @Mock + PatientDocumentService patientDocumentService; + @Mock + VisitDocumentService visitDocumentService; + @Mock + BahmniVisitLocationService bahmniVisitLocationService; + @Mock + UserContext userContext; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Rule + public final EnvironmentVariables environmentVariables + = new EnvironmentVariables(); + + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + environmentVariables.set("DOCUMENT_MAX_SIZE_MB","7"); + } + + @Test + public void shouldGetDefaultEncounterTypeIfNoEncounterTypeIsPassedInRequest() throws Exception { + PowerMockito.mockStatic(Context.class); + PowerMockito.when(Context.getPatientService()).thenReturn(patientService); + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("consultation"); + + Document document = new Document("abcd", "jpeg", null, "patient-uuid", "image", "file-name"); + + visitDocumentController.saveDocument(document); + + verify(patientDocumentService).saveDocument(1, "consultation", "abcd", "jpeg", document.getFileType(), document.getFileName()); + verify(administrationService).getGlobalProperty("bahmni.encounterType.default"); + } + + @Test + public void shouldNotGetDefaultEncounterTypeIfEncounterTypeIsPassedInRequest() throws Exception { + PowerMockito.mockStatic(Context.class); + PowerMockito.when(Context.getPatientService()).thenReturn(patientService); + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("consultation"); + + Document document = new Document("abcd", "jpeg", "radiology", "patient-uuid", "image", "file-name"); + + visitDocumentController.saveDocument(document); + + verify(patientDocumentService).saveDocument(1, "radiology", "abcd", "jpeg", document.getFileType(), document.getFileName()); + verifyZeroInteractions(administrationService); + } + + @Test + public void shouldSetVisitLocationUuid() throws Exception { + Visit visit = new Visit(); + visit.setUuid("visit-uuid"); + Encounter encounter = new Encounter(); + encounter.setUuid("encounterUuid"); + encounter.setVisit(visit); + VisitDocumentRequest visitDocumentRequest = new VisitDocumentRequest("patient-uuid", "visit-uuid", "visit-type-uuid", + null, null, "encounter-uuid", null, null, "provider-uuid", "location-uuid", null); + + when(visitDocumentService.upload(visitDocumentRequest)).thenReturn(encounter); + + when(bahmniVisitLocationService.getVisitLocationUuid("location-uuid")).thenReturn("VisitLocationuuid"); + visitDocumentController.save(visitDocumentRequest); + + verify(bahmniVisitLocationService).getVisitLocationUuid("location-uuid"); + } + + @Test + public void shouldCallDeleteWithGivenFileNameIfUserIsAuthenticated() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getUserContext()).thenReturn(userContext); + when(userContext.hasPrivilege(PrivilegeConstants.DELETE_PATIENT_DOCUMENT_PRIVILEGE)).thenReturn(true); + visitDocumentController.deleteDocument("testFile.png"); + verify(patientDocumentService, times(1)).delete("testFile.png"); + } + + @Test + public void shouldNotCallDeleteWithGivenFileNameIfUserIsNotAuthenticated() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getUserContext()).thenReturn(userContext); + when(userContext.isAuthenticated()).thenReturn(false); + visitDocumentController.deleteDocument("testFile.png"); + verifyZeroInteractions(patientDocumentService); + } + + /** + * Should be moved to PatientDocumentServiceImplIT + * @throws Exception + */ + @Test + public void shouldReturnHttpBadRequestIfFileNameIsNull() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getUserContext()).thenReturn(userContext); + when(userContext.hasPrivilege(PrivilegeConstants.DELETE_PATIENT_DOCUMENT_PRIVILEGE)).thenReturn(true); + doThrow(RuntimeException.class).when(patientDocumentService).delete(any()); + ResponseEntity responseEntity = visitDocumentController.deleteDocument(null); + Assert.assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + } + + /** + * should be moved to PatientDocumentServiceImplIT + * @throws Exception + */ + @Test + public void shouldNotCallDeleteWithGivenFileNameIfFileNameIsEmpty() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getUserContext()).thenReturn(userContext); + when(userContext.hasPrivilege(PrivilegeConstants.DELETE_PATIENT_DOCUMENT_PRIVILEGE)).thenReturn(true); + doThrow(RuntimeException.class).when(patientDocumentService).delete(any()); + ResponseEntity responseEntity = visitDocumentController.deleteDocument(""); + Assert.assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + } + + @Test + public void shouldFailIfFileNameWithSpecialCharsOtherThanDashAndUnderscoreIsPassedInRequest() throws Exception { + PowerMockito.mockStatic(Context.class); + PowerMockito.when(Context.getPatientService()).thenReturn(patientService); + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + + Document document = new Document("abcd", "jpeg", "consultation", "patient-uuid", "image", "file/name"); + + visitDocumentController.saveDocument(document); + } + + @Test + public void shouldSaveIfFileNameNotWithSpecialCharsOtherThanDashAndUnderscoreIsPassedInRequest() { + PowerMockito.mockStatic(Context.class); + PowerMockito.when(Context.getPatientService()).thenReturn(patientService); + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + + Document document = new Document("abcd", "jpeg", "consultation", "patient-uuid", "image", "file-name"); + + ResponseEntity> responseEntity = visitDocumentController.saveDocument(document); + HashMap mapWithUrl = responseEntity.getBody(); + if (mapWithUrl!=null) { + String documentSavedPath = (String) mapWithUrl.get("url"); + if (documentSavedPath!=null) { + assertTrue(documentSavedPath.endsWith("__file-name.jpeg")); + } + } + // Old files will follow: patientid-encounterName-uuid.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75.jpeg) + // New ones will follow: patientid_encounterName_uuid__filename.ext (eg. 6-Patient-Document-706a448b-3f10-11e4-adec-0800271c1b75__file-name.jpeg) + + verify(patientDocumentService, times(1)).saveDocument(1, "consultation", "abcd", "jpeg", document.getFileType(), document.getFileName()); + } + + @Test + public void shouldReturn413PayloadTooLargeIfDocumentSizeExceedsLimit() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getPatientService()).thenReturn(patientService); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("consultation"); + + Document document = new Document("abcd", "jpeg", null, "patient-uuid", "image", "file-name"); + + byte[] largeContent = new byte[8 * 1024 * 1024]; + String base64Content = Base64.getEncoder().encodeToString(largeContent); + document.setContent(base64Content); + System.out.println(document.getContent().length()); + + ResponseEntity> responseEntity = visitDocumentController.saveDocument(document); + + Assert.assertEquals(HttpStatus.PAYLOAD_TOO_LARGE, responseEntity.getStatusCode()); + } + + @Test + public void shouldSaveDocumentIfDocumentSizeIsLessThanSizeLimit() throws Exception { + PowerMockito.mockStatic(Context.class); + when(Context.getPatientService()).thenReturn(patientService); + + Patient patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + when(patientService.getPatientByUuid("patient-uuid")).thenReturn(patient); + + when(administrationService.getGlobalProperty("bahmni.encounterType.default")).thenReturn("consultation"); + + Document document = new Document("abcd", "jpeg", null, "patient-uuid", "image", "file-name"); + + byte[] largeContent = new byte[2 * 1024 * 1024]; + String base64Content = Base64.getEncoder().encodeToString(largeContent); + document.setContent(base64Content); + + ResponseEntity> responseEntity = visitDocumentController.saveDocument(document); + + Assert.assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + + verify(patientDocumentService, times(1)).saveDocument(1, "consultation", base64Content, "jpeg", document.getFileType(), document.getFileName()); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/WhoamiControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/WhoamiControllerIT.java new file mode 100644 index 0000000000..8391046e0b --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/WhoamiControllerIT.java @@ -0,0 +1,27 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.bahmni.module.bahmnicoreui.contract.Privilege; +import org.codehaus.jackson.type.TypeReference; +import org.junit.Test; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class WhoamiControllerIT extends BaseIntegrationTest { + + @Test + public void shouldRetrievePrivilegesForAValidSession() throws Exception { + List privileges = deserialize(handle( + newGetRequest("/rest/v1/bahmnicore/whoami")), + new TypeReference>() { + }); + assertThat(privileges.size(),is(equalTo(0))); + } + + + //Need to add test cases where there is no logged in user +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextControllerIT.java new file mode 100644 index 0000000000..8c65ad606c --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextControllerIT.java @@ -0,0 +1,148 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.patient.PatientContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class BahmniPatientContextControllerIT extends BaseIntegrationTest { + + @Before + public void setUp() throws Exception { + executeDataSet("patientContextDataSet.xml"); + + } + + @Test + public void shouldFetchCorePatientInformation() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", new Parameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5")); + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("101-6", patientContext.getIdentifier()); + assertEquals(0, patientContext.getPersonAttributes().size()); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldFetchCorePatientInformationAndConfiguredPersonAttributes() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"), + new Parameter("personAttributes", "Birthplace") + ); + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("101-6", patientContext.getIdentifier()); + assertEquals(1, patientContext.getPersonAttributes().size()); + assertTrue(patientContext.getPersonAttributes().keySet().contains("Birthplace")); + assertEquals("London", patientContext.getPersonAttributes().get("Birthplace").get("value")); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldFetchCorePatientInformationAndConfiguredProgramAttributes() throws Exception { + executeDataSet("programEnrollmentDataSet.xml"); + + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "75e04d42-3ca8-11e3-bf2b-0808633c1b75"), + new Parameter("programUuid", "9119b9f8-af3d-4ad8-9e2e-2317c3de91c6"), + new Parameter("programAttributes", "stage") + ); + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("75e04d42-3ca8-11e3-bf2b-0808633c1b75", patientContext.getUuid()); + assertEquals(1, patientContext.getProgramAttributes().size()); + assertTrue(patientContext.getProgramAttributes().keySet().contains("stage")); + assertEquals("Stage1", patientContext.getProgramAttributes().get("stage").get("value")); + assertEquals("stage description", patientContext.getProgramAttributes().get("stage").get("description")); + assertEquals(0, patientContext.getPersonAttributes().size()); + } + + @Test + public void shouldNotFetchAnyConfiguredProgramAttributesWhenThePatientIsNotEnrolledInAnyProgram() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"), + new Parameter("programAttributes", "stage") + ); + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("da7f524f-27ce-4bb2-86d6-6d1d05312bd5", patientContext.getUuid()); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldNotFetchAnyProgramAttributesWhenNoneIsSpecified() throws Exception { + executeDataSet("programEnrollmentDataSet.xml"); + + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "75e04d42-3ca8-11e3-bf2b-0808633c1b75"), + new Parameter("programUuid", "9119b9f8-af3d-4ad8-9e2e-2317c3de91c6") + ); + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("75e04d42-3ca8-11e3-bf2b-0808633c1b75", patientContext.getUuid()); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldFetchConceptNameAsValueForPersonAttributesOfConceptType() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"), + new Parameter("personAttributes", "Civil Status") + ); + + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals(1, patientContext.getPersonAttributes().size()); + assertEquals("MARRIED", patientContext.getPersonAttributes().get("Civil Status").get("value")); + assertEquals("Marriage status of this person", patientContext.getPersonAttributes().get("Civil Status").get("description")); + } + + @Test + public void shouldFetchExtraPatientIdentifiersIfConfigured() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"), + new Parameter("patientIdentifiers", "Old Identification Number") + ); + + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("101-6", patientContext.getIdentifier()); + assertEquals(1, patientContext.getAdditionalPatientIdentifiers().size()); + assertEquals("101", patientContext.getAdditionalPatientIdentifiers().get("Old Identification Number")); + } + + @Test + public void shouldNotFetchPrimaryIdentifierAsExtraPatientIdentifiersIfConfigured() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/bahmnicore/patientcontext", + new Parameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"), + new Parameter("patientIdentifiers", "OpenMRS Identification Number") + ); + + MockHttpServletResponse response = handle(request); + PatientContext patientContext = deserialize(response, PatientContext.class); + + assertNotNull(patientContext); + assertEquals("101-6", patientContext.getIdentifier()); + assertEquals(0, patientContext.getAdditionalPatientIdentifiers().size()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextControllerTest.java new file mode 100644 index 0000000000..c84cb987db --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniPatientContextControllerTest.java @@ -0,0 +1,87 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.BahmniPatientContextMapper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifierType; +import org.openmrs.PatientProgram; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.patient.PatientContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BahmniPatientContextControllerTest { + + @InjectMocks + private BahmniPatientContextController bahmniPatientContextController = new BahmniPatientContextController(); + + @Mock + private PatientService patientService; + + @Mock + private AdministrationService administrationService; + + @Mock + private BahmniProgramWorkflowService bahmniProgramWorkflowService; + + @Mock + private BahmniPatientContextMapper bahmniPatientContextMapper; + + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + initMocks(this); + PowerMockito.mockStatic(Context.class); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(bahmniProgramWorkflowService); + } + + @Test + public void shouldGetCorePersonInformationIfPersonAttributesAndProgramAttributesAreNotConfigured() { + String patientUuid = "patientUuid"; + String programUuid = "programUuid"; + Patient patient = new Patient(); + PatientContext expectedPatientContext = new PatientContext(); + List configuredPersonAttributes = Collections.singletonList("Caste"); + List configuredProgramAttributes = Collections.singletonList("IRDB Number"); + List configuredPatientIdentifiers = Collections.singletonList("National Identifier"); + PatientProgram bahmniPatientProgram = new PatientProgram(); + PatientIdentifierType primaryIdentifierType = new PatientIdentifierType(); + + when(patientService.getPatientByUuid(patientUuid)).thenReturn(patient); + when(administrationService.getGlobalProperty("bahmni.primaryIdentifierType")).thenReturn("primary-identifier-uuid"); + when(patientService.getPatientIdentifierTypeByUuid("primary-identifier-uuid")).thenReturn(primaryIdentifierType); + when(bahmniPatientContextMapper.map(patient, bahmniPatientProgram, configuredPersonAttributes, configuredProgramAttributes, configuredPatientIdentifiers, primaryIdentifierType)).thenReturn(expectedPatientContext); + when(bahmniProgramWorkflowService.getPatientProgramByUuid(programUuid)).thenReturn(bahmniPatientProgram); + + PatientContext actualPatientContext = bahmniPatientContextController.getPatientContext(patientUuid, programUuid, configuredPersonAttributes, configuredProgramAttributes, configuredPatientIdentifiers); + + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(bahmniPatientContextMapper, times(1)).map(patient, bahmniPatientProgram, configuredPersonAttributes, configuredProgramAttributes, configuredPatientIdentifiers, primaryIdentifierType); + verify(bahmniProgramWorkflowService, times(1)).getPatientProgramByUuid(programUuid); + assertEquals(expectedPatientContext, actualPatientContext); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramControllerIT.java new file mode 100644 index 0000000000..ae45156d24 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramControllerIT.java @@ -0,0 +1,306 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.drugogram.contract.RegimenRow; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.Iterator; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class DrugOGramControllerIT extends BaseIntegrationTest { + @Autowired + DrugOGramController drugOGramController; + + @Before + public void setUp() throws Exception { + executeDataSet("drugogram.xml"); + executeDataSet("revisedDrugsForDrugOGram.xml"); + executeDataSet("discontinueDrugsForDrugOGram.xml"); + executeDataSet("startAndStopOnSameDateDrugs.xml"); + } + + @Test + public void shouldFetchDrugsInRegimenTableFormat() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001ed98eb67a", null, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 08:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), secondRow.getDate()); + assertEquals("1000.0", secondRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-30 00:00:00.0")), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibuprofen")); + assertEquals(null, thirdRow.getDrugs().get("Crocin")); + } + + @Test + public void shouldFetchSpecifiedDrugsInRegimenTableFormat() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001ed98eb67a", null, Arrays.asList("Ibuprofen")); + + assertNotNull(treatmentRegimen); + assertEquals(1, treatmentRegimen.getHeaders().size()); + assertEquals(2, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 08:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals(false, firstRow.getDrugs().keySet().contains("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-30 00:00:00.0")), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibuprofen")); + assertEquals(false, firstRow.getDrugs().keySet().contains("Crocin")); + } + + @Test + public void shouldFetchSpecifiedDrugsWhenWeSpecifyConceptSetNameInRegimenTableFormat() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001ed98eb67a", null, Arrays.asList("TB Drugs")); + + assertNotNull(treatmentRegimen); + assertEquals(1, treatmentRegimen.getHeaders().size()); + assertEquals(2, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 09:00:00")), firstRow.getDate()); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Crocin")); + } + + @Test + public void shouldFetchRevisedDrugsInRegimenTableFormat() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001edc8eb67a", null, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 08:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-25 08:00:00")), secondRow.getDate()); + assertEquals("500.0", secondRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), thirdRow.getDate()); + assertEquals("500.0", thirdRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", thirdRow.getDrugs().get("Crocin")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-10-02 00:00:00.0")), fourthRow.getDate()); + assertEquals("Stop", fourthRow.getDrugs().get("Ibuprofen")); + assertEquals(null , fourthRow.getDrugs().get("Crocin")); + } + + @Test + public void shouldFetchDiscontinueDrugsInRegimenTableFormat() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001edxseb67a", null, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 08:00:00")), firstRow.getDate()); + assertEquals("Error", firstRow.getDrugs().get("Ibuprofen")); + assertEquals(null, firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-25 00:00:00.0")), secondRow.getDate()); + assertEquals(null, secondRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), thirdRow.getDate()); + assertEquals(null, thirdRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", thirdRow.getDrugs().get("Crocin")); + } + + @Test + public void shouldFetchOrdersWhichAreStartedAndStoppedOnSameDate() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001djxseb67a", null, null); + + assertNotNull(treatmentRegimen); + assertEquals(3, treatmentRegimen.getHeaders().size()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 08:00:00")), firstRow.getDate()); + assertEquals("Error", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + assertEquals(null, firstRow.getDrugs().get("Paracetamol")); + + + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-24 09:00:00")), secondRow.getDate()); + assertEquals(null, secondRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", secondRow.getDrugs().get("Crocin")); + assertEquals("40.0", secondRow.getDrugs().get("Paracetamol")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-25 00:00:00.0")), thirdRow.getDate()); + assertEquals(null, thirdRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", thirdRow.getDrugs().get("Crocin")); + assertEquals("40.0", thirdRow.getDrugs().get("Paracetamol")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-28 00:00:00.0")), fourthRow.getDate()); + assertEquals(null, fourthRow.getDrugs().get("Ibuprofen")); + assertEquals(null, fourthRow.getDrugs().get("Crocin")); + assertEquals("Stop", fourthRow.getDrugs().get("Paracetamol")); + } + + @Test + public void shouldRetrieveDrugsOrdersForGivenPatientUuid() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001edc8eb67a", null, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 08:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-25 08:00:00")), secondRow.getDate()); + assertEquals("500.0", secondRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), thirdRow.getDate()); + assertEquals("500.0", thirdRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", thirdRow.getDrugs().get("Crocin")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-10-02 08:00:00")), fourthRow.getDate()); + assertEquals("Stop", fourthRow.getDrugs().get("Ibuprofen")); + assertEquals(null, fourthRow.getDrugs().get("Crocin")); + } + + public void shouldFetchSpecifiedDrugsWhenWeSpecifyConceptNamesInRegimenTableFormat() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001ed98eb67a", null, Arrays.asList("Ibuprofen", "Crocin")); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibuprofen", headerIterator.next().getName()); + assertEquals("Crocin", headerIterator.next().getName()); + assertEquals(false, headerIterator.hasNext()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 09:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), secondRow.getDate()); + assertEquals("1000.0", secondRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-30 00:00:00.0")), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibuprofen")); + } + + @Test + public void shouldFetchSpecifiedDrugsWhenWeSpecifyConceptNamesInRegimenTableFormatCrocinShouldComeFirst() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001ed98eb67a", null, Arrays.asList("Crocin", "Ibuprofen")); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Crocin", headerIterator.next().getName()); + assertEquals("Ibuprofen", headerIterator.next().getName()); + assertEquals(false, headerIterator.hasNext()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 09:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), secondRow.getDate()); + assertEquals("1000.0", secondRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-30 00:00:00.0")), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibuprofen")); + } + + @Test + public void shouldNotFetchParacetamolAsItWasNotPrescribedToPatientButSpecifiedInConceptNames() throws Exception { + TreatmentRegimen treatmentRegimen = drugOGramController.getRegimen("1a246ed5-3c11-11de-a0ba-001ed98eb67a", null, Arrays.asList("Ibuprofen", "Crocin", "Paracetamol")); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-23 09:00:00")), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("Ibuprofen")); + assertEquals("450.0", firstRow.getDrugs().get("Crocin")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-26 00:00:00.0")), secondRow.getDate()); + assertEquals("1000.0", secondRow.getDrugs().get("Ibuprofen")); + assertEquals("Stop", secondRow.getDrugs().get("Crocin")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(stringToDate("2005-09-30 00:00:00.0")), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibuprofen")); + } + + + public Date getOnlyDate(Date date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(sdf.format(date)); + } + + public Date stringToDate(String dateString) throws ParseException { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); + return format.parse(dateString); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramControllerTest.java new file mode 100644 index 0000000000..1bb6bb6e0a --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/DrugOGramControllerTest.java @@ -0,0 +1,122 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.DrugOrderToRegimenMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.DrugOrderBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.module.bahmniemrapi.drugogram.contract.BaseTableExtension; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +public class DrugOGramControllerTest { + @Mock + private BahmniDrugOrderService bahmniDrugOrderService; + @Mock + private DrugOrderToRegimenMapper drugOrderToTreatmentRegimenMapper; + @Mock + private BahmniExtensions bahmniExtensions; + @Mock + private BahmniConceptService bahmniConceptService; + + private DrugOGramController drugOGramController; + + @Before + public void setUp() throws Exception { + drugOGramController = new DrugOGramController(bahmniDrugOrderService, drugOrderToTreatmentRegimenMapper, bahmniConceptService, bahmniExtensions); + when(bahmniExtensions.getExtension(anyString(), anyString())).thenReturn(new BaseTableExtension()); + } + + @Test + public void shouldFetchDrugsAsRegimen() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + + when(bahmniDrugOrderService.getAllDrugOrders("patientUuid", null, null, null, null)).thenReturn(drugOrders); + + TreatmentRegimen expected = new TreatmentRegimen(); + when(drugOrderToTreatmentRegimenMapper.map(drugOrders, null)).thenReturn(expected); + + TreatmentRegimen actual = drugOGramController.getRegimen("patientUuid", null, null); + + verify(bahmniDrugOrderService, times(1)).getAllDrugOrders("patientUuid", null, null, null, null); + + verify(drugOrderToTreatmentRegimenMapper, times(1)).map(drugOrders, null); + assertEquals(expected, actual); + assertEquals(0, expected.getHeaders().size()); + } + + @Test + public void shouldFetchSpecifiedDrugsAsRegimen() throws Exception { + Concept paracetemolConcept= new ConceptBuilder().withName("Paracetemol").withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Paracetemol").build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(new Date()).withDose(200.0).withConcept(paracetemolConcept).build(); + + List drugOrders = new ArrayList<>(); + drugOrders.add(paracetemol); + Set concepts = new LinkedHashSet<>(); + concepts.add(paracetemolConcept); + when(bahmniConceptService.getConceptByFullySpecifiedName("Paracetamol")).thenReturn(paracetemolConcept); + + when(bahmniDrugOrderService.getAllDrugOrders("patientUuid", null, concepts, null, null)).thenReturn(drugOrders); + + TreatmentRegimen expected = new TreatmentRegimen(); + when(drugOrderToTreatmentRegimenMapper.map(drugOrders, concepts)).thenReturn(expected); + + TreatmentRegimen actual = drugOGramController.getRegimen("patientUuid",null, Arrays.asList("Paracetamol")); + + verify(bahmniDrugOrderService, times(1)).getAllDrugOrders("patientUuid", null, concepts, null, null); + + verify(drugOrderToTreatmentRegimenMapper, times(1)).map(drugOrders, concepts); + assertEquals(expected, actual); + assertEquals(0, expected.getHeaders().size()); + } + + @Test + public void shouldFetchSpecifiedDrugsAsRegimenWhenTheyPassConceptSet() throws Exception { + Concept paracetamol = new ConceptBuilder().withName("Paracetemol").withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Paracetemol").build(); + Concept tbDrugs = new ConceptBuilder().withName("TB Drugs").withSet(true).withSetMember(paracetamol).build(); + DrugOrder paracetemolDrug = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(new Date()).withDose(200.0).withConcept(paracetamol).build(); + + when(bahmniConceptService.getConceptByFullySpecifiedName("TB Drugs")).thenReturn(tbDrugs); + when(bahmniConceptService.getConceptByFullySpecifiedName("Paracetemol")).thenReturn(paracetamol); + + ArrayList drugOrders = new ArrayList<>(); + drugOrders.add(paracetemolDrug); + Set concepts = new LinkedHashSet<>(); + concepts.add(paracetamol); + + when(bahmniDrugOrderService.getAllDrugOrders("patientUuid", null, concepts, null, null)).thenReturn(drugOrders); + + TreatmentRegimen expected = new TreatmentRegimen(); + when(drugOrderToTreatmentRegimenMapper.map(drugOrders, concepts)).thenReturn(expected); + + TreatmentRegimen actual = drugOGramController.getRegimen("patientUuid", null, Arrays.asList("TB Drugs")); + + verify(bahmniDrugOrderService, times(1)).getAllDrugOrders("patientUuid", null, concepts, null, null); + + verify(drugOrderToTreatmentRegimenMapper, times(1)).map(drugOrders, concepts); + assertEquals(expected, actual); + assertEquals(0, expected.getHeaders().size()); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetControllerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetControllerIT.java new file mode 100644 index 0000000000..f56398f428 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetControllerIT.java @@ -0,0 +1,137 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotRow; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class ObsToObsTabularFlowSheetControllerIT extends BaseIntegrationTest { + @Before + public void setUp() throws Exception { + executeDataSet("flowSheetTableDataSet.xml"); + executeDataSet("flowSheetDataSetWithMultipleLevelConcepts.xml"); + executeDataSet("flowSheetTableDataSetForConceptDetails.xml"); + } + + @Test + public void shouldReturnAllTheMembersIfTheConceptNamesAreNotPassed() throws Exception { + PivotTable pivotTable = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/observations/flowSheet", + new Parameter("patientUuid", "1a246ed5-3c11-11de-a0ba-001ed98eb67a"), + new Parameter("numberOfVisits", "1"), + new Parameter("conceptSet", "FOOD CONSTRUCT"), + new Parameter("groupByConcept", "FOOD ASSISTANCE") + )), PivotTable.class); + + List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + assertEquals(rows.get(0).getValue("FAVORITE FOOD, NON-CODED").get(0).getValueAsString(), "Favorite"); + assertEquals(rows.get(0).getValue("FOOD ASSISTANCE").get(0).getValueAsString(), "Yes"); + assertEquals(rows.get(0).getValue("DATE OF FOOD ASSISTANCE").get(0).getValueAsString(), "2008-08-14 00:00:00"); + assertNotNull(pivotTable.getHeaders()); + assertFalse(pivotTable.getHeaders().isEmpty()); + } + + @Test + public void shouldReturnOnlyConceptNamesWhichArePassed() throws Exception { + PivotTable pivotTable = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/observations/flowSheet", + new Parameter("patientUuid", "1a246ed5-3c11-11de-a0ba-001ed98eb67a"), + new Parameter("numberOfVisits", "1"), + new Parameter("conceptSet", "FOOD CONSTRUCT"), + new Parameter("groupByConcept", "FOOD ASSISTANCE"), + new Parameter("conceptNames", "FOOD ASSISTANCE"), + new Parameter("conceptNames", "DATE OF FOOD ASSISTANCE"), + new Parameter("name", null) + )), PivotTable.class); + + List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + assertEquals(rows.get(0).getValue("FOOD ASSISTANCE").get(0).getValueAsString(), "Yes"); + assertEquals(rows.get(0).getValue("DATE OF FOOD ASSISTANCE").get(0).getValueAsString(), "2008-08-14 00:00:00"); + assertNull("Should not return this concept", rows.get(0).getValue("FAVORITE FOOD, NON-CODED")); + assertNotNull(pivotTable.getHeaders()); + assertFalse(pivotTable.getHeaders().isEmpty()); + } + + @Test + public void shouldGetAllMemberNamesAsHeadersWhenConceptNamesAreNotPassed() throws Exception { + PivotTable pivotTable = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/observations/flowSheet", + new Parameter("patientUuid", "1a246ed5-3c11-11de-abaa-001ed98eb67a"), + new Parameter("numberOfVisits", "-1"), + new Parameter("conceptSet", "FOOD CONSTRUCT"), + new Parameter("groupByConcept", "FOOD ASSISTANCE") + )), PivotTable.class); + + List rows = pivotTable.getRows(); + assertEquals(2, rows.size()); + assertNotNull(pivotTable.getHeaders()); + assertFalse(pivotTable.getHeaders().isEmpty()); + } + + @Test + public void shouldGetAllChildMembersAsColumnsIfTheConceptIsSet() throws Exception { + PivotTable pivotTable = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/observations/flowSheet", + new Parameter("patientUuid", "1a246ed5-3c11-11de-a0ba-001ed98eb67b"), + new Parameter("conceptSet", "BACTERIOLOGY CONCEPT SET"), + new Parameter("groupByConcept", "SPECIMEN COLLECTION DATE") + )), PivotTable.class); + + List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + assertEquals("2008-08-14 00:00:00", rows.get(0).getValue("SPECIMEN COLLECTION DATE").get(0).getValueAsString()); + assertEquals("56.0", rows.get(0).getValue("WEIGHT (KG)").get(0).getValueAsString()); + assertNull("Should not return this concept", rows.get(0).getValue("BACTERIOLOGY ADDITIONAL ATTRIBUTES")); + assertNull("Should not return this concept", rows.get(0).getValue("BACTERIOLOGY RESULTS")); + assertNotNull(pivotTable.getHeaders()); + assertFalse(pivotTable.getHeaders().isEmpty()); + } + + @Test + public void shouldGetZeroRowsIfGroupByConceptSameAsConceptName() throws Exception { + executeDataSet("flowSheetTableDataSetForInitialAndLatestCount.xml"); + PivotTable pivotTable = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/observations/flowSheet", + new Parameter("patientUuid", "1a246ed5-3c11-11de-a0ba-001ed2aeb66u"), + new Parameter("conceptSet", "Vitals"), + new Parameter("groupByConcept", "Temperature Data"), + new Parameter("conceptNames", "Temperature Data"), + new Parameter("initialCount", "2"), + new Parameter("latestCount","0"), + new Parameter("numberOfVisits","1") + )), PivotTable.class); + + List rows = pivotTable.getRows(); + assertEquals(1, pivotTable.getHeaders().size()); + assertEquals(0, rows.size()); + } + + @Test + public void shouldGetHeadersWithNormalRangeWhenHeaderHasANumericConcept() throws Exception { + executeDataSet("flowSheetTableDataSetForInitialAndLatestCount.xml"); + PivotTable pivotTable = deserialize(handle(newGetRequest("/rest/v1/bahmnicore/observations/flowSheet", + new Parameter("patientUuid", "1a246ed5-3c11-11de-a0ba-001ed2aeb66u"), + new Parameter("conceptSet", "Vitals"), + new Parameter("groupByConcept", "Temperature Data"), + new Parameter("conceptNames", "Temperature Data"), + new Parameter("initialCount", "2"), + new Parameter("latestCount","0"), + new Parameter("numberOfVisits","1") + )), PivotTable.class); + + Set headers = pivotTable.getHeaders(); + assertEquals(1, headers.size()); + + EncounterTransaction.Concept temperatureConcept = (EncounterTransaction.Concept) headers.toArray()[0]; + assertEquals(108, temperatureConcept.getHiNormal(),0); + assertEquals(98, temperatureConcept.getLowNormal(),0); + } +} + diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetControllerTest.java new file mode 100644 index 0000000000..017380ca8e --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/ObsToObsTabularFlowSheetControllerTest.java @@ -0,0 +1,577 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.display.controls; + +import org.bahmni.module.admin.retrospectiveEncounter.domain.DuplicateObservationsMatcher; +import org.bahmni.module.bahmnicore.extensions.BahmniExtensions; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.BahmniFormBuilderObsToTabularViewMapper; +import org.bahmni.module.bahmnicore.web.v1_0.mapper.BahmniObservationsToTabularViewMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.openmrs.Concept; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.TestUsernameAuthenticationScheme; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.drugogram.contract.BaseTableExtension; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotRow; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.spy; +import static org.powermock.api.mockito.PowerMockito.verifyPrivate; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ObsToObsTabularFlowSheetController.class, DuplicateObservationsMatcher.class, LocaleUtility.class}) +public class ObsToObsTabularFlowSheetControllerTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + @Mock + private BahmniObservationsToTabularViewMapper bahmniObservationsToTabularViewMapper; + @Mock + private ConceptService conceptService; + @Mock + private BahmniObsService bahmniObsService; + @Mock + private BahmniExtensions bahmniExtensions; + @Mock + private BahmniConceptService bahmniConceptService; + @Mock + private BahmniFormBuilderObsToTabularViewMapper bahmniFormBuilderObsToTabularViewMapper; + + @Captor + private ArgumentCaptor> leafConceptsCaptured; + + private ObsToObsTabularFlowSheetController obsToObsPivotTableController; + private ConceptMapper conceptMapper = new ConceptMapper(); + + @Before + public void setUp() throws Exception { + initMocks(this); + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + Context.setUserContext(new UserContext(new TestUsernameAuthenticationScheme())); + obsToObsPivotTableController = new ObsToObsTabularFlowSheetController(bahmniObsService, conceptService, + bahmniObservationsToTabularViewMapper, bahmniExtensions, bahmniConceptService, + bahmniFormBuilderObsToTabularViewMapper); + } + + @Test + public void shouldCallGetPivotTableByConceptSetMethodWhenConceptSetIsGiven() throws Exception { + ObsToObsTabularFlowSheetController obsToObsTabularFlowSheetController = spy(obsToObsPivotTableController); + String getPivotTableByConceptSet = "getPivotTableByConceptSet"; + String getPivotTableByFormNames = "getPivotTableByFormNames"; + String conceptSetName = "ConceptSetName"; + doReturn(new PivotTable()).when(obsToObsTabularFlowSheetController, getPivotTableByConceptSet, any(), any(), + eq(conceptSetName), any(), any(), any(), any(), any(), any(), any()); + + obsToObsTabularFlowSheetController.constructPivotTableFor(null, null, + conceptSetName, null, null, null, + null, null, null, null, null, + null, null); + + verifyPrivate(obsToObsTabularFlowSheetController).invoke(getPivotTableByConceptSet, any(), any(), + eq(conceptSetName), any(), any(), any(), any(), any(), any(), any()); + verifyPrivate(obsToObsTabularFlowSheetController, never()).invoke(getPivotTableByFormNames, any(), any(), + any(), any(), any(), any(), any(), any(), any(), any()); + } + + @Test + public void shouldCallGetPivotTableByFormNamesSetMethodWhenConceptNamesAndFormNamesGiven() throws Exception { + ObsToObsTabularFlowSheetController obsToObsTabularFlowSheetController = spy(obsToObsPivotTableController); + String getPivotTableByFormNames = "getPivotTableByFormNames"; + String getPivotTableByConceptSet = "getPivotTableByConceptSet"; + List conceptNames = Arrays.asList("conceptOne", "conceptTwo"); + List formNames = Arrays.asList("FormOne", "FormTwo"); + doReturn(new PivotTable()).when(obsToObsTabularFlowSheetController, getPivotTableByFormNames, any(), any(), + any(), eq(conceptNames), any(), any(), any(), any(), any(), eq(formNames)); + + obsToObsTabularFlowSheetController.constructPivotTableFor(null, null, + null, null, null, conceptNames, + null, null, null, null, null, + null, formNames); + + verifyPrivate(obsToObsTabularFlowSheetController).invoke(getPivotTableByFormNames, any(), any(), + any(), eq(conceptNames), any(), any(), any(), any(), any(), eq(formNames)); + + verifyPrivate(obsToObsTabularFlowSheetController, never()).invoke(getPivotTableByConceptSet, any(), any(), + any(), any(), any(), any(), any(), any(), any(), any()); + } + + @Test + public void shouldReturnEmptyPivotTableWhenFormNamesAreNotGiven() throws ParseException { + + ObsToObsTabularFlowSheetController obsToObsTabularFlowSheetController = spy(obsToObsPivotTableController); + PivotTable pivotTable = obsToObsTabularFlowSheetController.constructPivotTableFor(any(), any(), any(), any(), any(), + eq(singletonList("")), any(), any(), any(), any(), any(), any(), eq(null)); + assertEquals(0, pivotTable.getHeaders().size()); + } + + @Test + public void shouldReturnEmptyPivotTableWhenConceptNamesAreNotGiven() throws ParseException { + + ObsToObsTabularFlowSheetController obsToObsTabularFlowSheetController = spy(obsToObsPivotTableController); + PivotTable pivotTable = obsToObsTabularFlowSheetController.constructPivotTableFor(any(), any(), any(), any(), any(), + eq(null), any(), any(), any(), any(), any(), any(), eq(singletonList(""))); + + assertEquals(0, pivotTable.getHeaders().size()); + } + + @Test + public void shouldReturnEmptyPivotTableWhenFormNamesAreEmpty() throws ParseException { + + ObsToObsTabularFlowSheetController obsToObsTabularFlowSheetController = spy(obsToObsPivotTableController); + PivotTable pivotTable = obsToObsTabularFlowSheetController.constructPivotTableFor(any(), any(), any(), any(), any(), + eq(null), any(), any(), any(), any(), any(), any(), eq(emptyList())); + + assertEquals(0, pivotTable.getHeaders().size()); + } + + @Test + public void shouldFetchObservationForSpecifiedConceptsAndGroupByConcept() throws ParseException { + Concept member1 = new ConceptBuilder().withName("Member1").withSet(false).withDataType("Numeric").build(); + Concept member2 = new ConceptBuilder().withName("Member2").withSet(false).withDataType("Numeric").build(); + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withSet(false).withDataType("Numeric").build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withSetMember(groupByConcept).withSetMember(member1).withSetMember(member2).withSet(true).withDataType("Numeric").build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + List conceptNames = Arrays.asList("Member1", "Member2"); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, + "ConceptSetName", "GroupByConcept", null, conceptNames,null, null, null, null, null, null, null); + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + verify(bahmniExtensions,times(0)).getExtension(anyString(),anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldFetchObservationForSpecifiedFormNamesAndGroupByConcept() throws ParseException { + Concept member1 = new ConceptBuilder().withName("Member1").withSet(false).withDataType("Numeric").build(); + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withSet(false).withDataType("Numeric").build(); + String groupByConceptName = "GroupByConcept"; + List formNames = singletonList("Form1"); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.getObsForFormBuilderForms("patientUuid", formNames, 1, null, null, null)).thenReturn(bahmniObservations); + + List conceptNames = new ArrayList<>(singletonList("Member1")); + List concepts = Arrays.asList(member1, groupByConcept); + when(bahmniConceptService.getConceptsByFullySpecifiedName(conceptNames)).thenReturn(concepts); + + PivotTable pivotTable = new PivotTable(); + when(bahmniFormBuilderObsToTabularViewMapper.constructTable(Matchers.>any(), + eq(bahmniObservations), eq(groupByConceptName))).thenReturn(pivotTable); + when(bahmniFormBuilderObsToTabularViewMapper.getNonEmptyRows(pivotTable.getRows(), groupByConceptName)).thenReturn(pivotTable.getRows()); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, + null, groupByConceptName, null, conceptNames,null, null, + null, null, null, null, formNames); + + verify(bahmniObsService).getObsForFormBuilderForms("patientUuid", formNames, 1, null, null, null); + conceptNames.addAll(singletonList(groupByConceptName)); + verify(bahmniConceptService).getConceptsByFullySpecifiedName(conceptNames); + verify(bahmniFormBuilderObsToTabularViewMapper).constructTable(Matchers.>any(), + eq(bahmniObservations), eq(groupByConceptName)); + verify(bahmniExtensions,times(0)).getExtension(anyString(),anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldFetchSpecifiedConceptSetsData() throws Exception { + Concept member1 = new ConceptBuilder().withName("Member1").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept member2 = new ConceptBuilder().withName("Member2").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept parent = new ConceptBuilder().withName("Parent").withSetMember(member1).withSetMember(member2).withSet(true).withClass("N/A").withDataType("N/A").build(); + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withSetMember(groupByConcept).withSetMember(parent).withClass("N/A").withDataType("Numeric").withSet(true).build(); + ArrayList bahmniObservations = new ArrayList<>(); + + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + List conceptNames = Arrays.asList("Parent"); + + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, + "ConceptSetName", "GroupByConcept", null, conceptNames, null, null, null, null, null, null, null); + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(conceptService, times(1)).getConceptByName("GroupByConcept"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldFetchAllVisitsDataIfNumberOfVisitsIsPassedAsNull() throws Exception { + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withDataType("Numeric").withSet(false).build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withSetMember(groupByConcept).withDataType("Numeric").withSet(true).build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, null, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + List conceptNames = Arrays.asList("GroupByConcept"); + + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", null, "ConceptSetName", "GroupByConcept", null, conceptNames, null, null, null, null, null, null, null); + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, null, null, null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldFetchAllVisitsDataIfNumberOfVisitsIsPassedAsZero() throws Exception { + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withClass("N/A").withSetMember(groupByConcept).withDataType("Numeric").withSet(true).build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, 0, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 0, "ConceptSetName", "GroupByConcept", null, null, null, null, null, null, null, null, null); + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, 0, null , null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldFetchAllVisitsDataIfNumberOfVisitsIsPassedAsNegative() throws Exception { + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withClass("N/A").withSetMember(groupByConcept).withDataType("Numeric").withSet(true).build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, -1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", -1, "ConceptSetName", "GroupByConcept", null, null, null, null, null, null, null, null, null); + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, -1, null, null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldThrowExceptionIfConceptSetNotFound() throws ParseException { + String conceptSetName = "ConceptSetName"; + when(conceptService.getConceptByName(conceptSetName)).thenReturn(null); + exception.expect(RuntimeException.class); + exception.expectMessage(containsString("Root concept not found for the name: " + conceptSetName)); + + obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, conceptSetName, "GroupByConcept", null, Collections.EMPTY_LIST, null, null, null, null, null, null, null); + } + + @Test + public void shouldThrowExceptionIfGroupByConceptIsNotProvided() throws ParseException { + String conceptSetName = "ConceptSetName"; + Concept conceptSet = new ConceptBuilder().withName(conceptSetName).withSetMember(new ConceptBuilder().withName("GroupByConcept").build()).build(); + when(conceptService.getConceptByName(conceptSetName)).thenReturn(conceptSet); + exception.expect(RuntimeException.class); + exception.expectMessage(containsString("null doesn't belong to the Root concept: " + conceptSetName)); + + obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, conceptSetName, null, null, Collections.EMPTY_LIST, null, null, null, null, null, null, null); + } + + @Test + public void shouldThrowExceptionIfGroupByConceptDoesNotBelongToConceptSet() throws ParseException { + String conceptSetName = "ConceptSetName"; + Concept conceptSet = new ConceptBuilder().withName(conceptSetName).withSetMember(new ConceptBuilder().withName("NotGroupByConcept").build()).build(); + when(conceptService.getConceptByName(conceptSetName)).thenReturn(conceptSet); + exception.expect(RuntimeException.class); + exception.expectMessage(containsString("GroupByConcept doesn't belong to the Root concept: " + conceptSetName)); + + obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, conceptSetName, "GroupByConcept", null, Collections.EMPTY_LIST, null, null, null, null, null, null, null); + } + + @Test + public void shouldFetchTheRequiredNoOfObservationsWhenInitialCountAndLatestCountAreGiven() throws Exception { + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withClass("N/A").withSetMember(groupByConcept).withDataType("Numeric").withSet(true).build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, -1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", -1, "ConceptSetName", "GroupByConcept", null, null, bahmniObservations.size(), 1, null, null, null, null, null); + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, -1, null, null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldSortTheConceptsAsTheOrderDefinedIntheConceptNames() throws Exception { + Concept member1 = new ConceptBuilder().withName("Member1").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept member2 = new ConceptBuilder().withName("Member2").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept parent = new ConceptBuilder().withName("Parent").withSetMember(member1).withSetMember(member2).withSet(true).withClass("N/A").withDataType("N/A").build(); + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withClass("N/A").withDataType("Numeric").withSet(false).build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withSetMember(groupByConcept).withSetMember(parent).withClass("N/A").withDataType("Numeric").withSet(true).build(); + ArrayList bahmniObservations = new ArrayList<>(); + + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + List conceptNames = Arrays.asList("Member2", "Member1"); + +// Set leafConcepts = new HashSet<>(Arrays.asList("Member1", "Member2", "GroupByConcept")); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, "ConceptSetName", "GroupByConcept", null, conceptNames, null, null, null, null, null, null, null); + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(conceptService, times(1)).getConceptByName("GroupByConcept"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null); + + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(leafConceptsCaptured.capture(), eq(bahmniObservations), anyString()); + Set actualLeafConcepts = leafConceptsCaptured.getValue(); + + Iterator iterator = actualLeafConcepts.iterator(); + assertEquals(iterator.next().getName(), "Member2"); + assertEquals(iterator.next().getName(), "Member1"); + + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + } + + @Test + public void shouldPassPatientProgramUuidToObsService() throws ParseException { + String patientProgramUuid = "auspiciousUuid"; + Concept member1 = new ConceptBuilder().withName("Member1").withSet(false).withDataType("Numeric").build(); + Concept member2 = new ConceptBuilder().withName("Member2").withSet(false).withDataType("Numeric").build(); + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withSet(false).withDataType("Numeric").build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withSetMember(groupByConcept).withSetMember(member1).withSetMember(member2).withSet(true).withDataType("Numeric").build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, patientProgramUuid)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + List conceptNames = Arrays.asList("Member1", "Member2"); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, "ConceptSetName", "GroupByConcept", null, conceptNames,null, null, null, null, null, patientProgramUuid, null); + + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, patientProgramUuid); + + } + + @Test + public void shouldFetchPivotTableWithHighNormalLowNormalAndUnitsForConceptWithConceptDetailsClass() throws Exception { + Concept labMagnesium = new ConceptBuilder().withName("Lab, Magnesium").withClass("Misc").withSet(false).withDataTypeNumeric().build(); + Concept labMagnesiumAbnormal = new ConceptBuilder().withName("Lab, Magnesium Abnormal").withClass("Abnormal").withDataType("Boolean").withSet(false).build(); + Concept labMagnesiumData = new ConceptBuilder().withName("Lab, Magnesium Data").withClass("Concept Details").withDataType("N/A").withSetMember(labMagnesium).withSetMember(labMagnesiumAbnormal).withSet(true).build(); + ConceptNumeric labMagnesiumNumeric = new ConceptNumeric(); + labMagnesiumNumeric.setHiNormal(5.0); + labMagnesiumNumeric.setLowNormal(2.0); + labMagnesiumNumeric.setUnits("mg"); + when(conceptService.getConceptNumeric(eq(null))).thenReturn(labMagnesiumNumeric); + + when(conceptService.getConceptByName("Lab, Magnesium Data")).thenReturn(labMagnesiumData); + when(conceptService.getConceptByName("Lab, Magnesium")).thenReturn(labMagnesium); + when(conceptService.getConceptByName("Lab, Magnesium Abnormal")).thenReturn(labMagnesiumAbnormal); + + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(new BahmniObservation().setConcept(conceptMapper.map(labMagnesium)).setValue(2.3)); + when(bahmniObsService.observationsFor("patientUuid", labMagnesiumData, labMagnesium, -1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + Set headers = new HashSet<>(); + + headers.add(conceptMapper.map(labMagnesiumData)); + pivotTable.setHeaders(headers); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + when(conceptService.getConceptsByConceptSet(conceptService.getConceptByUuid(anyString()))).thenReturn(Arrays.asList(labMagnesium,labMagnesiumAbnormal)); + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", -1, "Lab, Magnesium Data", "Lab, Magnesium", null, Arrays.asList("Lab, Magnesium"), bahmniObservations.size(), 1, null, null, null, null, null); + Set actualHeaders = actualPivotTable.getHeaders(); + EncounterTransaction.Concept header = actualHeaders.iterator().next(); + assertEquals(new Double(2.0), header.getLowNormal()); + assertEquals(new Double(5.0), header.getHiNormal()); + assertEquals("mg", header.getUnits()); + } + + @Test + public void ensureThatExtensionsAreNotLoadedWhenNameIsNotProvided() throws ParseException { + Concept member1 = new ConceptBuilder().withName("Member1").withSet(false).withDataType("Numeric").build(); + Concept member2 = new ConceptBuilder().withName("Member2").withSet(false).withDataType("Numeric").build(); + Concept groupByConcept = new ConceptBuilder().withName("GroupByConcept").withSet(false).withDataType("Numeric").build(); + Concept rootConcept = new ConceptBuilder().withName("ConceptSetName").withSetMember(groupByConcept).withSetMember(member1).withSetMember(member2).withSet(true).withDataType("Numeric").build(); + when(conceptService.getConceptByName("ConceptSetName")).thenReturn(rootConcept); + when(conceptService.getConceptByName("GroupByConcept")).thenReturn(groupByConcept); + + ArrayList bahmniObservations = new ArrayList<>(); + when(bahmniObsService.observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = new PivotTable(); + List conceptNames = Arrays.asList("Member1", "Member2"); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, "ConceptSetName", "GroupByConcept", null, conceptNames,null, null, "groovyFileName", null, null, null, null); + Mockito.when(bahmniExtensions.getExtension(ObsToObsTabularFlowSheetController.FLOWSHEET_EXTENSION, "groovyFileName.groovy")).thenReturn(new BaseTableExtension()); + + + verify(conceptService, times(1)).getConceptByName("ConceptSetName"); + verify(bahmniObsService, times(1)).observationsFor("patientUuid", rootConcept, groupByConcept, 1, null, null, null); + verify(bahmniObservationsToTabularViewMapper, times(1)).constructTable(Matchers.>any(), eq(bahmniObservations), anyString()); + assertNotNull(actualPivotTable); + assertEquals(pivotTable, actualPivotTable); + + + } + + @Test + public void shouldReturnOrderedPivotTableWhenOrderByConceptGiven() throws ParseException { + Concept saeTerm = new ConceptBuilder().withName("SAE Term").withDataType("Text").build(); + Concept saeDate = new ConceptBuilder().withName("SAE Date").withDataType("Date").build(); + Concept template = new ConceptBuilder().withName("SAE Template").withSet(true).withSetMember(saeTerm).withSetMember(saeDate).build(); + when(conceptService.getConceptByName("SAE Template")).thenReturn(template); + when(conceptService.getConceptByName("SAE Term")).thenReturn(saeTerm); + when(conceptService.getConceptByName("SAE Date")).thenReturn(saeDate); + + Map conceptToValueMap1 = new HashMap<>(); + conceptToValueMap1.put(saeTerm, "c"); + conceptToValueMap1.put(saeDate, "2016-01-11"); + Map conceptToValueMap2 = new HashMap<>(); + conceptToValueMap2.put(saeTerm, "a"); + conceptToValueMap2.put(saeDate, "2016-01-01"); + Map conceptToValueMap3 = new HashMap<>(); + conceptToValueMap3.put(saeTerm, "d"); + conceptToValueMap3.put(saeDate, "2016-01-05"); + List bahmniObservations = buildBahmniObservations(Arrays.asList(conceptToValueMap1, conceptToValueMap2, conceptToValueMap3)); + + when(bahmniObsService.observationsFor("patientUuid", template, saeTerm, 1, null, null, null)).thenReturn(bahmniObservations); + + PivotTable pivotTable = pivotTableBuilder(Arrays.asList(saeTerm, saeDate), bahmniObservations); + when(bahmniObservationsToTabularViewMapper.constructTable(Matchers.>any(), eq(bahmniObservations), anyString())).thenReturn(pivotTable); + + PivotTable actualPivotTable = obsToObsPivotTableController.constructPivotTableFor("patientUuid", 1, "SAE Template", "SAE Term", "SAE Term", Arrays.asList("SAE Date"), null, null, null, null, null, null, null); + assertEquals(actualPivotTable.getRows().get(0).getColumns().get("SAE Term").get(0).getValue(), "a"); + assertEquals(actualPivotTable.getRows().get(1).getColumns().get("SAE Term").get(0).getValue(), "c"); + assertEquals(actualPivotTable.getRows().get(2).getColumns().get("SAE Term").get(0).getValue(), "d"); + } + + private PivotTable pivotTableBuilder(List concepts, List bahmniObservations) { + PivotTable pivotTable = new PivotTable(); + Set headers = new HashSet<>(); + for (Concept concept:concepts) { + headers.add(conceptMapper.map(concept)); + } + List pivotRows = new ArrayList<>(); + for(BahmniObservation bahmniObservation : bahmniObservations) { + PivotRow pivotRow = new PivotRow(); + Collection groupMembers = bahmniObservation.getGroupMembers(); + for(BahmniObservation groupMember: groupMembers) { + pivotRow.addColumn(groupMember.getConcept().getName(), groupMember); + } + pivotRows.add(pivotRow); + } + pivotTable.setHeaders(headers); + pivotTable.setRows(pivotRows); + return pivotTable; + } + + private List buildBahmniObservations(List> conceptToValueMaps) { + List bahmniObservations = new ArrayList<>(); + for(Map conceptToValueMap : conceptToValueMaps) { + BahmniObservation bahmniObservation = new BahmniObservation(); + for(Entry entry : conceptToValueMap.entrySet()) { + BahmniObservation observation = new BahmniObservation(); + observation.setConcept(conceptMapper.map(entry.getKey())); + observation.setType(entry.getKey().getDatatype().getName()); + observation.setValue(entry.getValue()); + bahmniObservation.addGroupMember(observation); + } + bahmniObservations.add(bahmniObservation); + } + return bahmniObservations; + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonAttributeSearchControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonAttributeSearchControllerTest.java new file mode 100644 index 0000000000..1db7d323c0 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonAttributeSearchControllerTest.java @@ -0,0 +1,40 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.search; + +import org.bahmni.module.bahmnicore.dao.PersonAttributeDao; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import java.util.Arrays; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class PersonAttributeSearchControllerTest { + + private PersonAttributeSearchController controller; + + @Mock + PersonAttributeDao personAttributeDao; + + @Before + public void init() { + initMocks(this); + controller = new PersonAttributeSearchController(personAttributeDao); + } + + @Test + public void shouldCallDaoToSearchForPatientAttributeValuesForCaste() { + String query = "someCaste"; + String personAttribute = "caste"; + when(personAttributeDao.getUnique(personAttribute, query)).thenReturn( + new ResultList(Arrays.asList("blah1", "blah2", "blah3"))); + + controller.search(personAttribute, query); + + verify(personAttributeDao).getUnique(personAttribute, query); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonNameSearchControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonNameSearchControllerTest.java new file mode 100644 index 0000000000..eaabf1809c --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/search/PersonNameSearchControllerTest.java @@ -0,0 +1,44 @@ +package org.bahmni.module.bahmnicore.web.v1_0.controller.search; + +import org.bahmni.module.bahmnicore.dao.PersonNameDao; +import org.bahmni.module.bahmnicore.model.ResultList; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class PersonNameSearchControllerTest { + + @Mock + PersonNameDao lastNameList; + + @Before + public void setup() { + initMocks(this); + } + + @Test + public void shouldCallDaoToSearchForPatientLastNames() { + String query = "family"; + String key = "familyName"; + List requiredResult = Arrays.asList("familyName1", "familyName2", "familyName3"); + when(lastNameList.getUnique(key, query)).thenReturn(new ResultList(requiredResult)); + PersonNameSearchController controller = new PersonNameSearchController(lastNameList); + + ResultList resultList = controller.searchFor(query, key); + + verify(lastNameList).getUnique(key, query); + assertEquals(requiredResult.size(), resultList.size()); + for (String name : requiredResult) { + assertTrue(resultList.getResults().contains(name)); + } + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java new file mode 100644 index 0000000000..84d35ff3b8 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniDrugOrderMapperTest.java @@ -0,0 +1,301 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.apache.commons.lang3.time.DateUtils; +import org.bahmni.test.builder.DrugOrderBuilder; +import org.bahmni.test.builder.EncounterBuilder; +import org.bahmni.test.builder.PersonBuilder; +import org.bahmni.test.builder.VisitBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.Order; +import org.openmrs.Person; +import org.openmrs.SimpleDosingInstructions; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.drugorder.contract.BahmniDrugOrder; +import org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions.FlexibleDosingInstructions; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniDrugOrderMapper; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.BahmniProviderMapper; +import org.openmrs.module.bahmniemrapi.drugorder.mapper.OrderAttributesMapper; +import org.openmrs.module.emrapi.encounter.ConceptMapper; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +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.Locale; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@PrepareForTest(LocaleUtility.class) +@RunWith(PowerMockRunner.class) +public class BahmniDrugOrderMapperTest { + + @Mock + private BahmniProviderMapper providerMapper; + + @Mock + private ConceptMapper conceptMapper; + + @Mock + private OrderAttributesMapper orderAttributesMapper; + + @Mock + private Concept reasonConcept; + + @Mock + private EncounterTransaction.Concept reasonETConcept; + private BahmniDrugOrderMapper bahmniDrugOrderMapper; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + PowerMockito.mockStatic(LocaleUtility.class); + when(LocaleUtility.getLocalesInOrder()).thenReturn(new HashSet(Arrays.asList(Locale.getDefault()))); + when(providerMapper.map(null)).thenReturn(null); + bahmniDrugOrderMapper = new BahmniDrugOrderMapper(); + bahmniDrugOrderMapper.setMappers(providerMapper, orderAttributesMapper, conceptMapper); + } + + + @Test + public void shouldMapToResponseForFreeTextOrderDetails() throws Exception { + DrugOrderBuilder drugBuilder = new DrugOrderBuilder(); + Date visitDate; + Date dateActivated; + visitDate = dateActivated = new Date(); + Date dateScheduled = DateUtils.addDays(dateActivated, 2); + Date expireDate = DateUtils.addDays(dateActivated, 20); + + + Person person = new PersonBuilder().withUUID("puuid").build(); + Encounter encounter = new EncounterBuilder().build(); + Visit visit = new VisitBuilder().withPerson(person).withUUID("vuuid").withStartDatetime(visitDate).withEncounter( + encounter).build(); + + DrugOrder drugOrder1 = drugBuilder.withDrugName("Paracetamol 120mg/5ml 60ml") + .withDosingType(FlexibleDosingInstructions.class) + .withDrugForm("Capsule") + .withScheduledDate(dateScheduled) + .withDateActivated(dateActivated) + .withDurationUnits("Week") + .withDosingInstructions("{\"dose\": \"2.0\", \"doseUnits\": \"Tablet\"}") + .withVisit(visit) + .withDuration(18) + .withAutoExpireDate(expireDate) + .withCreator("testPersonName") + .build(); + + List drugOrderList = new ArrayList<>(); + drugOrderList.add(drugOrder1); + + List mappedDrugOrders = bahmniDrugOrderMapper.mapToResponse(drugOrderList, null, new HashMap(), null); + assertEquals(1, mappedDrugOrders.size()); + BahmniDrugOrder mappedOrder = mappedDrugOrders.get(0); + + assertEquals("Paracetamol 120mg/5ml 60ml", mappedOrder.getDrug().getName()); + assertEquals("Capsule", mappedOrder.getDrug().getForm()); + assertEquals(dateScheduled, mappedOrder.getEffectiveStartDate()); + assertEquals(expireDate, mappedOrder.getEffectiveStopDate()); + assertEquals(18, mappedOrder.getDuration(), 0); + assertEquals("Week", mappedOrder.getDurationUnits()); + assertEquals("vuuid", mappedOrder.getVisit().getUuid()); + assertEquals("{\"dose\": \"2.0\", \"doseUnits\": \"Tablet\"}", mappedOrder.getDosingInstructions().getAdministrationInstructions()); + assertEquals(visitDate, mappedOrder.getVisit().getStartDateTime()); + verify(providerMapper, times(1)).map(null); + } + + @Test + public void shouldMapToResponseForSimpleOrderDetails() throws Exception { + DrugOrderBuilder drugBuilder = new DrugOrderBuilder(); + + Date dateActivated; + Date visitDate; + dateActivated = visitDate = new Date(); + Date expireDate = DateUtils.addDays(dateActivated, 20); + Person person = new PersonBuilder().withUUID("puuid").build(); + Encounter encounter = new EncounterBuilder().build(); + Visit visit = new VisitBuilder().withPerson(person).withUUID("vuuid").withStartDatetime(visitDate).withEncounter(encounter).build(); + + int duration = 2; + String dosingInstructions = "{\"instructions\": \"Before meals\", \"additionalInstructions\": \"Take before waking up\"}"; + DrugOrder drugOrder1 = drugBuilder.withDrugName("Paracetamol 120mg/5ml 60ml") + .withDosingType(SimpleDosingInstructions.class) + .withDosingInstructions(dosingInstructions) + .withDrugForm("Tablet") + .withDateActivated(dateActivated) + .withDuration(duration) + .withDurationUnits("Week") + .withDose(2.0) + .withVisit(visit) + .withFrequency("Once a day") + .withRoute("Orally") + .withAutoExpireDate(expireDate) + .withDoseUnits("Capsule") + .withCreator("testPersonName") + .build(); + + + List drugOrderList = new ArrayList<>(); + drugOrderList.add(drugOrder1); + + List mappedDrugOrders = bahmniDrugOrderMapper.mapToResponse(drugOrderList, null, new HashMap(),"en"); + assertEquals(1, mappedDrugOrders.size()); + BahmniDrugOrder mappedOrder = mappedDrugOrders.get(0); + + assertEquals("Paracetamol 120mg/5ml 60ml", mappedOrder.getDrug().getName()); + assertEquals("Tablet", mappedOrder.getDrug().getForm()); + assertEquals(2.0, mappedOrder.getDosingInstructions().getDose(), 0); + assertEquals("Capsule", mappedOrder.getDosingInstructions().getDoseUnits()); + assertEquals(dateActivated, mappedOrder.getEffectiveStartDate()); + assertEquals(expireDate, mappedOrder.getEffectiveStopDate()); + assertEquals(duration, mappedOrder.getDuration(), 0); + assertEquals("Week", mappedOrder.getDurationUnits()); + assertEquals(dosingInstructions, mappedOrder.getDosingInstructions().getAdministrationInstructions()); + assertEquals("Once a day", mappedOrder.getDosingInstructions().getFrequency()); + assertEquals("Orally", mappedOrder.getDosingInstructions().getRoute()); + assertEquals("vuuid", mappedOrder.getVisit().getUuid()); + assertEquals(visitDate, mappedOrder.getVisit().getStartDateTime()); + verify(providerMapper, times(1)).map(null); + } + + @Test + public void shouldFillDrugOrderReasonTextAndReasonConcept() throws Exception { + + Date dateActivated, visitDate; + dateActivated = visitDate = new Date(); + Date expireDate = DateUtils.addDays(dateActivated, 20); + Person person = new PersonBuilder().withUUID("puuid").build(); + Encounter encounter = new EncounterBuilder().build(); + Visit visit = new VisitBuilder().withPerson(person).withUUID("vuuid").withStartDatetime(visitDate).withEncounter(encounter).build(); + + int duration = 2; + String dosingInstructions = "{\"instructions\": \"Before meals\", \"additionalInstructions\": \"Take before waking up\"}"; + DrugOrder drugOrder1 = new DrugOrderBuilder().withDrugName("Paracetamol 120mg/5ml 60ml") + .withDosingType(SimpleDosingInstructions.class) + .withDosingInstructions(dosingInstructions) + .withDrugForm("Tablet") + .withDateActivated(dateActivated) + .withDuration(duration) + .withDurationUnits("Week") + .withDose(2.0) + .withVisit(visit) + .withFrequency("Once a day") + .withRoute("Orally") + .withAutoExpireDate(expireDate) + .withDoseUnits("Capsule") + .withCreator("testPersonName") + .withOrderAction(Order.Action.NEW) + .withOrderNumber("1234") + .build(); + + DrugOrder drugOrderDiscontinued = new DrugOrderBuilder().withDrugName("Paracetamol 120mg/5ml 60ml") + .withDosingType(SimpleDosingInstructions.class) + .withDosingInstructions(dosingInstructions) + .withDrugForm("Tablet") + .withDateActivated(dateActivated) + .withDuration(duration) + .withDurationUnits("Week") + .withDose(2.0) + .withVisit(visit) + .withFrequency("Once a day") + .withRoute("Orally") + .withAutoExpireDate(expireDate) + .withDoseUnits("Capsule") + .withCreator("testPersonName") + .withOrderAction(Order.Action.DISCONTINUE) + .withPreviousOrder(drugOrder1) + .build(); + + drugOrderDiscontinued.setOrderReason(reasonConcept); + drugOrderDiscontinued.setOrderReasonNonCoded("AEID1234"); + + when(conceptMapper.map(reasonConcept)).thenReturn(reasonETConcept); + + List drugOrderList = new ArrayList<>(); + drugOrderList.add(drugOrder1); + + Map discontinuedOrders = new HashMap<>(); + discontinuedOrders.put("1234", drugOrderDiscontinued); + + List mappedDrugOrders = bahmniDrugOrderMapper.mapToResponse(drugOrderList, null, discontinuedOrders,"en"); + assertEquals(1, mappedDrugOrders.size()); + BahmniDrugOrder mappedOrder = mappedDrugOrders.get(0); + + assertEquals("Paracetamol 120mg/5ml 60ml", mappedOrder.getDrug().getName()); + assertEquals("Tablet", mappedOrder.getDrug().getForm()); + assertEquals(2.0, mappedOrder.getDosingInstructions().getDose(), 0); + assertEquals("Capsule", mappedOrder.getDosingInstructions().getDoseUnits()); + assertEquals(dateActivated, mappedOrder.getEffectiveStartDate()); + assertEquals(expireDate, mappedOrder.getEffectiveStopDate()); + assertEquals(duration, mappedOrder.getDuration(), 0); + assertEquals("Week", mappedOrder.getDurationUnits()); + assertEquals(dosingInstructions, mappedOrder.getDosingInstructions().getAdministrationInstructions()); + assertEquals("Once a day", mappedOrder.getDosingInstructions().getFrequency()); + assertEquals("Orally", mappedOrder.getDosingInstructions().getRoute()); + assertEquals("vuuid", mappedOrder.getVisit().getUuid()); + assertEquals(visitDate, mappedOrder.getVisit().getStartDateTime()); + assertEquals(reasonETConcept, mappedOrder.getOrderReasonConcept()); + assertEquals("AEID1234", mappedOrder.getOrderReasonText()); + verify(providerMapper, times(1)).map(null); + } + + @Test + public void shouldMapDrugOrderToResponse() throws Exception { + DrugOrderBuilder drugBuilder = new DrugOrderBuilder(); + Date visitDate; + Date dateActivated; + visitDate = dateActivated = new Date(); + Date dateScheduled = DateUtils.addDays(dateActivated, 2); + Date expireDate = DateUtils.addDays(dateActivated, 20); + + + Person person = new PersonBuilder().withUUID("puuid").build(); + Encounter encounter = new EncounterBuilder().build(); + Visit visit = new VisitBuilder().withPerson(person).withUUID("vuuid").withStartDatetime(visitDate).withEncounter( + encounter).build(); + + DrugOrder drugOrder = drugBuilder.withDrugName("Paracetamol 120mg/5ml 60ml") + .withDosingType(FlexibleDosingInstructions.class) + .withDrugForm("Capsule") + .withScheduledDate(dateScheduled) + .withDateActivated(dateActivated) + .withDurationUnits("Week") + .withDosingInstructions("{\"dose\": \"2.0\", \"doseUnits\": \"Tablet\"}") + .withVisit(visit) + .withDuration(18) + .withAutoExpireDate(expireDate) + .withCreator("testPersonName") + .build(); + + BahmniDrugOrder mappedDrugOrder = bahmniDrugOrderMapper.mapToResponse(drugOrder, new HashMap()); + + assertEquals("Paracetamol 120mg/5ml 60ml", mappedDrugOrder.getDrug().getName()); + assertEquals("Capsule", mappedDrugOrder.getDrug().getForm()); + assertEquals(dateScheduled, mappedDrugOrder.getEffectiveStartDate()); + assertEquals(expireDate, mappedDrugOrder.getEffectiveStopDate()); + assertEquals(18, mappedDrugOrder.getDuration(), 0); + assertEquals("Week", mappedDrugOrder.getDurationUnits()); + assertEquals("vuuid", mappedDrugOrder.getVisit().getUuid()); + assertEquals("{\"dose\": \"2.0\", \"doseUnits\": \"Tablet\"}", mappedDrugOrder.getDosingInstructions().getAdministrationInstructions()); + assertEquals(visitDate, mappedDrugOrder.getVisit().getStartDateTime()); + verify(providerMapper, times(1)).map(null); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniFormBuilderObsToTabularViewMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniFormBuilderObsToTabularViewMapperTest.java new file mode 100644 index 0000000000..8779b22dca --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniFormBuilderObsToTabularViewMapperTest.java @@ -0,0 +1,377 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotRow; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction.Concept; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class BahmniFormBuilderObsToTabularViewMapperTest { + + private BahmniFormBuilderObsToTabularViewMapper bahmniFormBuilderObsToTabularViewMapper; + + @Before + public void setUp() { + bahmniFormBuilderObsToTabularViewMapper = new BahmniFormBuilderObsToTabularViewMapper(); + } + + @Test + public void shouldReturnPivotTableWithEmptyHeadersWhenObservationsAreEmpty() { + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(Collections.emptySet(), + Collections.emptyList(), ""); + + assertEquals(0, pivotTable.getHeaders().size()); + assertEquals(0, pivotTable.getRows().size()); + } + + @Test + public void shouldReturnPivotTableWithRowForGivenObservations() { + String groupByConceptName = "id"; + String weightConceptName = "weight"; + + Concept groupByConcept = mock(Concept.class); + Concept weightConcept = mock(Concept.class); + when(groupByConcept.getUuid()).thenReturn("group-concept-uuid"); + when(groupByConcept.getName()).thenReturn(groupByConceptName); + when(weightConcept.getUuid()).thenReturn("weight-concept-uuid"); + when(weightConcept.getName()).thenReturn(weightConceptName); + + BahmniObservation idObservation = mock(BahmniObservation.class); + BahmniObservation weightObservation = mock(BahmniObservation.class); + when(idObservation.getConcept()).thenReturn(groupByConcept); + when(weightObservation.getConcept()).thenReturn(weightConcept); + when(weightObservation.getValue()).thenReturn("obs value"); + + String encounterUuid = "encounter-uuid"; + when(idObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(idObservation.getFormFieldPath()).thenReturn("MedicalForm.10/1-0"); + when(weightObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(weightObservation.getFormFieldPath()).thenReturn("MedicalForm.10/2-0"); + + BahmniObservation idObservationLatest = mock(BahmniObservation.class); + BahmniObservation weightObservationLatest = mock(BahmniObservation.class); + when(idObservationLatest.getConcept()).thenReturn(groupByConcept); + when(weightObservationLatest.getConcept()).thenReturn(weightConcept); + when(weightObservationLatest.getValue()).thenReturn("obs value"); + + String encounterUuidLatest = "encounter-uuid-latest"; + when(idObservationLatest.getEncounterUuid()).thenReturn(encounterUuidLatest); + when(idObservationLatest.getFormFieldPath()).thenReturn("MedicalForm.20/1-0"); + when(weightObservationLatest.getEncounterUuid()).thenReturn(encounterUuidLatest); + when(weightObservationLatest.getFormFieldPath()).thenReturn("MedicalForm.20/2-0"); + + HashSet concepts = new HashSet<>(asList(groupByConcept, weightConcept)); + List bahmniObservations = asList(idObservation, weightObservation, idObservationLatest, + weightObservationLatest); + + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(concepts, bahmniObservations, + groupByConceptName); + + assertEquals(2, pivotTable.getHeaders().size()); + assertThat(pivotTable.getHeaders(), containsInAnyOrder(groupByConcept, weightConcept)); + List rows = pivotTable.getRows(); + assertEquals(2, rows.size()); + Map> firstRowColumns = rows.get(0).getColumns(); + assertEquals(2, firstRowColumns.size()); + Map> secondRowColumns = rows.get(1).getColumns(); + assertEquals(2, secondRowColumns.size()); + + List actualFirstRowObs = asList(firstRowColumns.get(groupByConceptName).get(0), + firstRowColumns.get(weightConceptName).get(0)); + List actualSecondRowObs = asList(secondRowColumns.get(groupByConceptName).get(0), + secondRowColumns.get(weightConceptName).get(0)); + List expectedRowOneObs = asList(idObservation, weightObservation); + List expectedRowTwoObs = asList(idObservationLatest, weightObservationLatest); + + assertTrue(expectedRowOneObs.containsAll(actualFirstRowObs) + || expectedRowOneObs.containsAll(actualSecondRowObs)); + assertTrue(expectedRowTwoObs.containsAll(actualFirstRowObs) + || expectedRowTwoObs.containsAll(actualSecondRowObs)); + } + + @Test + public void shouldReturnPivotTableWithPivotRowsOnlyWhenGroupByConceptObsAvailable() { + String groupByConceptName = "id"; + String weightConceptName = "weight"; + + Concept groupByConcept = mock(Concept.class); + Concept weightConcept = mock(Concept.class); + when(groupByConcept.getUuid()).thenReturn("group-concept-uuid"); + when(groupByConcept.getName()).thenReturn(groupByConceptName); + when(weightConcept.getUuid()).thenReturn("weight-concept-uuid"); + when(weightConcept.getName()).thenReturn(weightConceptName); + + BahmniObservation idObservation = mock(BahmniObservation.class); + BahmniObservation weightObservation = mock(BahmniObservation.class); + when(idObservation.getConcept()).thenReturn(groupByConcept); + when(weightObservation.getConcept()).thenReturn(weightConcept); + + String encounterUuid = "encounter-uuid"; + when(idObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(idObservation.getFormFieldPath()).thenReturn("MedicalForm.10/1-0"); + when(weightObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(weightObservation.getFormFieldPath()).thenReturn("MedicalForm.10/2-0"); + when(weightObservation.getValue()).thenReturn("obs value"); + + BahmniObservation anotherWeightObs = mock(BahmniObservation.class); + when(anotherWeightObs.getConcept()).thenReturn(weightConcept); + + String anotherEncounterUuid = "another-encounter-uuid"; + when(anotherWeightObs.getEncounterUuid()).thenReturn(anotherEncounterUuid); + when(anotherWeightObs.getFormFieldPath()).thenReturn("MedicalForm.10/2-0"); + when(anotherWeightObs.getValue()).thenReturn("obs value"); + + HashSet concepts = new HashSet<>(asList(groupByConcept, weightConcept)); + List bahmniObservations = asList(idObservation, weightObservation, anotherWeightObs); + + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(concepts, bahmniObservations, + groupByConceptName); + + assertEquals(2, pivotTable.getHeaders().size()); + assertThat(pivotTable.getHeaders(), containsInAnyOrder(groupByConcept, weightConcept)); + List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + Map> firstRowColumns = rows.get(0).getColumns(); + assertEquals(2, firstRowColumns.size()); + assertEquals(idObservation, firstRowColumns.get(groupByConceptName).get(0)); + assertEquals(weightObservation, firstRowColumns.get(weightConceptName).get(0)); + } + + @Test + public void shouldGetPivotTableWithOnlyNonNullRows() { + String groupByConceptName = "id"; + String weightConceptName = "weight"; + + Concept groupByConcept = mock(Concept.class); + Concept weightConcept = mock(Concept.class); + when(groupByConcept.getUuid()).thenReturn("group-concept-uuid"); + when(groupByConcept.getName()).thenReturn(groupByConceptName); + when(weightConcept.getUuid()).thenReturn("weight-concept-uuid"); + when(weightConcept.getName()).thenReturn(weightConceptName); + + BahmniObservation idObservation = mock(BahmniObservation.class); + BahmniObservation weightObservation = mock(BahmniObservation.class); + when(idObservation.getConcept()).thenReturn(groupByConcept); + when(weightObservation.getConcept()).thenReturn(weightConcept); + when(weightObservation.getValue()).thenReturn("obs value"); + + String encounterUuid = "encounter-uuid"; + when(idObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(idObservation.getFormFieldPath()).thenReturn("MedicalForm.10/1-0"); + when(weightObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(weightObservation.getFormFieldPath()).thenReturn("MedicalForm.10/2-0"); + + BahmniObservation anotherIdObservation = mock(BahmniObservation.class); + when(anotherIdObservation.getConcept()).thenReturn(groupByConcept); + + String anotherEncounterUuid = "another-encounter-uuid"; + when(anotherIdObservation.getEncounterUuid()).thenReturn(anotherEncounterUuid); + when(anotherIdObservation.getFormFieldPath()).thenReturn("MedicalForm.10/1-0"); + + HashSet concepts = new HashSet<>(asList(groupByConcept, weightConcept)); + List bahmniObservations = asList(idObservation, weightObservation, anotherIdObservation); + + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(concepts, bahmniObservations, + groupByConceptName); + assertEquals(2, pivotTable.getHeaders().size()); + assertThat(pivotTable.getHeaders(), containsInAnyOrder(groupByConcept, weightConcept)); + assertEquals(2, pivotTable.getRows().size()); + + pivotTable.setRows(bahmniFormBuilderObsToTabularViewMapper.getNonEmptyRows(pivotTable.getRows(), + groupByConceptName)); + + List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + Map> firstRowColumns = rows.get(0).getColumns(); + assertEquals(2, firstRowColumns.size()); + assertEquals(idObservation, firstRowColumns.get(groupByConceptName).get(0)); + assertEquals(weightObservation, firstRowColumns.get(weightConceptName).get(0)); + } + + @Test + public void shouldReturnPivotTableForMultiSelectObs() { + String groupByConceptName = "id"; + String multiSelectConceptName = "speciality"; + + Concept groupByConcept = mock(Concept.class); + Concept multiSelectConcept = mock(Concept.class); + when(groupByConcept.getUuid()).thenReturn("group-concept-uuid"); + when(groupByConcept.getName()).thenReturn(groupByConceptName); + when(multiSelectConcept.getUuid()).thenReturn("speciality-concept-uuid"); + when(multiSelectConcept.getName()).thenReturn(multiSelectConceptName); + + BahmniObservation idObservation = mock(BahmniObservation.class); + when(idObservation.getConcept()).thenReturn(groupByConcept); + + BahmniObservation multiSelectFirstObs = mock(BahmniObservation.class); + when(multiSelectFirstObs.getConcept()).thenReturn(multiSelectConcept); + when(multiSelectFirstObs.getValue()).thenReturn("first obs value"); + + BahmniObservation multiSelectSecondObs = mock(BahmniObservation.class); + when(multiSelectSecondObs.getConcept()).thenReturn(multiSelectConcept); + when(multiSelectSecondObs.getValue()).thenReturn("second obs value"); + + String encounterUuid = "encounter-uuid"; + when(idObservation.getEncounterUuid()).thenReturn(encounterUuid); + when(idObservation.getFormFieldPath()).thenReturn("MedicalForm.10/1-0"); + when(multiSelectFirstObs.getEncounterUuid()).thenReturn(encounterUuid); + when(multiSelectFirstObs.getFormFieldPath()).thenReturn("MedicalForm.10/2-0"); + when(multiSelectSecondObs.getEncounterUuid()).thenReturn(encounterUuid); + when(multiSelectSecondObs.getFormFieldPath()).thenReturn("MedicalForm.10/2-0"); + + HashSet concepts = new HashSet<>(asList(groupByConcept, multiSelectConcept)); + List bahmniObservations = asList(idObservation, multiSelectFirstObs, multiSelectSecondObs); + + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(concepts, bahmniObservations, + groupByConceptName); + + assertEquals(2, pivotTable.getHeaders().size()); + assertThat(pivotTable.getHeaders(), containsInAnyOrder(groupByConcept, multiSelectConcept)); + List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + Map> firstRowColumns = rows.get(0).getColumns(); + assertEquals(2, firstRowColumns.size()); + assertEquals(idObservation, firstRowColumns.get(groupByConceptName).get(0)); + assertThat(firstRowColumns.get(multiSelectConceptName), + containsInAnyOrder(multiSelectFirstObs, multiSelectSecondObs)); + } + + @Test + public void shouldReturnPivotTableWithTwoRowsDifferentiatedByEncounterUUIDAndParentFormFieldPathsWhenAddMoreSectionHasAllConceptsIncludingGroupByConcept() { + + String groupByConceptName = "id"; + String weightConceptName = "weight"; + + Concept groupByConcept = new Concept(); + Concept weightConcept = new Concept(); + groupByConcept.setUuid("group-concept-uuid"); + groupByConcept.setName(groupByConceptName); + weightConcept.setUuid("weight-concept-uuid"); + weightConcept.setName(weightConceptName); + + BahmniObservation idObservation = new BahmniObservation(); + BahmniObservation weightObservation = new BahmniObservation(); + idObservation.setConcept(groupByConcept); + weightObservation.setConcept(weightConcept); + weightObservation.setValue("obs value"); + idObservation.setValue("1"); + String encounterUuid = "encounter-uuid"; + idObservation.setEncounterUuid(encounterUuid); + idObservation.setFormFieldPath("MedicalForm.10/1-0/2-0"); + weightObservation.setEncounterUuid(encounterUuid); + weightObservation.setFormFieldPath("MedicalForm.10/1-0/3-0"); + + BahmniObservation anotherIdObservation = new BahmniObservation(); + BahmniObservation anotherWeightObservation = new BahmniObservation(); + anotherIdObservation.setConcept(groupByConcept); + anotherWeightObservation.setConcept(weightConcept); + anotherWeightObservation.setValue("another obs value"); + anotherIdObservation.setValue(1); + anotherIdObservation.setEncounterUuid(encounterUuid); + anotherIdObservation.setFormFieldPath("MedicalForm.10/1-1/2-0"); + anotherWeightObservation.setUuid(encounterUuid); + anotherWeightObservation.setFormFieldPath("MedicalForm.10/1-1/3-0"); + anotherIdObservation.setEncounterUuid(encounterUuid); + anotherWeightObservation.setEncounterUuid(encounterUuid); + + HashSet concepts = new HashSet<>(asList(groupByConcept, weightConcept)); + List bahmniObservations = asList(idObservation, weightObservation, anotherIdObservation, + anotherWeightObservation); + + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(concepts, bahmniObservations, + groupByConceptName); + + assertEquals(2, pivotTable.getHeaders().size()); + final List rows = pivotTable.getRows(); + assertEquals(2, rows.size()); + assertEquals(2, rows.get(0).getColumns().size()); + assertEquals(2, rows.get(1).getColumns().size()); + + final Map> firstColumn = rows.get(0).getColumns(); + final Map> secondColumn = rows.get(1).getColumns(); + + final List actualFirstRow = asList(firstColumn.get(groupByConceptName).get(0), + firstColumn.get(weightConceptName).get(0)); + + final List actualSecondRow = asList(secondColumn.get(groupByConceptName).get(0), + secondColumn.get(weightConceptName).get(0)); + + List expectedFirstRow = asList(idObservation, weightObservation); + List expectedSecondRow = asList(anotherIdObservation, anotherWeightObservation); + + + assertTrue(expectedFirstRow.containsAll(actualFirstRow) + || expectedFirstRow.containsAll(actualSecondRow)); + assertTrue(expectedSecondRow.containsAll(actualFirstRow) + || expectedSecondRow.containsAll(actualSecondRow)); + } + + @Test + public void shouldReturnPivotTableWithOneRowWhenAddMoreSectionHasAllConceptsExceptGroupByConcept() { + String groupByConceptName = "id"; + String weightConceptName = "weight"; + + Concept groupByConcept = new Concept(); + Concept weightConcept = new Concept(); + groupByConcept.setUuid("group-concept-uuid"); + groupByConcept.setName(groupByConceptName); + weightConcept.setUuid("weight-concept-uuid"); + weightConcept.setName(weightConceptName); + + BahmniObservation idObservation = new BahmniObservation(); + BahmniObservation weightObservation = new BahmniObservation(); + idObservation.setConcept(groupByConcept); + weightObservation.setConcept(weightConcept); + weightObservation.setValue("obs value"); + idObservation.setValue("1"); + String encounterUuid = "encounter-uuid"; + idObservation.setEncounterUuid(encounterUuid); + idObservation.setFormFieldPath("MedicalForm.10/1-0"); + weightObservation.setEncounterUuid(encounterUuid); + weightObservation.setFormFieldPath("MedicalForm.10/2-0/3-0"); + + BahmniObservation anotherWeightObservation = new BahmniObservation(); + anotherWeightObservation.setConcept(weightConcept); + anotherWeightObservation.setValue("another obs value"); + anotherWeightObservation.setUuid(encounterUuid); + anotherWeightObservation.setFormFieldPath("MedicalForm.10/2-1/3-0"); + anotherWeightObservation.setEncounterUuid(encounterUuid); + + HashSet concepts = new HashSet<>(asList(groupByConcept, weightConcept)); + List bahmniObservations = asList(idObservation, weightObservation, + anotherWeightObservation); + + PivotTable pivotTable = bahmniFormBuilderObsToTabularViewMapper.constructTable(concepts, bahmniObservations, + groupByConceptName); + + assertEquals(2, pivotTable.getHeaders().size()); + final List rows = pivotTable.getRows(); + assertEquals(1, rows.size()); + assertEquals(2, rows.get(0).getColumns().size()); + + final Map> columns = rows.get(0).getColumns(); + + final List actualRow = asList(columns.get(groupByConceptName).get(0), + columns.get(weightConceptName).get(0), columns.get(weightConceptName).get(1)); + + List expectedRow = asList(idObservation, weightObservation, anotherWeightObservation); + + + assertTrue(expectedRow.containsAll(actualRow)); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniObservationsToTabularViewMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniObservationsToTabularViewMapperTest.java new file mode 100644 index 0000000000..aab4d23420 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniObservationsToTabularViewMapperTest.java @@ -0,0 +1,162 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.builder.BahmniObservationBuilder; +import org.openmrs.module.bahmniemrapi.builder.ETConceptBuilder; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.pivottable.contract.PivotTable; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class BahmniObservationsToTabularViewMapperTest { + + private BahmniObservationsToTabularViewMapper bahmniObservationsToTabularViewMapper = new BahmniObservationsToTabularViewMapper(); + private String groupByConcept = null; + + @Test + public void shouldReturnAllObservationsInTabularFormatIfTheConceptNamesAreNotPassed() throws Exception { + EncounterTransaction.Concept heightConcept = new ETConceptBuilder().withName("HEIGHT").withUuid("height uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept weightConcept = new ETConceptBuilder().withName("WEIGHT").withUuid("weight uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept vitalsConcept = new ETConceptBuilder().withName("Vitals").withUuid("vitals uuid").withSet(true).withClass("Misc").build(); + BahmniObservation height = new BahmniObservationBuilder().withConcept(heightConcept).withValue(170).build(); + BahmniObservation weight = new BahmniObservationBuilder().withConcept(weightConcept).withValue(80).build(); + BahmniObservation vitals = new BahmniObservationBuilder().withConcept(vitalsConcept).withGroupMember(height).withGroupMember(weight).build(); + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(vitals); + + Set conceptNames = new HashSet<>(); + conceptNames.add(heightConcept); + conceptNames.add(weightConcept); + PivotTable pivotTable = bahmniObservationsToTabularViewMapper.constructTable(conceptNames, bahmniObservations, groupByConcept); + + assertNotNull(pivotTable); + assertEquals(1, pivotTable.getRows().size()); + assertEquals(conceptNames, pivotTable.getHeaders()); + assertEquals(170, pivotTable.getRows().get(0).getValue("HEIGHT").get(0).getValue()); + assertEquals(80, pivotTable.getRows().get(0).getValue("WEIGHT").get(0).getValue()); + } + + @Test + public void shouldReturnObservationsInTabularFormatForOnlyTheConceptNamesArePassed() throws Exception { + EncounterTransaction.Concept heightConcept = new ETConceptBuilder().withName("HEIGHT").withUuid("height uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept weightConcept = new ETConceptBuilder().withName("WEIGHT").withUuid("weight uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept vitalsConcept = new ETConceptBuilder().withName("Vitals").withUuid("vitals uuid").withSet(true).withClass("Misc").build(); + BahmniObservation height = new BahmniObservationBuilder().withConcept(heightConcept).withValue(170).build(); + BahmniObservation weight = new BahmniObservationBuilder().withConcept(weightConcept).withValue(80).build(); + BahmniObservation vitals = new BahmniObservationBuilder().withConcept(vitalsConcept).withGroupMember(height).withGroupMember(weight).build(); + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(vitals); + + Set conceptNames = new HashSet<>(); + conceptNames.add(heightConcept); + PivotTable pivotTable = bahmniObservationsToTabularViewMapper.constructTable(conceptNames, bahmniObservations, groupByConcept); + + assertNotNull(pivotTable); + assertEquals(1, pivotTable.getRows().size()); + assertEquals(conceptNames, pivotTable.getHeaders()); + assertEquals(170, pivotTable.getRows().get(0).getValue("HEIGHT").get(0).getValue()); + } + + @Test + public void shouldReturnOnlyLeafObservationsInTabularFormat() throws Exception { + EncounterTransaction.Concept heightConcept = new ETConceptBuilder().withName("HEIGHT").withUuid("height uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept weightConcept = new ETConceptBuilder().withName("WEIGHT").withUuid("weight uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept vitalsConcept = new ETConceptBuilder().withName("Vitals").withUuid("vitals uuid").withSet(true).withClass("Misc").build(); + EncounterTransaction.Concept systolicConcept = new ETConceptBuilder().withName("Systolic").withUuid("Systolic uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept diastolicConcept = new ETConceptBuilder().withName("Diastolic").withUuid("Diastolic uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept bpConcept = new ETConceptBuilder().withName("BP").withUuid("BP uuid").withSet(true).withClass("Misc").build(); + + BahmniObservation systolic = new BahmniObservationBuilder().withConcept(systolicConcept).withValue(120).build(); + BahmniObservation diastolic = new BahmniObservationBuilder().withConcept(diastolicConcept).withValue(90).build(); + BahmniObservation bp = new BahmniObservationBuilder().withConcept(bpConcept).withGroupMember(systolic).withGroupMember(diastolic).build(); + BahmniObservation height = new BahmniObservationBuilder().withConcept(heightConcept).withValue(170).build(); + BahmniObservation weight = new BahmniObservationBuilder().withConcept(weightConcept).withValue(80).build(); + BahmniObservation vitals = new BahmniObservationBuilder().withConcept(vitalsConcept).withGroupMember(height).withGroupMember(weight).withGroupMember(bp).build(); + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(vitals); + + Set conceptNames = new HashSet<>(); + conceptNames.add(heightConcept); + conceptNames.add(weightConcept); + conceptNames.add(systolicConcept); + conceptNames.add(diastolicConcept); + + PivotTable pivotTable = bahmniObservationsToTabularViewMapper.constructTable(conceptNames, bahmniObservations, groupByConcept); + + assertNotNull(pivotTable); + assertEquals(1, pivotTable.getRows().size()); + assertEquals(conceptNames, pivotTable.getHeaders()); + assertEquals(170, pivotTable.getRows().get(0).getValue("HEIGHT").get(0).getValue()); + assertEquals(80, pivotTable.getRows().get(0).getValue("WEIGHT").get(0).getValue()); + assertEquals(120, pivotTable.getRows().get(0).getValue("Systolic").get(0).getValue()); + assertEquals(90, pivotTable.getRows().get(0).getValue("Diastolic").get(0).getValue()); + } + + @Test + public void shouldReturnMultipleRowsIfThereAreMultipleRootObservations() throws Exception { + EncounterTransaction.Concept heightConcept = new ETConceptBuilder().withName("HEIGHT").withUuid("height uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept weightConcept = new ETConceptBuilder().withName("WEIGHT").withUuid("weight uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept vitalsConcept = new ETConceptBuilder().withName("Vitals").withUuid("vitals uuid").withSet(true).withClass("Misc").build(); + BahmniObservation firstHeight = new BahmniObservationBuilder().withConcept(heightConcept).withValue(170).build(); + BahmniObservation firstWeight = new BahmniObservationBuilder().withConcept(weightConcept).withValue(80).build(); + BahmniObservation firstVitals = new BahmniObservationBuilder().withConcept(vitalsConcept).withGroupMember(firstHeight).withGroupMember(firstWeight).build(); + + + BahmniObservation secondHeight = new BahmniObservationBuilder().withConcept(heightConcept).withValue(180).build(); + BahmniObservation secondWeight = new BahmniObservationBuilder().withConcept(weightConcept).withValue(90).build(); + BahmniObservation secondVitals = new BahmniObservationBuilder().withConcept(vitalsConcept).withGroupMember(secondHeight).withGroupMember(secondWeight).build(); + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(firstVitals); + bahmniObservations.add(secondVitals); + + HashSet conceptNames = new HashSet<>(); + conceptNames.add(heightConcept); + conceptNames.add(weightConcept); + + PivotTable pivotTable = bahmniObservationsToTabularViewMapper.constructTable(conceptNames, bahmniObservations, groupByConcept); + + assertNotNull(pivotTable); + assertEquals(2, pivotTable.getRows().size()); + assertEquals(conceptNames, pivotTable.getHeaders()); + assertEquals(170, pivotTable.getRows().get(0).getValue("HEIGHT").get(0).getValue()); + assertEquals(80, pivotTable.getRows().get(0).getValue("WEIGHT").get(0).getValue()); + assertEquals(180, pivotTable.getRows().get(1).getValue("HEIGHT").get(0).getValue()); + assertEquals(90, pivotTable.getRows().get(1).getValue("WEIGHT").get(0).getValue()); + } + + @Test + public void shouldRetrunEmptyTableIfThereAreNoObservations() throws Exception { + PivotTable pivotTable = bahmniObservationsToTabularViewMapper.constructTable(null, null, groupByConcept); + + assertNotNull(pivotTable); + assertEquals(0, pivotTable.getRows().size()); + assertEquals(0, pivotTable.getHeaders().size()); + } + + @Test + public void shouldRetrunEmptyTableIfAllTheObservationValuesAreNull() throws Exception { + EncounterTransaction.Concept heightConcept = new ETConceptBuilder().withName("HEIGHT").withUuid("height uuid").withSet(false).withClass("Misc").build(); + EncounterTransaction.Concept weightConcept = new ETConceptBuilder().withName("WEIGHT").withUuid("weight uuid").withSet(false).withClass("Misc").build(); + + BahmniObservation height = new BahmniObservationBuilder().withConcept(heightConcept).withValue(null).build(); + BahmniObservation weight = new BahmniObservationBuilder().withConcept(weightConcept).withValue(null).build(); + ArrayList bahmniObservations = new ArrayList<>(); + bahmniObservations.add(height); + bahmniObservations.add(weight); + + Set conceptNames = new HashSet<>(); + conceptNames.add(heightConcept); + conceptNames.add(weightConcept); + PivotTable pivotTable = bahmniObservationsToTabularViewMapper.constructTable(conceptNames, bahmniObservations, "test concept"); + + assertNotNull(pivotTable); + assertEquals(0, pivotTable.getRows().size()); + assertEquals(2, pivotTable.getHeaders().size()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniPatientContextMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniPatientContextMapperTest.java new file mode 100644 index 0000000000..27b32a40f7 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/BahmniPatientContextMapperTest.java @@ -0,0 +1,213 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.PersonAttribute; +import org.openmrs.PersonAttributeType; +import org.openmrs.PersonName; +import org.openmrs.PatientProgram; +import org.openmrs.PatientProgramAttribute; +import org.openmrs.ProgramAttributeType; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.bahmniemrapi.patient.PatientContext; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class BahmniPatientContextMapperTest { + + private BahmniPatientContextMapper bahmniPatientContextMapper = new BahmniPatientContextMapper(); + private PatientIdentifierType primaryIdentifierType; + + @Before + public void setUp() throws Exception { + primaryIdentifierType = new PatientIdentifierType(); + primaryIdentifierType.setName("Primary Identifier"); + } + + @Test + public void shouldMapPatientInformationToPatientContext() { + Patient patient = new Patient(); + patient.setBirthdate(new Date()); + patient.setGender("Male"); + patient.setNames(getPersonNames("GivenName", "MiddleName", "FamilyName")); + patient.addIdentifier(createPrimaryIdentifier("GAN20000")); + Set attributes = new LinkedHashSet<>(); + attributes.add(getPersonAttribute("Caste", "Caste", "Caste Value", "java.lang.String")); + attributes.add(getPersonAttribute("Education", "Education", "Education Value", "java.lang.String")); + patient.setAttributes(attributes); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), Collections.singletonList("Caste"), Collections.singletonList("IRDB Number"), null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(patient.getBirthdate(), patientContext.getBirthdate()); + assertEquals(patient.getIdentifiers().iterator().next().getIdentifier(), patientContext.getIdentifier()); + assertEquals(patient.getGender(), patientContext.getGender()); + assertEquals(patient.getFamilyName(), patientContext.getFamilyName()); + assertEquals(patient.getMiddleName(), patientContext.getMiddleName()); + assertEquals(patient.getGivenName(), patientContext.getGivenName()); + assertEquals(1, patientContext.getPersonAttributes().size()); + assertEquals("Caste Value", patientContext.getPersonAttributes().get("Caste").get("value")); + assertEquals("Caste", patientContext.getPersonAttributes().get("Caste").get("description")); + } + + @Test + public void shouldNotReturnPersonAttributesIfTheConfiguredAttributesAreNotExists() { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), Collections.singletonList("Caste"), Arrays.asList("IRDB Number"), null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(0, patientContext.getPersonAttributes().size()); + } + + private Patient setUpPatient() { + Patient patient = new Patient(); + Set names = getPersonNames("GivenName", "MiddleName", "FamilyName"); + patient.setNames(names); + PatientIdentifier primaryIdentifier = createPrimaryIdentifier("GAN20000"); + Set identifiers = new HashSet<>(); + identifiers.addAll(Collections.singletonList(primaryIdentifier)); + patient.setIdentifiers(identifiers); + return patient; + } + + private PatientIdentifier createPrimaryIdentifier(String value) { + return new PatientIdentifier(value, primaryIdentifierType, null); + } + + @Test + public void shouldMapProgramAttributesToPatientContext() { + Patient patient = setUpPatient(); + + PatientProgram patientProgram = new PatientProgram(); + HashSet patientProgramAttributes = new HashSet<>(); + patientProgramAttributes.add(getPatientProgramAttribute("IRDB Number", "IRDB Number Description", "1234", "String")); + patientProgramAttributes.add(getPatientProgramAttribute("TSRT Number", "TSRT Number", "9876", "String")); + patientProgram.setAttributes(patientProgramAttributes); + PatientContext patientContext = bahmniPatientContextMapper.map(patient, patientProgram, Collections.singletonList("Caste"), Collections.singletonList("IRDB Number"), null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(1, patientContext.getProgramAttributes().size()); + assertEquals("1234", patientContext.getProgramAttributes().get("IRDB Number").get("value")); + } + + @Test + public void shouldNotReturnProgramAttributesIfTheConfiguredAttributesAreNotExists() { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), Collections.singletonList("Caste"), Collections.singletonList("IRDB Number"), null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldNotReturnProgramAttributesIfTheProgramDoesNotExists() { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, null, Collections.singletonList("Caste"), Collections.singletonList("IRDB Number"), null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldNotReturnProgramAttributesIfNotConfigured() { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), Collections.singletonList("Caste"), null, null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldNotReturnPersonAttributesIfNotConfigured() { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), null, Collections.singletonList("IRDTB Number"), null, primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals(0, patientContext.getProgramAttributes().size()); + } + + @Test + public void shouldReturnConfiguredExtraIdentifier() throws Exception { + Patient patient = setUpPatient(); + PatientIdentifier nationalIdentifier = createIdentifier("National Identifier", "NAT10020"); + patient.addIdentifier(nationalIdentifier); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), null, null, Collections.singletonList("National Identifier"), primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals("GAN20000", patientContext.getIdentifier()); + assertEquals(1, patientContext.getAdditionalPatientIdentifiers().size()); + assertEquals("NAT10020", patientContext.getAdditionalPatientIdentifiers().get("National Identifier")); + } + + @Test + public void shouldNotReturnConfiguredExtraIdentifierIfDataIsNotCaptured() throws Exception { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), null, null, Collections.singletonList("National Identifier"), primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals("GAN20000", patientContext.getIdentifier()); + assertEquals(0, patientContext.getAdditionalPatientIdentifiers().size()); + } + + @Test + public void shouldNotReturnPrimaryIdentifierInExtraIdentifiersListIfConfigured() throws Exception { + Patient patient = setUpPatient(); + + PatientContext patientContext = bahmniPatientContextMapper.map(patient, new PatientProgram(), null, null, Collections.singletonList("Primary Identifier"), primaryIdentifierType); + + assertNotNull(patientContext); + assertEquals("GAN20000", patientContext.getIdentifier()); + assertEquals(0, patientContext.getAdditionalPatientIdentifiers().size()); + } + + + + + private PatientIdentifier createIdentifier(String type, String value) { + PatientIdentifierType patientIdentifierType = new PatientIdentifierType(); + patientIdentifierType.setName(type); + return new PatientIdentifier(value, patientIdentifierType, null); + } + + private Set getPersonNames(String givenName, String middleName, String familyName) { + Set names = new LinkedHashSet<>(); + names.add(new PersonName(givenName, middleName, familyName)); + return names; + } + + private PatientProgramAttribute getPatientProgramAttribute(String typeName, String typeDescription, String value, String dataTypeClassName) { + PatientProgramAttribute patientProgramAttribute = new PatientProgramAttribute(); + ProgramAttributeType attributeType = new ProgramAttributeType(); + attributeType.setName(typeName); + attributeType.setDescription(typeDescription); + attributeType.setDatatypeClassname(dataTypeClassName); + patientProgramAttribute.setAttributeType(attributeType); + patientProgramAttribute.setValueReferenceInternal(value); + return patientProgramAttribute; + } + + private PersonAttribute getPersonAttribute(String typeName, String typeDescription, String value, String format) { + PersonAttributeType attributeType = new PersonAttributeType(); + attributeType.setName(typeName); + attributeType.setDescription(typeDescription); + attributeType.setFormat(format); + return new PersonAttribute(attributeType, value); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToRegimenMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToRegimenMapperTest.java new file mode 100644 index 0000000000..508203ab4b --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToRegimenMapperTest.java @@ -0,0 +1,342 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.OrderFrequency; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.TestUsernameAuthenticationScheme; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.builder.ConceptBuilder; +import org.openmrs.module.bahmniemrapi.drugogram.contract.RegimenRow; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({LocaleUtility.class}) +public class DrugOrderToRegimenMapperTest { + + private DrugOrderToRegimenMapper drugOrderToRegimenMapper; + + + Concept bdq; + + Concept dlm; + + + @Before + public void setUp() { + initMocks(this); + mockStatic(LocaleUtility.class); + PowerMockito.when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + Context.setUserContext(new UserContext(new TestUsernameAuthenticationScheme())); + bdq = new ConceptBuilder().withName("Bedaquiline").withDataType("N/A").build(); + dlm = new ConceptBuilder().withName("Delamanid").withDataType("N/A").build(); + drugOrderToRegimenMapper = new DrugOrderToRegimenMapper(); + } + + + @Test + public void shouldSetErrorWhenDrugIsStartedAndStoppedOnTheSameDate() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2016-01-10")); + drugOrder.setAutoExpireDate(sdf.parse("2016-01-10")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String value = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2016-01-10")); + assertEquals(value, "Error"); + } + + @Test + public void shouldSetDoseWhenDrugIsWithinTheRange() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2016-01-10")); + drugOrder.setAutoExpireDate(sdf.parse("2016-01-15")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String dose = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2016-01-12")); + assertEquals(dose, "200.0"); + } + + @Test + public void shouldSetStopWhenDrugIsStoppedOnRowDate() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2016-01-10")); + drugOrder.setAutoExpireDate(sdf.parse("2016-01-20")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String value = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2016-01-20")); + assertEquals(value, "Stop"); + } + + @Test + public void shouldSetEmptyStringWhenDrugOrderIsStoppedBeforeRowDate() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2015-01-10")); + drugOrder.setAutoExpireDate(sdf.parse("2015-01-20")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String value = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2015-01-21")); + assertEquals(value, ""); + } + + @Test + public void shouldSetEmptyStringWhenDrugOrderIsStoppedAfterRowDate() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2015-01-10")); + drugOrder.setAutoExpireDate(sdf.parse("2015-01-20")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String value = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2014-01-21")); + assertEquals(value, ""); + } + + @Test + public void shouldSetDoseForActiveDrugRegimen() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2015-01-10")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String value = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2015-01-21")); + assertEquals(value, "200.0"); + } + + @Test + public void shouldSetEmptyForActiveDrugRegimenAfterTheStartDate() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + drugOrder.setDateActivated(sdf.parse("2016-01-10")); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + + String value = drugOrderToRegimenMapper.getValueForField(drugOrder, sdf.parse("2015-01-21")); + assertEquals(value, ""); + } + + + @Test + public void shouldCreateTwoRegimenRowsForSingleDrugOrder() throws ParseException { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date dateActivated = sdf.parse("2015-01-10"); + Date dateStopped = sdf.parse("2015-01-20"); + drugOrder.setDateActivated(dateActivated); + drugOrder.setAutoExpireDate(dateStopped); + drugOrder.setDose(200.0); + drugOrder.setFrequency(orderFrequency); + drugOrder.setConcept(bdq); + + Set headerConfig = new LinkedHashSet<>(); + headerConfig.add(bdq); + + + TreatmentRegimen treatmentRegimen = drugOrderToRegimenMapper.map(asList((Order) drugOrder), headerConfig); + + List regimenRows = new ArrayList<>(); + regimenRows.addAll(treatmentRegimen.getRows()); + + assertEquals(2, regimenRows.size()); + assertEquals(regimenRows.get(0).getDate(), dateActivated); + assertEquals(regimenRows.get(1).getDate(), dateStopped); + + assertEquals(1, regimenRows.get(0).getDrugs().size()); + assertEquals(1, regimenRows.get(1).getDrugs().size()); + assertEquals("200.0", regimenRows.get(0).getDrugs().get("Bedaquiline")); + assertEquals("Stop", regimenRows.get(1).getDrugs().get("Bedaquiline")); + } + + @Test + public void shouldCreateRegimenRowsForDrugOrdersOfSameType() throws ParseException { + Set headerConfig = new LinkedHashSet<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + headerConfig.add(bdq); + + + List drugOrders = constructDrugOrdersForList(Arrays.asList( + new DrugOrderData("2016-01-10", "2016-01-20", bdq, 200.0), + new DrugOrderData("2016-01-21", "2016-01-30", bdq, 300.0), + new DrugOrderData("2016-01-30", "2016-02-20", bdq, 200.0), + new DrugOrderData("2016-03-03", "2016-03-03", bdq, 1000.0) + )); + + TreatmentRegimen treatmentRegimen = drugOrderToRegimenMapper.map(drugOrders, headerConfig); + + List regimenRows = new ArrayList<>(); + regimenRows.addAll(treatmentRegimen.getRows()); + + assertEquals(6, regimenRows.size()); + assertEquals(regimenRows.get(0).getDate(),sdf.parse("2016-01-10")); + assertEquals(regimenRows.get(1).getDate(),sdf.parse("2016-01-20")); + assertEquals(regimenRows.get(2).getDate(),sdf.parse("2016-01-21")); + assertEquals(regimenRows.get(3).getDate(),sdf.parse("2016-01-30")); + assertEquals(regimenRows.get(4).getDate(),sdf.parse("2016-02-20")); + assertEquals(regimenRows.get(5).getDate(),sdf.parse("2016-03-03")); + + assertEquals(1, regimenRows.get(0).getDrugs().size()); + assertEquals("200.0", regimenRows.get(0).getDrugs().get("Bedaquiline")); + assertEquals("Stop", regimenRows.get(1).getDrugs().get("Bedaquiline")); + assertEquals("300.0", regimenRows.get(2).getDrugs().get("Bedaquiline")); + assertEquals("200.0", regimenRows.get(3).getDrugs().get("Bedaquiline")); + assertEquals("Stop", regimenRows.get(4).getDrugs().get("Bedaquiline")); + assertEquals("Error", regimenRows.get(5).getDrugs().get("Bedaquiline")); + } + + @Test + public void shouldCreateRegimenRowsForTwoDifferentDrugOrders() throws ParseException { + Set headerConfig = new LinkedHashSet<>(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + + List drugOrders = constructDrugOrdersForList(Arrays.asList( + new DrugOrderData("2016-01-10", "2016-01-20", bdq, 200.0), + new DrugOrderData("2016-01-21", "2016-01-30", bdq, 300.0), + new DrugOrderData("2016-01-30", "2016-02-20", bdq, 400.0), + new DrugOrderData("2016-03-03", "2016-03-03", bdq, 450.0), + new DrugOrderData("2016-01-01", "2016-01-10", dlm, 500.0), + new DrugOrderData("2016-01-11", "2016-01-20", dlm, 600.0), + new DrugOrderData("2016-01-10", "2016-03-03", dlm, 550.0) + )); + + TreatmentRegimen treatmentRegimen = drugOrderToRegimenMapper.map(drugOrders, headerConfig); + + List regimenRows = new ArrayList<>(); + regimenRows.addAll(treatmentRegimen.getRows()); + + assertEquals(8, regimenRows.size()); + assertEquals(regimenRows.get(0).getDate(),sdf.parse("2016-01-01")); + assertEquals(regimenRows.get(1).getDate(),sdf.parse("2016-01-10")); + assertEquals(regimenRows.get(2).getDate(),sdf.parse("2016-01-11")); + assertEquals(regimenRows.get(3).getDate(),sdf.parse("2016-01-20")); + assertEquals(regimenRows.get(4).getDate(),sdf.parse("2016-01-21")); + assertEquals(regimenRows.get(5).getDate(),sdf.parse("2016-01-30")); + assertEquals(regimenRows.get(6).getDate(),sdf.parse("2016-02-20")); + assertEquals(regimenRows.get(7).getDate(),sdf.parse("2016-03-03")); + + assertEquals(1, regimenRows.get(0).getDrugs().size()); + assertEquals(2, regimenRows.get(1).getDrugs().size()); + assertEquals(2, regimenRows.get(2).getDrugs().size()); + assertEquals(2, regimenRows.get(3).getDrugs().size()); + assertEquals(2, regimenRows.get(4).getDrugs().size()); + assertEquals(2, regimenRows.get(5).getDrugs().size()); + assertEquals(2, regimenRows.get(6).getDrugs().size()); + assertEquals(2, regimenRows.get(7).getDrugs().size()); + + + assertNull(regimenRows.get(0).getDrugs().get("Bedaquiline")); + assertEquals("200.0", regimenRows.get(1).getDrugs().get("Bedaquiline")); + assertEquals("200.0", regimenRows.get(2).getDrugs().get("Bedaquiline")); + assertEquals("Stop", regimenRows.get(3).getDrugs().get("Bedaquiline")); + assertEquals("300.0", regimenRows.get(4).getDrugs().get("Bedaquiline")); + assertEquals("400.0", regimenRows.get(5).getDrugs().get("Bedaquiline")); + assertEquals("Stop", regimenRows.get(6).getDrugs().get("Bedaquiline")); + assertEquals("Error", regimenRows.get(7).getDrugs().get("Bedaquiline")); + + assertEquals("500.0",regimenRows.get(0).getDrugs().get("Delamanid")); + assertEquals("550.0", regimenRows.get(1).getDrugs().get("Delamanid")); + assertEquals("Error", regimenRows.get(2).getDrugs().get("Delamanid")); + assertEquals("550.0", regimenRows.get(3).getDrugs().get("Delamanid")); + assertEquals("550.0", regimenRows.get(4).getDrugs().get("Delamanid")); + assertEquals("550.0", regimenRows.get(5).getDrugs().get("Delamanid")); + assertEquals("550.0", regimenRows.get(6).getDrugs().get("Delamanid")); + assertEquals("Stop", regimenRows.get(7).getDrugs().get("Delamanid")); + } + + + + + private List constructDrugOrdersForList(List drugOrderList) throws ParseException { + List drugOrders = new ArrayList<>(); + + for (DrugOrderData orderData : drugOrderList) { + DrugOrder drugOrder = new DrugOrder(); + OrderFrequency orderFrequency = new OrderFrequency(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date dateActivated = sdf.parse(orderData.getDateActivated()); + Date dateStopped = sdf.parse(orderData.getDateStopped()); + drugOrder.setDateActivated(dateActivated); + drugOrder.setAutoExpireDate(dateStopped); + drugOrder.setDose(orderData.getDose()); + drugOrder.setFrequency(orderFrequency); + drugOrder.setConcept(orderData.getConcept()); + drugOrders.add((Order)drugOrder); + } + + return drugOrders; + } + + private class DrugOrderData { + private String dateActivated; + private String dateStopped; + private Double dose; + private Concept concept; + + private DrugOrderData(String dateActivated, String dateStopped, Concept concept, Double dose) { + this.dateActivated = dateActivated; + this.dose = dose; + this.dateStopped = dateStopped; + this.concept = concept; + } + + + public String getDateActivated() { + return dateActivated; + } + + public String getDateStopped() { + return dateStopped; + } + + public Double getDose() { + return dose; + } + + public void setDose(Double dose) { + this.dose = dose; + } + + public Concept getConcept() { + return concept; + } + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToTreatmentRegimenMapperTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToTreatmentRegimenMapperTest.java new file mode 100644 index 0000000000..89f36f0fdd --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/mapper/DrugOrderToTreatmentRegimenMapperTest.java @@ -0,0 +1,719 @@ +package org.bahmni.module.bahmnicore.web.v1_0.mapper; + +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.DrugOrderBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.DrugOrder; +import org.openmrs.Order; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.TestUsernameAuthenticationScheme; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bahmniemrapi.drugogram.contract.RegimenRow; +import org.openmrs.module.bahmniemrapi.drugogram.contract.TreatmentRegimen; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({LocaleUtility.class}) +public class DrugOrderToTreatmentRegimenMapperTest { + + private DrugOrderToRegimenMapper drugOrderToTreatmentRegimenMapper; + + public static final String DAY_DURATION_UNIT = "Day"; + + + @Before + public void setUp() throws Exception { + initMocks(this); + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + Context.setUserContext(new UserContext(new TestUsernameAuthenticationScheme())); + drugOrderToTreatmentRegimenMapper = new DrugOrderToRegimenMapper(); + } + + @Test + public void shouldMapDrugOrdersWhichStartOnSameDateAndEndOnDifferentDateAndCrossEachOther() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(now).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 6)).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", stoppedDateRow.getDrugs().get("Paracetemol")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 6)), thirdRow.getDate()); + assertEquals(null, thirdRow.getDrugs().get("Ibeprofen")); + assertEquals("Stop", thirdRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldMapDrugOrdersWhichStartAndEndOnSameDate() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(now).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(2, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldMapDrugOrdersWhichStartAndEndOnDifferentDateDoesntOverlap() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(addDays(now, 3)).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), stoppedDateRow.getDate()); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, stoppedDateRow.getDrugs().get("Paracetemol")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 3)), thirdRow.getDate()); + assertEquals(null, thirdRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", thirdRow.getDrugs().get("Paracetemol")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), fourthRow.getDate()); + assertEquals(null, fourthRow.getDrugs().get("Ibeprofen")); + assertEquals("Stop", fourthRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldMapDrugOrdersWhichStartAndEndOnDifferentDateAndOverlaps() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 3)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(addDays(now, 2)).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), stoppedDateRow.getDate()); + assertEquals("1000.0", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", stoppedDateRow.getDrugs().get("Paracetemol")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 3)), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", thirdRow.getDrugs().get("Paracetemol")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), fourthRow.getDate()); + assertEquals(null, fourthRow.getDrugs().get("Ibeprofen")); + assertEquals("Stop", fourthRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldSetErrorWhenDrugIsStartedAndStoppedOnTheSameDay() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(now).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(1, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals(1, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("Error", startDateRow.getDrugs().get("Ibeprofen")); + } + + + @Test + public void shouldMapTo2RowsIf2DrugsAreStartedAndStoppedOnTheSameDayButOnDifferentDays() throws Exception { + // I know the test name sounds weird. If you have any better name, feel free to change it. + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(now).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetamol = new DrugOrderBuilder().withDrugName("Paracetamol").withDateActivated(addDays(now, 2)).withDose(500.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withConcept(new ConceptBuilder().withName("Paracetamol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetamol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetamol", headerIterator.next().getName()); + assertEquals(2, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(now), firstRow.getDate()); + assertEquals("Error", firstRow.getDrugs().get("Ibeprofen")); + assertEquals(null, firstRow.getDrugs().get("Paracetamol")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now,2)), secondRow.getDate()); + assertEquals(null, secondRow.getDrugs().get("Ibeprofen")); + assertEquals("Error", secondRow.getDrugs().get("Paracetamol")); + + } + + @Test + public void shouldNotFetchTheDrugIfTheDrugIsStoppedBeforeScheduledDate() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withScheduledDate(addDays(now, 10)).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 3)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + + drugOrders.add(ibeprofen); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(1, treatmentRegimen.getHeaders().size()); + assertEquals(2, treatmentRegimen.getRows().size()); + } + + + + @Test + public void shouldMapScheduledDrugOrders() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder pmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(now).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder caffeine = new DrugOrderBuilder().withDrugName("Caffeine").withScheduledDate(now).withDose(500.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 3)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("Caffeine").withUUID("Caffeine uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder lajvanti = new DrugOrderBuilder().withDrugName("Lajvanti").withScheduledDate(addDays(now, 2)).withDose(3.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("Lajvanti").withUUID("Lajvanti uuid").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(pmg); + drugOrders.add(caffeine); + drugOrders.add(lajvanti); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(3, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("P 500mg", headerIterator.next().getName()); + assertEquals("Caffeine", headerIterator.next().getName()); + assertEquals("Lajvanti", headerIterator.next().getName()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(now), firstRow.getDate()); + assertEquals("Error", firstRow.getDrugs().get("P 500mg")); + assertEquals("500.0", firstRow.getDrugs().get("Caffeine")); + assertEquals(null, firstRow.getDrugs().get("Lajvanti")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), secondRow.getDate()); + assertEquals(null, secondRow.getDrugs().get("P 500mg")); + assertEquals("500.0", secondRow.getDrugs().get("Caffeine")); + assertEquals("3.0", secondRow.getDrugs().get("Lajvanti")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 3)), thirdRow.getDate()); + assertEquals(null, thirdRow.getDrugs().get("P 500mg")); + assertEquals("Stop", thirdRow.getDrugs().get("Caffeine")); + assertEquals("3.0", thirdRow.getDrugs().get("Lajvanti")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), fourthRow.getDate()); + assertEquals(null, fourthRow.getDrugs().get("P 500mg")); + assertEquals(null, fourthRow.getDrugs().get("Caffeine")); + assertEquals("Stop", fourthRow.getDrugs().get("Lajvanti")); + } + + @Test + public void shouldRetrieveIfTheDrugStartedAndStoppedOnTheSameDayLiesBetweenOtherDrug() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder pmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder revisedPmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(addDays(now, 2)).withDose(10.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 10)).withOrderAction(Order.Action.REVISE).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder caffeine = new DrugOrderBuilder().withDrugName("Caffeine").withDateActivated(addDays(now, 2)).withDose(600.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("Caffeine").withUUID("Caffeine uuid").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(pmg); + drugOrders.add(revisedPmg); + drugOrders.add(caffeine); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("P 500mg", headerIterator.next().getName()); + assertEquals("Caffeine", headerIterator.next().getName()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(now), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("P 500mg")); + assertEquals(null, firstRow.getDrugs().get("Caffeine")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), secondRow.getDate()); + assertEquals("10.0", secondRow.getDrugs().get("P 500mg")); + assertEquals("Error", secondRow.getDrugs().get("Caffeine")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 10)), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("P 500mg")); + assertEquals(null, thirdRow.getDrugs().get("Caffeine")); + } + + @Test + public void shouldRetrieveIfTheDrugStartsOntheDayOfTheOtherDrugsStopped() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder pmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder revisedPmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(addDays(now, 2)).withDose(10.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 10)).withOrderAction(Order.Action.REVISE).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder caffeine = new DrugOrderBuilder().withDrugName("Caffeine").withDateActivated(addDays(now, 10)).withDose(600.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 12)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("Caffeine").withUUID("Caffeine uuid").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(pmg); + drugOrders.add(revisedPmg); + drugOrders.add(caffeine); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("P 500mg", headerIterator.next().getName()); + assertEquals("Caffeine", headerIterator.next().getName()); + assertEquals(4, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(now), firstRow.getDate()); + assertEquals("1000.0", firstRow.getDrugs().get("P 500mg")); + assertEquals(null, firstRow.getDrugs().get("Caffeine")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), secondRow.getDate()); + assertEquals("10.0", secondRow.getDrugs().get("P 500mg")); + assertEquals(null, secondRow.getDrugs().get("Caffeine")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 10)), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("P 500mg")); + assertEquals("600.0", thirdRow.getDrugs().get("Caffeine")); + + RegimenRow fourthRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 12)), fourthRow.getDate()); + assertEquals(null, fourthRow.getDrugs().get("P 500mg")); + assertEquals("Stop", fourthRow.getDrugs().get("Caffeine")); + } + + @Test + public void shouldRetrieveIfTheDrugStartsOntheDayOfTheOtherDrugsStoppedAndTheDrugIsRevised() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder pmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(now).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder revisedPmg = new DrugOrderBuilder().withDrugName("P 500mg").withDateActivated(now).withDose(500.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 10)).withOrderAction(Order.Action.REVISE).withConcept(new ConceptBuilder().withName("P 500mg").withUUID("P 500mg uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder caffeine = new DrugOrderBuilder().withDrugName("Caffeine").withDateActivated(addDays(now, 10)).withDose(600.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 10)).withOrderAction(Order.Action.NEW).withConcept(new ConceptBuilder().withName("Caffeine").withUUID("Caffeine uuid").withSet(false).withDataType("N/A").build()).build(); + DrugOrder revisedCaffeine = new DrugOrderBuilder().withDrugName("Caffeine").withDateActivated(addDays(now, 10)).withDose(800.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 12)).withOrderAction(Order.Action.REVISE).withConcept(new ConceptBuilder().withName("Caffeine").withUUID("Caffeine uuid").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(pmg); + drugOrders.add(revisedPmg); + drugOrders.add(caffeine); + drugOrders.add(revisedCaffeine); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("P 500mg", headerIterator.next().getName()); + assertEquals("Caffeine", headerIterator.next().getName()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow firstRow = rowIterator.next(); + assertEquals(getOnlyDate(now), firstRow.getDate()); + assertEquals("Error", firstRow.getDrugs().get("P 500mg")); + assertEquals(null, firstRow.getDrugs().get("Caffeine")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 10)), secondRow.getDate()); + assertEquals("Stop", secondRow.getDrugs().get("P 500mg")); + assertEquals("Error", secondRow.getDrugs().get("Caffeine")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 12)), thirdRow.getDate()); + assertEquals(null, thirdRow.getDrugs().get("P 500mg")); + assertEquals("Stop", thirdRow.getDrugs().get("Caffeine")); + } + + private Date addDays(Date now, int days) { + Calendar c = Calendar.getInstance(); + c.setTime(now); + c.add(Calendar.DATE, days); + return c.getTime(); + } + + public Date getOnlyDate(Date date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(sdf.format(date)); + } + + @Test + public void shouldMapDrugOrdersWhichStartOnSameDateAndOneEndsInFiveDaysAnotherContinues() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(now).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(2, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", stoppedDateRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldMapDrugOrdersWhichStartOnDifferentDatesAndOneEndsInFiveDaysAnotherContinues() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(addDays(now, 2)).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), secondRow.getDate()); + assertEquals("1000.0", secondRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", secondRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", stoppedDateRow.getDrugs().get("Paracetemol")); + } + + + @Test + public void shouldMapDrugOrderWhichHaveNoStopDate() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(now).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(1, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(1, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("200.0", startDateRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldMapDrugOrdersWhichStartOnDifferentDatesAndOneStoppedBeforeAnotherStartsContinues() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(addDays(now, 5)).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, null); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals(3, treatmentRegimen.getRows().size()); + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), secondRow.getDate()); + assertEquals("Stop", secondRow.getDrugs().get("Ibeprofen")); + assertEquals(null, secondRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals(null, stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", stoppedDateRow.getDrugs().get("Paracetemol")); + } + + + @Test + public void shouldFetchTheAsTheOrderSpecifiedInTheConceptNames() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDose(1000.0).withFrequency(DAY_DURATION_UNIT).withAutoExpireDate(addDays(now, 2)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDateActivated(addDays(now, 5)).withDose(200.0).withFrequency(DAY_DURATION_UNIT).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + ConceptName paracetamolConceptName = new ConceptName("Paracetemol", new Locale("en", "in")); + ConceptName ibeprofenConceptName = new ConceptName("Ibeprofen", new Locale("en", "in")); + + Concept paracetemolConcept= new ConceptBuilder().withName(paracetamolConceptName).withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Paracetemol").build(); + Concept ibeprofenConcept= new ConceptBuilder().withName(ibeprofenConceptName).withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Paracetemol").build(); + + Set concepts = new LinkedHashSet<>(); + concepts.add(paracetemolConcept); + concepts.add(ibeprofenConcept); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, concepts); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals(false, headerIterator.hasNext()); + assertEquals(3, treatmentRegimen.getRows().size()); + + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1000.0", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 2)), secondRow.getDate()); + assertEquals("Stop", secondRow.getDrugs().get("Ibeprofen")); + assertEquals(null, secondRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals(null, stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("200.0", stoppedDateRow.getDrugs().get("Paracetemol")); + } + + @Test + public void shouldFetchTheAsTheOrderSpecifiedInTheConceptNamesWithVariableDosing() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + + String dosingInstructions = "{\"morningDose\": \"1\", \"afternoonDose\": \"2\", \"eveningDose\": \"3\"}"; + + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDosingInstructions(dosingInstructions).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDosingInstructions(dosingInstructions).withDateActivated(addDays(now, 3)).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + ConceptName paracetamolConceptName = new ConceptName("Paracetemol", new Locale("en", "in")); + ConceptName ibeprofenConceptName = new ConceptName("Ibeprofen", new Locale("en", "in")); + + Concept paracetemolConcept= new ConceptBuilder().withName(paracetamolConceptName).withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Paracetemol").build(); + Concept ibeprofenConcept= new ConceptBuilder().withName(ibeprofenConceptName).withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Ibeprofen").build(); + + Set concepts = new LinkedHashSet<>(); + concepts.add(paracetemolConcept); + concepts.add(ibeprofenConcept); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, concepts); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals(false, headerIterator.hasNext()); + assertEquals(3, treatmentRegimen.getRows().size()); + + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1-2-3", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 3)), secondRow.getDate()); + assertEquals("1-2-3", secondRow.getDrugs().get("Ibeprofen")); + assertEquals("1-2-3", secondRow.getDrugs().get("Paracetemol")); + + RegimenRow stoppedDateRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), stoppedDateRow.getDate()); + assertEquals("Stop", stoppedDateRow.getDrugs().get("Ibeprofen")); + assertEquals("1-2-3", stoppedDateRow.getDrugs().get("Paracetemol")); + } + + + @Test + public void shouldFetchTheAsTheOrderSpecifiedInTheConceptNamesWithVariableDosingAndOneStoppedOnTheSameDay() throws Exception { + ArrayList drugOrders = new ArrayList<>(); + Date now = new Date(); + + String dosingInstructions = "{\"morningDose\": \"1\", \"afternoonDose\": \"2\", \"eveningDose\": \"3\"}"; + + DrugOrder ibeprofen = new DrugOrderBuilder().withDrugName("Ibeprofen").withDateActivated(now).withDosingInstructions(dosingInstructions).withAutoExpireDate(addDays(now, 5)).withConcept(new ConceptBuilder().withName("Ibeprofen").withSet(false).withDataType("N/A").build()).build(); + DrugOrder paracetemol = new DrugOrderBuilder().withDrugName("Paracetemol").withDosingInstructions(dosingInstructions).withDateActivated(addDays(now, 3)).withAutoExpireDate(addDays(now, 3)).withConcept(new ConceptBuilder().withName("Paracetemol").withSet(false).withDataType("N/A").build()).build(); + drugOrders.add(ibeprofen); + drugOrders.add(paracetemol); + + ConceptName paracetamolConceptName = new ConceptName("Paracetemol", new Locale("en", "in")); + ConceptName ibeprofenConceptName = new ConceptName("Ibeprofen", new Locale("en", "in")); + + Concept paracetemolConcept= new ConceptBuilder().withName(paracetamolConceptName).withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Paracetemol").build(); + Concept ibeprofenConcept= new ConceptBuilder().withName(ibeprofenConceptName).withDescription("Description").withClass("Some").withDataType("N/A").withShortName("Ibeprofen").build(); + + Set concepts = new LinkedHashSet<>(); + concepts.add(paracetemolConcept); + concepts.add(ibeprofenConcept); + + TreatmentRegimen treatmentRegimen = drugOrderToTreatmentRegimenMapper.map(drugOrders, concepts); + + assertNotNull(treatmentRegimen); + assertEquals(2, treatmentRegimen.getHeaders().size()); + Iterator headerIterator = treatmentRegimen.getHeaders().iterator(); + assertEquals("Paracetemol", headerIterator.next().getName()); + assertEquals("Ibeprofen", headerIterator.next().getName()); + assertEquals(false, headerIterator.hasNext()); + assertEquals(3, treatmentRegimen.getRows().size()); + + Iterator rowIterator = treatmentRegimen.getRows().iterator(); + + RegimenRow startDateRow = rowIterator.next(); + assertEquals(getOnlyDate(now), startDateRow.getDate()); + assertEquals("1-2-3", startDateRow.getDrugs().get("Ibeprofen")); + assertEquals(null, startDateRow.getDrugs().get("Paracetemol")); + + RegimenRow secondRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 3)), secondRow.getDate()); + assertEquals("1-2-3", secondRow.getDrugs().get("Ibeprofen")); + assertEquals("Error", secondRow.getDrugs().get("Paracetemol")); + + RegimenRow thirdRow = rowIterator.next(); + assertEquals(getOnlyDate(addDays(now, 5)), thirdRow.getDate()); + assertEquals("Stop", thirdRow.getDrugs().get("Ibeprofen")); + assertEquals(null, thirdRow.getDrugs().get("Paracetemol")); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandlerIT.java new file mode 100644 index 0000000000..6aa3ba8287 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandlerIT.java @@ -0,0 +1,65 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.List; + +public class BacteriologySpecimenSearchHandlerIT extends BahmniMainResourceControllerTest { + @Override + public String getURI() { + return "specimen"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + + @Before + public void setUp() throws Exception { + executeDataSet("search/bacteriologySpecimen/baseBacteriologyData.xml"); + executeDataSet("search/bacteriologySpecimen/existingSpecimenObs.xml"); + executeDataSet("search/bacteriologySpecimen/programEpisodeMapping.xml"); + } + + @Test + public void shouldReturnNoSpecimenForGivenProgramEnrollmentUuidWhenNoDataExist() throws Exception{ + String patientProgramUuid = "patient_program_uuid-not-there"; + + MockHttpServletRequest request = request(RequestMethod.GET, getURI()); + request.addParameter("s", "byPatientProgram"); + request.addParameter("patientProgramUuid", patientProgramUuid); + request.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject object = deserialize(handle(request)); + + List results = object.get("results"); + Assert.assertEquals(0, results.size()); + } + + @Test + public void shouldReturnAllSpecimenForGivenProgramEnrollmentUuid() throws Exception { + String patientProgramUuid = "2edf272c-bf05-4208-9f93-2fa213ed0415";//standardTestDataset.xml + + MockHttpServletRequest request = request(RequestMethod.GET, getURI()); + request.addParameter("s", "byPatientProgram"); + request.addParameter("patientProgramUuid", patientProgramUuid); + request.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject object = deserialize(handle(request)); + + List results = object.get("results"); + Assert.assertEquals(1, results.size()); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandlerTest.java new file mode 100644 index 0000000000..1898d7358a --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BacteriologySpecimenSearchHandlerTest.java @@ -0,0 +1,82 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.api.ConceptService; +import org.openmrs.api.ObsService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.bacteriology.api.BacteriologyService; +import org.openmrs.module.bacteriology.api.encounter.domain.Specimen; +import org.openmrs.module.bacteriology.api.encounter.domain.Specimens; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class BacteriologySpecimenSearchHandlerTest { + + @Mock private ConceptService conceptService; + @Mock private BahmniProgramWorkflowService bahmniProgramWorkflowService; + @Mock private ObsService obsService; + @Mock private RequestContext requestContext; + @Mock private BacteriologyService bacteriologyService; + @Mock private UserContext userContext; + + private BacteriologySpecimenSearchHandler bacteriologySpecimenSearchHandler; + private final String BACTERIOLOGY_CONCEPT_SET = "BACTERIOLOGY CONCEPT SET"; + + @Before + public void before() { + initMocks(this); + when(requestContext.getLimit()).thenReturn(5); + PowerMockito.mockStatic(Context.class); + when(Context.getService(BacteriologyService.class)).thenReturn(bacteriologyService); + + bacteriologySpecimenSearchHandler = new BacteriologySpecimenSearchHandler(bahmniProgramWorkflowService, + conceptService, obsService); + } + + @Test + public void shouldSearchByPatientProgramUuid() { + Concept bacteriologyConceptSet = new Concept(); + Encounter encounter = new Encounter(); + Obs observation = new Obs(); + Specimen specimen = new Specimen(); + Specimens specimens = new Specimens(Arrays.asList(specimen)); + + List encounters = Arrays.asList(encounter); + List concepts = Arrays.asList(bacteriologyConceptSet); + + when(requestContext.getParameter("patientProgramUuid")).thenReturn("sample-patientProgramUuid"); + when(bahmniProgramWorkflowService.getEncountersByPatientProgramUuid("sample-patientProgramUuid")).thenReturn(encounters); + when(conceptService.getConceptByName(BACTERIOLOGY_CONCEPT_SET)).thenReturn(bacteriologyConceptSet); + List observations = Arrays.asList(observation); + when(obsService.getObservations(null, encounters, concepts, null, null, null, null, null, null, null, null, false)) + .thenReturn(observations); + when(bacteriologyService.getSpecimens(observations)).thenReturn(specimens); + + NeedsPaging pageableResult = (NeedsPaging)bacteriologySpecimenSearchHandler.search(requestContext); + Specimens resultSpecimens = new Specimens(pageableResult.getPageOfResults()); + assertEquals(1, resultSpecimens.size()); + assertEquals(specimens, resultSpecimens); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandlerIT.java new file mode 100644 index 0000000000..755cbb4593 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandlerIT.java @@ -0,0 +1,96 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.HashMap; +import java.util.List; + +public class BahmniConceptAnswerSearchHandlerIT extends BahmniMainResourceControllerTest { + @Override + public String getURI() { + return "bahmniconceptanswer"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + + @Before + public void setup() throws Exception { + executeDataSet("search/conceptAnswerSearch/testData.xml"); + } + + @Test + public void shouldSearchAllConceptAnswersOfQuery() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "SIN"); + req.addParameter("s", "byQuestion"); + req.addParameter("question", "CIVIL STATUS"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List bahmniConceptAnswers = result.get("results"); + Assert.assertEquals(1, bahmniConceptAnswers.size()); + + HashMap bahmniConceptAnswer = (HashMap) bahmniConceptAnswers.get(0); + HashMap concept = (HashMap) bahmniConceptAnswer.get("concept"); + String conceptUuid = (String) concept.get("uuid"); + Assert.assertEquals("32d3611a-6699-4d52-823f-b4b788bac3e3",conceptUuid); + + HashMap drug = (HashMap) bahmniConceptAnswer.get("drug"); + Assert.assertNull(drug); + } + + @Test + public void shouldPerformACaseInsensitiveSearch() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "sIn"); + req.addParameter("s", "byQuestion"); + req.addParameter("question", "CIVIL STATUS"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List bahmniConceptAnswers = result.get("results"); + Assert.assertEquals(1, bahmniConceptAnswers.size()); + + HashMap bahmniConceptAnswer = (HashMap) bahmniConceptAnswers.get(0); + HashMap concept = (HashMap) bahmniConceptAnswer.get("concept"); + String conceptUuid = (String) concept.get("uuid"); + Assert.assertEquals("32d3611a-6699-4d52-823f-b4b788bac3e3",conceptUuid); + + HashMap drug = (HashMap) bahmniConceptAnswer.get("drug"); + Assert.assertNull(drug); + } + + @Test + public void shouldSearchConceptDrugAsWell() throws Exception{ + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "Asperen"); + req.addParameter("s", "byQuestion"); + req.addParameter("question", "Diagnosis"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List bahmniConceptAnswers = result.get("results"); + HashMap bahmniConceptAnswer = (HashMap) bahmniConceptAnswers.get(0); + HashMap drug = (HashMap) bahmniConceptAnswer.get("drug"); + String drugName = (String) drug.get("display"); + Assert.assertEquals("Asperen 79 mg",drugName); + + HashMap concept = (HashMap) bahmniConceptAnswer.get("concept"); + Assert.assertNull(concept); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandlerTest.java new file mode 100644 index 0000000000..21d3585309 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptAnswerSearchHandlerTest.java @@ -0,0 +1,62 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniConceptAnswerSearchHandlerTest { + + public static final String QUESTION_CONCEPT = "questionConcept"; + public static final String QUERY = "query"; + @Mock + private BahmniConceptService bahmniConceptService; + private BahmniConceptAnswerSearchHandler bahmniConceptAnswerSearchHandler; + @Mock + RequestContext requestContext; + + @Before + public void before() { + initMocks(this); + bahmniConceptAnswerSearchHandler = new BahmniConceptAnswerSearchHandler(bahmniConceptService); + } + + @Test + public void shouldSearchByQuestion() { + SearchConfig searchConfig = bahmniConceptAnswerSearchHandler.getSearchConfig(); + assertThat(searchConfig.getId(), is(equalTo("byQuestion"))); + } + + @Test + public void shouldSupportVersions1_9To2() { + SearchConfig searchConfig = bahmniConceptAnswerSearchHandler.getSearchConfig(); + assertTrue(searchConfig.getSupportedOpenmrsVersions().contains("1.9.* - 2.*")); + } + + @Test + public void shouldDelegateSearchOfConceptsToBahmniConceptService() { + Collection conceptServiceResult = new ArrayList<>(); + when(bahmniConceptService.searchByQuestion(QUESTION_CONCEPT, QUERY)).thenReturn(conceptServiceResult); + when(requestContext.getParameter("question")).thenReturn(QUESTION_CONCEPT); + when(requestContext.getParameter("q")).thenReturn(QUERY); + + NeedsPaging searchResults = (NeedsPaging) bahmniConceptAnswerSearchHandler.search(requestContext); + + assertThat(searchResults.getPageOfResults().size(), is(equalTo(0))); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerIT.java new file mode 100644 index 0000000000..026f49bd36 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerIT.java @@ -0,0 +1,102 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertTrue; + +public class BahmniConceptSearchByDataTypeHandlerIT extends BahmniMainResourceControllerTest { + @Override + public String getURI() { + return "concept"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + + @Before + public void setup() throws Exception { + executeDataSet("search/conceptDataWithDatatypes.xml"); + updateSearchIndex(); + } + + public void updateSearchIndex() { + for (Class indexType : getIndexedTypes()) { + Context.updateSearchIndexForType(indexType); + } + } + + @Test + public void shouldSearchConceptsWithRequiredDataTypes() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("name", "Tem"); + req.addParameter("s", "byDataType"); + req.addParameter("dataTypes", "Boolean, Numeric, Text"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List concepts = result.get("results"); + + Assert.assertEquals(4, concepts.size()); + + List expectedConceptDisplayNames = Arrays.asList("Temperature-2", "Temperature notes", "Temperature Abnormal", "Temperature"); + + Iterator> iterator = concepts.iterator(); + + while(iterator.hasNext()){ + String actualConceptDisplayName = iterator.next().get("display").toString(); + assertTrue(expectedConceptDisplayNames.contains(actualConceptDisplayName)); + } + } + + @Test + public void shouldReturnAllConceptsWhenDatatypesAreNotSpecified() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("name", "Tem"); + req.addParameter("s", "byDataType"); + req.addParameter("dataTypes", ""); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List concepts = result.get("results"); + + Assert.assertEquals(6, concepts.size()); + } + + @Test + public void shouldSearchConceptsWithOneRequiredDataTypes() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("name", "Tem"); + req.addParameter("s", "byDataType"); + req.addParameter("dataTypes", "Boolean"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List concepts = result.get("results"); + + Assert.assertEquals(1, concepts.size()); + + HashMap bahmniConcept = (HashMap) concepts.get(0); + Assert.assertEquals("abnormal_concept_uuid", bahmniConcept.get("uuid")); + Assert.assertEquals("Temperature Abnormal", ((HashMap)bahmniConcept.get("name")).get("name")); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java new file mode 100644 index 0000000000..bc0bc6f888 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchByDataTypeHandlerTest.java @@ -0,0 +1,88 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.ConceptService; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + + +@RunWith(MockitoJUnitRunner.class) +public class BahmniConceptSearchByDataTypeHandlerTest { + + public static final String DATA_TYPES = "dataTypes"; + public static final String NAME = "ConceptName"; + + @Mock + ConceptService conceptService; + @Mock + RequestContext requestContext; + + @InjectMocks + BahmniConceptSearchByDataTypeHandler bahmniConceptSearchByDataTypeHandler; + + @Before + public void setup() throws Exception { + initMocks(this); + } + + @Test + public void shouldSearchByDataType() { + SearchConfig searchConfig = bahmniConceptSearchByDataTypeHandler.getSearchConfig(); + assertThat(searchConfig.getId(), is(equalTo("byDataType"))); + } + + @Test + public void shouldSupportVersions1_9To2() { + SearchConfig searchConfig = bahmniConceptSearchByDataTypeHandler.getSearchConfig(); + assertTrue(searchConfig.getSupportedOpenmrsVersions().contains("1.9.* - 2.*")); + } + + @Test + public void shouldDelegateSearchOfConceptsToConceptService() { + List conceptSearchResults = new ArrayList<>(); + ConceptSearchResult result = new ConceptSearchResult(); + Concept concept = new Concept(); + concept.setId(10); + result.setConcept(concept); + conceptSearchResults.add(result); + List conceptDatatypes = new ArrayList<>(); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setId(1); + conceptDatatypes.add(conceptDatatype); + List localeList = new ArrayList<>(); + localeList.add(Locale.ENGLISH); + when(conceptService.getConceptDatatypeByName(DATA_TYPES)).thenReturn(conceptDatatype); + when(conceptService.getConcepts(NAME, localeList, false, null, null, conceptDatatypes, + null, null, 0, 10)).thenReturn(conceptSearchResults); + + when(requestContext.getParameter("name")).thenReturn(NAME); + when(requestContext.getParameter("dataTypes")).thenReturn(DATA_TYPES); + when(requestContext.getParameter("locale")).thenReturn(Locale.ENGLISH.toString()); + when(requestContext.getLimit()).thenReturn(10); + + NeedsPaging searchResults = (NeedsPaging) bahmniConceptSearchByDataTypeHandler.search(requestContext); + + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + assertThat(searchResults.getPageOfResults().get(0).getId(), is(equalTo(10))); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java new file mode 100644 index 0000000000..5bdbd50bb0 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniConceptSearchHandlerTest.java @@ -0,0 +1,106 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class BahmniConceptSearchHandlerTest { + + @Mock + @Qualifier("conceptService") + private ConceptService conceptService; + + @Mock + RequestContext requestContext; + + @Mock + UserContext userContext; + + @InjectMocks + private BahmniConceptSearchHandler bahmniConceptSearchHandler; + + + @Test + public void shouldSearchByQuestion() { + SearchConfig searchConfig = bahmniConceptSearchHandler.getSearchConfig(); + assertEquals(searchConfig.getId(), "byFullySpecifiedName"); + } + + @Test + public void shouldSupportVersions1_8To2() { + SearchConfig searchConfig = bahmniConceptSearchHandler.getSearchConfig(); + assertTrue(searchConfig.getSupportedOpenmrsVersions().contains("1.8.* - 2.*")); + } + + @Test + public void shouldSearchByGivenLocale_whenLocaleIsSpecified() { + List conceptSearchResults = new ArrayList<>(); + ConceptSearchResult result = new ConceptSearchResult(); + Concept concept = new Concept(); + concept.setId(123); + ConceptName conceptNameFullySpecified = new ConceptName(); + conceptNameFullySpecified.setConceptNameType(ConceptNameType.FULLY_SPECIFIED); + conceptNameFullySpecified.setName("Nutritional Values"); + concept.setNames(Collections.singleton(conceptNameFullySpecified)); + result.setConcept(concept); + conceptSearchResults.add(result); + + List localeList = new ArrayList<>(); + localeList.add(Locale.FRENCH); + + when(conceptService.getConcepts(anyString(), anyList(), anyBoolean(), isNull(), isNull(), isNull(), isNull(), isNull(), any(Integer.class), isNull())).thenReturn(conceptSearchResults); + when(requestContext.getLimit()).thenReturn(10); + when(requestContext.getParameter("locale")).thenReturn("fr"); + when(requestContext.getParameter("name")).thenReturn("Nutritional Values"); + + + NeedsPaging searchResults = (NeedsPaging) bahmniConceptSearchHandler.search(requestContext); + + verify(conceptService, times(1)).getConcepts("Nutritional Values", localeList, false, null, null, null, null, null, 0, null); + assertEquals(1, searchResults.getPageOfResults().size()); + assertEquals(1, localeList.size()); + assertEquals(new Integer(123) , searchResults.getPageOfResults().get(0).getId()); + } + + @Test + public void shouldSearchByLoggedInLocaleAndDefaultLocale_whenLocaleIsNotSpecified() { + when(requestContext.getParameter("name")).thenReturn("Nutritional Values"); + + bahmniConceptSearchHandler.search(requestContext); + List localeList = new ArrayList<>(); + localeList.add(LocaleUtility.getDefaultLocale()); + + verify(conceptService, times(1)).getConcepts("Nutritional Values", localeList, false, null, null, null, null, null, 0, null); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniMainResourceControllerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniMainResourceControllerTest.java new file mode 100644 index 0000000000..1b39a4a85a --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniMainResourceControllerTest.java @@ -0,0 +1,215 @@ +/** + * 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.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.web.v1_0.BaseIntegrationTest; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.Assert; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; +import org.xml.sax.InputSource; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.List; + +/** + * Facilitates testing controllers. + */ +public abstract class BahmniMainResourceControllerTest extends BaseIntegrationTest { + + @Autowired + private RequestMappingHandlerAdapter handlerAdapter; + + @Autowired + private List handlerMappings; + + /** + * Creates a request from the given parameters. + *

+ * The requestURI is automatically preceded with "/rest/" + RestConstants.VERSION_1. + * + * @param method + * @param requestURI + * @return + */ + public MockHttpServletRequest request(RequestMethod method, String requestURI) { + MockHttpServletRequest request = new MockHttpServletRequest(method.toString(), "/rest/" + getNamespace() + "/" + + requestURI); + request.addHeader("content-type", "application/json"); + return request; + } + + /** + * Override this method to test a different namespace than v1. + * + * @return the namespace + */ + public String getNamespace() { + return RestConstants.VERSION_1; + } + + public static class Parameter { + + public String name; + + public String value; + + public Parameter(String name, String value) { + this.name = name; + this.value = value; + } + } + + public MockHttpServletRequest newRequest(RequestMethod method, String requestURI, Parameter... parameters) { + MockHttpServletRequest request = request(method, requestURI); + for (Parameter parameter : parameters) { + request.addParameter(parameter.name, parameter.value); + } + return request; + } + + public MockHttpServletRequest newDeleteRequest(String requestURI, Parameter... parameters) { + return newRequest(RequestMethod.DELETE, requestURI, parameters); + } + + public MockHttpServletRequest newGetRequest(String requestURI, Parameter... parameters) { + return newRequest(RequestMethod.GET, requestURI, parameters); + } + + public MockHttpServletRequest newPostRequest(String requestURI, Object content) { + MockHttpServletRequest request = request(RequestMethod.POST, requestURI); + try { + String json = new ObjectMapper().writeValueAsString(content); + request.setContent(json.getBytes("UTF-8")); + } + catch (Exception e) { + throw new RuntimeException(e); + } + return request; + } + + public MockHttpServletRequest newPostRequest(String requestURI, String content) { + MockHttpServletRequest request = request(RequestMethod.POST, requestURI); + try { + request.setContent(content.getBytes("UTF-8")); + } + catch (Exception e) { + throw new RuntimeException(e); + } + return request; + } + + /** + * Passes the given request to a proper controller. + * + * @param request + * @return + * @throws Exception + */ + public MockHttpServletResponse handle(HttpServletRequest request) throws Exception { + MockHttpServletResponse response = new MockHttpServletResponse(); + + HandlerExecutionChain handlerExecutionChain = null; + for (RequestMappingHandlerMapping handlerMapping : handlerMappings) { + handlerExecutionChain = handlerMapping.getHandler(request); + if (handlerExecutionChain != null) { + break; + } + } + Assert.assertNotNull("The request URI does not exist", handlerExecutionChain); + + handlerAdapter.handle(request, response, handlerExecutionChain.getHandler()); + + return response; + } + + /** + * Deserializes the JSON response. + * + * @param response + * @return + * @throws Exception + */ + public SimpleObject deserialize(MockHttpServletResponse response) throws Exception { + return new ObjectMapper().readValue(response.getContentAsString(), SimpleObject.class); + } + + + /** + * @return the URI of the resource + */ + public abstract String getURI(); + + /** + * @return the uuid of an existing object + */ + public abstract String getUuid(); + + /** + * @return the count of all not retired/voided objects + */ + public abstract long getAllCount(); + + /** + * Evaluates an XPath expression on a XML string + * + * @param xml + * @param xPath + * @return + * @throws XPathExpressionException + */ + protected String evaluateXPath(String xml, String xPath) throws XPathExpressionException { + InputSource source = new InputSource(new StringReader(xml)); + XPath xpath = XPathFactory.newInstance().newXPath(); + return xpath.evaluate(xPath, source); + } + + /** + * Prints an XML string indented + * + * @param xml + * @throws TransformerException + */ + protected void printXML(String xml) throws TransformerException { + + Source xmlInput = new StreamSource(new StringReader(xml)); + StringWriter stringWriter = new StringWriter(); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.transform(xmlInput, new StreamResult(stringWriter)); + + System.out.println(stringWriter.toString()); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniProviderSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniProviderSearchHandlerIT.java new file mode 100644 index 0000000000..d75267b110 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/BahmniProviderSearchHandlerIT.java @@ -0,0 +1,77 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.List; +import java.util.Map; + +public class BahmniProviderSearchHandlerIT extends BahmniMainResourceControllerTest { + @Override + public String getURI() { + return "provider"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + @Before + public void setup() throws Exception { + executeDataSet("providerDataSet.xml"); + } + + @Test + public void searchByOrgAttribute() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", ""); + req.addParameter("s", BahmniProviderSearchHandler.SEARCH_BY_ATTRIBUTE); + req.addParameter(BahmniProviderSearchHandler.PARAM_ATTRIBUTE_NAME, "organization"); + req.addParameter(BahmniProviderSearchHandler.PARAM_ATTRIBUTE_VALUE, "JSS"); + SimpleObject result = deserialize(handle(req)); + List providers = result.get("results"); + Assert.assertEquals(1, providers.size()); + Assert.assertTrue(providers.stream().anyMatch(provider -> "a3a5913e-6b94-11e0-93c3-18a905e044dc".equals(getProviderProperty(provider, "uuid")))); + } + + @Test + public void searchByApptAvailabilityAttribute() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", ""); + req.addParameter("s", BahmniProviderSearchHandler.SEARCH_BY_ATTRIBUTE); + req.addParameter(BahmniProviderSearchHandler.PARAM_ATTRIBUTE_NAME, "Available for appointments"); + req.addParameter(BahmniProviderSearchHandler.PARAM_ATTRIBUTE_VALUE, "true"); + SimpleObject result = deserialize(handle(req)); + List providers = result.get("results"); + Assert.assertEquals(2, providers.size()); + Assert.assertTrue(providers.stream().anyMatch(provider -> "a3a5913e-6b94-11e0-93c3-18a905e044dc".equals(getProviderProperty(provider, "uuid")))); + Assert.assertTrue(providers.stream().anyMatch(provider -> "161b3002-6b95-11e0-93c3-18a905e044dc".equals(getProviderProperty(provider, "uuid")))); + } + + @Test + public void searchByLocationAttribute() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", ""); + req.addParameter("s", BahmniProviderSearchHandler.SEARCH_BY_ATTRIBUTE); + req.addParameter(BahmniProviderSearchHandler.PARAM_ATTRIBUTE_NAME, "Department"); + req.addParameter(BahmniProviderSearchHandler.PARAM_ATTRIBUTE_VALUE, "c36006e5-9fbb-4f20-866b-0ece245615a1"); + SimpleObject result = deserialize(handle(req)); + List providers = result.get("results"); + Assert.assertEquals(1, providers.size()); + Assert.assertTrue(providers.stream().anyMatch(provider -> "ae401f88-6b94-11e0-93c3-18a905e044dc".equals(getProviderProperty(provider, "uuid")))); + } + + private Object getProviderProperty(Object provider, String propertyName) { + Map providerMap = (Map) provider; + return providerMap.get(propertyName); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/ConceptSetBasedDrugSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/ConceptSetBasedDrugSearchHandlerIT.java new file mode 100644 index 0000000000..18bbdadb0c --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/ConceptSetBasedDrugSearchHandlerIT.java @@ -0,0 +1,72 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Drug; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.List; + +import static org.junit.Assert.assertTrue; + +public class ConceptSetBasedDrugSearchHandlerIT extends BahmniMainResourceControllerTest { + + @Override + public String getURI() { + return "drug"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + + @Before + public void setUp() throws Exception { + executeDataSet("search/conceptSetBasedDrug/drugsWithConcepts.xml"); + } + + @Test + public void shouldReturnDrugsThatAreChildrenOfGivenConceptName() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "All TB Drugs"); + req.addParameter("s", "byConceptSet"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(3, hits.size()); + } + + @Test(expected = ConceptNotFoundException.class) + public void shouldThrowExceptionWhenConceptSetNotProvided() throws Exception { + MockHttpServletRequest requestWithoutAConceptSetName = request(RequestMethod.GET, getURI()); + requestWithoutAConceptSetName.addParameter("s", "byConceptSet"); + requestWithoutAConceptSetName.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + handle(requestWithoutAConceptSetName); + } + + @Test + public void shouldSearchForDrugBySearchTermAndConceptSet() throws Exception { + MockHttpServletRequest request = request(RequestMethod.GET, getURI()); + request.addParameter("s", "byConceptSet"); + request.addParameter("searchTerm", "aceta"); + request.addParameter("q", "All TB Drugs"); + request.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + SimpleObject result = deserialize(handle(request)); + List results = (List) result.get("results"); + Assert.assertEquals(2, results.size()); + assertTrue(results.toString().contains("name=Thioacetazone")); + assertTrue(results.toString().contains("name=Paracetamol High Dose")); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandlerIT.java new file mode 100644 index 0000000000..c5c768cd1d --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandlerIT.java @@ -0,0 +1,61 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.RestConstants; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.List; + +public class EntityMappingSearchHandlerIT extends BahmniMainResourceControllerTest { + + private static final String ENTITY_MAPPING_DATA_SET_XML = "entityMappingDataSet.xml"; + + @Before + public void init() throws Exception { + executeDataSet(ENTITY_MAPPING_DATA_SET_XML); + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getURI() + */ + @Override + public String getURI() { + return "entitymapping"; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getAllCount() + */ + @Override + public long getAllCount() { + return 0l; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getUuid() + */ + @Override + public String getUuid() { + return null; + } + + /** + * @verifies return location by tag uuid + */ + @Test + public void shouldRetrieveProgramEntityMapping() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("entityUuid", "e45931c5-cc97-48bd-b686-e64a28ab2bde"); + req.addParameter("mappingType", "program_obstemplate"); + req.addParameter("s", "byEntityAndMappingType"); + req.addParameter("v", RestConstants.REPRESENTATION_DEFAULT); + + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(1, hits.size()); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandlerTest.java new file mode 100644 index 0000000000..5069df16c9 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/EntityMappingSearchHandlerTest.java @@ -0,0 +1,137 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.contract.entityMapping.Entity; +import org.bahmni.module.bahmnicore.dao.EntityDao; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Concept; +import org.openmrs.Program; +import org.openmrs.module.bahmnimapping.dao.EntityMappingDao; +import org.openmrs.module.bahmnimapping.model.EntityMapping; +import org.openmrs.module.bahmnimapping.model.EntityMappingType; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.openmrs.module.webservices.rest.web.resource.impl.AlreadyPaged; +import org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class EntityMappingSearchHandlerTest { + + @Mock + EntityMappingDao entityMappingDao; + @Mock + EntityDao entityDao; + @Mock + RequestContext requestContext; + + @InjectMocks + EntityMappingSearchHandler entityMappingSearchHandler; + + private String PROGRAM_OBS_TEMPLATE = "program_obsTemplate"; + private String ENTITY1_UUID = "entity1-uuid"; + private String ENTITY2_UUID = "entity2-uuid"; + String ENTITY3_UUID = "entity3-uuid"; + String ENTITY4_UUID = "entity4-uuid"; + EntityMappingType programObsTemplateMappingType; + + @Before + public void setUp() throws Exception { + when(requestContext.getParameter("mappingType")).thenReturn(PROGRAM_OBS_TEMPLATE); + when(requestContext.getParameter("entityUuid")).thenReturn(ENTITY1_UUID); + programObsTemplateMappingType = new EntityMappingType(1, null, PROGRAM_OBS_TEMPLATE, "org.openmrs.Program", "org.openmrs.Concept"); + when(entityMappingDao.getEntityMappingTypeByName(PROGRAM_OBS_TEMPLATE)).thenReturn(programObsTemplateMappingType); + } + + @Test + public void shouldGetEntityWithMappingsWhenThereAreEntityMappings() throws Exception { + EntityMapping entityMapping = new EntityMapping(null, null, ENTITY1_UUID, ENTITY2_UUID, programObsTemplateMappingType); + + when(entityMappingDao.getMappingsOfEntity(ENTITY1_UUID, PROGRAM_OBS_TEMPLATE)).thenReturn(Collections.singletonList(entityMapping)); + + Program program = new Program(); + Concept concept = new Concept(); + + when(entityDao.getByUuid(ENTITY1_UUID, Program.class)).thenReturn(program); + when(entityDao.getByUuid(ENTITY2_UUID, Concept.class)).thenReturn(concept); + + AlreadyPaged pageableResult = (AlreadyPaged) entityMappingSearchHandler.search(requestContext); + Entity entityWithMappings = (Entity) pageableResult.getPageOfResults().get(0); + + assertNotNull(entityWithMappings); + assertEquals(program, entityWithMappings.getEntity()); + assertEquals(Collections.singletonList(concept), entityWithMappings.getMappings()); + } + + @Test + public void shouldGetEntityWithZeroMappingsWhenThereIsNoEntityMapping() throws Exception { + when(entityMappingDao.getMappingsOfEntity(ENTITY1_UUID, PROGRAM_OBS_TEMPLATE)).thenReturn(new ArrayList()); + + Program program = new Program(); + Concept concept = new Concept(); + + when(entityDao.getByUuid(ENTITY1_UUID, Program.class)).thenReturn(program); + + AlreadyPaged pageableResult = (AlreadyPaged) entityMappingSearchHandler.search(requestContext); + Entity entityWithMappings = (Entity) pageableResult.getPageOfResults().get(0); + + assertNotNull(entityWithMappings); + assertEquals(program, entityWithMappings.getEntity()); + assertEquals(new ArrayList(), entityWithMappings.getMappings()); + + } + + @Test + public void shouldGetAllEntityMappingsGivenAnEntityMappingType() throws Exception { + List entityMappingList = new ArrayList(); + when(requestContext.getParameter("entityUuid")).thenReturn(null); + EntityMapping entityMappingOne = new EntityMapping(null, null, ENTITY1_UUID, ENTITY2_UUID, programObsTemplateMappingType); + EntityMapping entityMappingTwo = new EntityMapping(null, null, ENTITY3_UUID, ENTITY4_UUID, programObsTemplateMappingType); + entityMappingList.add(entityMappingOne); + entityMappingList.add(entityMappingTwo); + + when(entityMappingDao.getAllEntityMappings(PROGRAM_OBS_TEMPLATE)).thenReturn(entityMappingList); + + Program programOne = new Program(); + Program programTwo = new Program(); + Concept concept = new Concept(); + + when(entityDao.getByUuid(ENTITY1_UUID, Program.class)).thenReturn(programOne); + when(entityDao.getByUuid(ENTITY2_UUID, Concept.class)).thenReturn(concept); + when(entityDao.getByUuid(ENTITY3_UUID, Program.class)).thenReturn(programTwo); + when(entityDao.getByUuid(ENTITY4_UUID, Concept.class)).thenReturn(concept); + + AlreadyPaged pageableResult = (AlreadyPaged) entityMappingSearchHandler.search(requestContext); + List entityWithMappings = new ArrayList<>(); + entityWithMappings.add((Entity) pageableResult.getPageOfResults().get(0)); + entityWithMappings.add((Entity) pageableResult.getPageOfResults().get(1)); + + assertNotNull(entityWithMappings); + assertEquals(programOne, entityWithMappings.get(0).getEntity()); + assertEquals(programTwo, entityWithMappings.get(1).getEntity()); + + } + + @Test + public void shouldGetWithZeroMappingsWhenThereIsNoEntityMappingType() throws Exception { + + when(entityMappingDao.getEntityMappingTypeByName(PROGRAM_OBS_TEMPLATE)).thenReturn(null); + + PageableResult pageableResult = entityMappingSearchHandler.search(requestContext); + + assertTrue(pageableResult instanceof EmptySearchResult); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandlerIT.java new file mode 100644 index 0000000000..ea4bf53ff7 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandlerIT.java @@ -0,0 +1,55 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.web.response.InvalidSearchException; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.List; +import java.util.Map; + +public class OrderSetSearchHandlerIT extends BahmniMainResourceControllerTest { + + @Override + public String getURI() { + return "bahmniorderset"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + @Before + public void setup() throws Exception { + executeDataSet("orderSet.xml"); + } + + @Test + public void shouldRetrieveAllOrderSetsWhichContainsSearchPramsInNameOrDescription() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "Order"); + req.addParameter("s", "byQuery"); + + SimpleObject result = deserialize(handle(req)); + List orderSets = result.get("results"); + Map firstOrderSet = (Map) orderSets.get(0); + Assert.assertEquals(3, orderSets.size()); + Assert.assertEquals("Order_Set_1", firstOrderSet.get("display")); + } + + @Test(expected = InvalidSearchException.class) + public void shouldNotRetriveOrderSetsIfSeachStringIsNotProper() throws Exception{ + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("q", "Order"); + req.addParameter("s", "byQsuery"); + deserialize(handle(req)); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandlerTest.java new file mode 100644 index 0000000000..036c2e35d0 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/OrderSetSearchHandlerTest.java @@ -0,0 +1,60 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniOrderSetService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.OrderSet; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; + +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class OrderSetSearchHandlerTest { + public static final String QUERY = "q"; + + @Mock + private BahmniOrderSetService bahmniOrderSetService; + private OrderSetSearchHandler orderSetSearchHandler; + + @Mock + RequestContext requestContext; + + @Before + public void before() { + initMocks(this); + orderSetSearchHandler = new OrderSetSearchHandler(bahmniOrderSetService); + } + + @Test + public void shouldSearchByQuery() { + SearchConfig searchConfig = orderSetSearchHandler.getSearchConfig(); + assertThat(searchConfig.getId(), is(equalTo("byQuery"))); + } + + @Test + public void shouldSupportVersions1_9To2() { + SearchConfig searchConfig = orderSetSearchHandler.getSearchConfig(); + assertTrue(searchConfig.getSupportedOpenmrsVersions().contains("1.9.* - 2.*")); + } + @Test + public void shouldDelegateSearchOfOrdersetToBahmniOrderSetService() { + List resultOrderSets = new ArrayList<>(); + when(bahmniOrderSetService.getOrderSetByQuery(QUERY)).thenReturn(resultOrderSets); + when(requestContext.getParameter("q")).thenReturn(QUERY); + + NeedsPaging searchResults = (NeedsPaging) orderSetSearchHandler.search(requestContext); + + assertThat(searchResults.getPageOfResults().size(), is(equalTo(0))); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerIT.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerIT.java new file mode 100644 index 0000000000..b48b1eb7df --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerIT.java @@ -0,0 +1,74 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.List; + +public class VisitFormsSearchHandlerIT extends BahmniMainResourceControllerTest { + private static final String VISIT_FORM_DATA_SET_XML = "visitFormDataSet.xml"; + + @Before + public void init() throws Exception { + executeDataSet(VISIT_FORM_DATA_SET_XML); + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getURI() + */ + @Override + public String getURI() { + return "obs"; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getAllCount() + */ + @Override + public long getAllCount() { + return 0l; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getUuid() + */ + @Override + public String getUuid() { + return null; + } + + /** + * @verifies return location by tag uuid + */ + @Test + public void shouldRetrieveObservationsForConcept() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("patient", "a76e8d23-0c38-408c-b2a8-ea5540f01b51"); + req.addParameter("numberOfVisits", "10"); + req.addParameter("s", "byPatientUuid"); + req.addParameter("conceptNames","HIV"); + + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(2, hits.size()); + } + + /** + * @verifies return location by tag uuid + */ + @Test + public void shouldRetrieveObservationsForAllConcepts() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + req.addParameter("patient", "a76e8d23-0c38-408c-b2a8-ea5540f01b51"); + req.addParameter("numberOfVisits", "10"); + req.addParameter("s", "byPatientUuid"); + + SimpleObject result = deserialize(handle(req)); + List hits = (List) result.get("results"); + Assert.assertEquals(4, hits.size()); + } +} diff --git a/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java new file mode 100644 index 0000000000..5135e6952c --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/search/VisitFormsSearchHandlerTest.java @@ -0,0 +1,341 @@ +package org.bahmni.module.bahmnicore.web.v1_0.search; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Encounter; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +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.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.episodes.Episode; +import org.openmrs.module.episodes.service.EpisodeService; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.SearchConfig; +import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; +import org.openmrs.module.webservices.rest.web.response.InvalidSearchException; +import org.openmrs.util.LocaleUtility; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.bahmnicore.web.v1_0.LocaleResolver.identifyLocale; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@PrepareForTest({Context.class, LocaleUtility.class, LocaleResolver.class}) +@RunWith(PowerMockRunner.class) +public class VisitFormsSearchHandlerTest { + + @InjectMocks + private VisitFormsSearchHandler visitFormsSearchHandler = new VisitFormsSearchHandler(); + @Mock + RequestContext context; + @Mock + PatientService patientService; + @Mock + ConceptService conceptService; + @Mock + EncounterService encounterService; + @Mock + VisitService visitService; + @Mock + ObsService obsService; + @Mock + private BahmniProgramWorkflowService programWorkflowService; + @Mock + private EpisodeService episodeService; + private Patient patient; + private Concept concept; + private Obs obs; + private final List concepts = new ArrayList<>(); + private final String conceptNames = null; + + + @Before + public void before() throws Exception { + initMocks(this); + mockStatic(LocaleUtility.class); + mockStatic(LocaleResolver.class); + setUp(); + } + + public Concept createConcept(String conceptName, String locale) { + concept = new Concept(); + concept.setFullySpecifiedName(new ConceptName(conceptName, new Locale(locale))); + return concept; + } + + public Obs createObs(Concept concept) { + obs = new Obs(); + obs.setConcept(concept); + return obs; + } + + public void setUp() throws Exception { + HttpServletRequest req = Mockito.mock(HttpServletRequest.class); + HttpSession session = Mockito.mock(HttpSession.class); + + when(context.getLimit()).thenReturn(3); + when(context.getRequest()).thenReturn(req); + when(context.getRequest().getSession()).thenReturn(session); + when(context.getRequest().getParameter("patient")).thenReturn("patientUuid"); + when(context.getRequest().getParameter("numberOfVisits")).thenReturn("10"); + when(context.getRequest().getSession().getAttribute("locale")).thenReturn(Locale.ENGLISH); + when(identifyLocale(any())).thenReturn(Locale.ENGLISH); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + + String[] conceptNames = {"Vitals"}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + patient = new Patient(); + patient.setId(1); + patient.setUuid("patient-uuid"); + + PowerMockito.mockStatic(Context.class); + PowerMockito.when(Context.getPatientService()).thenReturn(patientService); + when(patientService.getPatientByUuid("patientUuid")).thenReturn(patient); + PowerMockito.when(Context.getConceptService()).thenReturn(conceptService); + concept = createConcept("Vitals", "en"); + + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.ENGLISH); + + Visit visit = new Visit(); + PowerMockito.when(Context.getVisitService()).thenReturn(visitService); + PowerMockito.when(Context.getVisitService().getVisitsByPatient(patient)).thenReturn(Arrays.asList(visit)); + + PowerMockito.when(Context.getEncounterService()).thenReturn(encounterService); + Encounter encounter = mock(Encounter.class); + PowerMockito.when(encounterService.getEncounters(any(Patient.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), any(Collection.class), eq(false))).thenReturn(Arrays.asList(encounter)); + PowerMockito.when(Context.getObsService()).thenReturn(obsService); + obs = createObs(concept); + } + + @Test + public void testGetSearchConfig() throws Exception { + SearchConfig searchConfig = visitFormsSearchHandler.getSearchConfig(); + assertThat(searchConfig.getId(), is(equalTo("byPatientUuid"))); + + } + + @Test + public void shouldSupportVersions1_10To2() { + SearchConfig searchConfig = visitFormsSearchHandler.getSearchConfig(); + assertTrue(searchConfig.getSupportedOpenmrsVersions().contains("1.10.* - 2.*")); + } + + @Test + public void shouldReturnConceptSpecificObsIfConceptNameIsSpecified() { + String [] conceptNames = new String[]{"Vitals"}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + concept = createConcept("Vitals", "en"); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnConceptSpecificObsIfConceptNameIsFoundInUserLocale() { + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.FRENCH); + + String [] conceptNames = new String[]{"Vitals_fr"}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + + Concept obsConcept = createConcept("Vitals_fr", "fr"); + Obs obs = createObs(obsConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnConceptSpecificObsIfConceptNameIsNullInUserLocaleButFoundInDefaultSearch() { + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.FRENCH); + + String [] conceptNames = new String[]{"Vitals"}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + + Concept obsConcept = createConcept("Vitals", "en"); + Obs obs = createObs(obsConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnConceptSpecificObsIfConceptNameIsFoundInDefaultLocale() { + PowerMockito.when(identifyLocale(any())).thenReturn(Locale.FRENCH); + + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + + Concept parentConcept = new Concept(); + parentConcept.addSetMember(concept); + Concept historyConcept = createConcept("History and Examination", "en"); + parentConcept.addSetMember(historyConcept); + + when(conceptService.getConceptsByName("All Observation Templates", Locale.ENGLISH, false)).thenReturn(Arrays.asList(parentConcept)); + + Concept obsConcept = createConcept("History and Examination", "en"); + Obs obs = createObs(obsConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(1))); + } + + @Test + public void shouldReturnAllObsIfConceptNameIsNotSpecified() { + + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + Concept parentConcept = new Concept(); + parentConcept.addSetMember(concept); + Concept historyConcept = createConcept("History and Examination", "en"); + parentConcept.addSetMember(historyConcept); + + when(conceptService.getConceptsByName("All Observation Templates", Locale.ENGLISH, false)).thenReturn(Arrays.asList(parentConcept)); + + Obs obs2 = createObs(historyConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false))).thenReturn(Arrays.asList(obs, obs2)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(2))); + } + + @Test + public void shouldReturnEmptyObservationsIfAllConceptNamesAreInvalid() { + + String[] conceptNames = {null, null}; + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(conceptNames); + + Concept parentConcept = new Concept(); + parentConcept.addSetMember(concept); + Concept historyConcept = createConcept("History and Examination", "en"); + parentConcept.addSetMember(historyConcept); + + PowerMockito.when(Context.getConceptService()).thenReturn(conceptService); + + Obs obs2 = createObs(historyConcept); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(Integer.class), any(Integer.class), any(Date.class), any(Date.class), eq(false))).thenReturn(Arrays.asList(obs, obs2)); + NeedsPaging searchResults = (NeedsPaging) visitFormsSearchHandler.search(context); + assertThat(searchResults.getPageOfResults().size(), is(equalTo(0))); + } + + @Test(expected = InvalidSearchException.class) + public void shouldThrowExceptionIfThePatienUuidIsNull(){ + when(context.getRequest().getParameter("patient")).thenReturn(null); + + visitFormsSearchHandler.search(context); + } + + @Test + public void shouldGetObservationsWithinThePatientProgramIfThePatientProgramUuidIsPassed() { + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + when(conceptService.getConceptsByName("conceptNames",Locale.ENGLISH,null)).thenReturn(concepts); + String patientProgramUuid = "patient-program-uuid"; + when(context.getRequest().getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(programWorkflowService); + PatientProgram patientProgram = new PatientProgram(); + when(programWorkflowService.getPatientProgramByUuid(patientProgramUuid)).thenReturn(patientProgram); + when(Context.getService(EpisodeService.class)).thenReturn(episodeService); + Episode episode = new Episode(); + episode.addEncounter(new Encounter()); + when(episodeService.getEpisodeForPatientProgram(patientProgram)).thenReturn(episode); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(Integer.class), any(Integer.class), any(Date.class), any(Date.class), eq(false))).thenReturn(Arrays.asList(obs)); + + visitFormsSearchHandler.search(context); + + verify(conceptService, times(1)).getConceptsByName("All Observation Templates",Locale.ENGLISH, false); + verify(programWorkflowService, times(1)).getPatientProgramByUuid(patientProgramUuid); + verify(episodeService, times(1)).getEpisodeForPatientProgram(patientProgram); + verify(visitService, never()).getVisitsByPatient(patient); + verify(encounterService, never()).getEncounters(any(Patient.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), any(Collection.class), eq(false)); + verify(obsService, times(1)).getObservations(any(List.class), any(List.class), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(false)); + } + + @Test + public void shouldNotFetchAnyObservationsIfThereIsNoEpisodeForTheProgram() { + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + when(conceptService.getConceptsByName("conceptNames",Locale.ENGLISH, null)).thenReturn(concepts); + String patientProgramUuid = "patient-program-uuid"; + when(context.getRequest().getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(programWorkflowService); + PatientProgram patientProgram = new PatientProgram(); + when(programWorkflowService.getPatientProgramByUuid(patientProgramUuid)).thenReturn(patientProgram); + when(Context.getService(EpisodeService.class)).thenReturn(episodeService); + when(episodeService.getEpisodeForPatientProgram(patientProgram)).thenReturn(null); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(Integer.class), any(Integer.class), any(Date.class), any(Date.class), eq(false))).thenReturn(Arrays.asList(obs)); + + visitFormsSearchHandler.search(context); + + verify(conceptService, times(1)).getConceptsByName("All Observation Templates", Locale.ENGLISH, false); + verify(programWorkflowService, times(1)).getPatientProgramByUuid(patientProgramUuid); + verify(episodeService, times(1)).getEpisodeForPatientProgram(patientProgram); + verify(visitService, never()).getVisitsByPatient(patient); + verify(encounterService, never()).getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), eq(false)); + verify(obsService, never()).getObservations(any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(Integer.class), any(Integer.class), any(Date.class), any(Date.class), eq(false)); + } + + @Test + public void shouldNotFetchAnyObservationsIfThereAreNoEncountersInEpisode() { + when(conceptService.getConceptsByName(conceptNames, Locale.ENGLISH, null)).thenReturn(concepts); + when(context.getRequest().getParameterValues("conceptNames")).thenReturn(null); + String patientProgramUuid = "patient-program-uuid"; + when(context.getRequest().getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(programWorkflowService); + PatientProgram patientProgram = new PatientProgram(); + when(programWorkflowService.getPatientProgramByUuid(patientProgramUuid)).thenReturn(patientProgram); + when(Context.getService(EpisodeService.class)).thenReturn(episodeService); + Episode episode = new Episode(); + when(episodeService.getEpisodeForPatientProgram(patientProgram)).thenReturn(episode); + + PowerMockito.when(obsService.getObservations(any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(Integer.class), any(Integer.class), any(Date.class), any(Date.class), eq(false))).thenReturn(Arrays.asList(obs)); + + visitFormsSearchHandler.search(context); + + verify(conceptService, times(1)).getConceptsByName("All Observation Templates", Locale.ENGLISH, false); + verify(programWorkflowService, times(1)).getPatientProgramByUuid(patientProgramUuid); + verify(episodeService, times(1)).getEpisodeForPatientProgram(patientProgram); + verify(visitService, never()).getVisitsByPatient(patient); + verify(encounterService, never()).getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), any(Collection.class), eq(false)); + verify(obsService, never()).getObservations(any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(List.class), any(Integer.class), any(Integer.class), any(Date.class), any(Date.class), eq(false)); + } +} diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderResourceITBahmni.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderResourceITBahmni.java new file mode 100644 index 0000000000..79ad9e9436 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderResourceITBahmni.java @@ -0,0 +1,73 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.bahmni.module.bahmnicore.service.OrderService; +import org.bahmni.module.bahmnicore.web.v1_0.search.BahmniMainResourceControllerTest; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Order; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class BahmniOrderResourceITBahmni extends BahmniMainResourceControllerTest { + + @Autowired + OrderService orderService; + + + @Before + public void setUp() throws Exception { + executeDataSet("drugOrdersForDelete.xml"); + } + + @Test + public void shouldVoidChildOrders() throws Exception { + Order order = orderService.getOrderByUuid("6d0ae386-707a-4629-9850-f15206e63ab0"); + assertTrue(!order.isVoided()); + assertTrue(!order.getPreviousOrder().isVoided()); + assertNotNull(order); + Order childOrder = orderService.getChildOrder(order); + MockHttpServletRequest mockHttpServletRequest = request(RequestMethod.DELETE, getURI() + "/" + getUuid()); + handle(mockHttpServletRequest); + order = orderService.getOrderByUuid("6d0ae386-707a-4629-9850-f15206e63ab0"); + assertTrue(!order.getPreviousOrder().isVoided()); + assertTrue(order.isVoided()); + assertTrue(childOrder.isVoided()); + + } + + @Test + public void shouldVoidDiscontinuedOrder() throws Exception { + Order order = orderService.getOrderByUuid("DISCONTINUED_ORDER"); + assertTrue(!order.isVoided()); + assertTrue(!order.getPreviousOrder().isVoided()); + assertNotNull(order); + MockHttpServletRequest mockHttpServletRequest = request(RequestMethod.DELETE, getURI() + "/" + "DISCONTINUED_ORDER"); + handle(mockHttpServletRequest); + order = orderService.getOrderByUuid("DISCONTINUED_ORDER"); + assertTrue(!order.getPreviousOrder().isVoided()); + assertNull(order.getPreviousOrder().getDateStopped()); + assertTrue(order.isVoided()); + assertNull(orderService.getChildOrder(order)); + + } + + @Override + public String getURI() { + return "order"; + } + + @Override + public String getUuid() { + return "6d0ae386-707a-4629-9850-f15206e63ab0"; + } + + @Override + public long getAllCount() { + return 0; + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetControllerTestIT.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetControllerTestIT.java new file mode 100644 index 0000000000..94f5982b1a --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetControllerTestIT.java @@ -0,0 +1,161 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + + +import org.apache.commons.beanutils.PropertyUtils; +import org.bahmni.module.bahmnicore.web.v1_0.search.BahmniMainResourceControllerTest; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.OrderSet; +import org.openmrs.api.OrderSetService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.test.Util; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import static org.junit.Assert.assertEquals; + +public class BahmniOrderSetControllerTestIT extends BahmniMainResourceControllerTest { + + private OrderSetService orderSetService; + + @Before + public void init() throws Exception { + orderSetService = Context.getOrderSetService(); + executeDataSet(RestConstants.TEST_DATA_SET); + } + + /** + * @see BahmniMainResourceControllerTest#getURI() + */ + @Override + public String getURI() { + return "bahmniorderset"; + } + + /** + * @see BahmniMainResourceControllerTest#getAllCount() + */ + @Override + public long getAllCount() { + return orderSetService.getOrderSets(false).size(); + } + + @Override + public String getUuid() { + return RestConstants.ORDER_SET_UUID; + } + + public String getName() { + return "orderSet1"; + } + + @Test + public void shouldListAllUnRetiredOrderSets() throws Exception { + + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + SimpleObject result = deserialize(handle(req)); + + Assert.assertNotNull(result); + Assert.assertEquals(getAllCount(), Util.getResultsSize(result)); + } + + @Test + public void shouldGetAnOrderSetByUuid() throws Exception { + + MockHttpServletRequest req = request(RequestMethod.GET, getURI() + "/" + getUuid()); + SimpleObject result = deserialize(handle(req)); + + OrderSet orderSet = orderSetService.getOrderSetByUuid(getUuid()); + + Assert.assertNotNull(result); + Assert.assertEquals(orderSet.getUuid(), PropertyUtils.getProperty(result, "uuid")); + Assert.assertEquals(orderSet.getName(), PropertyUtils.getProperty(result, "name")); + Assert.assertEquals(orderSet.getDescription(), PropertyUtils.getProperty(result, "description")); + Assert.assertEquals(orderSet.getRetired(), PropertyUtils.getProperty(result, "retired")); + } + + @Test + public void shouldCreateAnOrderSet() throws Exception { + long originalCount = getAllCount(); + + SimpleObject orderSet = new SimpleObject(); + orderSet.add("name", "New OrderSet"); + orderSet.add("description", "OrderSet description"); + orderSet.add("operator", "ALL"); + + String json = new ObjectMapper().writeValueAsString(orderSet); + + MockHttpServletRequest req = request(RequestMethod.POST, getURI()); + req.setContent(json.getBytes()); + + SimpleObject newOrderSet = deserialize(handle(req)); + + Assert.assertNotNull(PropertyUtils.getProperty(newOrderSet, "uuid")); + Assert.assertEquals(originalCount + 1, getAllCount()); + } + + @Test + public void shouldCreateAnOrderSetWithSomeOrderSetMembers() throws Exception { + long originalCount = getAllCount(); + + String json = "{\n" + + " \"name\": \"A\",\n" + + " \"description\": \"OSA\",\n" + + " \"operator\": \"ALL\",\n" + + " \"orderSetMembers\": [\n" + + " {\n" + + " \"orderType\": {\n" + + " \"uuid\": \"131168f4-15f5-102d-96e4-000c29c2a5d7\"\n" + + " },\n" + + " \"concept\": {\n" + + " \"name\": \"Amoxicillin\",\n" + + " \"uuid\": \"concept_uuid1\"\n" + + " }\n" + + " }\n" + + " ]\n" + + "}"; + + System.out.println(json); + MockHttpServletRequest req = request(RequestMethod.POST, getURI()); + req.setContent(json.getBytes()); + + SimpleObject newOrderSet = deserialize(handle(req)); + + Assert.assertNotNull(PropertyUtils.getProperty(newOrderSet, "uuid")); + Assert.assertEquals(originalCount + 1, getAllCount()); + } + + @Test + public void shouldEditAnOrderSet() throws Exception { + + final String editedName = "OrderSet Edited"; + String json = "{ \"name\":\"" + editedName + "\" }"; + MockHttpServletRequest req = request(RequestMethod.POST, getURI() + "/" + getUuid()); + req.setContent(json.getBytes()); + handle(req); + + OrderSet editedOrderSet = orderSetService.getOrderSetByUuid(getUuid()); + + Assert.assertNotNull(editedOrderSet); + Assert.assertEquals(editedName, editedOrderSet.getName()); + } + + @Test + public void shouldRetireAnOrderSet() throws Exception { + assertEquals(false, orderSetService.getOrderSetByUuid(getUuid()).getRetired()); + + MockHttpServletRequest req = request(RequestMethod.DELETE, getURI() + "/" + getUuid()); + req.addParameter("!purge", ""); + req.addParameter("reason", "random reason"); + handle(req); + + OrderSet retiredOrderSet = orderSetService.getOrderSetByUuid(getUuid()); + + Assert.assertTrue(retiredOrderSet.isRetired()); + Assert.assertEquals("random reason", retiredOrderSet.getRetireReason()); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetMemberControllerIT.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetMemberControllerIT.java new file mode 100644 index 0000000000..60780dde78 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniOrderSetMemberControllerIT.java @@ -0,0 +1,142 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + + +import org.apache.commons.beanutils.PropertyUtils; +import org.bahmni.module.bahmnicore.web.v1_0.search.BahmniMainResourceControllerTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.OrderSet; +import org.openmrs.OrderSetMember; +import org.openmrs.api.OrderSetService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.test.Util; +import org.openmrs.module.webservices.rest.web.api.RestHelperService; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.Arrays; +import java.util.List; + +public class BahmniOrderSetMemberControllerIT extends BahmniMainResourceControllerTest { + + private String orderSetUuid = RestConstants.ORDER_SET_UUID; + + private String orderSetMemberUuid = RestConstants.ORDER_SET_MEMBER_UUID; + + private OrderSetService orderSetService; + + @Before + public void init() throws Exception { + orderSetService = Context.getOrderSetService(); + executeDataSet(RestConstants.TEST_DATA_SET); + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getURI() + */ + @Override + public String getURI() { + return "bahmniorderset/" + orderSetUuid + "/bahmniordersetmember"; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getUuid() + */ + @Override + public String getUuid() { + return orderSetMemberUuid; + } + + /** + * @see org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest#getAllCount() + */ + @Override + public long getAllCount() { + return orderSetService.getOrderSetByUuid(orderSetUuid).getOrderSetMembers().size(); + } + + @Test + public void shouldAddAnOrderSetMemberToAnOrderSet() throws Exception { + int before = (int) getAllCount(); + String json = "{\n" + + " \"orderType\": {\n" + + " \"uuid\": \"131168f4-15f5-102d-96e4-000c29c2a5d7\"\n" + + " },\n" + + " \"retired\": false\n" + + " }"; + + handle(newPostRequest(getURI(), json)); + + int after = orderSetService.getOrderSetByUuid(orderSetUuid).getOrderSetMembers().size(); + Assert.assertEquals(before + 1, after); + } + + @Test + public void shouldShowAllOrderSetMembersForAnOrderSet() throws Exception { + + OrderSet testOrderSet = Context.getOrderSetService().getOrderSetByUuid(orderSetUuid); + OrderSetMember testOrderSetMember = new OrderSetMember(); + testOrderSet.addOrderSetMember(testOrderSetMember); + Context.getOrderSetService().saveOrderSet(testOrderSet); + + Context.flushSession(); + Context.clearSession(); + + List orderSetMembers = Context.getOrderSetService().getOrderSetByUuid(orderSetUuid).getOrderSetMembers(); + + for (OrderSetMember orderSetMember : orderSetMembers) { + Assert.assertNotNull(orderSetMember.getOrderSetMemberId()); + } + + Assert.assertEquals(3, testOrderSet.getOrderSetMembers().size()); + + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + SimpleObject response = deserialize(handle(req)); + + List resultsList = Util.getResultsList(response); + Assert.assertEquals(3, resultsList.size()); + + List descriptions = Arrays.asList(PropertyUtils.getProperty(resultsList.get(0), "uuid"), + PropertyUtils.getProperty(resultsList.get(1), "uuid")); + + Assert.assertTrue(descriptions.contains("order_set_member_uuid1")); + Assert.assertTrue(descriptions.contains("order_set_member_uuid2")); + } + + @Test + public void shouldEditAnOrderSetMember() throws Exception { + OrderSetMember orderSetMember = Context.getService(RestHelperService.class).getObjectByUuid(OrderSetMember.class, orderSetMemberUuid); + Assert.assertEquals(null, orderSetMember.getOrderTemplate()); + + String json = "{\n" + + "\"orderTemplate\": \"NEW TEST TEMPLATE\"\n" + + " }"; + + deserialize(handle(newPostRequest(getURI() + "/" + getUuid(), json))); + + Assert.assertTrue(PropertyUtils.getProperty(orderSetMember, "orderTemplate").equals("NEW TEST TEMPLATE")); + } + + @Test + public void shouldRetireAnOrderSetMember() throws Exception { + int before = (int) getAllCount(); + + handle(newDeleteRequest(getURI() + "/" + getUuid(), new BahmniMainResourceControllerTest.Parameter("!purge", ""), new BahmniMainResourceControllerTest.Parameter("reason", "testing delete"))); + + int after = orderSetService.getOrderSetByUuid(orderSetUuid).getUnRetiredOrderSetMembers().size(); + Assert.assertEquals(before - 1, after); + } + + @Test + public void shouldPurgeAnOrderSetMember() throws Exception { + int before = (int) getAllCount(); + + handle(newDeleteRequest(getURI() + "/" + getUuid(), new BahmniMainResourceControllerTest.Parameter("purge", ""))); + + int after = orderSetService.getOrderSetByUuid(orderSetUuid).getOrderSetMembers().size(); + Assert.assertEquals(before - 1, after); + } + +} diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResourceITBahmni.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResourceITBahmni.java new file mode 100644 index 0000000000..c1864db658 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResourceITBahmni.java @@ -0,0 +1,64 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.bahmni.module.bahmnicore.web.v1_0.search.BahmniMainResourceControllerTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.SimpleObject; +import org.openmrs.module.webservices.rest.test.Util; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.util.HashMap; +import java.util.List; + +public class BahmniProgramEnrollmentResourceITBahmni extends BahmniMainResourceControllerTest { + + + private BahmniProgramWorkflowService service; + private PatientService patientService; + + @Before + public void before() { + this.service = Context.getService(BahmniProgramWorkflowService.class); + this.patientService = Context.getPatientService(); + } + + + @Test + //TODO Revisit and cleanup. No getting of first element of array + public void shouldGetProgramEnrollmentsByPatient() throws Exception { + MockHttpServletRequest req = request(RequestMethod.GET, getURI()); + String PATIENT_IN_A_PROGRAM_UUID = "da7f524f-27ce-4bb2-86d6-6d1d05312bd5"; + req.setParameter("patient", PATIENT_IN_A_PROGRAM_UUID); + SimpleObject result = deserialize(handle(req)); + + Patient patient = patientService.getPatientByUuid(PATIENT_IN_A_PROGRAM_UUID); + List patientPrograms = service.getPatientPrograms(patient, null, null, null, null, null, true); + Assert.assertEquals(patientPrograms.size(), Util.getResultsSize(result)); + PatientProgram bahmniPatientProgram = (PatientProgram) patientPrograms.get(0); + List results = (List) result.get("results"); + Assert.assertEquals(bahmniPatientProgram.getUuid(), ((HashMap) results.get(0)).get("uuid")); + } + + + @Override + public String getURI() { + return "bahmniprogramenrollment"; + } + + @Override + public String getUuid() { + return "b75462a0-4c92-451e-b8bc-e98b38b76534"; + } + + @Override + public long getAllCount() { + return 0; + } +} diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResourceTest.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResourceTest.java new file mode 100644 index 0000000000..b70026822c --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/BahmniProgramEnrollmentResourceTest.java @@ -0,0 +1,154 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.openmrs.PatientProgram; +import org.openmrs.Program; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.RequestContext; +import org.openmrs.module.webservices.rest.web.resource.api.PageableResult; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.Date; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.when; +@Ignore +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class BahmniProgramEnrollmentResourceTest { + + private BahmniProgramEnrollmentResource bahmniProgramEnrollmentResource; + @Mock + BahmniProgramWorkflowService bahmniProgramWorkflowService; + @Mock + RequestContext requestContext; + @Mock + HttpServletRequest httpServletRequest; + @Mock + private PatientService patientService; + + @Before + public void before() throws Exception { + initMocks(this); + PowerMockito.mockStatic(Context.class); + bahmniProgramEnrollmentResource = new BahmniProgramEnrollmentResource(); + } + + @Test + public void shouldSearchProgramsByPatientUuid() throws Exception { + String patientUuid = "patientUuid"; + when(requestContext.getRequest()).thenReturn(httpServletRequest); + when(requestContext.getIncludeAll()).thenReturn(true); + when(httpServletRequest.getParameter("patient")).thenReturn(patientUuid); + when(Context.getPatientService()).thenReturn(patientService); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(bahmniProgramWorkflowService); + Patient patient = new Patient(); + when(patientService.getPatientByUuid(patientUuid)).thenReturn(patient); + ArrayList expected = new ArrayList<>(); + when(bahmniProgramWorkflowService.getPatientPrograms(patient, null, null, null, null, null, true)).thenReturn(expected); + + PageableResult pageableResult = bahmniProgramEnrollmentResource.doSearch(requestContext); + + assertNotNull(pageableResult); + assertThat("org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult", is(not(equalTo(pageableResult.getClass().getName())))); + verify(requestContext, times(2)).getRequest(); + verify(requestContext, times(1)).getIncludeAll(); + verify(httpServletRequest, times(2)).getParameter(anyString()); + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(bahmniProgramWorkflowService, times(1)).getPatientPrograms(patient, null, null, null, null, null, true); + verify(bahmniProgramWorkflowService, never()).getPatientProgramByUuid(anyString()); + } + + @Test + public void shouldReturnEmptySearchResultIfThePatientIsNotExists() throws Exception { + String patientUuid = "patientUuid"; + when(requestContext.getRequest()).thenReturn(httpServletRequest); + when(requestContext.getIncludeAll()).thenReturn(true); + when(httpServletRequest.getParameter("patient")).thenReturn(patientUuid); + when(Context.getPatientService()).thenReturn(patientService); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(bahmniProgramWorkflowService); + when(patientService.getPatientByUuid(patientUuid)).thenReturn(null); + ArrayList expected = new ArrayList<>(); + when(bahmniProgramWorkflowService.getPatientPrograms(any(Patient.class), any(Program.class), any(Date.class), any(Date.class), any(Date.class), any(Date.class), anyBoolean())).thenReturn(expected); + + PageableResult pageableResult = bahmniProgramEnrollmentResource.doSearch(requestContext); + + assertNotNull(pageableResult); + assertEquals("org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult", pageableResult.getClass().getName()); + verify(requestContext, times(2)).getRequest(); + verify(httpServletRequest, times(2)).getParameter(anyString()); + verify(patientService, times(1)).getPatientByUuid(patientUuid); + verify(requestContext, never()).getIncludeAll(); + verify(bahmniProgramWorkflowService, never()).getPatientPrograms(any(Patient.class), any(Program.class), any(Date.class), any(Date.class), any(Date.class), any(Date.class), anyBoolean()); + verify(bahmniProgramWorkflowService, never()).getPatientProgramByUuid(anyString()); + } + + @Test + public void shouldSearchProgramByPatientProgramUuid() { + String patientProgramUuid = "patientProgramUuid"; + when(requestContext.getRequest()).thenReturn(httpServletRequest); + when(requestContext.getIncludeAll()).thenReturn(true); + when(httpServletRequest.getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); + when(Context.getPatientService()).thenReturn(patientService); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(bahmniProgramWorkflowService); + PatientProgram patientProgram = new PatientProgram(); + when(bahmniProgramWorkflowService.getPatientProgramByUuid(patientProgramUuid)).thenReturn(patientProgram); + + PageableResult pageableResult = bahmniProgramEnrollmentResource.doSearch(requestContext); + + assertNotNull(pageableResult); + assertThat("org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult", is(not(equalTo(pageableResult.getClass().getName())))); + verify(requestContext, times(2)).getRequest(); + verify(httpServletRequest, times(2)).getParameter(anyString()); + verify(bahmniProgramWorkflowService, times(1)).getPatientProgramByUuid(anyString()); + verify(requestContext, never()).getIncludeAll(); + verify(patientService, never()).getPatientByUuid(anyString()); + verify(bahmniProgramWorkflowService, never()).getPatientPrograms(any(Patient.class), any(Program.class), any(Date.class), any(Date.class), any(Date.class), any(Date.class), anyBoolean()); + } + + @Test + public void shouldReturnEmptySearchResultIfPatientProgramNotExists() { + String patientProgramUuid = "patientProgramUuid"; + when(requestContext.getRequest()).thenReturn(httpServletRequest); + when(requestContext.getIncludeAll()).thenReturn(true); + when(httpServletRequest.getParameter("patientProgramUuid")).thenReturn(patientProgramUuid); + when(Context.getPatientService()).thenReturn(patientService); + when(Context.getService(BahmniProgramWorkflowService.class)).thenReturn(bahmniProgramWorkflowService); + when(bahmniProgramWorkflowService.getPatientProgramByUuid(patientProgramUuid)).thenReturn(null); + + PageableResult pageableResult = bahmniProgramEnrollmentResource.doSearch(requestContext); + + assertNotNull(pageableResult); + assertEquals("org.openmrs.module.webservices.rest.web.resource.impl.EmptySearchResult", pageableResult.getClass().getName()); + verify(requestContext, times(2)).getRequest(); + verify(httpServletRequest, times(2)).getParameter(anyString()); + verify(bahmniProgramWorkflowService, times(1)).getPatientProgramByUuid(anyString()); + verify(requestContext, never()).getIncludeAll(); + verify(patientService, never()).getPatientByUuid(anyString()); + verify(bahmniProgramWorkflowService, never()).getPatientPrograms(any(Patient.class), any(Program.class), any(Date.class), any(Date.class), any(Date.class), any(Date.class), anyBoolean()); + } +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/PatientProgramAttributeResourceTest.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/PatientProgramAttributeResourceTest.java new file mode 100644 index 0000000000..4657a88966 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/PatientProgramAttributeResourceTest.java @@ -0,0 +1,51 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; + +import org.openmrs.PatientProgramAttribute; +import org.bahmni.module.bahmnicore.service.BahmniProgramWorkflowService; +import org.junit.Before; +import org.junit.Ignore; +import org.openmrs.api.context.Context; +import org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResourceTest; +import org.openmrs.module.webservices.rest.web.v1_0.resource.openmrs2_2.PatientProgramAttributeResource2_2; + +@Ignore +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class PatientProgramAttributeResourceTest extends BaseDelegatingResourceTest { + + @Before + public void before() throws Exception { + executeDataSet("programEnrollmentDataSet.xml"); + } + + @Override + public PatientProgramAttribute newObject() { + return Context.getService(BahmniProgramWorkflowService.class).getPatientProgramAttributeByUuid(getUuidProperty()); + } + + @Override + public void validateDefaultRepresentation() throws Exception { + super.validateDefaultRepresentation(); + assertPropEquals("value", getObject().getValue()); + assertPropPresent("attributeType"); + assertPropEquals("voided", getObject().getVoided()); + } + + @Override + public void validateFullRepresentation() throws Exception { + super.validateFullRepresentation(); + assertPropEquals("value", getObject().getValue()); + assertPropPresent("attributeType"); + assertPropEquals("voided", getObject().getVoided()); + assertPropPresent("auditInfo"); + } + + @Override + public String getDisplayProperty() { + return "stage: Stage1"; + } + + @Override + public String getUuidProperty() { + return RestConstants.PATIENT_PROGRAM_ATTRIBUTE_UUID; + } +} diff --git a/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/RestConstants.java b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/RestConstants.java new file mode 100644 index 0000000000..aadf7a7038 --- /dev/null +++ b/bahmnicore-omod/src/test/java/org/openmrs/module/bahmnicore/web/v1_0/resource/RestConstants.java @@ -0,0 +1,12 @@ +package org.openmrs.module.bahmnicore.web.v1_0.resource; +public class RestConstants { + public final static String PATIENT_PROGRAM_ATTRIBUTE_UUID = "3a2bdb18-6faa-11e0-8414-001e378eb67e"; + public final static String PROGRAM_ATTRIBUTE_TYPE_UUID = "d7477c21-bfc3-4922-9591-e89d8b9c8efb"; + public final static String PATIENT_PROGRAM_UUID = "9119b9f8-af3d-4ad8-9e2e-2317c3de91c6"; + + public final static String TEST_DATA_SET = "customTestDataset1_12.xml"; + + public final static String ORDER_SET_UUID = "order_set_uuid1"; + + public final static String ORDER_SET_MEMBER_UUID = "order_set_member_uuid1"; +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/TestingApplicationContext.xml b/bahmnicore-omod/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..513ae57c3a --- /dev/null +++ b/bahmnicore-omod/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + classpath:hibernate.cfg.xml + classpath:test-hibernate.cfg.xml + + + + + + + + org.openmrs + + + + + + + + + + org.openmrs.api.ProgramWorkflowService + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/activeOrderTests.xml b/bahmnicore-omod/src/test/resources/activeOrderTests.xml new file mode 100644 index 0000000000..11f99b566d --- /dev/null +++ b/bahmnicore-omod/src/test/resources/activeOrderTests.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/addressHierarchy.xml b/bahmnicore-omod/src/test/resources/addressHierarchy.xml new file mode 100644 index 0000000000..9c7ef47f78 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/addressHierarchy.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/allDrugOrdersForConcepts.xml b/bahmnicore-omod/src/test/resources/allDrugOrdersForConcepts.xml new file mode 100644 index 0000000000..2bd128d8e6 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/allDrugOrdersForConcepts.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/createPatientMetadata.xml b/bahmnicore-omod/src/test/resources/createPatientMetadata.xml new file mode 100644 index 0000000000..b109277e3f --- /dev/null +++ b/bahmnicore-omod/src/test/resources/createPatientMetadata.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/customTestDataset1_12.xml b/bahmnicore-omod/src/test/resources/customTestDataset1_12.xml new file mode 100644 index 0000000000..abda9a0c23 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/customTestDataset1_12.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/diagnosisMetadata.xml b/bahmnicore-omod/src/test/resources/diagnosisMetadata.xml new file mode 100644 index 0000000000..9540996eb7 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/diagnosisMetadata.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/discontinueDrugsForDrugOGram.xml b/bahmnicore-omod/src/test/resources/discontinueDrugsForDrugOGram.xml new file mode 100644 index 0000000000..e749f56dd8 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/discontinueDrugsForDrugOGram.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/discontinuedDrugOrder.xml b/bahmnicore-omod/src/test/resources/discontinuedDrugOrder.xml new file mode 100644 index 0000000000..3835b28199 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/discontinuedDrugOrder.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/dispositionMetadata.xml b/bahmnicore-omod/src/test/resources/dispositionMetadata.xml new file mode 100644 index 0000000000..3ef5d2c04f --- /dev/null +++ b/bahmnicore-omod/src/test/resources/dispositionMetadata.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/dispositionsForVisit.xml b/bahmnicore-omod/src/test/resources/dispositionsForVisit.xml new file mode 100644 index 0000000000..b4943e32c7 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/dispositionsForVisit.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/drugOrdersForDelete.xml b/bahmnicore-omod/src/test/resources/drugOrdersForDelete.xml new file mode 100644 index 0000000000..38f1d5ea57 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/drugOrdersForDelete.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/drugOrdersForVisits.xml b/bahmnicore-omod/src/test/resources/drugOrdersForVisits.xml new file mode 100644 index 0000000000..05294487ed --- /dev/null +++ b/bahmnicore-omod/src/test/resources/drugOrdersForVisits.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/drugogram.xml b/bahmnicore-omod/src/test/resources/drugogram.xml new file mode 100644 index 0000000000..fd723c5270 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/drugogram.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/entityMappingDataSet.xml b/bahmnicore-omod/src/test/resources/entityMappingDataSet.xml new file mode 100644 index 0000000000..9c6e7c36ce --- /dev/null +++ b/bahmnicore-omod/src/test/resources/entityMappingDataSet.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/flowSheetDataSetWithMultipleLevelConcepts.xml b/bahmnicore-omod/src/test/resources/flowSheetDataSetWithMultipleLevelConcepts.xml new file mode 100644 index 0000000000..59436bce16 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/flowSheetDataSetWithMultipleLevelConcepts.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/flowSheetTableDataSet.xml b/bahmnicore-omod/src/test/resources/flowSheetTableDataSet.xml new file mode 100644 index 0000000000..e008bfafcf --- /dev/null +++ b/bahmnicore-omod/src/test/resources/flowSheetTableDataSet.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/flowSheetTableDataSetForConceptDetails.xml b/bahmnicore-omod/src/test/resources/flowSheetTableDataSetForConceptDetails.xml new file mode 100644 index 0000000000..132586dd48 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/flowSheetTableDataSetForConceptDetails.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/flowSheetTableDataSetForInitialAndLatestCount.xml b/bahmnicore-omod/src/test/resources/flowSheetTableDataSetForInitialAndLatestCount.xml new file mode 100644 index 0000000000..c9d4a399ec --- /dev/null +++ b/bahmnicore-omod/src/test/resources/flowSheetTableDataSetForInitialAndLatestCount.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/formBuilderObs.xml b/bahmnicore-omod/src/test/resources/formBuilderObs.xml new file mode 100644 index 0000000000..c659c14597 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/formBuilderObs.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/labOrderTestData.xml b/bahmnicore-omod/src/test/resources/labOrderTestData.xml new file mode 100644 index 0000000000..5552b4d12b --- /dev/null +++ b/bahmnicore-omod/src/test/resources/labOrderTestData.xml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/labResult.xml b/bahmnicore-omod/src/test/resources/labResult.xml new file mode 100644 index 0000000000..c4db024855 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/labResult.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/labResultMetaData.xml b/bahmnicore-omod/src/test/resources/labResultMetaData.xml new file mode 100644 index 0000000000..3821513459 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/labResultMetaData.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/locationData.xml b/bahmnicore-omod/src/test/resources/locationData.xml new file mode 100644 index 0000000000..25ac1247e5 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/locationData.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/obsRelationshipDataset.xml b/bahmnicore-omod/src/test/resources/obsRelationshipDataset.xml new file mode 100644 index 0000000000..26cdfbc3b5 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/obsRelationshipDataset.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/patient.json b/bahmnicore-omod/src/test/resources/patient.json new file mode 100644 index 0000000000..c9395cb2bd --- /dev/null +++ b/bahmnicore-omod/src/test/resources/patient.json @@ -0,0 +1,47 @@ +{ + "patient": { + "person": { + "names": [ + { + "givenName": "fhqbe", + "middleName": "dw", + "familyName": "fen", + "preferred": false + } + ], + "addresses": [ + { + "cityVillage": "erwf", + "countyDistrict": "fwefe", + "stateProvince": "fewf", + "postalCode": "22" + } + ], + "birthdate": "1984-03-08", + "gender": "O", + "birthtime": null, + "attributes": [ + + ], + "deathDate": null, + "causeOfDeath": "" + }, + "identifiers": [ + { + "identifierType": "81433852-3f10-11e4-adec-0800271c1b75", + "identifierSourceUuid" : "dead-cafe", + "identifierPrefix": "BAH", + "preferred": true, + "voided": false + }, + { + "identifierType": "81433852-3f10-11e4-adec-0800271c1b76", + "identifier":"someId", + "preferred": false, + "voided": false + } + + ] + }, + "relationships": [] +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/patientContextDataSet.xml b/bahmnicore-omod/src/test/resources/patientContextDataSet.xml new file mode 100644 index 0000000000..42d2e224dc --- /dev/null +++ b/bahmnicore-omod/src/test/resources/patientContextDataSet.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/prescribedAndActiveDrugOrdersForVisits.xml b/bahmnicore-omod/src/test/resources/prescribedAndActiveDrugOrdersForVisits.xml new file mode 100644 index 0000000000..648eef9e5b --- /dev/null +++ b/bahmnicore-omod/src/test/resources/prescribedAndActiveDrugOrdersForVisits.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/programEnrollmentDataSet.xml b/bahmnicore-omod/src/test/resources/programEnrollmentDataSet.xml new file mode 100644 index 0000000000..2451e62dd3 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/programEnrollmentDataSet.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/providerDataSet.xml b/bahmnicore-omod/src/test/resources/providerDataSet.xml new file mode 100644 index 0000000000..38e47aa8ca --- /dev/null +++ b/bahmnicore-omod/src/test/resources/providerDataSet.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/revisedDrugsForDrugOGram.xml b/bahmnicore-omod/src/test/resources/revisedDrugsForDrugOGram.xml new file mode 100644 index 0000000000..321f6ec843 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/revisedDrugsForDrugOGram.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/baseBacteriologyData.xml b/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/baseBacteriologyData.xml new file mode 100644 index 0000000000..987b541c19 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/baseBacteriologyData.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/existingSpecimenObs.xml b/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/existingSpecimenObs.xml new file mode 100644 index 0000000000..d1490a71b3 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/existingSpecimenObs.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/programEpisodeMapping.xml b/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/programEpisodeMapping.xml new file mode 100644 index 0000000000..caa1efa4f9 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/search/bacteriologySpecimen/programEpisodeMapping.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/search/conceptAnswerSearch/testData.xml b/bahmnicore-omod/src/test/resources/search/conceptAnswerSearch/testData.xml new file mode 100644 index 0000000000..0a78c46745 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/search/conceptAnswerSearch/testData.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/search/conceptDataWithDatatypes.xml b/bahmnicore-omod/src/test/resources/search/conceptDataWithDatatypes.xml new file mode 100644 index 0000000000..88e5e5de46 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/search/conceptDataWithDatatypes.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/search/conceptSetBasedDrug/drugsWithConcepts.xml b/bahmnicore-omod/src/test/resources/search/conceptSetBasedDrug/drugsWithConcepts.xml new file mode 100644 index 0000000000..2251e23c7e --- /dev/null +++ b/bahmnicore-omod/src/test/resources/search/conceptSetBasedDrug/drugsWithConcepts.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/setup.xml b/bahmnicore-omod/src/test/resources/setup.xml new file mode 100644 index 0000000000..c06926984d --- /dev/null +++ b/bahmnicore-omod/src/test/resources/setup.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/startAndStopOnSameDateDrugs.xml b/bahmnicore-omod/src/test/resources/startAndStopOnSameDateDrugs.xml new file mode 100644 index 0000000000..be56a8caab --- /dev/null +++ b/bahmnicore-omod/src/test/resources/startAndStopOnSameDateDrugs.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/test-hibernate.cfg.xml b/bahmnicore-omod/src/test/resources/test-hibernate.cfg.xml new file mode 100644 index 0000000000..9270665683 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/test-hibernate.cfg.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/updatePatient.json b/bahmnicore-omod/src/test/resources/updatePatient.json new file mode 100644 index 0000000000..79501724d2 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/updatePatient.json @@ -0,0 +1,31 @@ +{ + "patient": { + "person": { + "names": [ + { + "uuid": "4e89ec9e-6bd7-43e5-b5b9-9671c1c3eb9b", + "givenName": "abishek", + "middleName": "kumar", + "familyName": "Anand", + "preferred": true + } + ], + "birthdate": "1984-03-07", + "birthdateEstimated": false, + "birthtime": null, + "gender": "M", + "dead": false, + "deathDate": null, + "causeOfDeath": "" + }, + "identifiers": [ + { + "display": "Patient Identifier = BDH202039", + "uuid": "12f43236-d986-4cd9-a8e2-733400649b3a", + "identifierType": "81433852-3f10-11e4-adec-0800271c1b76", + "identifier": "ABC123DEF" + } + ] + }, + "relationships": [] +} \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/uploadDocuments.xml b/bahmnicore-omod/src/test/resources/uploadDocuments.xml new file mode 100644 index 0000000000..3c5f25ed1d --- /dev/null +++ b/bahmnicore-omod/src/test/resources/uploadDocuments.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/userRolesAndPrivileges.xml b/bahmnicore-omod/src/test/resources/userRolesAndPrivileges.xml new file mode 100644 index 0000000000..b5c4a98e2b --- /dev/null +++ b/bahmnicore-omod/src/test/resources/userRolesAndPrivileges.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-omod/src/test/resources/visitFormDataSet.xml b/bahmnicore-omod/src/test/resources/visitFormDataSet.xml new file mode 100644 index 0000000000..6ddb0ee485 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/visitFormDataSet.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-omod/src/test/resources/visitInfo.xml b/bahmnicore-omod/src/test/resources/visitInfo.xml new file mode 100644 index 0000000000..55c6c48988 --- /dev/null +++ b/bahmnicore-omod/src/test/resources/visitInfo.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-ui/pom.xml b/bahmnicore-ui/pom.xml new file mode 100644 index 0000000000..c43c0c1438 --- /dev/null +++ b/bahmnicore-ui/pom.xml @@ -0,0 +1,193 @@ + + 4.0.0 + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + bahmnicore-ui + jar + Bahmnicore-ui + http://maven.apache.org + + + junit + junit + + + org.openmrs.test + openmrs-test + pom + test + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + jar + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + test-jar + test + + + javax.servlet + javax.servlet-api + + + org.openmrs.module + reporting-api + ${reportingModuleVersion} + test + + + org.openmrs.module + calculation-api + ${calculationModuleVersion} + test + + + org.openmrs.module + serialization.xstream-api-2.0 + ${serializationXstreamModuleVersion} + test + + + org.openmrs.module + appframework-api + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test + test-jar + + + org.bahmni.module + bahmnicore-api + ${project.version} + + + org.bahmni.module + reference-data-api + ${project.version} + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.openmrs.module + providermanagement-api + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + test-jar + test + + + org.openmrs.module + addresshierarchy-api + jar + ${addressHierarchyVersion} + + + org.openmrs.module + addresshierarchy-omod + jar + ${addressHierarchyVersion} + + + org.bahmni.module + episodes-api + ${episodes.version} + provided + + + org.ict4h.openmrs + openmrs-atomfeed-api + ${openmrsAtomfeedVersion} + test + + + org.openmrs.module + legacyui-omod + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + test + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.08 + + + BRANCH + COVEREDRATIO + 0.03 + + + + + + + + + + + + diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/constant/DiseaseSummaryConstants.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/constant/DiseaseSummaryConstants.java new file mode 100644 index 0000000000..e2001f5da3 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/constant/DiseaseSummaryConstants.java @@ -0,0 +1,12 @@ +package org.bahmni.module.bahmnicoreui.constant; + +public class DiseaseSummaryConstants { + + public static final String DATE_FORMAT = "yyyy-MM-dd"; + public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm"; + public static final String RESULT_TABLE_GROUP_BY_ENCOUNTER = "encounters"; + public static final String RESULT_TABLE_GROUP_BY_VISITS = "visits"; + public static final String RESULT_TABLE_GROUP_BY_OBS_DATETIME = "time"; + public static final String RESULT_TABLE_GROUP_BY_OBS_DATETIME_AND_CONCEPT = "obstime"; + +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/ConceptValue.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/ConceptValue.java new file mode 100644 index 0000000000..a05ac1100c --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/ConceptValue.java @@ -0,0 +1,24 @@ +package org.bahmni.module.bahmnicoreui.contract; + +public class ConceptValue { + private String value; + + private Boolean abnormal; + + public Boolean getAbnormal() { + return abnormal; + } + + public void setAbnormal(Boolean abnormal) { + this.abnormal = abnormal; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseDataParams.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseDataParams.java new file mode 100644 index 0000000000..91371f5c6e --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseDataParams.java @@ -0,0 +1,98 @@ +package org.bahmni.module.bahmnicoreui.contract; + +import java.util.Date; +import java.util.List; + +public class DiseaseDataParams { + + private Integer numberOfVisits; + private Integer initialCount; + private Integer latestCount; + private List obsConcepts; + private List drugConcepts; + private List labConcepts; + private String groupBy; + private String visitUuid; + private Date startDate; + private Date endDate; + + public Integer getNumberOfVisits() { + return numberOfVisits; + } + + public void setNumberOfVisits(Integer numberOfVisits) { + this.numberOfVisits = numberOfVisits; + } + + public Integer getLatestCount() { + return latestCount; + } + + public void setLatestCount(Integer latestCount) { + this.latestCount = latestCount; + } + + public Integer getInitialCount() { + return initialCount; + } + + public void setInitialCount(Integer initialCount) { + this.initialCount = initialCount; + } + + public List getObsConcepts() { + return obsConcepts; + } + + public void setObsConcepts(List obsConcepts) { + this.obsConcepts = obsConcepts; + } + + public List getLabConcepts() { + return labConcepts; + } + + public void setLabConcepts(List labConcepts) { + this.labConcepts = labConcepts; + } + + public List getDrugConcepts() { + return drugConcepts; + } + + public void setDrugConcepts(List drugConcepts) { + this.drugConcepts = drugConcepts; + } + + public String getGroupBy() { + return groupBy; + } + + public void setGroupBy(String groupBy) { + this.groupBy = groupBy; + } + + public String getVisitUuid() { + return visitUuid; + } + + public void setVisitUuid(String visitUuid) { + this.visitUuid = visitUuid; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryData.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryData.java new file mode 100644 index 0000000000..84e206fed7 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryData.java @@ -0,0 +1,51 @@ +package org.bahmni.module.bahmnicoreui.contract; + +import org.bahmni.module.referencedata.contract.ConceptDetails; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +public class DiseaseSummaryData { + + private DiseaseSummaryMap tabularData = new DiseaseSummaryMap(); + private Set conceptDetails = new LinkedHashSet<>(); + + public DiseaseSummaryMap getTabularData() { + return tabularData; + } + + public void setTabularData(DiseaseSummaryMap tabularData) { + this.tabularData = tabularData; + } + + public void addTabularData(Map> newTable){ + for (String visitDate : newTable.keySet()) { + Map valuesForVisit = getValuesForVisit(visitDate);//tabularData.toString(visitDate); + valuesForVisit.putAll(newTable.get(visitDate)); + } + } + + private Map getValuesForVisit(String visitDate) { + Map valuesForVisit = tabularData.get(visitDate); + if( valuesForVisit == null){ + valuesForVisit = new LinkedHashMap<>(); + tabularData.put(visitDate,valuesForVisit); + } + return valuesForVisit; + } + + public Set getConceptDetails() { + return conceptDetails; + } + + public void addConceptDetails(Set conceptDetails) { + this.conceptDetails.addAll(conceptDetails); + } + + public void concat(DiseaseSummaryData diseaseSummaryData){ + addTabularData(diseaseSummaryData.getTabularData()); + addConceptDetails(diseaseSummaryData.getConceptDetails()); + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryMap.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryMap.java new file mode 100644 index 0000000000..cace6a47e8 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryMap.java @@ -0,0 +1,28 @@ +package org.bahmni.module.bahmnicoreui.contract; + +import org.apache.commons.collections.MapUtils; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class DiseaseSummaryMap extends LinkedHashMap> { + + public Map get(String visitStartDateTime) { + Map mapValue = super.get(visitStartDateTime); + if(MapUtils.isEmpty(mapValue)){ + put(visitStartDateTime, new LinkedHashMap()); + } + return super.get(visitStartDateTime); + } + + public void put(String startDateTime, String conceptName, String value, Boolean abnormal, boolean replaceExisting) { + Map cellValue = this.get(startDateTime); + if (cellValue.containsKey(conceptName) && !replaceExisting) return; + + ConceptValue conceptValue = new ConceptValue(); + conceptValue.setValue(value); + conceptValue.setAbnormal(abnormal); + cellValue.put(conceptName, conceptValue); + super.put(startDateTime, cellValue); + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/Privilege.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/Privilege.java new file mode 100644 index 0000000000..b0f24dbb76 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/contract/Privilege.java @@ -0,0 +1,13 @@ +package org.bahmni.module.bahmnicoreui.contract; + +public class Privilege { + private String name; + + public Privilege(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/DrugOrderDiseaseSummaryAggregator.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/DrugOrderDiseaseSummaryAggregator.java new file mode 100644 index 0000000000..dafde033f2 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/DrugOrderDiseaseSummaryAggregator.java @@ -0,0 +1,65 @@ +package org.bahmni.module.bahmnicoreui.helper; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniDrugOrderService; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.mapper.DiseaseSummaryDrugOrderMapper; +import org.bahmni.module.referencedata.helper.ConceptHelper; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class DrugOrderDiseaseSummaryAggregator { + + private final Integer DEFAULT_VISIT_NUMBER = 50; + private final VisitService visitService; + private BahmniDrugOrderService drugOrderService; + private ConceptHelper conceptHelper; + private VisitDao visitDao; + private BahmniConceptService bahmniConceptService; + private final DiseaseSummaryDrugOrderMapper diseaseSummaryDrugOrderMapper = new DiseaseSummaryDrugOrderMapper(); + + @Autowired + public DrugOrderDiseaseSummaryAggregator(ConceptHelper conceptHelper, VisitService visitService, BahmniDrugOrderService drugOrderService, VisitDao visitDao, BahmniConceptService bahmniConceptService) { + this.visitService = visitService; + this.drugOrderService = drugOrderService; + this.conceptHelper = conceptHelper; + this.bahmniConceptService = bahmniConceptService; + this.visitDao = visitDao; + } + + public DiseaseSummaryData aggregate(Patient patient, DiseaseDataParams diseaseDataParams) { + DiseaseSummaryData diseaseSummaryData = new DiseaseSummaryData(); + List concepts = bahmniConceptService.getConceptsByFullySpecifiedName(diseaseDataParams.getDrugConcepts()); + if (!concepts.isEmpty()) { + List drugOrders = drugOrderService.getPrescribedDrugOrdersForConcepts(patient, true, getVisits(patient, diseaseDataParams), concepts, diseaseDataParams.getStartDate(), diseaseDataParams.getEndDate() ); + diseaseSummaryData.addTabularData(diseaseSummaryDrugOrderMapper.map(drugOrders, diseaseDataParams.getGroupBy())); + diseaseSummaryData.addConceptDetails(conceptHelper.getConceptDetails(concepts)); + } + return diseaseSummaryData; + } + + private List getVisits(Patient patient, final DiseaseDataParams diseaseDataParams) { + if (StringUtils.isBlank(diseaseDataParams.getVisitUuid())) { + return visitDao.getVisitsByPatient(patient, getNumberOfVisits(diseaseDataParams.getNumberOfVisits())); + } + return new ArrayList() {{ + add(visitService.getVisitByUuid(diseaseDataParams.getVisitUuid())); + }}; + } + + private int getNumberOfVisits(Integer numberOfVisit) { + return null != numberOfVisit ? numberOfVisit : DEFAULT_VISIT_NUMBER; + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/LabDiseaseSummaryAggregator.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/LabDiseaseSummaryAggregator.java new file mode 100644 index 0000000000..4df2ea7227 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/LabDiseaseSummaryAggregator.java @@ -0,0 +1,90 @@ +package org.bahmni.module.bahmnicoreui.helper; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicore.dao.VisitDao; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.mapper.DiseaseSummaryLabMapper; +import org.bahmni.module.referencedata.contract.ConceptDetails; +import org.bahmni.module.referencedata.helper.ConceptHelper; +import org.openmrs.Concept; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.VisitService; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.service.LabOrderResultsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class LabDiseaseSummaryAggregator { + + private final Integer DEFAULT_VISIT_NUMBER = 50; + private final ConceptHelper conceptHelper; + private LabOrderResultsService labOrderResultsService; + private VisitService visitService; + private VisitDao visitDao; + private BahmniConceptService bahmniConceptService; + private final DiseaseSummaryLabMapper diseaseSummaryLabMapper = new DiseaseSummaryLabMapper(); + + + @Autowired + public LabDiseaseSummaryAggregator(ConceptHelper conceptHelper, LabOrderResultsService labOrderResultsService, VisitService visitService, VisitDao visitDao,BahmniConceptService bahmniConceptService) { + this.labOrderResultsService = labOrderResultsService; + this.visitService = visitService; + this.conceptHelper = conceptHelper; + this.visitDao = visitDao; + this.bahmniConceptService = bahmniConceptService; + } + + public DiseaseSummaryData aggregate(Patient patient, DiseaseDataParams diseaseDataParams) { + DiseaseSummaryData diseaseSummaryData = new DiseaseSummaryData(); + List concepts = bahmniConceptService.getConceptsByFullySpecifiedName(diseaseDataParams.getLabConcepts()); + if(!concepts.isEmpty()){ + List labOrderResults = labOrderResultsService.getAllForConcepts(patient, diseaseDataParams.getLabConcepts(), getVisits(patient, diseaseDataParams), diseaseDataParams.getStartDate(), diseaseDataParams.getEndDate()); + diseaseSummaryData.addTabularData(diseaseSummaryLabMapper.map(labOrderResults, diseaseDataParams.getGroupBy())); + diseaseSummaryData.addConceptDetails(conceptHelper.getLeafConceptDetails(concepts, false)); + mapLowNormalAndHiNormal(diseaseSummaryData, labOrderResults); + } + return diseaseSummaryData; + } + + private void mapLowNormalAndHiNormal(DiseaseSummaryData diseaseSummaryData, List labOrderResults) { + for (ConceptDetails conceptDetails : diseaseSummaryData.getConceptDetails()) { + LabOrderResult labOrderResult = findLabOrder(conceptDetails.getName(), labOrderResults); + if (labOrderResult!= null){ + conceptDetails.setHiNormal(labOrderResult.getMaxNormal()); + conceptDetails.setLowNormal(labOrderResult.getMinNormal()); + conceptDetails.setUnits(labOrderResult.getTestUnitOfMeasurement() != null ? labOrderResult.getTestUnitOfMeasurement() : conceptDetails.getUnits()); + } + } + + } + + private LabOrderResult findLabOrder(String name, List labOrderResults) { + for (LabOrderResult labOrderResult : labOrderResults) { + if(labOrderResult.getTestName().equals(name)){ + return labOrderResult; + } + } + return null; + } + + private List getVisits(Patient patient, final DiseaseDataParams diseaseDataParams) { + if(StringUtils.isBlank(diseaseDataParams.getVisitUuid())){ + return visitDao.getVisitsByPatient(patient, getNumberOfVisits(diseaseDataParams.getNumberOfVisits())); + } + return new ArrayList() {{ + add(visitService.getVisitByUuid(diseaseDataParams.getVisitUuid())); + }}; + } + + private int getNumberOfVisits(Integer numberOfVisit) { + return null != numberOfVisit ? numberOfVisit : DEFAULT_VISIT_NUMBER; + } + +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/ObsDiseaseSummaryAggregator.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/ObsDiseaseSummaryAggregator.java new file mode 100644 index 0000000000..9a26e80723 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/helper/ObsDiseaseSummaryAggregator.java @@ -0,0 +1,71 @@ +package org.bahmni.module.bahmnicoreui.helper; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.Predicate; +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.bahmnicore.service.BahmniConceptService; +import org.bahmni.module.bahmnicore.service.BahmniObsService; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.mapper.DiseaseSummaryObsMapper; +import org.bahmni.module.referencedata.helper.ConceptHelper; +import org.openmrs.Concept; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Component +public class ObsDiseaseSummaryAggregator { + + private final ConceptHelper conceptHelper; + private BahmniObsService bahmniObsService; + private BahmniConceptService bahmniConceptService; + private final DiseaseSummaryObsMapper diseaseSummaryObsMapper = new DiseaseSummaryObsMapper(); + + @Autowired + public ObsDiseaseSummaryAggregator(ConceptHelper conceptHelper, BahmniObsService bahmniObsService, BahmniConceptService bahmniConceptService) { + this.bahmniObsService = bahmniObsService; + this.conceptHelper = conceptHelper; + this.bahmniConceptService = bahmniConceptService; + } + + public DiseaseSummaryData aggregate(Patient patient, DiseaseDataParams queryParams) { + DiseaseSummaryData diseaseSummaryData = new DiseaseSummaryData(); + List concepts = bahmniConceptService.getConceptsByFullySpecifiedName(queryParams.getObsConcepts()); + Collection bahmniObservations = fetchBahmniObservations(patient, queryParams, concepts); + bahmniObservations.forEach(bahmniObservation -> bahmniObservation.setAbnormal((bahmniObservation.getInterpretation() != null && bahmniObservation.getInterpretation().equals(String.valueOf(Obs.Interpretation.ABNORMAL))))); + constructDiseaseSummaryData(bahmniObservations, concepts, queryParams.getGroupBy(), diseaseSummaryData); + return diseaseSummaryData; + } + + private Collection fetchBahmniObservations(Patient patient, DiseaseDataParams queryParams, List concepts) { + if (StringUtils.isBlank(queryParams.getVisitUuid())) { + if (!concepts.isEmpty()) { + return bahmniObsService.observationsFor(patient.getUuid(), concepts, queryParams.getNumberOfVisits(), null, false, null, queryParams.getStartDate(), queryParams.getEndDate()); + } + return Collections.EMPTY_LIST; + } + return filterObservationsLinkedWithOrders(bahmniObsService.getObservationForVisit(queryParams.getVisitUuid(), queryParams.getObsConcepts(), null, false, null)); + } + + private Collection filterObservationsLinkedWithOrders(Collection bahmniObservations) { + CollectionUtils.filter(bahmniObservations,new Predicate() { + @Override + public boolean evaluate(Object bahmniObservation) { + return ((BahmniObservation)bahmniObservation).getOrderUuid() == null; + } + }); + return bahmniObservations; + } + + private void constructDiseaseSummaryData(Collection bahmniObservations, List concepts, String groupBy, DiseaseSummaryData diseaseSummaryData) { + diseaseSummaryData.setTabularData(diseaseSummaryObsMapper.map(bahmniObservations, groupBy)); + diseaseSummaryData.addConceptDetails(conceptHelper.getLeafConceptDetails(concepts, false)); + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryDrugOrderMapper.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryDrugOrderMapper.java new file mode 100644 index 0000000000..270822905d --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryDrugOrderMapper.java @@ -0,0 +1,43 @@ +package org.bahmni.module.bahmnicoreui.mapper; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.bahmnicoreui.constant.DiseaseSummaryConstants; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryMap; +import org.openmrs.Concept; +import org.openmrs.DrugOrder; + +import java.io.IOException; +import java.util.List; + +public class DiseaseSummaryDrugOrderMapper{ + + private Logger logger = LogManager.getLogger(this.getClass()); + + public DiseaseSummaryMap map(List drugOrders, String groupBy) { + DiseaseSummaryMap diseaseSummaryMap = new DiseaseSummaryMap(); + for (DrugOrder drugOrder : drugOrders) { + String startDateTime = (DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_ENCOUNTER.equals(groupBy)) ? + DateFormatUtils.format(drugOrder.getEncounter().getEncounterDatetime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()) : DateFormatUtils.format(drugOrder.getEncounter().getVisit().getStartDatetime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + String conceptName = drugOrder.getDrug().getConcept().getName().getName(); + try { + diseaseSummaryMap.put(startDateTime, conceptName, formattedDrugOrderValue(drugOrder), null, false); + } catch (IOException e) { + logger.error("Could not parse dosing instructions",e); + throw new RuntimeException("Could not parse dosing instructions",e); + } + } + return diseaseSummaryMap; + } + + private String formattedDrugOrderValue(DrugOrder drugOrder) throws IOException { + String strength = drugOrder.getDrug().getStrength(); + Concept doseUnitsConcept = drugOrder.getDoseUnits(); + String doseUnit = doseUnitsConcept == null ? "" : " " + doseUnitsConcept.getName().getName(); + String dose = drugOrder.getDose() == null ? "" : drugOrder.getDose() + doseUnit; + String frequency = DoseInstructionMapper.getFrequency(drugOrder); + String asNeeded = drugOrder.getAsNeeded() ? "SOS" : null; + return DoseInstructionMapper.concat(",", strength, dose, frequency, asNeeded); + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryLabMapper.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryLabMapper.java new file mode 100644 index 0000000000..f4396bc222 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryLabMapper.java @@ -0,0 +1,24 @@ +package org.bahmni.module.bahmnicoreui.mapper; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.bahmni.module.bahmnicoreui.constant.DiseaseSummaryConstants; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryMap; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; + +import java.util.List; + +public class DiseaseSummaryLabMapper { + + public DiseaseSummaryMap map(List labOrderResults, String groupBy) { + DiseaseSummaryMap diseaseSummaryMap = new DiseaseSummaryMap(); + for (LabOrderResult labOrderResult : labOrderResults) { + String startDateTime = (DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_ENCOUNTER.equals(groupBy)) ? + DateFormatUtils.format(labOrderResult.getAccessionDateTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()) : DateFormatUtils.format(labOrderResult.getVisitStartTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + String conceptName = labOrderResult.getTestName(); + if (conceptName != null) { + diseaseSummaryMap.put(startDateTime, conceptName, labOrderResult.getResult(), labOrderResult.getAbnormal(), true); + } + } + return diseaseSummaryMap; + } +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryObsMapper.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryObsMapper.java new file mode 100644 index 0000000000..1afadd7408 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryObsMapper.java @@ -0,0 +1,99 @@ +package org.bahmni.module.bahmnicoreui.mapper; + + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.bahmni.module.bahmnicoreui.constant.DiseaseSummaryConstants; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryMap; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.ETObsToBahmniObsMapper; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class DiseaseSummaryObsMapper { + + public DiseaseSummaryMap map(Collection bahmniObservations, String groupBy) { + DiseaseSummaryMap diseaseSummaryMap = new DiseaseSummaryMap(); + bahmniObservations = extractGroupObservationFromParent(bahmniObservations); + if (CollectionUtils.isNotEmpty(bahmniObservations)) { + Map> observationsByEncounter = groupObsByEncounterUuid(bahmniObservations); + for (BahmniObservation bahmniObservation : bahmniObservations) { + List observationsFromConceptSet = new ArrayList<>(); + constructLeafObservationsFromConceptSet(bahmniObservation, observationsFromConceptSet); + for (BahmniObservation leafObservation : observationsFromConceptSet) { + String startDateTime = getGroupByDate(leafObservation, groupBy); + String conceptName = leafObservation.getConcept().getShortName(); + String observationValue = computeValueForLeafObservation(leafObservation, observationsByEncounter, !DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_OBS_DATETIME_AND_CONCEPT.equals(groupBy)); + diseaseSummaryMap.put(startDateTime, conceptName, observationValue, leafObservation.isAbnormal(), false); + } + } + } + return diseaseSummaryMap; + } + + private String getGroupByDate(BahmniObservation observation, String groupBy) { + switch (StringUtils.defaultString(groupBy)) { + case DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_ENCOUNTER: return DateFormatUtils.format(observation.getEncounterDateTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + case DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_OBS_DATETIME: + case DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_OBS_DATETIME_AND_CONCEPT: + return DateFormatUtils.format(observation.getObservationDateTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + default: return DateFormatUtils.format(observation.getVisitStartDateTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + } + } + + private List extractGroupObservationFromParent(Collection bahmniObservations){ + List finalObservations = new ArrayList<>(); + for (BahmniObservation bahmniObservation : bahmniObservations) { + constructLeafObservationsFromConceptSet(bahmniObservation, finalObservations); + } + return finalObservations; + } + + private Map> groupObsByEncounterUuid(Collection bahmniObservations) { + Map> result = new LinkedHashMap<>(); + for (BahmniObservation bahmniObservation : bahmniObservations) { + List bahmniObservationsForEncounter = result.get(bahmniObservation.getEncounterUuid()) == null?new ArrayList():result.get(bahmniObservation.getEncounterUuid()); + bahmniObservationsForEncounter.add(bahmniObservation); + result.put(bahmniObservation.getEncounterUuid(), bahmniObservationsForEncounter); + } + return result; + } + + private void constructLeafObservationsFromConceptSet(BahmniObservation bahmniObservation, List observationsFromConceptSet) { + if (bahmniObservation.getGroupMembers().size() > 0) { + for (BahmniObservation groupMember : bahmniObservation.getGroupMembers()) + constructLeafObservationsFromConceptSet(groupMember, observationsFromConceptSet); + } else { + if (!ETObsToBahmniObsMapper.ABNORMAL_CONCEPT_CLASS.equals(bahmniObservation.getConcept().getConceptClass())) { + observationsFromConceptSet.add(bahmniObservation); + } + } + } + + private String computeValueForLeafObservation(BahmniObservation observation, Map> observationsByEncounter, boolean allowMultiValue) { + String observationValue = null; + if (observationsByEncounter.containsKey(observation.getEncounterUuid())) { + List observationsInEncounter = observationsByEncounter.get(observation.getEncounterUuid()); + String multiSelectObsValue = ""; + for (BahmniObservation bahmniObservationInEncounter : observationsInEncounter) { + if ( allowMultiValue && arePartOfMultiSelectObservation(observation,bahmniObservationInEncounter) ) { + multiSelectObsValue = multiSelectObsValue + "," + bahmniObservationInEncounter.getValueAsString(); + } + } + observationValue = StringUtils.isBlank(multiSelectObsValue)? observation.getValueAsString(): observation.getValueAsString() + multiSelectObsValue; + } + return observationValue; + } + + private boolean arePartOfMultiSelectObservation(BahmniObservation observation,BahmniObservation observationInEncounter){ + return observation.getConcept().getName().equals(observationInEncounter.getConcept().getName()) + && StringUtils.equals(observation.getObsGroupUuid(),observationInEncounter.getObsGroupUuid()) + && !observation.getUuid().equals(observationInEncounter.getUuid()); + } + +} diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DoseInstructionMapper.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DoseInstructionMapper.java new file mode 100644 index 0000000000..729fa0400f --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/mapper/DoseInstructionMapper.java @@ -0,0 +1,50 @@ +package org.bahmni.module.bahmnicoreui.mapper; + +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.type.TypeReference; +import org.openmrs.DrugOrder; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class DoseInstructionMapper { + + public static String getFrequency(DrugOrder drugOrder) throws IOException { + if (drugOrder.getFrequency() == null) { + String dosingInstructions = drugOrder.getDosingInstructions(); + Map instructions = hashMapForJson(dosingInstructions); + return concat("-", getEmptyIfNull(instructions.get("morningDose")), + getEmptyIfNull(instructions.get("afternoonDose")), + getEmptyIfNull(instructions.get("eveningDose"))); + } + return drugOrder.getFrequency().getName(); + } + + private static String getEmptyIfNull(Object text) { + return text == null ? "" : text.toString(); + } + + public static Map hashMapForJson(String dosingInstructions) throws IOException { + if (dosingInstructions == null || dosingInstructions.isEmpty()) { + return Collections.EMPTY_MAP; + } + ObjectMapper objectMapper = new ObjectMapper(new JsonFactory()); + TypeReference> typeRef + = new TypeReference>() { + }; + return objectMapper.readValue(dosingInstructions, typeRef); + } + + public static String concat(String separator, String... values) { + StringBuilder stringBuilder = new StringBuilder(); + for (String value : values) { + if (value != null && !value.isEmpty()) { + stringBuilder.append(separator).append(value); + } + } + return stringBuilder.length() > 1 ? stringBuilder.substring(1) : ""; + } +} \ No newline at end of file diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/service/BahmniDiseaseSummaryService.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/service/BahmniDiseaseSummaryService.java new file mode 100644 index 0000000000..9a9a5363ca --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/service/BahmniDiseaseSummaryService.java @@ -0,0 +1,11 @@ +package org.bahmni.module.bahmnicoreui.service; + +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; + +public interface BahmniDiseaseSummaryService { + + DiseaseSummaryData getDiseaseSummary(String patientUuid, DiseaseDataParams queryParams); +} + + diff --git a/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImpl.java b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImpl.java new file mode 100644 index 0000000000..afc80cfc18 --- /dev/null +++ b/bahmnicore-ui/src/main/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImpl.java @@ -0,0 +1,103 @@ +package org.bahmni.module.bahmnicoreui.service.impl; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryMap; +import org.bahmni.module.bahmnicoreui.helper.DrugOrderDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.helper.LabDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.helper.ObsDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.service.BahmniDiseaseSummaryService; +import org.openmrs.Patient; +import org.openmrs.api.PatientService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Set; + + +@Service +public class BahmniDiseaseSummaryServiceImpl implements BahmniDiseaseSummaryService { + + private PatientService patientService; + private LabDiseaseSummaryAggregator labDiseaseSummaryAggregator; + private DrugOrderDiseaseSummaryAggregator drugOrderDiseaseSummaryAggregator; + private ObsDiseaseSummaryAggregator obsDiseaseSummaryAggregator; + + @Autowired + public BahmniDiseaseSummaryServiceImpl(PatientService patientService, LabDiseaseSummaryAggregator labDiseaseSummaryAggregator, DrugOrderDiseaseSummaryAggregator drugOrderDiseaseSummaryAggregator, ObsDiseaseSummaryAggregator obsDiseaseSummaryAggregator){ + this.patientService = patientService; + this.labDiseaseSummaryAggregator = labDiseaseSummaryAggregator; + this.drugOrderDiseaseSummaryAggregator = drugOrderDiseaseSummaryAggregator; + this.obsDiseaseSummaryAggregator = obsDiseaseSummaryAggregator; + } + + @Override + @Transactional(readOnly = true) + public DiseaseSummaryData getDiseaseSummary(String patientUuid, DiseaseDataParams queryParams) { + DiseaseSummaryData diseaseSummaryData = new DiseaseSummaryData(); + + Patient patient = patientService.getPatientByUuid(patientUuid); + + diseaseSummaryData.concat(obsDiseaseSummaryAggregator.aggregate(patient, queryParams)); + diseaseSummaryData.concat(labDiseaseSummaryAggregator.aggregate(patient, queryParams)); + diseaseSummaryData.concat(drugOrderDiseaseSummaryAggregator.aggregate(patient, queryParams)); + diseaseSummaryData.setTabularData(filterDataByCount(diseaseSummaryData.getTabularData(), queryParams.getInitialCount(), queryParams.getLatestCount())); + return diseaseSummaryData; + } + + private DiseaseSummaryMap filterDataByCount(DiseaseSummaryMap diseaseSummaryMap, Integer initialCount, Integer latestCount) { + if(initialCount == null && latestCount == null) return filter(diseaseSummaryMap, 0, diseaseSummaryMap.size()); + DiseaseSummaryMap summaryMap = new DiseaseSummaryMap(); + summaryMap.putAll(filter(diseaseSummaryMap, 0, getIntegerValue(latestCount))); + summaryMap.putAll(filter(diseaseSummaryMap, diseaseSummaryMap.size() - getIntegerValue(initialCount), diseaseSummaryMap.size())); + + return summaryMap; + } + + private DiseaseSummaryMap filter(DiseaseSummaryMap diseaseSummaryMap, int fromIndex, int toIndex) { + DiseaseSummaryMap summaryMap = new DiseaseSummaryMap(); + fromIndex = (fromIndex > diseaseSummaryMap.size() || fromIndex < 0) ? 0 : fromIndex; + toIndex = (toIndex > diseaseSummaryMap.size()) ? diseaseSummaryMap.size() : toIndex; + + List summaryMapKeys = sortByDate(diseaseSummaryMap.keySet()); + for(int index=fromIndex; index sortByDate(Set dataSet) { + List sortedList = new ArrayList<>(dataSet); + Collections.sort(sortedList, new Comparator() { + public int compare(String o1, String o2) { + return convertToDate(o2).compareTo(convertToDate(o1)); + } + }); + return sortedList; + } + + private Date convertToDate(String dateString) { + Date startDate = null; + try { + startDate = DateUtils.parseDate(dateString, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + } catch (ParseException e) { + e.printStackTrace(); + } + return startDate; + } + + private int getIntegerValue(Integer value) { + if(value == null) return 0; + return value; + } +} diff --git a/bahmnicore-ui/src/main/resources/moduleApplicationContext.xml b/bahmnicore-ui/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..345df76949 --- /dev/null +++ b/bahmnicore-ui/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryDataTest.java b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryDataTest.java new file mode 100644 index 0000000000..7e60f99c7e --- /dev/null +++ b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/contract/DiseaseSummaryDataTest.java @@ -0,0 +1,76 @@ +package org.bahmni.module.bahmnicoreui.contract; + +import org.bahmni.module.referencedata.contract.ConceptDetails; +import org.junit.Test; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import static java.util.AbstractMap.SimpleEntry; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class DiseaseSummaryDataTest { + + @Test + public void shouldAddTabularDataToExistingTabularData(){ + DiseaseSummaryData diseaseSummaryData = new DiseaseSummaryData(); + Map> existingTabularData = new LinkedHashMap<>(); + existingTabularData.put("12-12-2012", createConceptValueMap(new SimpleEntry<>("Blood Pressure", "120/80"), new SimpleEntry<>("Temperature", "101"))); + existingTabularData.put("13-12-2012", createConceptValueMap(new SimpleEntry<>("pulse", "100"), new SimpleEntry<>("Temperature", "104"))); + diseaseSummaryData.addTabularData(existingTabularData); + + Map> newTabularData = new LinkedHashMap<>(); + newTabularData.put("11-12-2012", createConceptValueMap(new SimpleEntry<>("Paracetamol", "500mg"), new SimpleEntry<>("cetrizine", "200mg"))); + newTabularData.put("13-12-2012", createConceptValueMap(new SimpleEntry<>("White blood cells", "100000"), new SimpleEntry<>("serum creatinine", "5"))); + + diseaseSummaryData.addTabularData(newTabularData); + + Map> tabularData = diseaseSummaryData.getTabularData(); + assertEquals(3, tabularData.size()); + assertEquals(4, tabularData.get("13-12-2012").size()); + + assertEquals("500mg", tabularData.get("11-12-2012").get("Paracetamol").getValue()); + assertEquals("200mg", tabularData.get("11-12-2012").get("cetrizine").getValue()); + + assertEquals("100000", tabularData.get("13-12-2012").get("White blood cells").getValue()); + assertEquals("5", tabularData.get("13-12-2012").get("serum creatinine").getValue()); + + + } + + @Test + public void shouldAddConceptNamesToExistingSetOfConceptNames(){ + DiseaseSummaryData diseaseSummaryData = new DiseaseSummaryData(); + Set existingConceptNames = new LinkedHashSet<>(); + ConceptDetails bloodConceptDetails = new ConceptDetails(); + bloodConceptDetails.setName("blood"); + ConceptDetails fluidConceptDetails = new ConceptDetails(); + fluidConceptDetails.setName("fluid"); + existingConceptNames.add(bloodConceptDetails); + existingConceptNames.add(fluidConceptDetails); + + Set newConceptNames = new LinkedHashSet<>(); + ConceptDetails temperatureConceptDetails = new ConceptDetails(); + temperatureConceptDetails.setName("temperature"); + newConceptNames.add(temperatureConceptDetails); + diseaseSummaryData.addConceptDetails(existingConceptNames); + diseaseSummaryData.addConceptDetails(newConceptNames); + + Set conceptDetails = diseaseSummaryData.getConceptDetails(); + assertEquals(conceptDetails.size(), 3); + assertTrue(conceptDetails.contains(temperatureConceptDetails)); + } + + private Map createConceptValueMap(Map.Entry... values){ + Map conceptValuesForDate = new LinkedHashMap<>(); + for (Map.Entry concept : values) { + ConceptValue value = new ConceptValue(); + value.setValue(concept.getValue()); + conceptValuesForDate.put(concept.getKey(),value); + } + return conceptValuesForDate; + } +} \ No newline at end of file diff --git a/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryMapperTest.java b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryMapperTest.java new file mode 100644 index 0000000000..35b098cb8f --- /dev/null +++ b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/mapper/DiseaseSummaryMapperTest.java @@ -0,0 +1,405 @@ +package org.bahmni.module.bahmnicoreui.mapper; + +import junit.framework.Assert; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.bahmni.module.bahmnicoreui.constant.DiseaseSummaryConstants; +import org.bahmni.module.bahmnicoreui.contract.ConceptValue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.Drug; +import org.openmrs.DrugOrder; +import org.openmrs.Encounter; +import org.openmrs.OrderFrequency; +import org.openmrs.Visit; +import org.openmrs.module.bahmniemrapi.drugorder.dosinginstructions.FlexibleDosingInstructions; +import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction; +import org.openmrs.util.LocaleUtility; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(LocaleUtility.class) +public class DiseaseSummaryMapperTest { + + private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DiseaseSummaryConstants.DATE_FORMAT); + private SimpleDateFormat simpleDateTimeFormat = new SimpleDateFormat(DiseaseSummaryConstants.DATE_TIME_FORMAT); + private String date1; + private String date2; + private String date3; + private String visit1Encounter1Date; + private String visit1Encounter2Date; + private String visit1Encounter3Date; + + @Before + public void setUp() throws Exception { + date1 = "2014-09-12"; + date2 = "2014-09-13"; + date3 = "2014-09-14"; + visit1Encounter1Date = date1 +" 12:30"; + visit1Encounter2Date = date1 + " 05:30"; + visit1Encounter3Date = date1 +" 07:30"; + mockStatic(LocaleUtility.class); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + } + + @Test + public void shouldMapObservationsToResponseFormat() throws ParseException { + + DiseaseSummaryObsMapper diseaseSummaryObsMapper = new DiseaseSummaryObsMapper(); + Map> obsTable = diseaseSummaryObsMapper.map(createBahmniObsList(), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS); + assertNotNull(obsTable); + assertEquals(3, obsTable.size()); + Map firstDayValue = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse(date1))); + assertEquals(2, firstDayValue.size()); + assertEquals("101", firstDayValue.get("temperature").getValue()); + assertEquals("90", firstDayValue.get("pulse").getValue()); + + Map secondDayValue = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse(date2))); + assertEquals(1, secondDayValue.size()); + assertEquals("100", secondDayValue.get("pulse").getValue()); + + Map thirdDayValue = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse(date3))); + assertEquals(1, thirdDayValue.size()); + assertEquals("120", thirdDayValue.get("bp").getValue()); + } + + @Test + public void shouldMapObservationsAndGroupByEncounters() throws ParseException { + DiseaseSummaryObsMapper diseaseSummaryObsMapper = new DiseaseSummaryObsMapper(); + Map> obsTable = diseaseSummaryObsMapper.map(createBahmniObsList(), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_ENCOUNTER); + assertNotNull(obsTable); + assertEquals(5,obsTable.size()); + assertTrue(obsTable.containsKey(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse(visit1Encounter1Date)))); + + Map visit1Encounter1Map = obsTable.get(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse(visit1Encounter1Date))); + assertEquals(2, visit1Encounter1Map.size()); + assertEquals("101",visit1Encounter1Map.get("temperature").getValue()); + assertEquals("90",visit1Encounter1Map.get("pulse").getValue()); + + Map visit1Encounter2Map = obsTable.get(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse(visit1Encounter2Date))); + assertEquals(1, visit1Encounter2Map.size()); + assertEquals("102",visit1Encounter2Map.get("temperature").getValue()); + + Map visit1Encounter3Map = obsTable.get(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse(visit1Encounter3Date))); + assertEquals(1, visit1Encounter3Map.size()); + assertEquals("103",visit1Encounter3Map.get("temperature").getValue()); + + } + + @Test + public void shouldMapMultiselectObservations() throws ParseException { + DiseaseSummaryObsMapper diseaseSummaryObsMapper = new DiseaseSummaryObsMapper(); + Collection bahmniObsListWithMultiselectObs = createBahmniObsListWithMultiselectObs(); + Map> obsTable = diseaseSummaryObsMapper.map(bahmniObsListWithMultiselectObs, null); + Assert.assertEquals("2-3days,5-6days", obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-12"))).get("m/c days").getValue()); + Assert.assertEquals("102", obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-12"))).get("temperature").getValue()); + Assert.assertEquals("90", obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-12"))).get("pulse").getValue()); + Assert.assertEquals("100", obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-13"))).get("pulse").getValue()); + + Assert.assertEquals("Child_value2,Child_value1", obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-12"))).get("childobservation").getValue()); + + } + + private Collection createBahmniObsListWithMultiselectObs() throws ParseException { + List bahmniObservations = new ArrayList<>(); + Date visit1 = simpleDateFormat.parse(date1); + Date visit2 = simpleDateFormat.parse(date2); + + Date encounter1 = simpleDateTimeFormat.parse(visit1Encounter1Date); + Date encounter2 = simpleDateTimeFormat.parse(visit1Encounter2Date); + Date encounter3 = simpleDateTimeFormat.parse(visit1Encounter3Date); + + bahmniObservations.add(createBahmniObservation(visit1,encounter1, "M/C days","2-3days")); + bahmniObservations.add(createBahmniObservation(visit1,encounter1, "M/C days","5-6days")); + bahmniObservations.add(createBahmniObservation(visit1,encounter1, "Temperature","102")); + bahmniObservations.add(createBahmniObservation(visit1,encounter1, "Pulse","90")); + + bahmniObservations.add(createBahmniObservation(visit1,encounter2, "Temperature","102")); + bahmniObservations.add(createBahmniObservation(visit1,encounter3, "Temperature","103")); + + BahmniObservation bahmniObservationParent = createBahmniObservation(visit1, encounter3, "ParentObservation", ""); + final BahmniObservation bahmniObservationChild1 = createBahmniObservation(visit1,encounter3, "ChildObservation","Child_value1"); + final BahmniObservation bahmniObservationChild2 = createBahmniObservation(visit1,encounter3, "ChildObservation","Child_value2"); + bahmniObservationParent.setGroupMembers(new ArrayList(){{ + add(bahmniObservationChild1); + add(bahmniObservationChild2); + }}); + bahmniObservations.add(bahmniObservationParent); + + bahmniObservations.add(createBahmniObservation(visit2,simpleDateTimeFormat.parse(date2 +" 12:30"),"Pulse","100")); + return bahmniObservations; + } + + @Test + public void shouldMapCodedConceptValues() throws ParseException { + DiseaseSummaryObsMapper diseaseSummaryObsMapper = new DiseaseSummaryObsMapper(); + List bahmniObservations = new ArrayList<>(); + + Date visit1 = simpleDateFormat.parse(date1); + bahmniObservations.add(createBahmniObservation(visit1,simpleDateTimeFormat.parse(date1 +" 12:30"),"Pulse",new EncounterTransaction.Concept("uuid-pulse","very high pulse"))); + + Map> obsTable = diseaseSummaryObsMapper.map(bahmniObservations, DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS); + + Map dayValue = obsTable.get(frameDiseaseSummaryMapKey(visit1)); + assertEquals(1, dayValue.size()); + assertEquals("very high pulse", dayValue.get("pulse").getValue()); + + } + + @Test + public void shouldMapDrugOrders() throws ParseException, IOException { + DiseaseSummaryDrugOrderMapper diseaseSummaryDrugOrderMapper = new DiseaseSummaryDrugOrderMapper(); + Map> drugOrderData = diseaseSummaryDrugOrderMapper.map(mockDrugOrders(new String[]{"paracetamol", "2014-08-15","2014-08-15 05:30"}, new String[]{"paracetamol1", "2014-08-15","2014-08-15 06:30"},new String[]{"penicillin", "2014-09-11","2014-09-11 06:30"}), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS); + + assertNotNull(drugOrderData); + assertEquals(2, drugOrderData.size()); + Map firstDayValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-08-15"))); + assertEquals(2, firstDayValue.size()); + assertEquals("paracetamol-500mg,10.0 mg,daily,SOS", firstDayValue.get("paracetamol").getValue()); + assertEquals("paracetamol1-500mg,10.0 mg,daily,SOS", firstDayValue.get("paracetamol1").getValue()); + + Map secondDayValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-11"))); + assertEquals(1, secondDayValue.size()); + assertEquals("penicillin-500mg,10.0 mg,daily,SOS", secondDayValue.get("penicillin").getValue()); + } + + @Test + public void shouldMapDrugOrdersForEncounters() throws ParseException, IOException { + DiseaseSummaryDrugOrderMapper diseaseSummaryDrugOrderMapper = new DiseaseSummaryDrugOrderMapper(); + Map> drugOrderData = diseaseSummaryDrugOrderMapper.map(mockDrugOrders(new String[]{"paracetamol", "2014-08-15","2014-08-15 05:30"}, new String[]{"paracetamol1", "2014-08-15","2014-08-15 06:30"},new String[]{"penicillin", "2014-09-11","2014-09-11 06:30"}), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_ENCOUNTER); + assertNotNull(drugOrderData); + assertEquals(3, drugOrderData.size()); + Map firstEncounterValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse("2014-08-15 05:30"))); + assertEquals(1, firstEncounterValue.size()); + assertEquals("paracetamol-500mg,10.0 mg,daily,SOS", firstEncounterValue.get("paracetamol").getValue()); + + Map secondEncounterValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse("2014-08-15 06:30"))); + assertEquals(1, secondEncounterValue.size()); + assertEquals("paracetamol1-500mg,10.0 mg,daily,SOS", secondEncounterValue.get("paracetamol1").getValue()); + + Map thirdEncounterValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateTimeFormat.parse("2014-09-11 06:30"))); + assertEquals(1, thirdEncounterValue.size()); + assertEquals("penicillin-500mg,10.0 mg,daily,SOS", thirdEncounterValue.get("penicillin").getValue()); + } + + @Test + public void shouldMapDrugOrdersWithFlexibleDosing() throws ParseException, IOException { + DiseaseSummaryDrugOrderMapper diseaseSummaryDrugOrderMapper = new DiseaseSummaryDrugOrderMapper(); + Map> drugOrderData = diseaseSummaryDrugOrderMapper.map(mockDrugOrdersWithFlexibleDosing(new String[]{"paracetamol", "2014-08-15", "2014-08-15 05:30"}, new String[]{"penicillin", "2014-09-11", "2014-09-11 05:30"}), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS); + + assertNotNull(drugOrderData); + assertEquals(2, drugOrderData.size()); + + Map firstDayValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-08-15"))); + assertEquals(1, firstDayValue.size()); + assertEquals("paracetamol-500mg,10.0 mg,1-0-1,SOS", firstDayValue.get("paracetamol").getValue()); + + Map secondDayValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-11"))); + assertEquals(1, secondDayValue.size()); + assertEquals("penicillin-500mg,10.0 mg,1-0-1,SOS", secondDayValue.get("penicillin").getValue()); + } + + @Test + public void shouldMapDrugOrdersWithoutAnyExceptionsWhenThereIsNoData() throws ParseException, IOException { + try{ + DiseaseSummaryDrugOrderMapper diseaseSummaryDrugOrderMapper = new DiseaseSummaryDrugOrderMapper(); + Map> drugOrderData = diseaseSummaryDrugOrderMapper.map(mockDrugOrdersWithoutAnyData(new String[]{"paracetamol", "2014-08-15", "2014-08-15 05:30"}, new String[]{"penicillin", "2014-09-11", "2014-09-11 05:30"}), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS); + + assertNotNull(drugOrderData); + assertEquals(2, drugOrderData.size()); + + Map firstDayValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-08-15"))); + assertEquals(1, firstDayValue.size()); + assertEquals("", firstDayValue.get("paracetamol").getValue()); + + Map secondDayValue = drugOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-09-11"))); + assertEquals(1, secondDayValue.size()); + assertEquals("", secondDayValue.get("penicillin").getValue()); + }catch (Exception e){ + throw new RuntimeException("Should not throw any exception when drug orders dont have strength,dosage and freequency",e); + } + + } + + private List mockDrugOrdersWithFlexibleDosing(String[]... drugInfoList) throws ParseException { + List drugOrders = new ArrayList<>(); + for (String[] drugInfo : drugInfoList) { + DrugOrder drugOrder = new DrugOrder(); + drugOrder.setConcept(createMRSConcept(drugInfo[0])); + drugOrder.setEncounter(createEncounterWithVisitDateInfo(getDateFromString(drugInfo[1]), getDateTimeFromString(drugInfo[2]))); + drugOrder.setDrug(createDrugWithNameAndStrength(drugInfo[0], drugInfo[0] + "-500mg")); + drugOrder.setDose(10.0); + Concept doseUnits = new Concept(); + doseUnits.setFullySpecifiedName(new ConceptName("mg",Locale.getDefault())); + drugOrder.setDoseUnits(doseUnits); + drugOrder.setAsNeeded(true); + drugOrder.setDosingInstructions("{\"instructions\":\"Before meals\",\"morningDose\":1,\"afternoonDose\":0,\"eveningDose\":1}"); + drugOrder.setDosingType(FlexibleDosingInstructions.class); + drugOrders.add(drugOrder); + } + return drugOrders; + } + + private List mockDrugOrdersWithoutAnyData(String[]... drugInfoList) throws ParseException { + List drugOrders = new ArrayList<>(); + for (String[] drugInfo : drugInfoList) { + DrugOrder drugOrder = new DrugOrder(); + drugOrder.setConcept(createMRSConcept(drugInfo[0])); + drugOrder.setEncounter(createEncounterWithVisitDateInfo(getDateFromString(drugInfo[1]), getDateFromString(drugInfo[2]))); + drugOrder.setDrug(createDrugWithNameAndStrength(drugInfo[0], "")); + drugOrders.add(drugOrder); + } + return drugOrders; + } + + @Test + public void shouldMapLabOrders() throws ParseException { + DiseaseSummaryLabMapper diseaseSummaryLabMapper = new DiseaseSummaryLabMapper(); + Map> labOrderData = diseaseSummaryLabMapper.map(mockLabOrders(), DiseaseSummaryConstants.RESULT_TABLE_GROUP_BY_VISITS); + + assertNotNull(labOrderData); + assertEquals(2, labOrderData.size()); + + Map firstDayValue = labOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-07-22"))); + assertEquals(1, firstDayValue.size()); + assertEquals("120", firstDayValue.get("Blood glucose").getValue()); + + Map secondDayValue = labOrderData.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2014-07-23"))); + assertEquals(2, secondDayValue.size()); + assertEquals("140", secondDayValue.get("Blood glucose").getValue()); + assertEquals("3.0", secondDayValue.get("serum creatinine").getValue()); + + } + + private List mockLabOrders() throws ParseException { + List labOrderResults = new ArrayList<>(); + labOrderResults.add(createLabOrder("2014-07-22","Blood glucose","120")); + labOrderResults.add(createLabOrder("2014-07-23","Blood glucose","140")); + labOrderResults.add(createLabOrder("2014-07-23","serum creatinine","3.0")); + return labOrderResults; + } + + private LabOrderResult createLabOrder(String visitDate, String conceptName, String value) throws ParseException { + + LabOrderResult labOrderResult = new LabOrderResult(); + Date date = simpleDateFormat.parse(visitDate); + labOrderResult.setVisitStartTime(date); + labOrderResult.setResult(value); + labOrderResult.setTestName(conceptName); + return labOrderResult; + } + + + private List mockDrugOrders(String[]... drugInfoList) throws ParseException { + List drugOrders = new ArrayList<>(); + for (String[] drugInfo : drugInfoList) { + DrugOrder drugOrder = new DrugOrder(); + drugOrder.setConcept(createMRSConcept(drugInfo[0])); + drugOrder.setEncounter(createEncounterWithVisitDateInfo(getDateFromString(drugInfo[1]), getDateTimeFromString(drugInfo[2]))); + drugOrder.setDrug(createDrugWithNameAndStrength(drugInfo[0], drugInfo[0] + "-500mg")); + drugOrder.setDose(10.0); + Concept doseUnits = new Concept(); + doseUnits.setFullySpecifiedName(new ConceptName("mg",Locale.getDefault())); + drugOrder.setDoseUnits(doseUnits); + drugOrder.setAsNeeded(true); + OrderFrequency frequency = new OrderFrequency(); + frequency.setConcept(createMRSConcept("daily")); + drugOrder.setFrequency(frequency); + drugOrders.add(drugOrder); + } + return drugOrders; + } + + private Drug createDrugWithNameAndStrength(String drugName, String strength) { + Drug drug = new Drug(); + drug.setName(drugName); + drug.setStrength(strength); + drug.setConcept(createMRSConcept(drugName)); + return drug; + } + + private Encounter createEncounterWithVisitDateInfo(Date visitDate, Date encounterDate) { + Encounter encounter = new Encounter(); + Visit visit = new Visit(); + visit.setStartDatetime(visitDate); + encounter.setVisit(visit); + encounter.setEncounterDatetime(encounterDate); + + return encounter; + } + + private Date getDateFromString(String dateString) throws ParseException { + return simpleDateFormat.parse(dateString); + } + + private Date getDateTimeFromString(String dateString) throws ParseException { + return simpleDateTimeFormat.parse(dateString); + } + + private Concept createMRSConcept(String drugName) { + Concept concept = new Concept(); + concept.setFullySpecifiedName(new ConceptName(drugName, Locale.getDefault())); + return concept; + } + + + private List createBahmniObsList() throws ParseException { + List bahmniObservations = new ArrayList<>(); + Date visit1 = simpleDateFormat.parse(date1); + Date visit2 = simpleDateFormat.parse(date2); + Date visit3 = simpleDateFormat.parse(date3); + + Date encounter1 = simpleDateTimeFormat.parse(visit1Encounter1Date); + Date encounter2 = simpleDateTimeFormat.parse(visit1Encounter2Date); + Date encounter3 = simpleDateTimeFormat.parse(visit1Encounter3Date); + + bahmniObservations.add(createBahmniObservation(visit1,encounter1, "Temperature","101")); + bahmniObservations.add(createBahmniObservation(visit1,encounter1, "Pulse","90")); + + bahmniObservations.add(createBahmniObservation(visit1,encounter2, "Temperature","102")); + bahmniObservations.add(createBahmniObservation(visit1,encounter3, "Temperature","103")); + + bahmniObservations.add(createBahmniObservation(visit2,simpleDateTimeFormat.parse(date2 +" 12:30"),"Pulse","100")); + bahmniObservations.add(createBahmniObservation(visit3,simpleDateTimeFormat.parse(date3 +" 12:30"),"bp","120")); + return bahmniObservations; + } + + + private BahmniObservation createBahmniObservation(Date visitStartTime, Date encounterDateTime, String conceptName, Object value) { + BahmniObservation bahmniObservation = new BahmniObservation(); + bahmniObservation.setVisitStartDateTime(visitStartTime); + bahmniObservation.setEncounterDateTime(encounterDateTime); + EncounterTransaction.Concept concept = new EncounterTransaction.Concept("uuid-"+conceptName,conceptName); + concept.setShortName(conceptName.toLowerCase()); + bahmniObservation.setConcept(concept); + bahmniObservation.setValue(value); + bahmniObservation.setEncounterUuid("uuid-"+encounterDateTime); + bahmniObservation.setUuid("uuid-obs-"+conceptName+Math.random()); + return bahmniObservation; + } + + private String frameDiseaseSummaryMapKey(Date date) { + return DateFormatUtils.format(date, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + } +} \ No newline at end of file diff --git a/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImplIT.java b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImplIT.java new file mode 100644 index 0000000000..9ba7fd6c4f --- /dev/null +++ b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImplIT.java @@ -0,0 +1,376 @@ +package org.bahmni.module.bahmnicoreui.service.impl; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.bahmni.module.bahmnicoreui.constant.DiseaseSummaryConstants; +import org.bahmni.module.bahmnicoreui.contract.ConceptValue; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.helper.DrugOrderDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.helper.LabDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.helper.ObsDiseaseSummaryAggregator; +import org.bahmni.module.referencedata.contract.ConceptDetails; +import org.junit.Test; +import org.openmrs.api.PatientService; +import org.openmrs.api.context.Context; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BahmniDiseaseSummaryServiceImplIT extends BaseModuleContextSensitiveTest { + + private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DiseaseSummaryConstants.DATE_FORMAT); + + private BahmniDiseaseSummaryServiceImpl bahmniDiseaseSummaryData; + @Autowired + private PatientService patientService; + + @Autowired + private ObsDiseaseSummaryAggregator obsDiseaseSummaryAggregator; + @Autowired + private LabDiseaseSummaryAggregator labDiseaseSummaryAggregator; + @Autowired + private DrugOrderDiseaseSummaryAggregator drugOrderDiseaseSummaryAggregator; + + @org.junit.Before + public void setUp() throws Exception { + bahmniDiseaseSummaryData = new BahmniDiseaseSummaryServiceImpl(patientService, labDiseaseSummaryAggregator, drugOrderDiseaseSummaryAggregator, obsDiseaseSummaryAggregator); + executeDataSet("diagnosisMetadata.xml"); + executeDataSet("dispositionMetadata.xml"); + } + + private void setUpObservationTestData() throws Exception { + executeDataSet("observationsTestData.xml"); + updateSearchIndex(); + } + + private void setUpLabOrderTestData() throws Exception { + executeDataSet("labOrderTestData.xml"); + updateSearchIndex(); + } + + private void setUpDrugOrderTestData() throws Exception { + executeDataSet("drugOrderTestData.xml"); + updateSearchIndex(); + } + + @Test + public void shouldReturnObsForGivenConceptsAndNoOfVisits() throws Exception { + setUpObservationTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(1); + ArrayList obsConcepts = new ArrayList() {{ + add("Weight"); + add("Blood Pressure"); + }}; + + diseaseDataParams.setObsConcepts(obsConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("86526ed5-3c11-11de-a0ba-001e378eb67a", diseaseDataParams); + Map> obsTable = diseaseSummary.getTabularData(); + + assertNotNull(obsTable); + assertEquals(1, obsTable.size()); + + Map obsInVisit = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2008-09-18"))); + assertEquals(1, obsInVisit.size()); + assertEquals("120.0", obsInVisit.get("Weight").getValue()); + + } + + @Test + public void shouldReturnObsForGivenConceptsForAllVisitsWhenNoOfVisitsNotSpecifed() throws Exception { + setUpObservationTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + ArrayList obsConcepts = new ArrayList() {{ + add("Blood Pressure"); + add("Weight"); + }}; + + diseaseDataParams.setObsConcepts(obsConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("86526ed5-3c11-11de-a0ba-001e378eb67a", diseaseDataParams); + Map> obsTable = diseaseSummary.getTabularData(); + + assertNotNull(obsTable); + assertEquals(2, obsTable.size()); + + Map obsForVisit = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2008-09-18"))); + assertEquals(1, obsForVisit.size()); + assertEquals("120.0", obsForVisit.get("Weight").getValue()); + + obsForVisit = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2008-08-18"))); + assertEquals(2, obsForVisit.size()); + assertEquals("120.0", obsForVisit.get("Systolic Data").getValue()); + assertTrue(obsForVisit.get("Systolic Data").getAbnormal()); + assertEquals("40.0", obsForVisit.get("Diastolic Data").getValue()); + assertTrue(obsForVisit.get("Diastolic Data").getAbnormal()); + } + + @Test + public void shouldReturnLabResultsForGivenConceptsAndNoOfVisits() throws Exception { + setUpLabOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(1); + ArrayList labConcepts = new ArrayList() {{ + add("PS for Malaria"); + }}; + + diseaseDataParams.setLabConcepts(labConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-0800271c1b75", diseaseDataParams); + Map> labTable = diseaseSummary.getTabularData(); + + assertNotNull(labTable); + assertEquals(1, labTable.size()); + + Map labResultsInVisit = labTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2013-09-26"))); + assertNotNull(labResultsInVisit); + assertEquals(1, labResultsInVisit.size()); + assertEquals("new Result for PS Malaria", labResultsInVisit.get("PS for Malaria").getValue()); + + } + + @Test + public void shouldReturnLabResultsForGivenConceptsForAllVisits() throws Exception { + setUpLabOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + ArrayList labConcepts = new ArrayList() {{ + add("PS for Malaria"); + }}; + + diseaseDataParams.setLabConcepts(labConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-0800271c1b75", diseaseDataParams); + Map> labTable = diseaseSummary.getTabularData(); + + assertNotNull(labTable); + assertEquals(2, labTable.size()); + + Map labResultsInVisit = labTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2013-09-26"))); + assertNotNull(labResultsInVisit); + assertEquals(1, labResultsInVisit.size()); + assertEquals("new Result for PS Malaria", labResultsInVisit.get("PS for Malaria").getValue()); + + labResultsInVisit = labTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2005-09-26"))); + assertNotNull(labResultsInVisit); + assertEquals(1, labResultsInVisit.size()); + assertEquals("almost dead of PS Malaria", labResultsInVisit.get("PS for Malaria").getValue()); + } + + @Test + public void shouldReturnDrugOrdersForGivenConceptsAndNoOfVisits() throws Exception { + setUpDrugOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(2); + ArrayList drugConcepts = new ArrayList() {{ + add("Calpol 250mg"); + }}; + + diseaseDataParams.setDrugConcepts(drugConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-080027175c1b", diseaseDataParams); + Map> drugTable = diseaseSummary.getTabularData(); + + assertNotNull(drugTable); + assertEquals(1, drugTable.size()); + + Map durgOrdersInVisit = drugTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2012-12-12"))); + assertNotNull(durgOrdersInVisit); + assertEquals(1, durgOrdersInVisit.size()); + assertEquals("250mg,325.0,1/day x 7 days/week", durgOrdersInVisit.get("Calpol 250mg").getValue()); + } + + @Test + public void shouldNotReturnVisitIfNoDrugsAreOrdered() throws Exception { + setUpDrugOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(1); + ArrayList drugConcepts = new ArrayList() {{ + add("Calpol 250mg"); + }}; + + diseaseDataParams.setDrugConcepts(drugConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-080027175c1b", diseaseDataParams); + Map> drugTable = diseaseSummary.getTabularData(); + + assertNotNull(drugTable); + assertEquals(0, drugTable.size()); + + } + + + @Test + public void shouldReturnDrugOrdersForGivenConceptsForAllVisits() throws Exception { + setUpDrugOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + ArrayList drugConcepts = new ArrayList() {{ + add("cetirizine 100mg"); + add("Calpol 250mg"); + }}; + + diseaseDataParams.setDrugConcepts(drugConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-080027175c1b", diseaseDataParams); + Map> drugTable = diseaseSummary.getTabularData(); + + assertNotNull(drugTable); + assertEquals(2, drugTable.size()); + + Map durgOrdersInVisit = drugTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2001-09-22"))); + assertNotNull(durgOrdersInVisit); + assertEquals(1, durgOrdersInVisit.size()); + assertEquals("250mg,125.0,1/day x 7 days/week", durgOrdersInVisit.get("Calpol 250mg").getValue()); + + } + + @Test + public void shouldReturnDrugOrdersForGivenConceptsForAllVisitsDependingOnTheInitialOrFinalCount() throws Exception { + setUpDrugOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setGroupBy("visits"); + diseaseDataParams.setInitialCount(1); + ArrayList drugConcepts = new ArrayList() {{ + add("cetirizine 100mg"); + add("Calpol 250mg"); + }}; + + diseaseDataParams.setDrugConcepts(drugConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-080027175c1b", diseaseDataParams); + Map> drugTable = diseaseSummary.getTabularData(); + + assertNotNull(drugTable); + assertEquals(1, drugTable.size()); + + Map durgOrdersInVisit = drugTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2001-09-22"))); + assertNotNull(durgOrdersInVisit); + assertEquals(1, durgOrdersInVisit.size()); + assertEquals("250mg,125.0,1/day x 7 days/week", durgOrdersInVisit.get("Calpol 250mg").getValue()); + + } + + @Test + public void shouldReturnObsForGivenConceptsAndVisitUuid() throws Exception { + setUpObservationTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + ArrayList obsConcepts = new ArrayList() {{ + add("Weight"); + add("Blood Pressure"); + }}; + + diseaseDataParams.setObsConcepts(obsConcepts); + diseaseDataParams.setVisitUuid("e10186d8-1c8e-11e4-bb80-f18addb6f9bb"); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("86526ed5-3c11-11de-a0ba-001e378eb67a", diseaseDataParams); + Map> obsTable = diseaseSummary.getTabularData(); + + assertNotNull(obsTable); + assertEquals(1, obsTable.size()); + + Map obsForVisit = obsTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2008-09-18"))); + assertEquals(1, obsForVisit.size()); + assertEquals("120.0", obsForVisit.get("Weight").getValue()); + + } + + @Test + public void shouldReturnLabResultsForGivenConceptsAndVisitUuid() throws Exception { + setUpLabOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + ArrayList labConcepts = new ArrayList() {{ + add("PS for Malaria"); + }}; + + diseaseDataParams.setLabConcepts(labConcepts); + diseaseDataParams.setVisitUuid("9d705396-0c0c-11e4-bb80-f18addb6f9bb"); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-0800271c1b75", diseaseDataParams); + Map> labTable = diseaseSummary.getTabularData(); + + assertNotNull(labTable); + assertEquals(1, labTable.size()); + + Map labResultsInVisit = labTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2013-09-26"))); + assertNotNull(labResultsInVisit); + assertEquals(1, labResultsInVisit.size()); + assertEquals("new Result for PS Malaria", labResultsInVisit.get("PS for Malaria").getValue()); + } + + @Test + public void shouldReturnDrugOrdersForGivenConceptsAndVisitUuid() throws Exception { + setUpDrugOrderTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + ArrayList drugConcepts = new ArrayList() {{ + add("cetirizine 100mg"); + add("Calpol 250mg"); + }}; + + diseaseDataParams.setDrugConcepts(drugConcepts); + diseaseDataParams.setVisitUuid("8244fcd2-f20f-11e3-b47b-c6959a4485cd"); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("75e04d42-3ca8-11e3-bf2b-080027175c1b", diseaseDataParams); + Map> drugTable = diseaseSummary.getTabularData(); + + assertNotNull(drugTable); + assertEquals(1, drugTable.size()); + + Map drugOrdersInVisit = drugTable.get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2001-09-22"))); + assertNotNull(drugOrdersInVisit); + assertEquals(1, drugOrdersInVisit.size()); + assertEquals("250mg,125.0,1/day x 7 days/week", drugOrdersInVisit.get("Calpol 250mg").getValue()); + } + + @Test + public void shouldReturnLeafConceptsNames() throws Exception { + setUpObservationTestData(); + Context.getAuthenticatedUser().setUserProperty("defaultLocale","en"); + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(3); + List obsConcepts = new ArrayList() {{ + add("Blood Pressure"); + add("Weight"); + }}; + diseaseDataParams.setObsConcepts(obsConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("86526ed5-3c11-11de-a0ba-001e378eb67a", diseaseDataParams); + Set conceptNames = diseaseSummary.getConceptDetails(); + + + assertNotNull(conceptNames); + assertEquals(3, conceptNames.size()); + Iterator conceptDetailsIterator = conceptNames.iterator(); + assertEquals("Systolic", conceptDetailsIterator.next().getName()); + assertEquals("Diastolic", conceptDetailsIterator.next().getName()); + assertEquals("Weight", conceptDetailsIterator.next().getName()); + } + + @Test + public void shouldReturnShortNamesForCodedConceptObservations() throws Exception { + setUpObservationTestData(); + + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + diseaseDataParams.setNumberOfVisits(3); + ArrayList obsConcepts = new ArrayList() {{ + add("CodedConcept"); + }}; + Context.getAuthenticatedUser().setUserProperty("defaultLocale", "en"); + diseaseDataParams.setObsConcepts(obsConcepts); + DiseaseSummaryData diseaseSummary = bahmniDiseaseSummaryData.getDiseaseSummary("86526ed5-3c11-11de-a0ba-001e378eb67a", diseaseDataParams); + assertEquals("CCAnswer1", diseaseSummary.getTabularData().get(frameDiseaseSummaryMapKey(simpleDateFormat.parse("2008-09-18"))).get("CodedConcept").getValue()); + } + + private String frameDiseaseSummaryMapKey(Date date) { + return DateFormatUtils.format(date, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()); + } +} \ No newline at end of file diff --git a/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImplTest.java b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImplTest.java new file mode 100644 index 0000000000..04205186ce --- /dev/null +++ b/bahmnicore-ui/src/test/java/org/bahmni/module/bahmnicoreui/service/impl/BahmniDiseaseSummaryServiceImplTest.java @@ -0,0 +1,97 @@ +package org.bahmni.module.bahmnicoreui.service.impl; + +import org.bahmni.module.bahmnicoreui.contract.ConceptValue; +import org.bahmni.module.bahmnicoreui.contract.DiseaseDataParams; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryData; +import org.bahmni.module.bahmnicoreui.contract.DiseaseSummaryMap; +import org.bahmni.module.bahmnicoreui.helper.DrugOrderDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.helper.LabDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.helper.ObsDiseaseSummaryAggregator; +import org.bahmni.module.bahmnicoreui.service.BahmniDiseaseSummaryService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Patient; +import org.openmrs.api.PatientService; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class BahmniDiseaseSummaryServiceImplTest { + BahmniDiseaseSummaryService bahmniDiseaseSummaryService; + + @Mock + private PatientService patientServiceMock; + @Mock + private LabDiseaseSummaryAggregator labDiseaseSummaryAggregatorMock; + @Mock + private DrugOrderDiseaseSummaryAggregator drugOrderDiseaseSummaryAggregatorMock; + @Mock + private ObsDiseaseSummaryAggregator obsDiseaseSummaryAggregatorMock; + + @Before + public void setUp() throws Exception { + initMocks(this); + bahmniDiseaseSummaryService = new BahmniDiseaseSummaryServiceImpl(patientServiceMock, + labDiseaseSummaryAggregatorMock, drugOrderDiseaseSummaryAggregatorMock, obsDiseaseSummaryAggregatorMock); + } + + @Test + public void shouldSortDiseaseSummaryDataByVisitStartDate() throws Exception { + String patientUuid = "somePatientUuid"; + Patient patient = new Patient(); + DiseaseDataParams diseaseDataParams = new DiseaseDataParams(); + + DiseaseSummaryData obsDiseaseSummaryData = setupDiseaseSummaryData(new DiseaseSummaryData(), + Arrays.asList("2016-07-05T13:13:25+05:30", "2016-07-04T13:13:25+05:30")); + + DiseaseSummaryData drugDiseaseSummaryData = setupDiseaseSummaryData(new DiseaseSummaryData(), + Arrays.asList("2016-07-05T13:13:25+05:30", "2016-07-05T12:13:25+05:30")); + + DiseaseSummaryData labDiseaseSummaryData = setupDiseaseSummaryData(new DiseaseSummaryData(), + Arrays.asList("2016-07-05T13:13:25+05:30", "2016-06-05T13:13:25+05:30", "2016-08-05T13:13:25+05:30")); + + when(patientServiceMock.getPatientByUuid(patientUuid)).thenReturn(patient); + when(obsDiseaseSummaryAggregatorMock.aggregate(patient, diseaseDataParams)).thenReturn(obsDiseaseSummaryData); + when(drugOrderDiseaseSummaryAggregatorMock.aggregate(patient, diseaseDataParams)).thenReturn(drugDiseaseSummaryData); + when(labDiseaseSummaryAggregatorMock.aggregate(patient, diseaseDataParams)).thenReturn(labDiseaseSummaryData); + + DiseaseSummaryData actualDiseaseSummary = bahmniDiseaseSummaryService.getDiseaseSummary(patientUuid, diseaseDataParams); + assertEquals(5, actualDiseaseSummary.getTabularData().size()); + List actualOrderedVisitDates = getOrderedKeysFor(actualDiseaseSummary.getTabularData()); + List expectedOrderedVisitDates = Arrays.asList("2016-08-05T13:13:25+05:30", "2016-07-05T13:13:25+05:30", + "2016-07-05T12:13:25+05:30", "2016-07-04T13:13:25+05:30", "2016-06-05T13:13:25+05:30"); + assertEquals(expectedOrderedVisitDates, actualOrderedVisitDates); + } + + private static List getOrderedKeysFor(DiseaseSummaryMap diseaseSummaryMap) { + List keys = new ArrayList<>(); + for (Map.Entry> t : diseaseSummaryMap.entrySet()) { + keys.add(t.getKey()); + } + return keys; + } + + private DiseaseSummaryData setupDiseaseSummaryData(DiseaseSummaryData diseaseSummaryData, List visitDates) { + ConceptValue conceptValue = new ConceptValue(); + conceptValue.setValue("someConceptValue"); + + LinkedHashMap conceptMap = new LinkedHashMap<>(); + conceptMap.put("someConceptKey", conceptValue); + + for (String visitDateString : visitDates) { + LinkedHashMap> visitDateToConceptMap = new LinkedHashMap<>(); + visitDateToConceptMap.put(visitDateString, conceptMap); + + diseaseSummaryData.addTabularData(visitDateToConceptMap); + } + return diseaseSummaryData; + } +} \ No newline at end of file diff --git a/bahmnicore-ui/src/test/resources/TestingApplicationContext.xml b/bahmnicore-ui/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..29ffb2443d --- /dev/null +++ b/bahmnicore-ui/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/bahmnicore-ui/src/test/resources/diagnosisMetadata.xml b/bahmnicore-ui/src/test/resources/diagnosisMetadata.xml new file mode 100644 index 0000000000..575664c973 --- /dev/null +++ b/bahmnicore-ui/src/test/resources/diagnosisMetadata.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-ui/src/test/resources/dispositionMetadata.xml b/bahmnicore-ui/src/test/resources/dispositionMetadata.xml new file mode 100644 index 0000000000..edf8d0328f --- /dev/null +++ b/bahmnicore-ui/src/test/resources/dispositionMetadata.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-ui/src/test/resources/drugOrderTestData.xml b/bahmnicore-ui/src/test/resources/drugOrderTestData.xml new file mode 100644 index 0000000000..95f75f7c3f --- /dev/null +++ b/bahmnicore-ui/src/test/resources/drugOrderTestData.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bahmnicore-ui/src/test/resources/labOrderTestData.xml b/bahmnicore-ui/src/test/resources/labOrderTestData.xml new file mode 100644 index 0000000000..a08a59e946 --- /dev/null +++ b/bahmnicore-ui/src/test/resources/labOrderTestData.xml @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore-ui/src/test/resources/observationsTestData.xml b/bahmnicore-ui/src/test/resources/observationsTestData.xml new file mode 100644 index 0000000000..e9cd0305e3 --- /dev/null +++ b/bahmnicore-ui/src/test/resources/observationsTestData.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bahmnicore.properties b/bahmnicore.properties new file mode 100644 index 0000000000..df7827ab9b --- /dev/null +++ b/bahmnicore.properties @@ -0,0 +1,15 @@ +openerp.port=8069 +openerp.host=localhost +openerp.database=openerp +openerp.user=admin +openerp.password=password +openerp.connectionTimeoutInMilliseconds=10000 +openerp.replyTimeoutInMilliseconds=20000 + +bahmnicore.datamigration.mode=false + +#Make sure this directory exists +bahmnicore.images.directory=/tmp/patient_images +bahmnicore.urls.patientimages=http://localhost:8080/patient_images + +bahmnicore.documents.baseDirectory=/home/jss/document_images \ No newline at end of file diff --git a/jss-old-data/pom.xml b/jss-old-data/pom.xml new file mode 100644 index 0000000000..1887c40f25 --- /dev/null +++ b/jss-old-data/pom.xml @@ -0,0 +1,103 @@ + + + + bahmni + org.bahmni.module + 0.94-SNAPSHOT + + 4.0.0 + + jss-old-data + + + org.bahmni.module + bahmni-migrator + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + openmrs-connector + ${bahmniJavaUtilsVersion} + + + joda-time + joda-time + 2.0 + + + commons-lang + commons-lang + 2.6 + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + mysql + mysql-connector-java + 5.1.48 + + + org.springframework + spring-jdbc + ${springVersion} + + + org.codehaus.jackson + jackson-core-asl + + + org.springframework + spring-web + ${springVersion} + + + commons-logging + commons-logging + + + + + org.codehaus.jackson + jackson-mapper-asl + + + net.sf.opencsv + opencsv + 2.0 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + jar-with-dependencies + + + + org.bahmni.jss.JSSMigrator + + + + + + package + + single + + + + + + + diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/AddressService.java b/jss-old-data/src/main/java/org/bahmni/datamigration/AddressService.java new file mode 100644 index 0000000000..6e55f685ad --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/AddressService.java @@ -0,0 +1,37 @@ +package org.bahmni.datamigration; + +import org.apache.commons.lang.StringUtils; + +public class AddressService { + private MasterTehsils masterTehsils; + private AmbiguousTehsils ambiguousTehsils; + private CorrectedTehsils correctedTehsils; + + public AddressService(MasterTehsils masterTehsils, AmbiguousTehsils ambiguousTehsils, CorrectedTehsils correctedTehsils) { + this.masterTehsils = masterTehsils; + this.ambiguousTehsils = ambiguousTehsils; + this.correctedTehsils = correctedTehsils; + } + + public FullyQualifiedTehsil getTehsilFor(FullyQualifiedTehsil tehsilFromPatientRecord) { + String tehsil = tehsilFromPatientRecord.getTehsil(); + if (StringUtils.isBlank(tehsil)) return tehsilFromPatientRecord; + + String correctedTehsil = correctedTehsils.correctedTehsil(tehsil); + if (correctedTehsil == null) + return tehsilFromPatientRecord; + + if (StringUtils.isBlank(correctedTehsil)) + return new FullyQualifiedTehsil("", tehsilFromPatientRecord.getDistrict(), tehsilFromPatientRecord.getState()); + + FullyQualifiedTehsil matchingMasterTehsil = masterTehsils.getFullyQualifiedTehsil(correctedTehsil); + if (matchingMasterTehsil == null) + return new FullyQualifiedTehsil(correctedTehsil, tehsilFromPatientRecord.getDistrict(), tehsilFromPatientRecord.getState()); + + if (ambiguousTehsils.contains(matchingMasterTehsil.getTehsil())) { + return new FullyQualifiedTehsil(matchingMasterTehsil.getTehsil(), + tehsilFromPatientRecord.getDistrict(), tehsilFromPatientRecord.getState()); + } + return matchingMasterTehsil; + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/AllLookupValues.java b/jss-old-data/src/main/java/org/bahmni/datamigration/AllLookupValues.java new file mode 100644 index 0000000000..50595f85bb --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/AllLookupValues.java @@ -0,0 +1,55 @@ +package org.bahmni.datamigration; + +import au.com.bytecode.opencsv.CSVReader; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AllLookupValues implements LookupValueProvider { + private static Logger logger = LogManager.getLogger(AllLookupValues.class); + private Map map = new HashMap(); + + protected AllLookupValues() { + } + + public AllLookupValues(String csvLocation, String fileName) throws IOException { + File file = new File(csvLocation, fileName); + if (!file.exists()) throw new FileNotFoundException(file.getAbsolutePath()); + + CSVReader reader = null; + try { + reader = new CSVReader(new FileReader(file), ','); + reader.readNext(); //ignore header + List rows = reader.readAll(); + logger.info(String.format("Found %d lookupValues", rows.size())); + for (String[] row : rows) { + Object[] allExceptFirstIndex = ArrayUtils.remove(row, 0); + map.put(Integer.parseInt(row[0].trim()), allExceptFirstIndex); + } + } finally { + if (reader != null) reader.close(); + } + } + + public String getLookUpValue(String key) { + return getLookUpValue(key, 0); + } + + @Override + public String getLookUpValue(String key, int valueIndexExcludesFirstColumn) { + if (StringUtils.equals("0", key)) return null; + + int keyAsNumber = Integer.parseInt(key.trim()); + Object[] values = map.get(keyAsNumber); + if (values == null) return null; + return values[valueIndexExcludesFirstColumn].toString(); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/AmbiguousTehsils.java b/jss-old-data/src/main/java/org/bahmni/datamigration/AmbiguousTehsils.java new file mode 100644 index 0000000000..d744fd5c1f --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/AmbiguousTehsils.java @@ -0,0 +1,32 @@ +package org.bahmni.datamigration; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import java.util.HashSet; + +public class AmbiguousTehsils { + private static Logger logger = LogManager.getLogger(CorrectedTehsils.class); + private HashSet tehsils = new HashSet(); + + public AmbiguousTehsils(String fileLocation, String fileName) throws IOException { + File file = new File(fileLocation, fileName); + if (!file.exists()) throw new FileNotFoundException(file.getAbsolutePath()); + + BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); + try { + while (true) { + String line = bufferedReader.readLine(); + if (line == null) break; + + tehsils.add(line); + } + logger.info(String.format("Found %d ambiguous tehsils", tehsils.size())); + } finally { + bufferedReader.close(); + } + } + + public boolean contains(String tehsil) { + return tehsils.contains(tehsil); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/CorrectedTehsils.java b/jss-old-data/src/main/java/org/bahmni/datamigration/CorrectedTehsils.java new file mode 100644 index 0000000000..e10bd99785 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/CorrectedTehsils.java @@ -0,0 +1,40 @@ +package org.bahmni.datamigration; + +import au.com.bytecode.opencsv.CSVReader; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CorrectedTehsils { + private static Logger logger = LogManager.getLogger(CorrectedTehsils.class); + private Map oldNewTehsils; + + public CorrectedTehsils(String csvLocation, String fileName) throws IOException { + File file = new File(csvLocation, fileName); + if (!file.exists()) throw new FileNotFoundException(file.getAbsolutePath()); + + CSVReader reader = null; + try { + reader = new CSVReader(new FileReader(file), ','); + reader.readNext(); //ignore header + List rows = reader.readAll(); + oldNewTehsils = new HashMap(rows.size()); + logger.info(String.format("Found %d tehsil mapping", rows.size())); + for (String[] row : rows) { + oldNewTehsils.put(row[0].trim(), row[1].trim()); + } + } finally { + if (reader != null) reader.close(); + } + } + + public String correctedTehsil(String tehsil) { + return oldNewTehsils.get(tehsil); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/DataScrub.java b/jss-old-data/src/main/java/org/bahmni/datamigration/DataScrub.java new file mode 100644 index 0000000000..82f64288c2 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/DataScrub.java @@ -0,0 +1,11 @@ +package org.bahmni.datamigration; + +public class DataScrub { + + public static String scrubData(String value) { + if(value == null) + return ""; + return value.replace("\\", "").trim(); + } + +} diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/FullyQualifiedTehsil.java b/jss-old-data/src/main/java/org/bahmni/datamigration/FullyQualifiedTehsil.java new file mode 100644 index 0000000000..af9e9a5b6d --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/FullyQualifiedTehsil.java @@ -0,0 +1,57 @@ +package org.bahmni.datamigration; + +public class FullyQualifiedTehsil { + private String tehsil; + private String district; + private String state; + + public FullyQualifiedTehsil(String tehsil, String district, String state) { + this.tehsil = tehsil; + this.district = district; + this.state = state; + } + + public FullyQualifiedTehsil() { + } + + public void setTehsil(String tehsil) { + this.tehsil = tehsil; + } + + public void setDistrict(String district) { + this.district = district; + } + + public void setState(String state) { + this.state = state; + } + + public String getTehsil() { + return tehsil; + } + + public String getDistrict() { + return district; + } + + public String getState() { + return state; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FullyQualifiedTehsil that = (FullyQualifiedTehsil) o; + return district.equals(that.district) && state.equals(that.state) && tehsil.equals(that.tehsil); + } + + @Override + public int hashCode() { + int result = tehsil.hashCode(); + result = 31 * result + district.hashCode(); + result = 31 * result + state.hashCode(); + return result; + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/LookupValueProvider.java b/jss-old-data/src/main/java/org/bahmni/datamigration/LookupValueProvider.java new file mode 100644 index 0000000000..6eb8a24616 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/LookupValueProvider.java @@ -0,0 +1,6 @@ +package org.bahmni.datamigration; + +public interface LookupValueProvider { + String getLookUpValue(String key); + String getLookUpValue(String key, int valueIndex); +} diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/MasterTehsils.java b/jss-old-data/src/main/java/org/bahmni/datamigration/MasterTehsils.java new file mode 100644 index 0000000000..f52f1e47dd --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/MasterTehsils.java @@ -0,0 +1,39 @@ +package org.bahmni.datamigration; + +import au.com.bytecode.opencsv.CSVReader; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MasterTehsils { + private static Logger logger = LogManager.getLogger(CorrectedTehsils.class); + private Map fullyQualifiedTehsils = new HashMap(); + + public MasterTehsils(String csvLocation, String fileName) throws IOException { + File file = new File(csvLocation, fileName); + if (!file.exists()) throw new FileNotFoundException(file.getAbsolutePath()); + + CSVReader reader = null; + try { + reader = new CSVReader(new FileReader(file), ','); + reader.readNext(); //ignore header + List rows = reader.readAll(); + logger.info(String.format("Found %d master fullyQualifiedTehsils", rows.size())); + for (String[] row : rows) { + fullyQualifiedTehsils.put(row[2].trim(), new FullyQualifiedTehsil(row[2].trim(), row[1].trim(), row[0].trim())); + } + } finally { + if (reader != null) reader.close(); + } + } + + public FullyQualifiedTehsil getFullyQualifiedTehsil(String tehsil) { + return fullyQualifiedTehsils.get(tehsil); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/csv/Patient.java b/jss-old-data/src/main/java/org/bahmni/datamigration/csv/Patient.java new file mode 100644 index 0000000000..f054a44fec --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/csv/Patient.java @@ -0,0 +1,81 @@ +package org.bahmni.datamigration.csv; + + +import org.bahmni.csv.CSVEntity; +import org.bahmni.csv.annotation.CSVHeader; + +public class Patient extends CSVEntity { + @CSVHeader(name="REG_NO") + public String registrationNumber; + @CSVHeader(name="REG_DATE") + public String registrationDate; + @CSVHeader(name="FNAME") + public String firstName; + @CSVHeader(name="LNAME") + public String lastName; + @CSVHeader(name="FHNAME") + public String fathersName; + @CSVHeader(name="P_SEX") + public String sex; + @CSVHeader(name="P_DOB") + public String dob; + @CSVHeader(name="P_AGE") + public String age; + @CSVHeader(name="P_HEIGHT") + public String height; + @CSVHeader(name="P_WEIGHT") + public String weight; + @CSVHeader(name="VILLAGE") + public String village; + @CSVHeader(name="CITY") + public String city; + @CSVHeader(name="P_POST") + public String postOffice; + @CSVHeader(name="EDUCATION") + public String education; + @CSVHeader(name="OCCUPATION") + public String occupation; + @CSVHeader(name="P_MEMBER") + public String primaryMember; + @CSVHeader(name="P_TB") + public String hasTB; + @CSVHeader(name="BALANCE_AMT") + public String balanceAmount; + @CSVHeader(name="Remark") + public String remark; + @CSVHeader(name="FNameID") + public String fNameId; + @CSVHeader(name="CasteID") + public String casteId; + @CSVHeader(name="FHNameID") + public String fhNameId; + @CSVHeader(name="EducationID") + public String educationId; + @CSVHeader(name="OccupationID") + public String occupationId; + @CSVHeader(name="VillageID") + public String villageId; + @CSVHeader(name="TahsilID") + public String tahsilId; + @CSVHeader(name="DistrictID") + public String districtId; + @CSVHeader(name="TahsilID2") + public String tahsilId2; + @CSVHeader(name="VillageID2") + public String villageId2; + @CSVHeader(name="Neighborhood") + public String neighbourhood; + @CSVHeader(name="GramPanchID") + public String gramPanchayatId; + @CSVHeader(name="LNameID") + public String lastNameId; + @CSVHeader(name="ClassID") + public String classId; + @CSVHeader(name="memberVillageID") + public String memberVillageId; + @CSVHeader(name="GramPanch") + public String gramPanch; + @CSVHeader(name="Tahsil") + public String tahsil; + +} diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/csv/PatientPersister.java b/jss-old-data/src/main/java/org/bahmni/datamigration/csv/PatientPersister.java new file mode 100644 index 0000000000..ee16d470df --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/csv/PatientPersister.java @@ -0,0 +1,192 @@ +package org.bahmni.datamigration.csv; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.bahmni.csv.EntityPersister; +import org.bahmni.csv.RowResult; +import org.bahmni.datamigration.AddressService; +import org.bahmni.datamigration.AllLookupValues; +import org.bahmni.datamigration.FullyQualifiedTehsil; +import org.bahmni.datamigration.LookupValueProvider; +import org.bahmni.datamigration.request.patient.CenterId; +import org.bahmni.datamigration.request.patient.Name; +import org.bahmni.datamigration.request.patient.PatientAddress; +import org.bahmni.datamigration.request.patient.PatientAttribute; +import org.bahmni.datamigration.request.patient.PatientRequest; +import org.bahmni.jss.registration.RegistrationFields; +import org.bahmni.jss.registration.RegistrationNumber; +import org.bahmni.openmrsconnector.AllPatientAttributeTypes; +import org.bahmni.openmrsconnector.OpenMRSRESTConnection; +import org.codehaus.jackson.map.ObjectMapper; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.LinkedHashMap; + +import static org.bahmni.jss.registration.RegistrationFields.sentenceCase; + +public class PatientPersister implements EntityPersister { + private static ObjectMapper objectMapper = new ObjectMapper(); + private static final Log log = LogFactory.getLog(PatientPersister.class); + private static Logger logger = LogManager.getLogger(PatientPersister.class); + + private static int count; + + private final HashMap lookupValuesMap; + private final AddressService addressService; + private final AllPatientAttributeTypes allPatientAttributeTypes; + private OpenMRSRESTConnection openMRSRESTConnection; + private String sessionId; + + private RestTemplate restTemplate = new RestTemplate(); + + public PatientPersister(HashMap lookupValuesMap, AddressService addressService, + AllPatientAttributeTypes allPatientAttributeTypes, OpenMRSRESTConnection openMRSRESTConnection, String sessionId) { + this.lookupValuesMap = lookupValuesMap; + this.addressService = addressService; + this.allPatientAttributeTypes = allPatientAttributeTypes; + this.openMRSRESTConnection = openMRSRESTConnection; + this.sessionId = sessionId; + } + + @Override + public RowResult persist(Patient patient) { + int i = incrementCounter(); + PatientRequest patientRequest = createPatientRequest(patient); + + String jsonRequest = null; + ResponseEntity out; + try { + jsonRequest = objectMapper.writeValueAsString(patientRequest); + if (logger.isDebugEnabled()) logger.debug(jsonRequest); + + HttpHeaders httpHeaders = getHttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity(patientRequest, httpHeaders); + + String url = openMRSRESTConnection.getRestApiUrl() + "bahmnicore/patient"; + out = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); + if (logger.isDebugEnabled()) logger.debug(out.getBody()); + log.info(String.format("%d Successfully created %s", i, patientRequest.getIdentifier())); + } catch (HttpServerErrorException serverErrorException) { + log.info(String.format("%d Failed to create %s", i, patientRequest.getIdentifier())); + log.info("Patient request: " + jsonRequest); + log.error("Patient create response: " + serverErrorException.getResponseBodyAsString()); + return new RowResult(patient, serverErrorException); + } catch (Exception e) { + log.info(String.format("%d Failed to create", i)); + log.info("Patient request: " + jsonRequest); + log.error("Failed to process a patient", e); + log.info("Patient request: " + jsonRequest); + return new RowResult(patient, e); + } + + return new RowResult(patient); + } + + @Override + public RowResult validate(Patient patient) { + return new RowResult<>(patient); + } + + private synchronized int incrementCounter() { + return count++; + } + + private HttpHeaders getHttpHeaders() { + HttpHeaders requestHeaders = new HttpHeaders(); + requestHeaders.set("Cookie", "JSESSIONID=" + sessionId); + return requestHeaders; + } + + private PatientRequest createPatientRequest(Patient patient) { + try { + PatientRequest patientRequest = new PatientRequest(); + RegistrationNumber registrationNumber = RegistrationFields.parseRegistrationNumber(patient.registrationNumber); + CenterId centerID = new CenterId(registrationNumber.getCenterCode()); + patientRequest.setIdentifier(centerID.getName() + registrationNumber.getId()); + patientRequest.setCenterID(centerID); + + Name name = RegistrationFields.name(patient.firstName, patient.lastName); + patientRequest.setName(RegistrationFields.sentenceCase(name.getGivenName()), RegistrationFields.sentenceCase(name.getFamilyName())); + + addPatientAttribute(patient.fathersName, patientRequest, "primaryRelative", null, 0); + patientRequest.setDateOfRegistration(RegistrationFields.getDate(patient.registrationDate)); + + patientRequest.setGender(patient.sex); + String birthdate = RegistrationFields.getDate(patient.dob); + patientRequest.setBirthdate(birthdate == null ? RegistrationFields.UnknownDateOfBirthAsString : birthdate); + + LinkedHashMap ageMap = new LinkedHashMap<>(); + ageMap.put("years", RegistrationFields.getAge(patient.age)); + patientRequest.setAge(ageMap); + + PatientAddress patientAddress = new PatientAddress(); + patientRequest.addPatientAddress(patientAddress); + + patientRequest.setBalance(patient.balanceAmount); + + addPatientAttribute(patient.casteId, patientRequest, "caste", lookupValuesMap.get("Castes"), 0); + addPatientAttribute(patient.classId, patientRequest, "class", lookupValuesMap.get("Classes"), 0); + + //Address information + patientAddress.setAddress2(sentenceCase(patient.gramPanch)); + + FullyQualifiedTehsil fullyQualifiedTehsil = new FullyQualifiedTehsil(); + String stateId = lookupValuesMap.get("Districts").getLookUpValue(patient.districtId, 0); + if (stateId != null) { + String state = lookupValuesMap.get("States").getLookUpValue(stateId); + fullyQualifiedTehsil.setState(sentenceCase(state)); + } + + String district = lookupValuesMap.get("Districts").getLookUpValue(patient.districtId, 2); + fullyQualifiedTehsil.setDistrict(sentenceCase(district)); + + String village = patient.village; + patientAddress.setCityVillage(sentenceCase(village)); + + String tehsil = patient.tahsil; + fullyQualifiedTehsil.setTehsil(sentenceCase(tehsil)); + + FullyQualifiedTehsil correctedFullyQualifiedTehsil = addressService.getTehsilFor(fullyQualifiedTehsil); + setPatientAddressFrom(correctedFullyQualifiedTehsil, patientAddress); + return patientRequest; + } catch (Exception e) { + throw new RuntimeException("Cannot create request from this row: " + ArrayUtils.toString(patient.getOriginalRow()), e); + } + } + + private void setPatientAddressFrom(FullyQualifiedTehsil fullyQualifiedTehsil, PatientAddress patientAddress) { + patientAddress.setStateProvince(fullyQualifiedTehsil.getState()); + patientAddress.setCountyDistrict(fullyQualifiedTehsil.getDistrict()); + patientAddress.setAddress3(fullyQualifiedTehsil.getTehsil()); + } + + private void addPatientAttribute(String value, PatientRequest patientRequest, String name, + LookupValueProvider lookupValueProvider, int valueIndex) { + if (lookupValueProvider != null) { + String lookUpValue = lookupValueProvider.getLookUpValue(value, valueIndex); + if (lookUpValue == null) return; + } + if (StringUtils.isEmpty(value)) return; + + PatientAttribute patientAttribute = new PatientAttribute(); + patientAttribute.setAttributeType(allPatientAttributeTypes.getAttributeUUID(name)); + patientAttribute.setName(name); + String valueToSet = lookupValueProvider == null ? value : lookupValueProvider.getLookUpValue(value, valueIndex); + valueToSet = "class".equals(name) ? valueToSet : sentenceCase(valueToSet); + patientAttribute.setValue(valueToSet); + patientRequest.addPatientAttribute(patientAttribute); + } + +} diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/CenterId.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/CenterId.java new file mode 100644 index 0000000000..bf853d5be6 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/CenterId.java @@ -0,0 +1,17 @@ +package org.bahmni.datamigration.request.patient; + +public class CenterId { + private String name; + + public CenterId(String name) { + this.name = name; + } + + public String getName() { + return name == null ? null : name.toUpperCase(); + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/Name.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/Name.java new file mode 100644 index 0000000000..0e95ac4b3f --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/Name.java @@ -0,0 +1,25 @@ +package org.bahmni.datamigration.request.patient; + +import static org.bahmni.datamigration.DataScrub.scrubData; + + +public class Name { + private String familyName; + private String givenName; + + public String getFamilyName() { + return familyName; + } + + public void setFamilyName(String familyName) { + this.familyName = scrubData(familyName); + } + + public String getGivenName() { + return givenName; + } + + public void setGivenName(String givenName) { + this.givenName = scrubData(givenName); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientAddress.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientAddress.java new file mode 100644 index 0000000000..8a5b30ba9d --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientAddress.java @@ -0,0 +1,60 @@ +package org.bahmni.datamigration.request.patient; + +import static org.bahmni.datamigration.DataScrub.scrubData; + +public class PatientAddress { + private String address1; + private String cityVillage; + private String address3; + private String countyDistrict; + private String stateProvince; + private String address2; + + public String getAddress1() { + return address1; + } + + public void setAddress1(String address1) { + this.address1 = scrubData(address1); + } + + public String getCityVillage() { + return cityVillage; + } + + public void setCityVillage(String cityVillage) { + this.cityVillage = scrubData(cityVillage); + } + + public String getAddress3() { + return address3; + } + + public void setAddress3(String address3) { + this.address3 = scrubData(address3); + } + + public String getCountyDistrict() { + return countyDistrict; + } + + public void setCountyDistrict(String countyDistrict) { + this.countyDistrict = scrubData(countyDistrict); + } + + public String getStateProvince() { + return stateProvince; + } + + public void setStateProvince(String stateProvince) { + this.stateProvince = scrubData(stateProvince); + } + + public String getAddress2() { + return address2; + } + + public void setAddress2(String address2) { + this.address2 = scrubData(address2); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientAttribute.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientAttribute.java new file mode 100644 index 0000000000..353a884b6c --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientAttribute.java @@ -0,0 +1,33 @@ +package org.bahmni.datamigration.request.patient; + +import static org.bahmni.datamigration.DataScrub.scrubData; + +public class PatientAttribute { + private String attributeType; + private String name; + private String value; + + public String getAttributeType() { + return attributeType; + } + + public void setAttributeType(String attributeType) { + this.attributeType = attributeType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = scrubData(name); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = scrubData(value); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientRequest.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientRequest.java new file mode 100644 index 0000000000..202cdbb0e9 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/patient/PatientRequest.java @@ -0,0 +1,143 @@ +package org.bahmni.datamigration.request.patient; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import static org.bahmni.datamigration.DataScrub.scrubData; +// +//attributeType: "cd7b242c-9790-11e2-99c1-005056b562c5" +// name: "caste" +// value: "bar" +// 1: {attributeType:ce85ffc2-9790-11e2-99c1-005056b562c5, name:class, value:OBC} +// attributeType: "ce85ffc2-9790-11e2-99c1-005056b562c5" +// name: "class" +// value: "OBC" +// 2: {attributeType:cd7be7fe-9790-11e2-99c1-005056b562c5, name:education, value:Uneducated} +// attributeType: "cd7be7fe-9790-11e2-99c1-005056b562c5" +// name: "education" +// value: "Uneducated" +// 3: {attributeType:cd7c99ba-9790-11e2-99c1-005056b562c5, name:occupation, value:Student} +// attributeType: "cd7c99ba-9790-11e2-99c1-005056b562c5" +// name: "occupation" +// value: "Student" +// 4: {attributeType:cd7d5878-9790-11e2-99c1-005056b562c5, name:primaryContact, value:23432} +// attributeType: "cd7d5878-9790-11e2-99c1-005056b562c5" +// name: "primaryContact" +// value: "23432" +// 5: {attributeType:cd7e34e6-9790-11e2-99c1-005056b562c5, name:secondaryContact, value:34324} +// attributeType: "cd7e34e6-9790-11e2-99c1-005056b562c5" +// name: "secondaryContact" +// value: "34324" +// 6: {attributeType:cd7faff6-9790-11e2-99c1-005056b562c5, name:primaryRelative, value:sfgfdg} +// attributeType: "cd7faff6-9790-11e2-99c1-005056b562c5" +// name: "primaryRelative" +// value: "sfgfdg" + +public class PatientRequest { + private List names = new ArrayList(); + private LinkedHashMap age; + private String birthdate; + private String gender; + private String identifier; + private CenterId centerID; + private List addresses = new ArrayList(); + private List attributes = new ArrayList(); + private String dateOfRegistration; + private String balance; + + public void setAge(LinkedHashMap age) { + this.age = age; + } + + public void setBirthdate(String birthdate) { + this.birthdate = birthdate; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public void setCenterID(CenterId centerID) { + this.centerID = centerID; + } + + public void setName(String givenName, String familyName) { + Name name = new Name(); + name.setGivenName(givenName); + name.setFamilyName(familyName); + names.add(name); + } + + public void addPatientAttribute(PatientAttribute patientAttribute) { + attributes.add(patientAttribute); + } + + public List getNames() { + return names; + } + + public void setNames(List names) { + this.names = names; + } + + public LinkedHashMap getAge() { + return age; + } + + public String getBirthdate() { + return birthdate; + } + + public String getGender() { + return gender; + } + + public String getIdentifier() { + return identifier; + } + + public CenterId getCenterID() { + return centerID; + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } + + public List getAttributes() { + return attributes; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + public void addPatientAddress(PatientAddress patientAddress) { + addresses.add(patientAddress); + } + + public String getDateOfRegistration() { + return dateOfRegistration; + } + + public void setDateOfRegistration(String dateOfRegistration) { + this.dateOfRegistration = dateOfRegistration; + } + + public String getBalance() { + return balance; + } + + public void setBalance(String balance) { + this.balance = scrubData(balance); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/referencedata/PersonAttribute.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/referencedata/PersonAttribute.java new file mode 100644 index 0000000000..9d37ef69b3 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/referencedata/PersonAttribute.java @@ -0,0 +1,42 @@ +package org.bahmni.datamigration.request.referencedata; + +import static org.bahmni.datamigration.DataScrub.scrubData; + +public class PersonAttribute { + private String uuid; + private String display; + private String name; + private String description; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = scrubData(name); + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = scrubData(description); + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/datamigration/request/referencedata/PersonAttributeRequest.java b/jss-old-data/src/main/java/org/bahmni/datamigration/request/referencedata/PersonAttributeRequest.java new file mode 100644 index 0000000000..24b7322637 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/datamigration/request/referencedata/PersonAttributeRequest.java @@ -0,0 +1,9 @@ +package org.bahmni.datamigration.request.referencedata; + +public class PersonAttributeRequest { + private String display; + private String uuid; + private String value; + private String attributeType; + private String voided; +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/jss/JSSMigrator.java b/jss-old-data/src/main/java/org/bahmni/jss/JSSMigrator.java new file mode 100644 index 0000000000..1b98d8290a --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/jss/JSSMigrator.java @@ -0,0 +1,112 @@ +package org.bahmni.jss; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.bahmni.csv.MigrateResult; +import org.bahmni.csv.MigratorBuilder; +import org.bahmni.csv.exception.MigrationException; +import org.bahmni.datamigration.AddressService; +import org.bahmni.datamigration.AllLookupValues; +import org.bahmni.datamigration.AmbiguousTehsils; +import org.bahmni.datamigration.CorrectedTehsils; +import org.bahmni.datamigration.MasterTehsils; +import org.bahmni.datamigration.csv.Patient; +import org.bahmni.datamigration.csv.PatientPersister; +import org.bahmni.openmrsconnector.AllPatientAttributeTypes; +import org.bahmni.openmrsconnector.OpenMRSRESTConnection; +import org.bahmni.openmrsconnector.OpenMRSRestService; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.sql.SQLException; +import java.util.HashMap; + +public class JSSMigrator { + private final OpenMRSRestService openMRSRestService; + private final HashMap lookupValuesMap; + private String csvLocation; + private final int numberOfValidationThreads; + private final int numberOfMigrationThreads; + private static Logger logger = LogManager.getLogger(JSSMigrator.class); + + public static void main(String[] args) throws URISyntaxException, IOException, ClassNotFoundException, SQLException, InterruptedException { + if (args.length < 2) { + logger.error(String.format("Usage %s CSV-File-Location RegistrationCSVFileName", JSSMigrator.class.getName())); + logPropertyUsage("localhost", "root", "password", "admin", "test"); + System.exit(1); + } + String csvLocation = args[0]; + String registrationCSVFileName = args[1]; + int numberOfValidationThreads = 1; + int numberOfMigrationThreads = 20; + if(args[2] != null) + numberOfValidationThreads = Integer.valueOf(args[2]); + if(args[3] != null) + numberOfMigrationThreads = Integer.valueOf(args[3]); + + logger.info(String.format("Using CSVFileLocation=%s; RegistrationFileName=%s", new File(csvLocation).getAbsolutePath(), registrationCSVFileName)); + String openMRSHostName = System.getProperty("openmrs.host.name", "localhost"); + String databaseUserId = System.getProperty("database.user.id", "root"); + String databasePassword = System.getProperty("database.user.password", "password"); + String openmrsUserId = System.getProperty("openmrs.user.id", "admin"); + String openmrsUserPassword = System.getProperty("openmrs.user.password", "Admin123"); + logPropertyUsage(openMRSHostName, databaseUserId, databasePassword, openmrsUserId, openmrsUserPassword); + + OpenMRSRESTConnection openMRSRESTConnection = new OpenMRSRESTConnection(openMRSHostName, openmrsUserId, openmrsUserPassword); + MasterTehsils masterTehsils = new MasterTehsils(csvLocation, "MasterTehsils.csv"); + AmbiguousTehsils ambiguousTehsils = new AmbiguousTehsils(csvLocation, "AmbiguousTehsils.txt"); + CorrectedTehsils correctedTehsils = new CorrectedTehsils(csvLocation, "CorrectedTehsils.csv"); + AddressService addressService = new AddressService(masterTehsils, ambiguousTehsils, correctedTehsils); + + JSSMigrator jssMigrator = new JSSMigrator(csvLocation, "LU_Caste.csv", "LU_District.csv", "LU_State.csv", + "LU_Class.csv", "LU_Tahsil.csv", openMRSRESTConnection, numberOfValidationThreads, numberOfMigrationThreads); + jssMigrator.migratePatient(registrationCSVFileName, addressService, openMRSRESTConnection); + } + + private static void logPropertyUsage(String openMRSHostName, String databaseUserId, String databaseUserPassword, String openmrsUserId, String openmrsPassword) { + logger.printf(Level.INFO, "By default uses following properties: openmrs.host.name=%s; database.user.id=%s; openmrs.user.id=%s;", openMRSHostName, databaseUserId, openmrsUserId); + } + + public JSSMigrator(String csvLocation, String casteFileName, String districtFileName, String stateFileName, + String classFileName, String tahsilFileName, OpenMRSRESTConnection openMRSRESTConnection, + int numberOfValidationThreads, int numberOfMigrationThreads) throws IOException, + URISyntaxException { + this.csvLocation = csvLocation; + this.numberOfValidationThreads = numberOfValidationThreads; + this.numberOfMigrationThreads = numberOfMigrationThreads; + AllLookupValues allCastes = new AllLookupValues(csvLocation, casteFileName); + AllLookupValues allDistricts = new AllLookupValues(csvLocation, districtFileName); + AllLookupValues allStates = new AllLookupValues(csvLocation, stateFileName); + AllLookupValues allClasses = new AllLookupValues(csvLocation, classFileName); + AllLookupValues allTahsils = new AllLookupValues(csvLocation, tahsilFileName); + lookupValuesMap = new HashMap<>(); + lookupValuesMap.put("Castes", allCastes); + lookupValuesMap.put("Districts", allDistricts); + lookupValuesMap.put("States", allStates); + lookupValuesMap.put("Classes", allClasses); + lookupValuesMap.put("Tahsils", allTahsils); + + openMRSRestService = new OpenMRSRestService(openMRSRESTConnection); + } + + public void migratePatient(String csvFileName, AddressService addressService, OpenMRSRESTConnection openMRSRESTConnection) throws IOException { + AllPatientAttributeTypes allPatientAttributeTypes = openMRSRestService.getAllPatientAttributeTypes(); + + PatientPersister patientPersister = new PatientPersister(lookupValuesMap, addressService, + allPatientAttributeTypes, openMRSRESTConnection, openMRSRestService.getSessionId()); + org.bahmni.csv.Migrator migrator = new MigratorBuilder(Patient.class) + .readFrom(csvLocation, csvFileName) + .persistWith(patientPersister) + .withMultipleValidators(numberOfValidationThreads) + .withMultipleMigrators(numberOfMigrationThreads) + .build(); + try { + MigrateResult migrateResult = migrator.migrate(); + logger.info("Migration was {}", (migrateResult.hasFailed() ? "unsuccessful" : "successful")); + logger.info("Stage : {} . Success count : {} . Fail count : {}", migrateResult.getStageName(), migrateResult.numberOfSuccessfulRecords(), migrateResult.numberOfFailedRecords()); + } catch (MigrationException e) { + logger.error("There was an error during migration. {}", e.getMessage()); + } + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/jss/registration/AllStates.java b/jss-old-data/src/main/java/org/bahmni/jss/registration/AllStates.java new file mode 100644 index 0000000000..f07abb53a9 --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/jss/registration/AllStates.java @@ -0,0 +1,22 @@ +package org.bahmni.jss.registration; + +import org.bahmni.datamigration.AllLookupValues; + +import java.io.IOException; + +public class AllStates extends AllLookupValues { + private AllLookupValues allDistricts; + + public AllStates(String csvLocation, String fileName, AllLookupValues allDistricts) throws IOException { + super(csvLocation, fileName); + this.allDistricts = allDistricts; + } + + @Override + public String getLookUpValue(String key) { + String stateId = allDistricts.getLookUpValue(key); + String lookUpValue = allDistricts.getLookUpValue(stateId); + "Madya Pradesh".equals(lookUpValue) return "Madhya Pradesh"; + return lookUpValue; + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/jss/registration/RegistrationFields.java b/jss-old-data/src/main/java/org/bahmni/jss/registration/RegistrationFields.java new file mode 100644 index 0000000000..dfb20f9e8a --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/jss/registration/RegistrationFields.java @@ -0,0 +1,73 @@ +package org.bahmni.jss.registration; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.WordUtils; +import org.bahmni.datamigration.request.patient.Name; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; +import org.joda.time.format.DateTimeFormat; + +import java.util.StringTokenizer; + +import static org.bahmni.datamigration.DataScrub.scrubData; + +public class RegistrationFields { + private static final String patternWhenYearSpecifiedAs4Digits = "dd/MM/yyyy"; + private static final String patternWhenYearSpecifiedAs2Digits = "dd/MM/yy"; + public static final LocalDate UnknownDateOfBirth = new LocalDate(1900, 1, 1); + public static final String UnknownDateOfBirthAsString = UnknownDateOfBirth.toString("dd-MM-yyyy"); + + public static String getDate(String s) { + StringTokenizer stringTokenizer = new StringTokenizer(s.trim(), " "); + if (!stringTokenizer.hasMoreTokens()) return null; + String datePart = stringTokenizer.nextToken(); + String pattern = datePart.length() == 8 ? patternWhenYearSpecifiedAs2Digits : patternWhenYearSpecifiedAs4Digits; + LocalDate localDate = LocalDateTime.parse(datePart, DateTimeFormat.forPattern(pattern)).toLocalDate(); + if(localDate.getYear() <= 1900 || localDate.isAfter(LocalDate.now())) + localDate = UnknownDateOfBirth; + return localDate.toString("dd-MM-yyyy"); + } + + public static String sentenceCase(String s) { + return WordUtils.capitalizeFully(s); + } + + public static RegistrationNumber parseRegistrationNumber(String registrationNumber) { + StringTokenizer stringTokenizer = new StringTokenizer(registrationNumber, "/"); + String id = stringTokenizer.nextToken(); + String centerCode = stringTokenizer.nextToken(); + return new RegistrationNumber(scrubData(centerCode), scrubData(id)); + } + + public static Name name(String firstName, String lastName) { + String[] splitFirstNames = StringUtils.split(firstName, " "); + String givenName; + String familyName = null; + + Name name = new Name(); + if (StringUtils.isEmpty(lastName) && splitFirstNames.length > 1) { + Object[] splitFirstNamesExceptLastWord = ArrayUtils.remove(splitFirstNames, splitFirstNames.length - 1); + givenName = StringUtils.join(splitFirstNamesExceptLastWord, " "); + familyName = splitFirstNames[splitFirstNames.length - 1]; + } else { + givenName = firstName; + familyName = lastName; + } + name.setGivenName((givenName == null || StringUtils.isEmpty(givenName)) ? "." : givenName); + name.setFamilyName((familyName == null || StringUtils.isEmpty(familyName)) ? "." : familyName); + return name; + } + + public static int getAge(String fieldValue) { + double doubleValue; + try { + doubleValue = Double.parseDouble(fieldValue); + } catch (NumberFormatException e) { + return 0; + } + return (int) Math.round(doubleValue); + } + + +} \ No newline at end of file diff --git a/jss-old-data/src/main/java/org/bahmni/jss/registration/RegistrationNumber.java b/jss-old-data/src/main/java/org/bahmni/jss/registration/RegistrationNumber.java new file mode 100644 index 0000000000..04a99af9ad --- /dev/null +++ b/jss-old-data/src/main/java/org/bahmni/jss/registration/RegistrationNumber.java @@ -0,0 +1,19 @@ +package org.bahmni.jss.registration; + +public class RegistrationNumber { + private String centerCode; + private String id; + + public RegistrationNumber(String centerCode, String id) { + this.centerCode = centerCode; + this.id = id; + } + + public String getCenterCode() { + return centerCode; + } + + public String getId() { + return id; + } +} \ No newline at end of file diff --git a/jss-old-data/src/main/resources/jssApplicationContext.xml b/jss-old-data/src/main/resources/jssApplicationContext.xml new file mode 100644 index 0000000000..ff5706fdcf --- /dev/null +++ b/jss-old-data/src/main/resources/jssApplicationContext.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/jss-old-data/src/main/resources/log4j2.xml b/jss-old-data/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..ff03962b76 --- /dev/null +++ b/jss-old-data/src/main/resources/log4j2.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jss-old-data/src/test/java/org/bahmni/datamigration/AddressServiceTest.java b/jss-old-data/src/test/java/org/bahmni/datamigration/AddressServiceTest.java new file mode 100644 index 0000000000..27e044ca65 --- /dev/null +++ b/jss-old-data/src/test/java/org/bahmni/datamigration/AddressServiceTest.java @@ -0,0 +1,44 @@ +package org.bahmni.datamigration; + +import org.junit.Test; +import org.mockito.Mock; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class AddressServiceTest { + @Mock + private MasterTehsils masterTehsils; + @Mock + private AmbiguousTehsils ambiguousTehsils; + @Mock + private CorrectedTehsils correctedTehsils; + + @Test + public void getTehsilFor() { + initMocks(this); + FullyQualifiedTehsil rightTehsil = new FullyQualifiedTehsil("Kota", "Dota", "Stota"); + when(masterTehsils.getFullyQualifiedTehsil("Kota")).thenReturn(rightTehsil); + when(ambiguousTehsils.contains("Kota")).thenReturn(false); + when(correctedTehsils.correctedTehsil("Kota")).thenReturn("Kota"); + + AddressService addressService = new AddressService(masterTehsils, ambiguousTehsils, correctedTehsils); + FullyQualifiedTehsil tehsilFor = addressService.getTehsilFor(new FullyQualifiedTehsil("Kota", "WrDota", "WrStota")); + assertEquals(rightTehsil, tehsilFor); + } + + @Test + public void getTehsilFor2() { + initMocks(this); + FullyQualifiedTehsil rightTehsil = new FullyQualifiedTehsil("Kota", "Dota", "Stota"); + when(masterTehsils.getFullyQualifiedTehsil("Kota")).thenReturn(rightTehsil); + when(ambiguousTehsils.contains("Kota")).thenReturn(true); + when(correctedTehsils.correctedTehsil("Kota")).thenReturn("Kota"); + + AddressService addressService = new AddressService(masterTehsils, ambiguousTehsils, correctedTehsils); + FullyQualifiedTehsil tehsilFromPatientRecord = new FullyQualifiedTehsil("Kota", "WrDota", "WrStota"); + FullyQualifiedTehsil tehsilFor = addressService.getTehsilFor(tehsilFromPatientRecord); + assertEquals(tehsilFromPatientRecord, tehsilFor); + } +} \ No newline at end of file diff --git a/jss-old-data/src/test/java/org/bahmni/jss/registration/RegistrationFieldsTest.java b/jss-old-data/src/test/java/org/bahmni/jss/registration/RegistrationFieldsTest.java new file mode 100644 index 0000000000..be5336161d --- /dev/null +++ b/jss-old-data/src/test/java/org/bahmni/jss/registration/RegistrationFieldsTest.java @@ -0,0 +1,53 @@ +package org.bahmni.jss.registration; + +import org.bahmni.datamigration.request.patient.Name; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class RegistrationFieldsTest { + @Test + public void parseDate() { + assertEquals("05-08-1979", RegistrationFields.getDate("05/08/79 0:00")); + assertEquals("05-08-1979", RegistrationFields.getDate("05/08/1979 00:00:00")); + assertEquals("01-01-1900", RegistrationFields.getDate("05/08/1579 00:00:00")); + assertEquals(null, RegistrationFields.getDate("")); + assertEquals(null, RegistrationFields.getDate(" ")); + } + + @Test + public void parseDateInFuture() { + assertEquals("01-01-1900", RegistrationFields.getDate("05/08/2079 0:00")); + assertEquals("01-01-1900", RegistrationFields.getDate("05/08/2028 0:00")); + } + + @Test + public void sentenceCase() { + assertEquals("Devari", RegistrationFields.sentenceCase("DEVARI")); + assertEquals("Chakra Kund", RegistrationFields.sentenceCase("CHAKRA KUND")); + } + + @Test + public void name() { + assertName("MILAPA BAI", "", "MILAPA", "BAI"); + assertName("MILAPA", "", "MILAPA", "."); + assertName("MILAPA", "BAI", "MILAPA", "BAI"); + assertName("MILAPA JI", "BAI", "MILAPA JI", "BAI"); + assertName("MILAPA JI", "", "MILAPA", "JI"); + assertName("", "BAI", ".", "BAI"); + assertName("", "", ".", "."); + } + + private void assertName(String firstName, String lastName, String givenName, String familyName) { + Name name = RegistrationFields.name(firstName, lastName); + assertEquals(givenName, name.getGivenName()); + assertEquals(familyName, name.getFamilyName()); + } + + @Test + public void getAge() { + assertEquals(1, RegistrationFields.getAge("1")); + assertEquals(2, RegistrationFields.getAge("1.5")); + assertEquals(0, RegistrationFields.getAge("10 Day")); + } +} \ No newline at end of file diff --git a/jss-old-data/src/test/resources/RegistrationMaster_Sample.csv b/jss-old-data/src/test/resources/RegistrationMaster_Sample.csv new file mode 100644 index 0000000000..3112a3dbea --- /dev/null +++ b/jss-old-data/src/test/resources/RegistrationMaster_Sample.csv @@ -0,0 +1 @@ +REG_NO,REG_DATE,FNAME,LNAME,FHNAME,P_SEX,P_DOB,P_AGE,P_HEIGHT,P_WEIGHT,VILLAGE,CITY,P_POST,EDUCATION,OCCUPATION,P_MEMBER,P_TB,BALANCE_AMT,Remark,FNameID,CasteID,FHNameID,EducationID,OccupationID,VillageID,TahsilID,DistrictID,TahsilID2,VillageID2,Neighborhood,GramPanchID,LNameID,ClassID,memberVillageID,GramPanch,Tahsil 52174/GAN,29/07/2005 00:00:00,UMASHANKAR,,VISHAL,M,05/08/79 0:00,26,,34.6,DEVARI,,BHARANI,,,,0,0,,20937,1,21393,0,0,3084,1,0,0,0,,0,2,0,0,, 8370/GAN,27/06/2003 00:00:00,Binda Bai Goswami,,Kunj Bharati,F,,y/70,,52,Patharra,,Peepertarai,,,,0,0,,2931,1,28226,0,0,8846,1,0,0,0,,0,2,0,0,, \ No newline at end of file diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000..5643201c7d --- /dev/null +++ b/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000000..8a15b7f311 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/obs-relation/pom.xml b/obs-relation/pom.xml new file mode 100644 index 0000000000..959203f92d --- /dev/null +++ b/obs-relation/pom.xml @@ -0,0 +1,85 @@ + + 4.0.0 + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + obs-relationship + jar + Obs relationship + + + + org.openmrs.test + openmrs-test + pom + test + + + + org.openmrs.api + openmrs-api + jar + + + + org.openmrs.api + openmrs-api + test-jar + test + + + + junit + junit + test + + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test-jar + test + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.00 + + + BRANCH + COVEREDRATIO + 0.00 + + + + + + + + + + + diff --git a/obs-relation/src/main/java/org/bahmni/module/obsrelationship/api/ObsRelationService.java b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/api/ObsRelationService.java new file mode 100644 index 0000000000..d89f616bb7 --- /dev/null +++ b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/api/ObsRelationService.java @@ -0,0 +1,22 @@ +package org.bahmni.module.obsrelationship.api; + + +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.openmrs.Obs; + +import java.util.List; + +public interface ObsRelationService { + ObsRelationship saveOrUpdate(ObsRelationship obsRelationship); + ObsRelationshipType saveOrUpdateRelationshipType(ObsRelationshipType obsRelationshipType); + ObsRelationship getRelationByUuid(String uuid); + List getRelationsBy(Obs sourceObs, Obs targetObs); + + List getRelationsWhereSourceObsInEncounter(String encounterUuid); + + List getAllRelationshipTypes(); + ObsRelationshipType getRelationshipTypeByName(String name); + + List getObsRelationshipsByTargetObsUuid(String targetObsUuid); +} diff --git a/obs-relation/src/main/java/org/bahmni/module/obsrelationship/api/impl/ObsRelationServiceImpl.java b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/api/impl/ObsRelationServiceImpl.java new file mode 100644 index 0000000000..0f7ab958c4 --- /dev/null +++ b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/api/impl/ObsRelationServiceImpl.java @@ -0,0 +1,66 @@ +package org.bahmni.module.obsrelationship.api.impl; + +import org.bahmni.module.obsrelationship.api.ObsRelationService; +import org.bahmni.module.obsrelationship.dao.ObsRelationshipDao; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.openmrs.Obs; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class ObsRelationServiceImpl implements ObsRelationService { + + @Autowired + private ObsRelationshipDao obsRelationshipDao; + + public ObsRelationshipDao getObsRelationshipDao() { + return obsRelationshipDao; + } + + public void setObsRelationshipDao(ObsRelationshipDao obsRelationshipDao) { + this.obsRelationshipDao = obsRelationshipDao; + } + + @Override + public ObsRelationship saveOrUpdate(ObsRelationship obsRelationship) { + return obsRelationshipDao.saveOrUpdate(obsRelationship); + } + + @Override + public ObsRelationshipType saveOrUpdateRelationshipType(ObsRelationshipType obsRelationshipType) { + return obsRelationshipDao.saveOrUpdateRelationshipType(obsRelationshipType); + } + + @Override + public ObsRelationship getRelationByUuid(String uuid) { + return obsRelationshipDao.getRelationByUuid(uuid); + } + + @Override + public List getRelationsBy(Obs sourceObs, Obs targetObs) { + return obsRelationshipDao.getRelationsBy(sourceObs,targetObs); + } + + @Override + public List getRelationsWhereSourceObsInEncounter(String encounterUuid){ + return obsRelationshipDao.getRelationsWhereSourceObsInEncounter(encounterUuid); + } + + @Override + public List getAllRelationshipTypes() { + return obsRelationshipDao.getAllRelationshipTypes(); + } + + @Override + public ObsRelationshipType getRelationshipTypeByName(String name) { + return obsRelationshipDao.getRelationshipTypeByName(name); + } + + @Override + public List getObsRelationshipsByTargetObsUuid(String targetObsUuid) { + return obsRelationshipDao.getObsRelationshipsByTargetObsUuid(targetObsUuid); + } +} diff --git a/obs-relation/src/main/java/org/bahmni/module/obsrelationship/dao/ObsRelationshipDao.java b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/dao/ObsRelationshipDao.java new file mode 100644 index 0000000000..5576ebd9a5 --- /dev/null +++ b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/dao/ObsRelationshipDao.java @@ -0,0 +1,20 @@ +package org.bahmni.module.obsrelationship.dao; + +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.openmrs.Obs; + +import java.util.List; + +public interface ObsRelationshipDao { + ObsRelationship saveOrUpdate(ObsRelationship obsRelationship); + ObsRelationshipType saveOrUpdateRelationshipType(ObsRelationshipType obsRelationshipType); + ObsRelationship getRelationByUuid(String uuid); + List getRelationsBy(Obs sourceObs, Obs targetObs); + List getAllRelationshipTypes(); + ObsRelationshipType getRelationshipTypeByName(String name); + + List getRelationsWhereSourceObsInEncounter(String encounterUuid); + + List getObsRelationshipsByTargetObsUuid(String targetObsUuid); +} diff --git a/obs-relation/src/main/java/org/bahmni/module/obsrelationship/dao/impl/ObsRelationshipDaoImpl.java b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/dao/impl/ObsRelationshipDaoImpl.java new file mode 100644 index 0000000000..3bca24fd39 --- /dev/null +++ b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/dao/impl/ObsRelationshipDaoImpl.java @@ -0,0 +1,122 @@ +package org.bahmni.module.obsrelationship.dao.impl; + +import org.bahmni.module.obsrelationship.dao.ObsRelationshipDao; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.openmrs.Obs; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Component +public class ObsRelationshipDaoImpl implements ObsRelationshipDao { + /** + * Hibernate session factory + */ + + private SessionFactory sessionFactory; + + /** + * Set session factory + * + * @param sessionFactory + */ + @Autowired + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + @Override + @Transactional + public ObsRelationship saveOrUpdate(ObsRelationship obsRelationship) { + sessionFactory.getCurrentSession().saveOrUpdate(obsRelationship); + return obsRelationship; + } + + @Override + @Transactional + public ObsRelationshipType saveOrUpdateRelationshipType(ObsRelationshipType obsRelationshipType) { + sessionFactory.getCurrentSession().saveOrUpdate(obsRelationshipType); + return obsRelationshipType; + } + + @Override + @Transactional + public ObsRelationship getRelationByUuid(String uuid) { + Query query = sessionFactory.getCurrentSession().createQuery("from ObsRelationship where uuid=:uuid"); + query.setString("uuid",uuid); + List list = query.list(); + if(list.size() != 0){ + return list.get(0); + } + return null; + } + + @Override + @Transactional + public List getRelationsBy(Obs sourceObs, Obs targetObs) { + Query query = createGetRelationsQueryFor(sourceObs, targetObs); + List obsRelationshipList = query.list(); + return obsRelationshipList; + } + + @Override + @Transactional + public List getAllRelationshipTypes() { + Query query = sessionFactory.getCurrentSession().createQuery("from ObsRelationshipType"); + return query.list(); + } + + @Override + @Transactional + public ObsRelationshipType getRelationshipTypeByName(String name) { + Query query = sessionFactory.getCurrentSession().createQuery("from ObsRelationshipType where name=:name"); + query.setString("name", name); + List obsRelationshipTypes = query.list(); + if(obsRelationshipTypes.size()>0){ + return (ObsRelationshipType) query.list().get(0); + } + return null; + } + + @Override + @Transactional + public List getRelationsWhereSourceObsInEncounter(String encounterUuid) { + Query query = sessionFactory.getCurrentSession().createQuery("from ObsRelationship obsRel where obsRel.sourceObs.encounter.uuid =:encounterUuid"); + query.setString("encounterUuid", encounterUuid); + return query.list(); + } + + @Override + public List getObsRelationshipsByTargetObsUuid(String targetObsUuid) { + Query query = sessionFactory.getCurrentSession().createQuery("from ObsRelationship obsRel where obsRel.targetObs.uuid =:targetObsUuid"); + query.setString("targetObsUuid", targetObsUuid); + return query.list(); + } + + private Query createGetRelationsQueryFor(Obs sourceObs, Obs targetObs) { + Query query = null; + if(sourceObs == null && targetObs == null){ + throw new IllegalArgumentException("SourceObs and TargetObs are both null in method getRelationByUuid()"); + } + if(sourceObs == null ){ + query = sessionFactory.getCurrentSession().createQuery("from ObsRelationship where targetObs=:targetObs"); + query.setInteger("targetObs", targetObs.getId()); + } + else if(targetObs == null){ + query = sessionFactory.getCurrentSession().createQuery("from ObsRelationship where sourceObs=:sourceObs"); + query.setInteger("sourceObs", sourceObs.getId()); + } + else{ + query = sessionFactory.getCurrentSession().createQuery("from ObsRelationship where sourceObs=:sourceObs and targetObs=:targetObs"); + query.setInteger("sourceObs", sourceObs.getId()); + query.setInteger("targetObs", targetObs.getId()); + } + return query; + } + +} diff --git a/obs-relation/src/main/java/org/bahmni/module/obsrelationship/model/ObsRelationship.java b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/model/ObsRelationship.java new file mode 100644 index 0000000000..3423807cd2 --- /dev/null +++ b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/model/ObsRelationship.java @@ -0,0 +1,97 @@ +package org.bahmni.module.obsrelationship.model; + + +import org.openmrs.Auditable; +import org.openmrs.BaseOpenmrsObject; +import org.openmrs.Obs; +import org.openmrs.User; + +import java.io.Serializable; +import java.util.Date; + +public class ObsRelationship extends BaseOpenmrsObject implements Auditable, Serializable { + + private int id; + private Obs targetObs; + private Obs sourceObs; + private User creator; + private Date dateCreated; + private ObsRelationshipType obsRelationshipType; + + @Override + public User getCreator() { + return this.creator; + } + + + @Override + public void setCreator(User creator) { + this.creator = creator; + } + + @Override + public Date getDateCreated() { + return this.dateCreated; + } + + @Override + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + @Override + public User getChangedBy() { + return null; + } + + @Override + public void setChangedBy(User changedBy) { + + } + + @Override + public Date getDateChanged() { + return null; + } + + @Override + public void setDateChanged(Date dateChanged) { + + } + + @Override + public Integer getId() { + return this.id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public Obs getTargetObs() { + return targetObs; + } + + public void setTargetObs(Obs targetObs) { + this.targetObs = targetObs; + } + + public Obs getSourceObs() { + return sourceObs; + } + + public void setSourceObs(Obs sourceObs) { + this.sourceObs = sourceObs; + } + + public ObsRelationshipType getObsRelationshipType() { + return obsRelationshipType; + } + + public void setObsRelationshipType(ObsRelationshipType obsRelationshipType) { + this.obsRelationshipType = obsRelationshipType; + } + + +} diff --git a/obs-relation/src/main/java/org/bahmni/module/obsrelationship/model/ObsRelationshipType.java b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/model/ObsRelationshipType.java new file mode 100644 index 0000000000..67dafdc6ed --- /dev/null +++ b/obs-relation/src/main/java/org/bahmni/module/obsrelationship/model/ObsRelationshipType.java @@ -0,0 +1,18 @@ +package org.bahmni.module.obsrelationship.model; + +import org.openmrs.BaseOpenmrsMetadata; + + +public class ObsRelationshipType extends BaseOpenmrsMetadata implements java.io.Serializable{ + private int id; + + @Override + public Integer getId() { + return this.id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } +} diff --git a/obs-relation/src/main/resources/moduleApplicationContext.xml b/obs-relation/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..2cea5f9692 --- /dev/null +++ b/obs-relation/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/obs-relation/src/main/resources/obsrelation-hibernate.cfg.xml b/obs-relation/src/main/resources/obsrelation-hibernate.cfg.xml new file mode 100644 index 0000000000..77a230251f --- /dev/null +++ b/obs-relation/src/main/resources/obsrelation-hibernate.cfg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/obs-relation/src/main/resources/org/bahmni/module/db/hibernate/ObsRelationship.hbm.xml b/obs-relation/src/main/resources/org/bahmni/module/db/hibernate/ObsRelationship.hbm.xml new file mode 100644 index 0000000000..95ce826b9e --- /dev/null +++ b/obs-relation/src/main/resources/org/bahmni/module/db/hibernate/ObsRelationship.hbm.xml @@ -0,0 +1,30 @@ + + + + + + obs_relationship_obs_relationship_id_seq + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/obs-relation/src/main/resources/org/bahmni/module/db/hibernate/ObsRelationshipType.hbm.xml b/obs-relation/src/main/resources/org/bahmni/module/db/hibernate/ObsRelationshipType.hbm.xml new file mode 100644 index 0000000000..5ab0c1faca --- /dev/null +++ b/obs-relation/src/main/resources/org/bahmni/module/db/hibernate/ObsRelationshipType.hbm.xml @@ -0,0 +1,27 @@ + + + + + + obs_relationship_type_obs_relationship_type_id_seq + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/obs-relation/src/test/java/org/bahmni/module/obsrelationship/dao/impl/ObsRelationshipDaoImplIT.java b/obs-relation/src/test/java/org/bahmni/module/obsrelationship/dao/impl/ObsRelationshipDaoImplIT.java new file mode 100644 index 0000000000..9e492105d8 --- /dev/null +++ b/obs-relation/src/test/java/org/bahmni/module/obsrelationship/dao/impl/ObsRelationshipDaoImplIT.java @@ -0,0 +1,156 @@ +package org.bahmni.module.obsrelationship.dao.impl; + +import org.bahmni.module.obsrelationship.dao.ObsRelationshipDao; +import org.bahmni.module.obsrelationship.model.ObsRelationship; +import org.bahmni.module.obsrelationship.model.ObsRelationshipType; +import org.junit.Test; +import org.openmrs.Obs; +import org.openmrs.api.ObsService; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; + +import java.text.ParseException; +import java.util.List; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +public class ObsRelationshipDaoImplIT extends BaseModuleContextSensitiveTest { + + @Autowired + ObsRelationshipDao obsRelationshipDao; + + @Autowired + ObsService obsService; + + @org.junit.Before + public void setUp() throws Exception { +// obsRelationshipDao = new ObsRelationshipDaoImpl(); + executeDataSet("obsRelationshipDataset.xml"); + } + + @Test + public void shouldCreateNewObsRelationship(){ + ObsRelationship obsRelationship = new ObsRelationship(); + obsRelationship.setSourceObs(new Obs(7)); + obsRelationship.setTargetObs(new Obs(9)); + obsRelationship.setObsRelationshipType(new ObsRelationshipType(){{setId(1);}}); + assert(obsRelationship.getId() == 0); + + obsRelationshipDao.saveOrUpdate(obsRelationship); + assert(obsRelationship.getId()> 0); + } + + @Test + public void shouldCreateNewObsRelationshipType(){ + ObsRelationshipType obsRelationshipType = new ObsRelationshipType(); + obsRelationshipType.setName("has-member"); + obsRelationshipType.setDescription("has-member"); + assert(obsRelationshipType.getId() == 0); + obsRelationshipDao.saveOrUpdateRelationshipType(obsRelationshipType); + assert(obsRelationshipType.getId()> 0); + assertThat(obsRelationshipType.getName(),is("has-member")); + } + + @Test + public void shouldUpdateObsRelationship() throws ParseException { + String uuid = "2cc6880e-2c46-11e4-9038-a6c5e4d22fb7"; + ObsRelationship obsRelationship = obsRelationshipDao.getRelationByUuid(uuid); + obsRelationship.setSourceObs(obsService.getObs(11)); + obsRelationshipDao.saveOrUpdate(obsRelationship); + assertThat (obsRelationship.getId(),is(1)); + assertThat(obsRelationship.getSourceObs().getId(),is(11)); + } + + @Test + public void shouldGetRelationsByUuid() + { + String uuid = "2cc6880e-2c46-11e4-9038-a6c5e4d22fb7"; + ObsRelationship obsRelationship = obsRelationshipDao.getRelationByUuid(uuid); + assertThat( obsRelationship.getId(),is(1)); + assertThat (obsRelationship.getTargetObs().getId(),is(7)); + assertThat (obsRelationship.getSourceObs().getId(),is(9)); + assertEquals("qualified-by", obsRelationship.getObsRelationshipType().getName()); + + } + + @Test + public void shouldGetRelationsBySourceAndTargetObs(){ + Obs sourceObs = obsService.getObs(9); + Obs targetObs = obsService.getObs(7); + List obsRelationships = obsRelationshipDao.getRelationsBy(sourceObs, targetObs); + assertNotNull(obsRelationships.get(0)); + assertThat( obsRelationships.get(0).getId(),is(1)); + } + + @Test + public void shouldGetRelationsBySourceOrTargetObs(){ + Obs sourceObs = obsService.getObs(9); + List obsRelationships = obsRelationshipDao.getRelationsBy(sourceObs, null); + assertNotNull(obsRelationships); + assertThat(obsRelationships.size(),is(2)); + assertThat( obsRelationships.get(0).getId(),is(1)); + assertThat( obsRelationships.get(1).getId(),is(2)); + } + + @Test + public void shouldNotGetRelationsBySourceAndTargetObsWhenThereIsOnlyASingleMatch(){ + Obs sourceObs = obsService.getObs(9); + Obs targetObs = obsService.getObs(16); + List obsRelationships = obsRelationshipDao.getRelationsBy(sourceObs, targetObs); + assertThat(obsRelationships.size(),is(0)); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionWhenGetRelationsBySourceOrTargetObsAreBothNullValues(){ + Obs sourceObs = null; + Obs targetObs = null; + obsRelationshipDao.getRelationsBy(sourceObs, targetObs); + } + + @Test + public void shouldNotGetRelationsBySourceAndTargetObsWhenBothDoNotMatch(){ + Obs sourceObs = obsService.getObs(15); + Obs targetObs = obsService.getObs(16); + List obsRelationships = obsRelationshipDao.getRelationsBy(sourceObs, targetObs); + assertThat(obsRelationships.size(),is(0)); + } + + @Test + public void shouldGetAllRelationshipTypes(){ + List relationshipTypes = obsRelationshipDao.getAllRelationshipTypes(); + assertThat(relationshipTypes.size(), is(2)); + } + + @Test + public void shouldGetRelationshipTypeByName(){ + String relationshipName = "derived-from"; + ObsRelationshipType relationshipType = obsRelationshipDao.getRelationshipTypeByName(relationshipName); + assertThat(relationshipType.getName(), is(relationshipName)); + } + + @Test + public void shouldReturnNullWhenNameInGetRelationshipTypeByNameDoesNotMatch(){ + String relationshipName = "replaces"; + ObsRelationshipType relationshipType = obsRelationshipDao.getRelationshipTypeByName(relationshipName); + assertNull(relationshipType); + } + + @Test + public void shouldReturnObsRelationsInGivenEncounter(){ + String encounterUuid = "6519d653-393b-4118-9c83-a3715b82d4ac"; + List obsRelationships = obsRelationshipDao.getRelationsWhereSourceObsInEncounter(encounterUuid); + assertEquals(2,obsRelationships.size()); + assertEquals("2cc6880e-2c46-11e4-9038-a6c5e4d22fb7", obsRelationships.get(0).getUuid()); + assertEquals(new Integer(9), obsRelationships.get(0).getSourceObs().getId()); + assertEquals(new Integer(7), obsRelationships.get(0).getTargetObs().getId()); + + assertEquals("2cc6880e-2c46-11e4-9038-a6c5e4d22222", obsRelationships.get(1).getUuid()); + assertEquals(new Integer(9), obsRelationships.get(1).getSourceObs().getId()); + assertEquals(new Integer(11), obsRelationships.get(1).getTargetObs().getId()); + } + +} \ No newline at end of file diff --git a/obs-relation/src/test/resources/TestingApplicationContext.xml b/obs-relation/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..f69336a772 --- /dev/null +++ b/obs-relation/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + classpath:hibernate.cfg.xml + classpath:test-hibernate.cfg.xml + + + + + + + + org.openmrs + + + + + + diff --git a/obs-relation/src/test/resources/obsRelationshipDataset.xml b/obs-relation/src/test/resources/obsRelationshipDataset.xml new file mode 100644 index 0000000000..26cdfbc3b5 --- /dev/null +++ b/obs-relation/src/test/resources/obsRelationshipDataset.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/obs-relation/src/test/resources/test-hibernate.cfg.xml b/obs-relation/src/test/resources/test-hibernate.cfg.xml new file mode 100644 index 0000000000..3d2be5af34 --- /dev/null +++ b/obs-relation/src/test/resources/test-hibernate.cfg.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/omod/pom.xml b/omod/pom.xml deleted file mode 100644 index 24b2d2f9a0..0000000000 --- a/omod/pom.xml +++ /dev/null @@ -1,254 +0,0 @@ - - 4.0.0 - - org.raxa.module - raxacore - 0.2-SNAPSHOT - - raxacore-omod - jar - RaxaEMR Core OMOD - OpenMRS module project for RaxaEMR Core Module - - - - org.raxa.module - raxacore-api - ${project.parent.version} - - - - org.openmrs.api - openmrs-api - jar - - - org.openmrs.web - openmrs-web - jar - - - org.openmrs.api - openmrs-api - test-jar - test - - - org.openmrs.web - openmrs-web - test-jar - test - - - org.openmrs.test - openmrs-test - pom - test - - - - - org.openmrs.module - webservices.rest-api - - - org.openmrs.module - webservices.rest-omod - - - org.openmrs.module - webservices.rest-omod - tests - - - - - - com.google.code.gson - gson - 2.2.1 - - - com.google.guava - guava - 10.0.1 - - - - - ${project.parent.artifactId}-${project.parent.version} - - - src/main/resources - true - - - src/main/webapp - false - - resources - - web/module - - - src/main/webapp - false - - resources - - web/module - - - - - src/test/resources - true - - - - - - maven-resources-plugin - - true - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.openmrs.maven.plugins - - - maven-openmrs-plugin - - - [1.0.1,) - - - - initialize-module - - - - - - - - - - - com.googlecode.maven-java-formatter-plugin - - - maven-java-formatter-plugin - - - [0.3.1,) - - - format - - - - - - - - - - org.apache.maven.plugins - - - maven-dependency-plugin - - - [2.4,) - - - - unpack-dependencies - - - - - - - - - - - - - - - - org.openmrs.maven.plugins - maven-openmrs-plugin - true - - - init - initialize - - initialize-module - - - - pack - package - - package-module - - - - - - com.googlecode.maven-java-formatter-plugin - maven-java-formatter-plugin - - - - format - - - - - - 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 - - - - - - - - - ${project.parent.artifactId} - ${project.parent.name} - ${project.parent.version} - ${project.parent.groupId}.${project.parent.artifactId} - - diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugGroupController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugGroupController.java deleted file mode 100644 index c5771d7cae..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugGroupController.java +++ /dev/null @@ -1,322 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Encounter; -import org.openmrs.Obs; -import org.openmrs.Drug; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.DrugGroupService; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the DrugGroup resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/druggroup") -public class DrugGroupController extends BaseRestController { - - DrugGroupService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "name", "description" }; - - public void initDrugGroupController() { - service = Context.getService(DrugGroupService.class); - } - - // - /** - * Returns the Resource Version - */ - private String getResourceVersion() { - return "1.0"; - } - - // - // - /** - * Create new drug group by POST'ing atleast name and description property - * in the request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and DrugGroup object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New DrugGroup") - @ResponseBody - public Object createNewDrugGroup(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugGroupController(); - DrugGroup drugGroup = new DrugGroup(); - drugGroup.setName(post.get("name").toString()); - drugGroup.setDescription(post.get("description").toString()); - DrugGroup created = service.saveDrugGroup(drugGroup); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.created(response, obj); - } - - // - // - /** - * Updates the Drug Group by making a POST call with uuid in URL and - * - * @param uuid the uuid for the drug group resource - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing drug group") - @ResponseBody - public Object updateDrugGroup(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, - HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugGroupController(); - DrugGroup drugGroup = service.getDrugGroupByUuid(uuid); - drugGroup.setName(post.get("name").toString()); - drugGroup.setDescription(post.get("description").toString()); - DrugGroup created = service.updateDrugGroup(drugGroup); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.noContent(response); - } - - // - // - /** - * Get all the unretired drug groups (as REF representation) in the system - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Drug Groups in the system") - @ResponseBody() - public String getAllDrugGroups(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugGroupController(); - List allDrugGroup = service.getAllDrugGroup(false); - ArrayList results = new ArrayList(); - for (DrugGroup drugGroup : allDrugGroup) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drugGroup.getUuid()); - obj.add("name", drugGroup.getName()); - obj.add("description", drugGroup.getDescription()); - results.add(obj); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - // - // - /** - * Search DrugGroup by Name and get the resource as REF representation - * - * @param query the string to search name of drugGroup - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "q") - @WSDoc("Gets Drug Groups by name") - @ResponseBody() - public String getDrugGroupsByName(@RequestParam("q") String query, HttpServletRequest request) throws ResponseException { - initDrugGroupController(); - List allDrugGroup = service.getDrugGroupByName(query); - ArrayList results = new ArrayList(); - for (DrugGroup drugGroup : allDrugGroup) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drugGroup.getUuid()); - obj.add("name", drugGroup.getName()); - obj.add("description", drugGroup.getDescription()); - results.add(obj); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - // - // - /** - * Get the DrugGroup along with drugs, encounters and obs (DEFAULT rep). - * Contains all encounters of the searched encounterType between the - * startDate and endDate - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Drug Groups for the uuid path") - @ResponseBody() - public String getAllDrugGroupByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initDrugGroupController(); - DrugGroup drugGroup = service.getDrugGroupByUuid(uuid); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drugGroup.getUuid()); - obj.add("name", drugGroup.getName()); - obj.add("description", drugGroup.getDescription()); - ArrayList drugs = new ArrayList(); - List drugsInDrugGroup = new ArrayList(drugGroup.getDrugs()); - for (Drug p : drugsInDrugGroup) { - SimpleObject drug = new SimpleObject(); - drug.add("uuid", p.getUuid()); - drugs.add(drug); - } - obj.add("drugs", drugs); - return gson.toJson(obj); - } - - // - // - /** - * Get the drug group as FULL representation that shows drugs, - * encounters and obs. Contains all encounters of the searched encounterType - * between the startDate and endDate. Contains drugGroup.searchQuery, - * encounter.provider and obs.comment and obs.order compared to DEFAULT rep - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET, params = "v") - @WSDoc("Gets Full representation of Drug Groups for the uuid path") - @ResponseBody() - public String getAllDrugGroupByUuidFull(@PathVariable("uuid") String uuid, @RequestParam("v") String rep, - HttpServletRequest request) throws ResponseException { - initDrugGroupController(); - DrugGroup drugGroup = service.getDrugGroupByUuid(uuid); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drugGroup.getUuid()); - obj.add("name", drugGroup.getName()); - obj.add("description", drugGroup.getDescription()); - ArrayList drugs = new ArrayList(); - List drugsInDrugGroup = new ArrayList(drugGroup.getDrugs()); - for (Drug p : drugsInDrugGroup) { - SimpleObject drug = new SimpleObject(); - drug.add("uuid", p.getUuid()); - drugs.add(drug); - } - obj.add("drugs", drugs); - if (rep.equals("full")) { - obj.add("retired", drugGroup.getRetired()); - if (drugGroup.getRetired()) { - obj.add("retiredBy", drugGroup.getRetiredBy().getUuid()); - obj.add("retireReason", drugGroup.getRetireReason()); - } - SimpleObject auditInfo = new SimpleObject(); - auditInfo.add("creator", drugGroup.getCreator().getUuid()); - auditInfo.add("dateCreated", df.format(drugGroup.getDateCreated())); - if (drugGroup.getChangedBy() != null) { - auditInfo.add("changedBy", drugGroup.getChangedBy().getUuid()); - auditInfo.add("dateChanged", df.format(drugGroup.getDateChanged())); - } - obj.add("auditInfo", auditInfo); - } - obj.add("resourceVersion", getResourceVersion()); - return gson.toJson(obj); - } - - // - // - /** - * Retires the drug group resource by making a DELETE call with the - * '!purge' param - * - * @param uuid - * @param reason - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "!purge") - @WSDoc("Retires the Drug Group") - @ResponseBody - public Object retireDrugGroup(@PathVariable("uuid") String uuid, - @RequestParam(value = "reason", defaultValue = "web service call") String reason, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initDrugGroupController(); - DrugGroup drugGroup = service.getDrugGroupByUuid(uuid); - if (drugGroup != null) { - drugGroup.setRetired(true); - drugGroup.setRetireReason(reason); - drugGroup.setRetiredBy(Context.getAuthenticatedUser()); - service.updateDrugGroup(drugGroup); - } - return RestUtil.noContent(response); - } - - // - // - /** - * Purges (Complete Delete) the drug group resource by making a DELETE - * call and passing the 'purge' param - * - * @param uuid - * @param request - * @param response - * @throws Exception - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "purge") - @ResponseBody - public Object purgeDrugGroup(@PathVariable("uuid") String uuid, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugGroupController(); - DrugGroup drugGroup = service.getDrugGroupByUuid(uuid); - if (drugGroup != null) { - service.deleteDrugGroup(drugGroup); - } - return RestUtil.noContent(response); - } - // -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInfoController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInfoController.java deleted file mode 100644 index a8bbfd4cc9..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInfoController.java +++ /dev/null @@ -1,342 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Encounter; -import org.openmrs.Obs; -import org.openmrs.Patient; -import org.openmrs.Drug; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the DrugInfo resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/druginfo") -public class DrugInfoController extends BaseRestController { - - DrugInfoService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "name", "description", "price", "cost" }; - - public void initDrugInfoController() { - service = Context.getService(DrugInfoService.class); - } - - /** - * Returns the Resource Version - */ - private String getResourceVersion() { - return "1.0"; - } - - /** - * Create new drug info by POST'ing atleast name and description property in - * the request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and DrugInfo object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New DrugInfo") - @ResponseBody - public Object createNewDrugInfo(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugInfoController(); - - String drugUuid = post.get("drug").toString(); - Drug drug = Context.getConceptService().getDrugByUuid(drugUuid); - - if (drug == null) { - // drug doesn't exist, so we won't create the drug info - throw new ObjectNotFoundException(); - } - - // create drug info POJO and add required relationship with a Drug - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setDrug(drug); - - // add data that was sent in the POST payload - updateDrugInfoFieldsFromPostData(drugInfo, post); - - // save new object and prepare response - DrugInfo drugInfoJustCreated = service.saveDrugInfo(drugInfo); - - return RestUtil.created(response, getDrugInfoAsSimpleObject(drugInfoJustCreated)); - } - - /** - * Updates the Drug Info by making a POST call with uuid in URL and - * - * @param uuid the uuid for the drug info resource - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing drug info") - @ResponseBody - public Object updateDrugInfo(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, - HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugInfoController(); - DrugInfo drugInfo = service.getDrugInfoByUuid(uuid); - updateDrugInfoFieldsFromPostData(drugInfo, post); - service.updateDrugInfo(drugInfo); - return RestUtil.created(response, getDrugInfoAsSimpleObject(drugInfo)); - } - - /** - * Updates attributes of a DrugInfo copying them from a SimpleObject - * - * @param drugInfo - * @param obj - */ - private void updateDrugInfoFieldsFromPostData(DrugInfo drugInfo, SimpleObject obj) { - if (obj.get("name") != null) { - drugInfo.setName(obj.get("name").toString()); - } - if (obj.get("description") != null) { - drugInfo.setDescription(obj.get("description").toString()); - } - if (obj.get("price") != null) { - drugInfo.setPrice(Double.parseDouble(obj.get("price").toString())); - } - if (obj.get("cost") != null) { - drugInfo.setCost(Double.parseDouble(obj.get("cost").toString())); - } - if (obj.get("reorderLevel") != null) { - drugInfo.setReorderLevel(Integer.parseInt(obj.get("reorderLevel").toString())); - } - if (obj.get("supplier") != null) { - drugInfo.setSupplier((obj.get("supplier").toString())); - } - if (obj.get("manufacturer") != null) { - drugInfo.setManufacturer((obj.get("manufacturer").toString())); - } - if (obj.get("shortName") != null) { - drugInfo.setShortName(obj.get("shortName").toString()); - } - if (obj.get("brandName") != null) { - drugInfo.setBrandName(obj.get("brandName").toString()); - } - } - - /** - * Returns a SimpleObject containing some fields of DrugInfo - * - * @param drugInfo - * @return - */ - private SimpleObject getDrugInfoAsSimpleObject(DrugInfo drugInfo) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drugInfo.getUuid()); - obj.add("name", drugInfo.getName()); - obj.add("drugUuid", drugInfo.getDrug().getUuid()); - obj.add("drugName", drugInfo.getDrug().getName()); - obj.add("description", drugInfo.getDescription()); - obj.add("shortName", drugInfo.getShortName()); - obj.add("brandName", drugInfo.getBrandName()); - obj.add("supplier", drugInfo.getSupplier()); - obj.add("manufacturer", drugInfo.getManufacturer()); - obj.add("price", drugInfo.getPrice()); - obj.add("reorderLevel", drugInfo.getReorderLevel()); - obj.add("cost", drugInfo.getCost()); - return obj; - } - - /** - * Get all the unvoided drug info (as REF representation) in the system - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unvoided Drug Info in the system") - @ResponseBody() - public String getAllDrugInfo(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugInfoController(); - List allDrugInfo = service.getAllDrugInfo(false); - ArrayList results = new ArrayList(); - for (DrugInfo drugInfo : allDrugInfo) { - results.add(getDrugInfoAsSimpleObject(drugInfo)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Get the DrugInfo - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Drug Info for the uuid path") - @ResponseBody() - public String getAllDrugInfoByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initDrugInfoController(); - DrugInfo drugInfo = service.getDrugInfoByUuid(uuid); - return gson.toJson(getDrugInfoAsSimpleObject(drugInfo)); - } - - /** - * Get the drug info as FULL representation - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET, params = "v") - @WSDoc("Gets Full representation of Drug Info for the uuid path") - @ResponseBody() - public String getAllDrugInfoByUuidFull(@PathVariable("uuid") String uuid, @RequestParam("v") String rep, - HttpServletRequest request) throws ResponseException { - initDrugInfoController(); - DrugInfo drugInfo = service.getDrugInfoByUuid(uuid); - SimpleObject obj = getDrugInfoAsSimpleObject(drugInfo); - if (rep.equals("full")) { - obj.add("retired", drugInfo.getRetired()); - if (drugInfo.getRetired()) { - obj.add("retiredBy", drugInfo.getRetiredBy().getUuid()); - obj.add("retireReason", drugInfo.getRetireReason()); - } - SimpleObject auditInfo = new SimpleObject(); - auditInfo.add("creator", drugInfo.getCreator().getUuid()); - auditInfo.add("dateCreated", df.format(drugInfo.getDateCreated())); - if (drugInfo.getChangedBy() != null) { - auditInfo.add("changedBy", drugInfo.getChangedBy().getUuid()); - auditInfo.add("dateChanged", df.format(drugInfo.getDateChanged())); - } - obj.add("auditInfo", auditInfo); - } - obj.add("resourceVersion", getResourceVersion()); - return gson.toJson(obj); - } - - /** - * Search Druginfo by drug name - * - * @param query the name to search for specific drug - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "drugname") - @WSDoc("Gets drug info by drug name") - @ResponseBody() - public String getDrugInfosByName(@RequestParam("drugname") String query, HttpServletRequest request) - throws ResponseException { - initDrugInfoController(); - List allDrugInfos = service.getDrugInfosByDrugName(query); - ArrayList results = new ArrayList(); - for (DrugInfo drugInfo : allDrugInfos) { - if (drugInfo != null) { - results.add(getDrugInfoAsSimpleObject(drugInfo)); - } - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Voids the drug info resource by making a DELETE call with the '!purge' - * param - * - * @param uuid - * @param reason - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "!purge") - @WSDoc("Retires the Drug Info") - @ResponseBody - public Object retireDrugInfo(@PathVariable("uuid") String uuid, - @RequestParam(value = "reason", defaultValue = "web service call") String reason, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initDrugInfoController(); - DrugInfo drugInfo = service.getDrugInfoByUuid(uuid); - if (drugInfo != null) { - drugInfo.setRetired(true); - drugInfo.setRetireReason(reason); - drugInfo.setRetiredBy(Context.getAuthenticatedUser()); - service.updateDrugInfo(drugInfo); - } - return RestUtil.noContent(response); - } - - /** - * Purges (Complete Delete) the drug info resource by making a DELETE call - * and passing the 'purge' param - * - * @param uuid - * @param request - * @param response - * @throws Exception - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "purge") - @ResponseBody - public Object purgeDrugInfo(@PathVariable("uuid") String uuid, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugInfoController(); - DrugInfo drugInfo = service.getDrugInfoByUuid(uuid); - if (drugInfo != null) { - service.deleteDrugInfo(drugInfo); - } - return RestUtil.noContent(response); - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInventoryController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInventoryController.java deleted file mode 100644 index fb5051e1f1..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInventoryController.java +++ /dev/null @@ -1,296 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.openmrs.Drug; -import org.openmrs.Location; -import org.openmrs.Provider; -import org.openmrs.User; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugInventoryService; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.DrugPurchaseOrderService; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the Drug Inventory resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/druginventory") -public class DrugInventoryController extends BaseRestController { - - DrugInventoryService service; - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "drugId", "quantity" }; - - public void initDrugInventoryController() { - service = Context.getService(DrugInventoryService.class); - } - - private String getResourceVersion() { - return "1.0"; - } - - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save DrugInventory") - @ResponseBody - public Object saveDrugInventory(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugInventoryController(); - DrugInventory drugInventory = setPostFields(post, new DrugInventory()); - DrugInventory created; - SimpleObject obj = obj = new SimpleObject(); - created = service.saveDrugInventory(drugInventory); - obj.add("uuid", created.getUuid()); - obj.add("drugId", created.getDrugId()); - obj.add("quantity", created.getQuantity()); - return RestUtil.created(response, obj); - } - - /** - * Helper function to get fields from POST and put into DrugInventory - */ - public DrugInventory setPostFields(SimpleObject post, DrugInventory drugInventory) { - if (post.get("name") != null) { - drugInventory.setName(post.get("name").toString()); - } - if (post.get("description") != null) { - drugInventory.setDescription(post.get("description").toString()); - } - if (post.get("drug") != null) { - Drug d = Context.getConceptService().getDrugByUuid(post.get("drug").toString()); - drugInventory.setDrugId(d.getDrugId()); - drugInventory.setDrug(d); - } - if (post.get("quantity") != null) { - drugInventory.setQuantity(Integer.parseInt(post.get("quantity").toString())); - } - if (post.get("originalQuantity") != null) { - drugInventory.setOriginalQuantity(Integer.parseInt(post.get("originalQuantity").toString())); - } - if (post.get("expiryDate") != null) { - String[] supportedFormats = { "EEE MMM dd yyyy HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss.SSSZ", - "yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(post.get("expiryDate").toString()); - drugInventory.setExpiryDate(date); - } - catch (Exception ex) {} - } - } - if (post.get("batch") != null) { - drugInventory.setBatch(post.get("batch").toString()); - } - if (post.get("supplier") != null) { - drugInventory.setSupplier(post.get("supplier").toString()); - } - if (post.get("value") != null) { - drugInventory.setValue(Integer.parseInt(post.get("value").toString())); - } - if (post.get("status") != null) { - drugInventory.setStatus(post.get("status").toString()); - } - if (post.get("roomLocation") != null) { - drugInventory.setRoomLocation(post.get("roomLocation").toString()); - } - if (post.get("provider") != null) { - Provider p = Context.getProviderService().getProviderByUuid(post.get("provider").toString()); - drugInventory.setProviderId(p.getId()); - drugInventory.setProvider(p); - } - if (post.get("location") != null) { - Location l = Context.getLocationService().getLocationByUuid(post.get("location").toString()); - drugInventory.setLocationId(l.getId()); - drugInventory.setLocation(l); - } - if (post.get("drugPurchaseOrder") != null) { - DrugPurchaseOrder dPO = Context.getService(DrugPurchaseOrderService.class).getDrugPurchaseOrderByUuid( - post.get("drugPurchaseOrder").toString()); - drugInventory.setDrugPurchaseOrderId(dPO.getId()); - drugInventory.setDrugPurchaseOrder(dPO); - } - return drugInventory; - } - - /** - * Helper function to return Drug Inventory to front end - * - * @param di - * @return SimpleObject the representation of Drug Inventory - */ - private SimpleObject getFieldsFromDrugInventory(DrugInventory di) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", di.getUuid()); - obj.add("name", di.getName()); - obj.add("description", di.getDescription()); - SimpleObject drugObj = new SimpleObject(); - Drug d = di.getDrug(); - if (d != null) { - drugObj.add("uuid", d.getUuid()); - drugObj.add("display", d.getName()); - if (d.getDosageForm() != null) { - drugObj.add("dosageForm", d.getDosageForm().getName().getName()); - } - } - obj.add("drug", drugObj); - obj.add("quantity", di.getQuantity()); - obj.add("originalQuantity", di.getOriginalQuantity()); - obj.add("expiryDate", di.getExpiryDate()); - obj.add("batch", di.getBatch()); - obj.add("supplier", di.getSupplier()); - obj.add("value", di.getValue()); - obj.add("status", di.getStatus()); - obj.add("roomLocation", di.getRoomLocation()); - SimpleObject pObj = new SimpleObject(); - Provider p = di.getProvider(); - if (p != null) { - pObj.add("uuid", p.getUuid()); - pObj.add("display", p.getName()); - } - obj.add("provider", pObj); - SimpleObject lObj = new SimpleObject(); - Location l = di.getLocation(); - if (l != null) { - lObj.add("uuid", l.getUuid()); - lObj.add("display", l.getName()); - } - obj.add("location", lObj); - SimpleObject dPOObj = new SimpleObject(); - DrugPurchaseOrder dPO = di.getDrugPurchaseOrder(); - if (dPO != null) { - dPOObj.add("uuid", dPO.getUuid()); - dPOObj.add("display", dPO.getName()); - } - obj.add("drugPurchaseOrder", dPOObj); - return obj; - } - - /** - * Gets drug inventory by uuid - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets drug inventory for the uuid path") - @ResponseBody() - public String getDrugInventoryByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initDrugInventoryController(); - DrugInventory drugInventory = service.getDrugInventoryByUuid(uuid); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drugInventory.getUuid()); - obj.add("drugId", drugInventory.getDrugId()); - obj.add("quantity", drugInventory.getQuantity()); - return gson.toJson(obj); - } - - /** - * Updates the Drug Inventory by making a POST call with uuid in URL - * - * @param uuid the uuid for the drug inventory resource - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing drug inventory") - @ResponseBody - public Object updateDrugInventory(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, - HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugInventoryController(); - DrugInventory di = service.getDrugInventoryByUuid(uuid); - di = setPostFields(post, di); - DrugInventory created = service.updateDrugInventory(di); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return gson.toJson(obj); - } - - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Drug Inventories in the system") - @ResponseBody() - public String getAllDrugInventories(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugInventoryController(); - List allDIs = service.getAllDrugInventories(); - ArrayList results = new ArrayList(); - for (DrugInventory di : allDIs) { - results.add(getFieldsFromDrugInventory(di)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Helper function that parses a list of Inventories, returns a JSon - */ - private String inventoryListToJson(List drugInventories) { - ArrayList results = new ArrayList(); - for (DrugInventory di : drugInventories) { - results.add(getFieldsFromDrugInventory(di)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Fetch Drug Inventories according to location - * - * @param location - * @param request - * @param response - * @return drug inventories for the given location - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "location") - @WSDoc("Fetch all non-retired inventories according to location") - @ResponseBody() - public String searchByLocation(@RequestParam("location") String location, HttpServletRequest request) - throws ResponseException { - initDrugInventoryController(); - List dIs = service.getDrugInventoriesByLocation(Context.getLocationService().getLocationByUuid( - location).getId()); - return inventoryListToJson(dIs); - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugPurchaseOrderController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugPurchaseOrderController.java deleted file mode 100644 index 52fd40b2e5..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/DrugPurchaseOrderController.java +++ /dev/null @@ -1,462 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.map.JsonMappingException; -import org.codehaus.jackson.map.ObjectMapper; -import org.openmrs.Drug; -import org.openmrs.Location; - -import org.openmrs.Provider; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugInventoryService; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.DrugPurchaseOrderService; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the DrugPurchaseOrder resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/drugpurchaseorder") -public class DrugPurchaseOrderController extends BaseRestController { - - DrugPurchaseOrderService service; - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "name", "providerId" }; - - public void initDrugPurchaseOrderController() { - service = Context.getService(DrugPurchaseOrderService.class); - } - - // - /** - * Returns the Resource Version - */ - private String getResourceVersion() { - return "1.0"; - } - - // - // - /** - * Create new drug purchase order by POST'ing atleast name and providerId property in the request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and DrugPurchaseOrder object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New DrugPurchaseOrder") - @ResponseBody - public Object createNewDrugPurchaseOrder(@RequestBody SimpleObject post, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initDrugPurchaseOrderController(); - - DrugPurchaseOrder purchaseOrder = setPostFields(post, new DrugPurchaseOrder()); - DrugPurchaseOrder created; - SimpleObject obj = obj = new SimpleObject(); - //if it is not a prescription, save it - //(we don't want prescriptions to show up in purchase order histories -- they will come as orders) - if (!purchaseOrder.getName().equals(DrugPurchaseOrder.PRESCRIPTIONNAME)) { - created = service.saveDrugPurchaseOrder(purchaseOrder); - saveOrUpdateDrugInventories(post, purchaseOrder); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - return RestUtil.created(response, obj); - } else { - saveOrUpdateDrugInventories(post, purchaseOrder); - return RestUtil.noContent(response); - } - } - - /** - * Updates the Purchase Order by making a POST call with uuid in URL - * - * @param uuid the uuid for the purchase order - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing purchase order") - @ResponseBody - public Object updateDrugPurchaseOrder(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, - HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugPurchaseOrderController(); - DrugPurchaseOrder dPO = service.getDrugPurchaseOrderByUuid(uuid); - dPO = setPostFields(post, dPO); - saveOrUpdateDrugInventories(post, dPO); - DrugPurchaseOrder created = service.updateDrugPurchaseOrder(dPO); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.noContent(response); - } - - /** - * Get the DrugPurchaseOrder - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets DrugPurchaseOrder for the uuid path") - @ResponseBody() - public String getDrugPuchaseOrderByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initDrugPurchaseOrderController(); - DrugPurchaseOrder drugOrder = service.getDrugPurchaseOrderByUuid(uuid); - SimpleObject obj = this.getFieldsFromDrugPurchaseOrder(drugOrder); - return gson.toJson(obj); - } - - /** - * Helper function to get fields from POST and put into purchaseOrder - */ - public DrugPurchaseOrder setPostFields(SimpleObject post, DrugPurchaseOrder purchaseOrder) { - if (post.get("name") != null) { - purchaseOrder.setName(post.get("name").toString()); - } - if (post.get("description") != null) { - purchaseOrder.setDescription(post.get("description").toString()); - } - if (post.get("received") != null) { - purchaseOrder.setReceived(Boolean.parseBoolean(post.get("received").toString())); - } - if (post.get("drugPurchaseOrderDate") != null) { - String[] supportedFormats = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(post.get("expiryDate").toString()); - purchaseOrder.setDrugPurchaseOrderDate(date); - } - catch (Exception ex) {} - } - } - if (post.get("provider") != null) { - Provider p = Context.getProviderService().getProviderByUuid(post.get("provider").toString()); - purchaseOrder.setProviderId(p.getId()); - purchaseOrder.setProvider(p); - } - if (post.get("dispenseLocation") != null) { - Location l = Context.getLocationService().getLocationByUuid(post.get("dispenseLocation").toString()); - purchaseOrder.setDispenseLocationId(l.getId()); - purchaseOrder.setDispenseLocation(l); - } - if (post.get("stockLocation") != null) { - Location l = Context.getLocationService().getLocationByUuid(post.get("stockLocation").toString()); - purchaseOrder.setStockLocationId(l.getId()); - purchaseOrder.setStockLocation(l); - } - return purchaseOrder; - } - - /** - * Helper function to create drug inventories from drug purchase order - */ - private void saveOrUpdateDrugInventories(SimpleObject post, DrugPurchaseOrder purchaseOrder) throws ResponseException { - if (post.get("inventories") != null) { - List inventoryObjects = (List) post.get("inventories"); - //need to differentiate between inventories we are creating, and ones we are updating - List newInventories = new ArrayList(); - List updateInventories = new ArrayList(); - List updateBatches = new ArrayList(); - for (int i = 0; i < inventoryObjects.size(); i++) { - //whether or not current inventory is new or an update - boolean update = false; - DrugInventory di = new DrugInventory(); - if (inventoryObjects.get(i).get("uuid") != null) { - System.out.println("getting existing uuid"); - di = Context.getService(DrugInventoryService.class).getDrugInventoryByUuid( - inventoryObjects.get(i).get("uuid").toString()); - update = true; - } - setDrugInventoryFields(di, inventoryObjects.get(i)); - di.setDrugPurchaseOrder(purchaseOrder); - di.setDrugPurchaseOrderId(purchaseOrder.getId()); - if (inventoryObjects.get(i).get("batchUuid") != null) { - DrugInventory batchDrugInv = Context.getService(DrugInventoryService.class).getDrugInventoryByUuid( - inventoryObjects.get(i).get("batchUuid").toString()); - if (batchDrugInv == null) { - throw new ResponseException( - "Batch uuid not found") {}; - } - if (batchDrugInv.getQuantity() < di.getQuantity()) { - throw new ResponseException( - "Requested quantity cannot exceed batch quantity") {}; - } - batchDrugInv.setQuantity(batchDrugInv.getQuantity() - di.getQuantity()); - if (batchDrugInv.getQuantity() == 0) - batchDrugInv.setStatus("out"); - updateBatches.add(batchDrugInv); - } - if (update) { - updateInventories.add(di); - } else { - newInventories.add(di); - } - } - if (!purchaseOrder.getName().equals(DrugPurchaseOrder.PRESCRIPTIONNAME)) { - for (int n = 0; n < newInventories.size(); n++) { - Context.getService(DrugInventoryService.class).saveDrugInventory(newInventories.get(n)); - } - for (int n = 0; n < updateInventories.size(); n++) { - Context.getService(DrugInventoryService.class).updateDrugInventory(updateInventories.get(n)); - } - } - for (int n = 0; n < updateBatches.size(); n++) { - Context.getService(DrugInventoryService.class).updateDrugInventory(updateBatches.get(n)); - } - - } - } - - /** - * Helper function to manually set the field for a Drug Inventory this manual setting should be done with a - * Resource, however a bug exists in OpenMRS: https://tickets.openmrs.org/browse/TRUNK-2205 - */ - private void setDrugInventoryFields(DrugInventory drugInventory, LinkedHashMap postFields) throws ResponseException { - if (postFields.get("name") != null) { - drugInventory.setName(postFields.get("name").toString()); - } - if (postFields.get("description") != null) { - drugInventory.setDescription(postFields.get("description").toString()); - } - if (postFields.get("drug") != null) { - Drug d = Context.getConceptService().getDrugByUuid(postFields.get("drug").toString()); - if (d == null) { - throw new ResponseException( - "Drug uuid not found") {}; - } - drugInventory.setDrugId(d.getDrugId()); - drugInventory.setDrug(d); - } - if (postFields.get("quantity") != null) { - drugInventory.setQuantity(Integer.parseInt(postFields.get("quantity").toString())); - } - if (postFields.get("originalQuantity") != null) { - drugInventory.setOriginalQuantity(Integer.parseInt(postFields.get("originalQuantity").toString())); - } - if (postFields.get("expiryDate") != null) { - Date date = null; - String[] supportedFormats = { "EEE MMM dd yyyy HH:mm:ss z (zzzz)", "EEE MMM dd yyyy HH:mm:ss z (zzzz)", - "MMM dd, yyyy HH:mm:ss a", "EEE MMM dd yyyy HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss.SSSZ", - "yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - date = new SimpleDateFormat(supportedFormats[i]).parse(postFields.get("expiryDate").toString()); - drugInventory.setExpiryDate(date); - } - catch (Exception ex) {} - } - if (date == null) { - throw new ResponseException( - "Invalid date " + postFields.get("expiryDate")) {}; - } - } - if (postFields.get("batch") != null) { - drugInventory.setBatch(postFields.get("batch").toString()); - } - if (postFields.get("supplier") != null) { - drugInventory.setSupplier(postFields.get("supplier").toString()); - } - if (postFields.get("roomLocation") != null) { - drugInventory.setRoomLocation(postFields.get("roomLocation").toString()); - } - if (postFields.get("value") != null) { - drugInventory.setValue(Integer.parseInt(postFields.get("value").toString())); - } - if (postFields.get("status") != null) { - drugInventory.setStatus(postFields.get("status").toString()); - } - if (postFields.get("provider") != null) { - Provider p = Context.getProviderService().getProviderByUuid(postFields.get("provider").toString()); - if (p == null) { - throw new ResponseException( - "Provider uuid not found") {}; - } - drugInventory.setProviderId(p.getId()); - drugInventory.setProvider(p); - } - if (postFields.get("location") != null) { - Location l = Context.getLocationService().getLocationByUuid(postFields.get("location").toString()); - if (l == null) { - throw new ResponseException( - "Location uuid not found") {}; - } - drugInventory.setLocationId(l.getId()); - drugInventory.setLocation(l); - } - if (postFields.get("drugPurchaseOrder") != null) { - DrugPurchaseOrder dPOrder = Context.getService(DrugPurchaseOrderService.class).getDrugPurchaseOrderByUuid( - postFields.get("drugPurchaseOrder").toString()); - if (dPOrder == null) { - throw new ResponseException( - "DrugPurchaseOrder uuid not found") {}; - } - drugInventory.setDrugPurchaseOrderId(dPOrder.getId()); - drugInventory.setDrugPurchaseOrder(dPOrder); - } - } - - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Drug Purchase Orders in the system") - @ResponseBody() - public String getAllDrugPurchaseOrders(HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugPurchaseOrderController(); - List allDPOs = service.getAllDrugPurchaseOrders(); - return purchaseOrderListToJson(allDPOs); - } - - /** - * Fetch Drug Purchase Orders according to stockLocation - * - * @param stockLocation - * @param request - * @param response - * @return drug purchase orders for the given stockLocation - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "stockLocation") - @WSDoc("Fetch all non-retired drug purchase orders according to stockLocation") - @ResponseBody() - public String searchByStockLocation(@RequestParam("stockLocation") String stockLocation, HttpServletRequest request) - throws ResponseException { - initDrugPurchaseOrderController(); - List dPOs = service.getDrugPurchaseOrderByStockLocation(Context.getLocationService() - .getLocationByUuid(stockLocation).getId()); - return purchaseOrderListToJson(dPOs); - } - - /** - * Helper function that parses a list of Inventories, returns a JSon - */ - private String purchaseOrderListToJson(List drugPurchaseOrders) { - ArrayList results = new ArrayList(); - for (DrugPurchaseOrder dpo : drugPurchaseOrders) { - results.add(getFieldsFromDrugPurchaseOrder(dpo)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Helper function to return Drug Purchase Order to front end - * - * @param dpo - * @return SimpleObject the representation of Drug Inventory - */ - private SimpleObject getFieldsFromDrugPurchaseOrder(DrugPurchaseOrder dpo) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", dpo.getUuid()); - obj.add("name", dpo.getName()); - obj.add("description", dpo.getDescription()); - obj.add("received", dpo.isReceived()); - SimpleObject pObj = new SimpleObject(); - Provider p = dpo.getProvider(); - if (p != null) { - pObj.add("uuid", p.getUuid()); - pObj.add("display", p.getName()); - } - obj.add("provider", pObj); - obj.add("date", dpo.getDrugPurchaseOrderDate()); - SimpleObject dispenseObj = new SimpleObject(); - Location dispenseLoc = dpo.getDispenseLocation(); - if (dispenseLoc != null) { - dispenseObj.add("uuid", dispenseLoc.getUuid()); - dispenseObj.add("display", dispenseLoc.getName()); - } - obj.add("dispenseLocation", dispenseObj); - SimpleObject stockObj = new SimpleObject(); - Location stockLoc = dpo.getStockLocation(); - if (stockLoc != null) { - stockObj.add("uuid", stockLoc.getUuid()); - stockObj.add("display", stockLoc.getName()); - } - obj.add("stockLocation", stockObj); - //getting all associated drug inventories: - List inventories = Context.getService(DrugInventoryService.class) - .getDrugInventoriesByDrugPurchaseOrder(dpo.getId()); - if (!inventories.isEmpty()) { - ArrayList invObjs = new ArrayList(); - //List invObjs = new ArrayList(); - for (int i = 0; i < inventories.size(); i++) { - SimpleObject newInvObj = new SimpleObject(); - newInvObj.add("name", inventories.get(i).getName()); - newInvObj.add("description", inventories.get(i).getDescription()); - newInvObj.add("uuid", inventories.get(i).getUuid()); - SimpleObject drugObj = new SimpleObject(); - Drug d = inventories.get(i).getDrug(); - if (d != null) { - drugObj.add("uuid", d.getUuid()); - drugObj.add("display", d.getName()); - } - newInvObj.add("drug", drugObj); - newInvObj.add("quantity", inventories.get(i).getQuantity()); - newInvObj.add("originalQuantity", inventories.get(i).getOriginalQuantity()); - newInvObj.add("expiryDate", inventories.get(i).getExpiryDate()); - newInvObj.add("batch", inventories.get(i).getBatch()); - newInvObj.add("supplier", inventories.get(i).getSupplier()); - newInvObj.add("roomLocation", inventories.get(i).getRoomLocation()); - newInvObj.add("value", inventories.get(i).getValue()); - newInvObj.add("status", inventories.get(i).getStatus()); - SimpleObject providerObj = new SimpleObject(); - Provider provider = inventories.get(i).getProvider(); - if (provider != null) { - providerObj.add("uuid", provider.getUuid()); - providerObj.add("display", provider.getName()); - } - newInvObj.add("provider", providerObj); - SimpleObject locObj = new SimpleObject(); - Location l = inventories.get(i).getLocation(); - if (l != null) { - locObj.add("uuid", l.getUuid()); - locObj.add("display", l.getName()); - } - newInvObj.add("location", locObj); - invObjs.add(newInvObj); - } - obj.add("inventories", invObjs); - } - return obj; - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/PatientListController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/PatientListController.java deleted file mode 100644 index e063763319..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/PatientListController.java +++ /dev/null @@ -1,620 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Encounter; -import org.openmrs.Obs; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the PatientList resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/patientlist") -public class PatientListController extends BaseRestController { - - PatientListService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "name", "description" }; - - public void initPatientListController() { - service = Context.getService(PatientListService.class); - } - - // - /** - * Returns the Resource Version - */ - private String getResourceVersion() { - return "1.0"; - } - - // - - // - /** - * Create new patient list by POST'ing atleast name and description property - * in the request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and PatientList object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New PatientList") - @ResponseBody - public Object createNewPatientList(@RequestBody SimpleObject post, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initPatientListController(); - PatientList patientList = new PatientList(); - patientList.setName(post.get("name").toString()); - patientList.setDescription(post.get("description").toString()); - if (post.get("searchQuery") != null) { - patientList.setSearchQuery(post.get("searchQuery").toString()); - } - PatientList created = service.savePatientList(patientList); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.created(response, obj); - } - - // - - // - /** - * Updates the Patient List by making a POST call with uuid in URL - * and - * - * @param uuid the uuid for the patient list resource - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing patient list") - @ResponseBody - public Object updatePatientList(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, - HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initPatientListController(); - PatientList patientList = service.getPatientListByUuid(uuid); - patientList.setName(post.get("name").toString()); - patientList.setDescription(post.get("description").toString()); - if (post.get("searchQuery") != null) { - patientList.setSearchQuery(post.get("searchQuery").toString()); - } - PatientList created = service.updatePatientList(patientList); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.noContent(response); - } - - // - - // - /** - * Get all the unretired patient lists (as REF representation) in the system - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Patient Lists in the system") - @ResponseBody() - public String getAllPatientLists(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initPatientListController(); - List allPatientList = service.getAllPatientList(false); - ArrayList results = new ArrayList(); - for (PatientList patientList : allPatientList) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", patientList.getUuid()); - obj.add("name", patientList.getName()); - obj.add("description", patientList.getDescription()); - results.add(obj); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - // - - // - /** - * Search PatientList by Name and get the resource as REF representation - * - * @param query the string to search name of patientlist - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "q") - @WSDoc("Gets Patient Lists by name") - @ResponseBody() - public String getPatientListsByName(@RequestParam("q") String query, HttpServletRequest request) - throws ResponseException { - initPatientListController(); - List allPatientList = service.getPatientListByName(query); - ArrayList results = new ArrayList(); - for (PatientList patientList : allPatientList) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", patientList.getUuid()); - obj.add("name", patientList.getName()); - obj.add("description", patientList.getDescription()); - results.add(obj); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - // - - // - /** - * Get the Patientlist along with patients, encounters and obs (DEFAULT rep). - * Contains all encounters of the searched encounterType between the startDate - * and endDate - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Patient Lists for the uuid path") - @ResponseBody() - public String getAllPatientListByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initPatientListController(); - PatientList patientList = service.getPatientListByUuid(uuid); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", patientList.getUuid()); - obj.add("name", patientList.getName()); - obj.add("description", patientList.getDescription()); - ArrayList patients = new ArrayList(); - List patientsInPatientList = service.getPatientsInPatientList(patientList); - for (Patient p : patientsInPatientList) { - SimpleObject patient = new SimpleObject(); - patient.add("uuid", p.getUuid()); - patient.add("display", p.getPersonName().getFullName()); - patient.add("gender", p.getGender()); - patient.add("age", p.getAge()); - ArrayList encounters = new ArrayList(); - List encountersInPatientList = service.getEncountersInPatientList(patientList); - for (Encounter e : encountersInPatientList) { - if (e.getPatient().equals(p)) { - SimpleObject encounter = new SimpleObject(); - encounter.add("uuid", e.getUuid()); - encounter.add("display", e.getEncounterType().getName() + " - " + e.getEncounterDatetime()); - encounter.add("encounterType", e.getEncounterType().getUuid()); - encounter.add("encounterDatetime", df.format(e.getEncounterDatetime())); - ArrayList obsArray = new ArrayList(); - Set obsAll = e.getObs(); - for (Obs o : obsAll) { - SimpleObject obs = new SimpleObject(); - obs.add("uuid", o.getUuid()); - obs.add("display", o.getConcept().getName().getName() + " = " - + o.getValueAsString(request.getLocale())); - obs.add("obsDatetime", df.format(o.getObsDatetime())); - obs.add("value", o.getValueAsString(request.getLocale())); - obsArray.add(obs); - } - encounter.add("obs", obsArray); - encounters.add(encounter); - } - } - patient.add("encounters", encounters); - patients.add(patient); - } - obj.add("patients", patients); - return gson.toJson(obj); - } - - // - - // - /** - * Get the patient list as FULL representation that shows patients, encounters and obs. - * Contains all encounters of the searched encounterType between the startDate - * and endDate. Contains patientList.searchQuery, encounter.provider and obs.comment - * and obs.order compared to DEFAULT rep - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET, params = "v") - @WSDoc("Gets Full representation of Patient Lists for the uuid path") - @ResponseBody() - public String getAllPatientListByUuidFull(@PathVariable("uuid") String uuid, @RequestParam("v") String rep, - HttpServletRequest request) throws ResponseException { - initPatientListController(); - PatientList patientList = service.getPatientListByUuid(uuid); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", patientList.getUuid()); - obj.add("name", patientList.getName()); - obj.add("description", patientList.getDescription()); - obj.add("searchQuery", patientList.getSearchQuery()); - ArrayList patients = new ArrayList(); - List patientsInPatientList = service.getPatientsInPatientList(patientList); - for (Patient p : patientsInPatientList) { - SimpleObject patient = new SimpleObject(); - patient.add("uuid", p.getUuid()); - patient.add("display", p.getPersonName().getFullName()); - patient.add("gender", p.getGender()); - patient.add("age", p.getAge()); - ArrayList encounters = new ArrayList(); - List encountersInPatientList = service.getEncountersInPatientList(patientList); - for (Encounter e : encountersInPatientList) { - if (e.getPatient().equals(p)) { - SimpleObject encounter = new SimpleObject(); - encounter.add("uuid", e.getUuid()); - encounter.add("display", e.getEncounterType().getName() + " - " + e.getEncounterDatetime()); - encounter.add("encounterType", e.getEncounterType().getUuid()); - encounter.add("encounterDatetime", df.format(e.getEncounterDatetime())); - if (e.getProvider() != null) { - encounter.add("provider", e.getProvider().getUuid()); - } else { - encounter.add("provider", null); - } - ArrayList obsArray = new ArrayList(); - Set obsAll = e.getObs(); - for (Obs o : obsAll) { - SimpleObject obs = new SimpleObject(); - obs.add("uuid", o.getUuid()); - obs.add("display", o.getConcept().getName().getName() + " = " - + o.getValueAsString(request.getLocale())); - obs.add("obsDatetime", df.format(o.getObsDatetime())); - obs.add("value", o.getValueAsString(request.getLocale())); - obs.add("comment", o.getComment()); - if (o.getOrder() != null) { - obs.add("order", o.getOrder().getUuid()); - } else { - obs.add("order", null); - } - obsArray.add(obs); - } - encounter.add("obs", obsArray); - encounters.add(encounter); - } - } - patient.add("encounters", encounters); - patients.add(patient); - } - obj.add("patients", patients); - if (rep.equals("full")) { - obj.add("retired", patientList.getRetired()); - if (patientList.getRetired()) { - obj.add("retiredBy", patientList.getRetiredBy().getUuid()); - obj.add("retireReason", patientList.getRetireReason()); - } - SimpleObject auditInfo = new SimpleObject(); - auditInfo.add("creator", patientList.getCreator().getUuid()); - auditInfo.add("dateCreated", df.format(patientList.getDateCreated())); - if (patientList.getChangedBy() != null) { - auditInfo.add("changedBy", patientList.getChangedBy().getUuid()); - auditInfo.add("dateChanged", df.format(patientList.getDateChanged())); - } - obj.add("auditInfo", auditInfo); - } - obj.add("resourceVersion", getResourceVersion()); - return gson.toJson(obj); - } - - // - - // - /** - * This is the on-the-fly generated patient list, by passing the searchQuery - * as part of the resource URL as params. encounterType is required param. - * Gives the FULL rep for the Patient list resource. - * - * @param params - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "encounterType") - @WSDoc("Gets Patients Without Saving the Patient list") - @ResponseBody() - public String getPatientsInPatientList(@RequestParam Map params, HttpServletRequest request) - throws ResponseException { - initPatientListController(); - PatientList patientList = new PatientList(); - patientList.setSearchQuery("?" + Joiner.on("&").withKeyValueSeparator("=").join(params)); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", patientList.getUuid()); - obj.add("name", patientList.getName()); - obj.add("description", patientList.getDescription()); - obj.add("searchQuery", patientList.getSearchQuery()); - ArrayList patients = new ArrayList(); - List patientsInPatientList = service.getPatientsInPatientList(patientList); - for (Patient p : patientsInPatientList) { - SimpleObject patient = new SimpleObject(); - patient.add("uuid", p.getUuid()); - patient.add("display", p.getPersonName().getFullName()); - patient.add("gender", p.getGender()); - patient.add("age", p.getAge()); - ArrayList encounters = new ArrayList(); - List encountersInPatientList = service.getEncountersInPatientList(patientList); - for (Encounter e : encountersInPatientList) { - if (e.getPatient().equals(p)) { - SimpleObject encounter = new SimpleObject(); - encounter.add("uuid", e.getUuid()); - encounter.add("display", e.getEncounterType().getName() + " - " + e.getEncounterDatetime()); - encounter.add("encounterType", e.getEncounterType().getUuid()); - encounter.add("encounterDatetime", df.format(e.getEncounterDatetime())); - if (e.getProvider() != null) { - encounter.add("provider", e.getProvider().getUuid()); - } else { - encounter.add("provider", null); - } - ArrayList obsArray = new ArrayList(); - Set obsAll = e.getObs(); - for (Obs o : obsAll) { - SimpleObject obs = new SimpleObject(); - obs.add("uuid", o.getUuid()); - obs.add("display", o.getConcept().getName().getName() + " = " - + o.getValueAsString(request.getLocale())); - obs.add("obsDatetime", df.format(o.getObsDatetime())); - obs.add("value", o.getValueAsString(request.getLocale())); - obs.add("comment", o.getComment()); - if (o.getOrder() != null) { - obs.add("order", o.getOrder().getUuid()); - } else { - obs.add("order", null); - } - obsArray.add(obs); - } - encounter.add("obs", obsArray); - encounters.add(encounter); - } - } - patient.add("encounters", encounters); - patients.add(patient); - } - obj.add("patients", patients); - obj.add("resourceVersion", getResourceVersion()); - return gson.toJson(obj); - } - - // - - // - /** - * This is the on-the-fly generated patient list, by passing the searchQuery - * as part of the resource URL as params. encounterType is required param. - * Gives the FULL rep for the Patient list resource. - * Now optimized into one call - * - * @param params - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/optimized", method = RequestMethod.GET, params = "encounterType") - @WSDoc("Gets Patients Without Saving the Patient list") - @ResponseBody() - public String getPatientsInPatientListV2(@RequestParam Map params, HttpServletRequest request) - throws ResponseException { - initPatientListController(); - //?encounterType=<>&startDate=<>&endDate=<>&excludeEncounterType=<>.... - //placeholder until service code is re-written - String inListQuery = ("?encounterType=" + params.get("encounterType") + "&startDate=" + params.get("startDate") - + "&endDate=" + params.get("endDate")); - if (params.get("patient") != null) { - inListQuery += "&patient=" + params.get("patient"); - } - if (params.get("provider") != null) { - inListQuery += "&provider=" + params.get("provider"); - } - if (params.get("location") != null) { - inListQuery += "&location=" + params.get("location"); - } - if (params.get("containsOrderType") != null) { - inListQuery += "&containsOrderType=" + params.get("containsOrderType"); - } - String notInListQuery = ("?encounterType=" + params.get("excludeEncounterType") + "&startDate=" - + params.get("startDate") + "&endDate=" + params.get("endDate")); - if (params.get("patient") != null) { - notInListQuery += "&patient=" + params.get("patient"); - } - if (params.get("provider") != null) { - notInListQuery += "&provider=" + params.get("provider"); - } - if (params.get("location") != null) { - notInListQuery += "&location=" + params.get("location"); - } - if (params.get("containsOrderType") != null) { - notInListQuery += "&containsOrderType=" + params.get("containsOrderType"); - } - PatientList inList = new PatientList(); - inList.setSearchQuery(inListQuery); - inList = service.savePatientList(inList); - - PatientList notInList = new PatientList(); - notInList.setSearchQuery(notInListQuery); - notInList = service.savePatientList(notInList); - - String finalQuery = ("?encounterType=" + params.get("encounterType") + "&inList=" + inList.getUuid() + "¬InList=" + notInList - .getUuid()); - - PatientList patientList = new PatientList(); - patientList.setSearchQuery(finalQuery); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", patientList.getUuid()); - obj.add("name", patientList.getName()); - obj.add("description", patientList.getDescription()); - obj.add("searchQuery", patientList.getSearchQuery()); - ArrayList patients = new ArrayList(); - List patientsInPatientList = service.getPatientsInPatientList(patientList); - List encountersInPatientList = service.getEncountersInPatientList(patientList); - - for (Patient p : patientsInPatientList) { - SimpleObject patient = new SimpleObject(); - patient.add("uuid", p.getUuid()); - SimpleObject person = new SimpleObject(); - person.add("uuid", p.getUuid()); - person.add("display", p.getPersonName().getFullName()); - SimpleObject name = new SimpleObject(); - name.add("display", p.getPersonName().getFullName()); - person.add("preferredName", name); - person.add("gender", p.getGender()); - person.add("age", p.getAge()); - patient.add("person", person); - ArrayList identifiers = new ArrayList(); - SimpleObject id = new SimpleObject(); - id.add("identifier", p.getPatientIdentifier().getIdentifier()); - identifiers.add(id); - patient.add("identifiers", identifiers); - //patient.add("identifiers", p.getActiveIdentifiers()); - ArrayList encounters = new ArrayList(); - //TODO: refactor this so we don't have to go through each time - for (Encounter e : encountersInPatientList) { - if (e.getPatient().equals(p)) { - SimpleObject encounter = new SimpleObject(); - encounter.add("uuid", e.getUuid()); - encounter.add("display", e.getEncounterType().getName() + " - " + e.getEncounterDatetime()); - encounter.add("encounterType", e.getEncounterType().getUuid()); - encounter.add("encounterDatetime", df.format(e.getEncounterDatetime())); - if (e.getProvider() != null) { - encounter.add("provider", e.getProvider().getUuid()); - } else { - encounter.add("provider", null); - } - if (params.get("containsOrderType") != null) { - encounter.add("obs", null); - } else { - ArrayList obsArray = new ArrayList(); - Set obsAll = e.getObs(); - for (Obs o : obsAll) { - SimpleObject obs = new SimpleObject(); - obs.add("uuid", o.getUuid()); - obs.add("display", o.getConcept().getName().getName() + " = " - + o.getValueAsString(request.getLocale())); - obs.add("obsDatetime", df.format(o.getObsDatetime())); - obs.add("value", o.getValueAsString(request.getLocale())); - obs.add("comment", o.getComment()); - if (o.getOrder() != null) { - obs.add("order", o.getOrder().getUuid()); - } else { - obs.add("order", null); - } - obsArray.add(obs); - } - encounter.add("obs", obsArray); - } - encounters.add(encounter); - } - } - patient.add("encounters", encounters); - patients.add(patient); - } - obj.add("patients", patients); - obj.add("resourceVersion", getResourceVersion()); - return gson.toJson(obj); - } - - // - /** - * Retires the patient list resource by making a DELETE call with the '!purge' param - * - * @param uuid - * @param reason - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "!purge") - @WSDoc("Retires the Patient List") - @ResponseBody - public Object retirePatientList(@PathVariable("uuid") String uuid, - @RequestParam(value = "reason", defaultValue = "web service call") String reason, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initPatientListController(); - PatientList patientList = service.getPatientListByUuid(uuid); - if (patientList != null) { - patientList.setRetired(true); - patientList.setRetireReason(reason); - patientList.setRetiredBy(Context.getAuthenticatedUser()); - service.updatePatientList(patientList); - } - return RestUtil.noContent(response); - } - - // - - // - /** - * Purges (Complete Delete) the patient list resource by making a DELETE - * call and passing the 'purge' param - * - * @param uuid - * @param request - * @param response - * @throws Exception - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "purge") - @ResponseBody - public Object purgePatientList(@PathVariable("uuid") String uuid, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initPatientListController(); - PatientList patientList = service.getPatientListByUuid(uuid); - if (patientList != null) { - service.deletePatientList(patientList); - } - return RestUtil.noContent(response); - } - // -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaAlertController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaAlertController.java deleted file mode 100644 index c5fbdd99dd..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaAlertController.java +++ /dev/null @@ -1,328 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Location; -import org.openmrs.Patient; -import org.openmrs.Provider; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseCrudController; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.RaxaAlert; -import org.raxa.module.raxacore.RaxaAlertService; -import org.raxa.module.raxacore.web.v1_0.resource.RaxaAlertResource; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the RaxaAlert resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/raxaalert") -public class RaxaAlertController { - - RaxaAlertService service; - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "name", "description" }; - - /** - * Before each function, initialize our service - */ - public void initRaxaAlertController() { - service = Context.getService(RaxaAlertService.class); - } - - /** - * Create new Raxa Alert by POST'ing atleast name and description property in the request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and PatientList object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New RaxaAlert") - @ResponseBody - public Object createNewRaxaAlert(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initRaxaAlertController(); - RaxaAlert raxaAlert = setPostFields(new RaxaAlert(), post); - raxaAlert.setSeen(Boolean.FALSE); - RaxaAlert created = service.saveRaxaAlert(raxaAlert); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.created(response, obj); - } - - /** - * Helper function to set fields from a POST call - * - * @param rAlert our Raxa Alert to change - * @param post our REST call - * @return the changed raxa alert - */ - private RaxaAlert setPostFields(RaxaAlert raxaAlert, SimpleObject post) { - if (post.get("providerRecipient") != null) { - Provider pRecipient = Context.getProviderService().getProviderByUuid(post.get("providerRecipient").toString()); - raxaAlert.setProviderRecipientId(pRecipient.getId()); - raxaAlert.setProviderRecipient(pRecipient); - } - if (post.get("providerSent") != null) { - Provider pSender = Context.getProviderService().getProviderByUuid(post.get("providerSent").toString()); - raxaAlert.setProviderSentId(pSender.getId()); - raxaAlert.setProviderSent(pSender); - } - if (post.get("toLocation") != null) { - Location toLocation = Context.getLocationService().getLocationByUuid(post.get("toLocation").toString()); - raxaAlert.setToLocationId(toLocation.getId()); - raxaAlert.setToLocation(toLocation); - } - if (post.get("fromLocation") != null) { - Location fromLocation = Context.getLocationService().getLocationByUuid(post.get("fromLocation").toString()); - raxaAlert.setFromLocationId(fromLocation.getId()); - raxaAlert.setFromLocation(fromLocation); - } - if (post.get("patient") != null) { - Patient patient = Context.getPatientService().getPatientByUuid(post.get("patient").toString()); - raxaAlert.setPatientId(patient.getId()); - raxaAlert.setPatient(patient); - } - if (post.get("name") != null) { - raxaAlert.setName(post.get("name").toString()); - } - if (post.get("description") != null) { - raxaAlert.setDescription(post.get("description").toString()); - } - if (post.get("alertType") != null) { - raxaAlert.setAlertType(post.get("alertType").toString()); - } - if (post.get("defaultTask") != null) { - raxaAlert.setDefaultTask(post.get("defaultTask").toString()); - } - if (post.get("seen") != null) { - raxaAlert.setSeen(Boolean.parseBoolean(post.get("seen").toString())); - } - if (post.get("time") != null) { - String[] supportedFormats = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(post.get("time").toString()); - raxaAlert.setTime(date); - } - catch (Exception ex) {} - } - } - return raxaAlert; - } - - /** - * - * @param rAlert - * @return SimpleObject the representation of Raxa Alert - */ - private SimpleObject getFieldsFromRaxaAlert(RaxaAlert rAlert) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", rAlert.getUuid()); - obj.add("name", rAlert.getName()); - obj.add("description", rAlert.getDescription()); - SimpleObject pRecipientObj = new SimpleObject(); - Provider pRecipient = rAlert.getProviderRecipient(); - if (pRecipient != null) { - pRecipientObj.add("uuid", pRecipient.getUuid()); - pRecipientObj.add("display", pRecipient.getName()); - } - obj.add("providerRecipient", pRecipientObj); - SimpleObject pSentObj = new SimpleObject(); - Provider pSent = rAlert.getProviderSent(); - if (pSent != null) { - pSentObj.add("uuid", pSent.getUuid()); - pSentObj.add("display", pSent.getName()); - } - obj.add("providerSent", pSentObj); - SimpleObject toLocationObj = new SimpleObject(); - Location toLocation = rAlert.getToLocation(); - if (toLocation != null) { - toLocationObj.add("uuid", toLocation.getUuid()); - toLocationObj.add("display", toLocation.getName()); - } - obj.add("toLocation", toLocationObj); - SimpleObject fromLocationObj = new SimpleObject(); - Location fromLocation = rAlert.getFromLocation(); - if (fromLocation != null) { - fromLocationObj.add("uuid", fromLocation.getUuid()); - fromLocationObj.add("display", fromLocation.getName()); - } - obj.add("fromLocation", fromLocationObj); - obj.add("alertType", rAlert.getAlertType()); - obj.add("defaultTask", rAlert.getDefaultTask()); - obj.add("seen", rAlert.getSeen()); - obj.add("time", rAlert.getTime()); - return obj; - } - - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Raxa Alerts in the system") - @ResponseBody() - public String getAllRaxaAlerts(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initRaxaAlertController(); - List allRaxaAlert = service.getAllRaxaAlerts(true); - ArrayList results = new ArrayList(); - for (RaxaAlert raxaAlert : allRaxaAlert) { - results.add(getFieldsFromRaxaAlert(raxaAlert)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Fetch raxa alerts according to provider - * - * @param providerRecipient - * @param request - * @param response - * @return encounters for the given patient - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "providerRecipient") - @WSDoc("Fetch all non-retired alerts according to providerRecipient") - @ResponseBody() - public String searchByProviderRecipient(@RequestParam("providerRecipient") String providerRecipient, - HttpServletRequest request) throws ResponseException { - initRaxaAlertController(); - return alertListToJson(service.getRaxaAlertByProviderRecipientUuid(providerRecipient, false)); - } - - /** - * Fetch raxa alerts according to provider - * - * @param providerRecipient - * @param request - * @param response - * @return encounters for the given patient - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "toLocation") - @WSDoc("Fetch all non-retired alerts according to toLocation") - @ResponseBody() - public String searchByToLocation(@RequestParam("toLocation") String toLocation, HttpServletRequest request) - throws ResponseException { - initRaxaAlertController(); - return alertListToJson(service.getRaxaAlertByToLocationUuid(toLocation, false)); - } - - /** - * Helper function that parses a list of Raxa Alerts, returns a JSon - */ - private String alertListToJson(List raxaAlerts) { - ArrayList results = new ArrayList(); - for (RaxaAlert raxaAlert : raxaAlerts) { - results.add(getFieldsFromRaxaAlert(raxaAlert)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Updates the Raxa Alert by making a POST call with uuid in URL - * - * @param uuid the uuid for the raxa alert resource - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing raxa alert") - @ResponseBody - public Object updateRaxaAlert(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, - HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initRaxaAlertController(); - RaxaAlert rAlert = service.getRaxaAlertByUuid(uuid); - rAlert = setPostFields(rAlert, post); - RaxaAlert created = service.updateRaxaAlert(rAlert); - SimpleObject obj = new SimpleObject(); - obj.add("uuid", created.getUuid()); - obj.add("name", created.getName()); - obj.add("description", created.getDescription()); - return RestUtil.noContent(response); - } - - /** - * Get the Raxa Alert by uuid - * @param uuid - * @param request - * @return response string - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Raxa Alert for the given uuid") - @ResponseBody() - public String getRaxaAlertByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) throws ResponseException { - initRaxaAlertController(); - RaxaAlert rAlert = service.getRaxaAlertByUuid(uuid); - return gson.toJson(getFieldsFromRaxaAlert(rAlert)); - } - -} -//Currently a bug exists in serializer that won't allow us to use resources automatically -////http://tickets.openmrs.org/browse/TRUNK-2205 -//@Controller -//@RequestMapping(value = "/rest/v1/raxacore/raxaalert") -//public class RaxaAlertController extends BaseCrudController { -// -// /** -// * Fetch encounters for a given patient -// * @param patientUniqueId -// * @param request -// * @param response -// * @return encounters for the given patient -// * @throws ResponseException -// */ -// @RequestMapping(method = RequestMethod.GET, params = "provider") -// @WSDoc("Fetch all non-retired alerts for a provider with the given uuid") -// @ResponseBody -// public SimpleObject searchByPatient(@RequestParam("provider") String providerUniqueId, HttpServletRequest request, -// HttpServletResponse response) throws ResponseException { -// RaxaAlertResource raxaAlertResource = getResource(); -// RequestContext context = RestUtil.getRequestContext(request); -// return raxaAlertResource.getRaxaAlertsByProvider(providerUniqueId, context); -// } -//}; -// diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaDrugController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaDrugController.java deleted file mode 100644 index 40317e8768..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaDrugController.java +++ /dev/null @@ -1,314 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Concept; -import org.openmrs.Encounter; -import org.openmrs.Obs; -import org.openmrs.Patient; -import org.openmrs.Drug; -import org.openmrs.api.ConceptService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the Drug resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/drug") -public class RaxaDrugController extends BaseRestController { - - ConceptService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REF = { "uuid", "name", "description" }; - - public void initDrugController() { - service = Context.getConceptService(); - } - - /** - * Returns the Resource Version - */ - private String getResourceVersion() { - return "1.0"; - } - - /** - * Create new drug by POST'ing at least name and description property in the - * request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and Drug object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New Drug") - @ResponseBody - public Object createNewDrug(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initDrugController(); - String conceptUuid = post.get("concept").toString(); - Concept concept = service.getConceptByUuid(conceptUuid); - - if (concept == null) { - throw new ObjectNotFoundException(); - } - - Drug drug = new Drug(); - drug.setConcept(concept); - updateDrugFieldsFromPostData(drug, post); - Drug drugJustCreated = service.saveDrug(drug); - if (post.get("drugInfo") != null) { - this.createNewDrugInfo(drugJustCreated, (LinkedHashMap) post.get("drugInfo")); - } - return RestUtil.created(response, getDrugAsSimpleObject(drugJustCreated)); - } - - /** - * Updates the Drug by making a POST call with uuid in URL and - * - * @param uuid the uuid for the drug resource - * @param post - * @param request - * @param response - * @return 200 response status - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.POST) - @WSDoc("Updates an existing drug") - @ResponseBody - public Object updateDrug(@PathVariable("uuid") String uuid, @RequestBody SimpleObject post, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initDrugController(); - Drug drug = service.getDrugByUuid(uuid); - updateDrugFieldsFromPostData(drug, post); - service.saveDrug(drug); - return RestUtil.created(response, getDrugAsSimpleObject(drug)); - } - - /** - * Updates attributes of a Drug copying them from a SimpleObject - * - * @param drug - * @param obj - */ - private void updateDrugFieldsFromPostData(Drug drug, SimpleObject obj) { - if (obj.get("name") != null) { - drug.setName(obj.get("name").toString()); - } - if (obj.get("description") != null) { - drug.setDescription(obj.get("description").toString()); - } - if (obj.get("combination") != null) { - drug.setCombination(Boolean.parseBoolean(obj.get("combination").toString())); - } - if (obj.get("maximumDailyDose") != null) { - drug.setMaximumDailyDose(Double.parseDouble(obj.get("maximumDailyDose").toString())); - } - if (obj.get("minimumDailyDose") != null) { - drug.setMinimumDailyDose(Double.parseDouble(obj.get("minimumDailyDose").toString())); - } - if (obj.get("dosageForm") != null) { - drug.setDosageForm(Context.getConceptService().getConceptByUuid(obj.get("dosageForm").toString())); - } - if (obj.get("units") != null) { - drug.setUnits(obj.get("units").toString()); - } - } - - /** - * Creates a drug info for the given drug - */ - private void createNewDrugInfo(Drug drug, LinkedHashMap drugInfoMap) { - String drugUuid = drug.getUuid(); - - // create drug info POJO and add required relationship with a Drug - DrugInfo drugInfo = new DrugInfo(); - drugInfo.setDrug(drug); - if (drugInfoMap.get("name") != null) { - drugInfo.setName(drugInfoMap.get("name").toString()); - } - if (drugInfoMap.get("description") != null) { - drugInfo.setDescription(drugInfoMap.get("description").toString()); - } - if (drugInfoMap.get("price") != null) { - drugInfo.setPrice(Double.parseDouble(drugInfoMap.get("price").toString())); - } - if (drugInfoMap.get("cost") != null) { - drugInfo.setCost(Double.parseDouble(drugInfoMap.get("cost").toString())); - } - // save new object and prepare response - DrugInfo drugInfoJustCreated = Context.getService(DrugInfoService.class).saveDrugInfo(drugInfo); - } - - /** - * Returns a SimpleObject containing some fields of Drug - * - * @param drug - * @return - */ - private SimpleObject getDrugAsSimpleObject(Drug drug) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", drug.getUuid()); - obj.add("name", drug.getName()); - obj.add("description", drug.getDescription()); - obj.add("minimumDailyDose", drug.getMinimumDailyDose()); - obj.add("maximumDailyDose", drug.getMaximumDailyDose()); - if (drug.getDosageForm() != null) { - obj.add("dosageForm", drug.getDosageForm().getName().getName()); - } - obj.add("strength", drug.getDoseStrength()); - obj.add("units", drug.getUnits()); - obj.add("combination", drug.getCombination()); - obj.add("concept", drug.getConcept().getUuid()); - obj.add("fullName", drug.getFullName(Context.getLocale())); - return obj; - } - - /** - * Get all the unretired drug (as REF representation) in the system - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Drug in the system") - @ResponseBody() - public String getAllDrugs(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initDrugController(); - List allDrug = service.getAllDrugs(false); - ArrayList results = new ArrayList(); - for (Drug drug : allDrug) { - results.add(getDrugAsSimpleObject(drug)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Get the Drug - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Drug for the uuid path") - @ResponseBody() - public String getDrugByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) throws ResponseException { - initDrugController(); - Drug drug = service.getDrugByUuid(uuid); - return gson.toJson(getDrugAsSimpleObject(drug)); - } - - /** - * Get the drug as FULL representation - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET, params = "v") - @WSDoc("Gets Full representation of Drug for the uuid path") - @ResponseBody() - public String getDrugByUuidFull(@PathVariable("uuid") String uuid, @RequestParam("v") String rep, - HttpServletRequest request) throws ResponseException { - initDrugController(); - Drug drug = service.getDrugByUuid(uuid); - SimpleObject obj = getDrugAsSimpleObject(drug); - if (rep.equals("full")) { - obj.add("retired", drug.getRetired()); - if (drug.getRetired()) { - obj.add("retiredBy", drug.getRetiredBy().getUuid()); - obj.add("retireReason", drug.getRetireReason()); - } - SimpleObject auditInfo = new SimpleObject(); - auditInfo.add("creator", drug.getCreator().getUuid()); - auditInfo.add("dateCreated", df.format(drug.getDateCreated())); - if (drug.getChangedBy() != null) { - auditInfo.add("changedBy", drug.getChangedBy().getUuid()); - auditInfo.add("dateChanged", df.format(drug.getDateChanged())); - } - obj.add("auditInfo", auditInfo); - } - obj.add("resourceVersion", getResourceVersion()); - return gson.toJson(obj); - } - - /** - * Retires the drug resource by making a DELETE call with the '!purge' param - * - * @param uuid - * @param reason - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.DELETE, params = "!purge") - @WSDoc("Retires the Drug") - @ResponseBody - public Object retireDrug(@PathVariable("uuid") String uuid, - @RequestParam(value = "reason", defaultValue = "web service call") String reason, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initDrugController(); - Drug drug = service.getDrugByUuid(uuid); - if (drug != null) { - drug.setRetired(true); - drug.setRetireReason(reason); - drug.setRetiredBy(Context.getAuthenticatedUser()); - service.updateDrug(drug); - } - return RestUtil.noContent(response); - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaEncounterController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaEncounterController.java deleted file mode 100644 index 2db9dcab1e..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaEncounterController.java +++ /dev/null @@ -1,432 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; -import org.openmrs.Concept; -import org.openmrs.ConceptNumeric; -import org.openmrs.DrugOrder; -import org.openmrs.Encounter; -import org.openmrs.Obs; -import org.openmrs.Order; -import org.openmrs.Provider; -import org.openmrs.api.EncounterService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.ConversionUtil; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.openmrs.util.OpenmrsConstants; -import org.openmrs.util.OpenmrsUtil; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the Encounter resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/encounter") -public class RaxaEncounterController extends BaseRestController { - - EncounterService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REQUIRED_FIELDS = { "encounterDatetime", "patient", "encounterType" }; - - private static final String[] DATE_FORMATS = { "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSSZ", - "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE MMM d yyyy HH:mm:ss zZzzzz", "yyyy-MM-dd'T'HH:mm:ssZ", - "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - - public void initEncounterController() { - service = Context.getEncounterService(); - } - - private void validatePost(SimpleObject post) throws ResponseException { - for (int i = 0; i < REQUIRED_FIELDS.length; i++) { - if (post.get(REQUIRED_FIELDS[i]) == null) { - throw new ResponseException( - "Required field " + REQUIRED_FIELDS[i] + " not found") {}; - } - } - } - - /** - * Create new encounter by POST'ing at least name and description property in the - * request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and Encounter object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New Encounter") - @ResponseBody - public Object createNewEncounter(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initEncounterController(); - validatePost(post); - Encounter encounter = createEncounterFromPost(post); - return RestUtil.created(response, getEncounterAsSimpleObject(encounter)); - } - - /** - * Creates an encounter based on fields in the post object - * @param post - * @return - */ - private Encounter createEncounterFromPost(SimpleObject post) throws ResponseException { - Encounter encounter = new Encounter(); - encounter.setPatient(Context.getPatientService().getPatientByUuid(post.get("patient").toString())); - for (int i = 0; i < DATE_FORMATS.length; i++) { - try { - Date date = new SimpleDateFormat(DATE_FORMATS[i]).parse(post.get("encounterDatetime").toString()); - //Openmrs doesn't allow future encounters - if (date.after(new Date())) { - encounter.setEncounterDatetime(new Date()); - break; - } else { - encounter.setEncounterDatetime(date); - break; - } - } - catch (Exception ex) {} - } - encounter.setEncounterType(service.getEncounterTypeByUuid(post.get("encounterType").toString())); - if (post.get("location") != null) { - encounter.setLocation(Context.getLocationService().getLocationByUuid(post.get("location").toString())); - } - if (post.get("provider") != null) { - encounter.setProvider(Context.getPersonService().getPersonByUuid(post.get("provider").toString())); - } - //if no provider is given in the post, set as the current user - else { - encounter.setProvider(Context.getAuthenticatedUser().getPerson()); - } - Encounter newEncounter = service.saveEncounter(encounter); - if (post.get("obs") != null) { - createObsFromPost(post, newEncounter); - } - if (post.get("orders") != null) { - createOrdersFromPost(post, newEncounter); - } - return encounter; - } - - /** - * Creates and saves the obs from the given post - * @param post - * @param encounter - */ - private void createObsFromPost(SimpleObject post, Encounter encounter) throws ResponseException { - List obsObjects = (List) post.get("obs"); - List encounterObs = new ArrayList(); - for (int i = 0; i < obsObjects.size(); i++) { - Obs obs = new Obs(); - obs.setPerson(encounter.getPatient()); - obs.setConcept(Context.getConceptService().getConceptByUuid(obsObjects.get(i).get("concept").toString())); - obs.setObsDatetime(encounter.getEncounterDatetime()); - if (encounter.getLocation() != null) { - obs.setLocation(encounter.getLocation()); - } - obs.setEncounter(encounter); - if (obsObjects.get(i).get("value") != null) { - setObsValue(obs, obsObjects.get(i).get("value").toString()); - } - if (obsObjects.get(i).get("comment") != null) { - obs.setComment(obsObjects.get(i).get("comment").toString()); - } - encounter.addObs(obs); - //Context.getObsService().saveObs(obs, "saving new obs"); - } - } - - private Obs setObsValue(Obs obs, Object value) throws ResponseException { - if (obs.getConcept().getDatatype().isCoded()) { - // setValueAsString is not implemented for coded obs (in core) - Concept valueCoded = (Concept) ConversionUtil.convert(value, Concept.class); - obs.setValueCoded(valueCoded); - } else if (obs.getConcept().getDatatype().isComplex()) { - obs.setValueComplex(value.toString()); - } else { - if (obs.getConcept().isNumeric()) { - //get the actual persistent object rather than the hibernate proxy - ConceptNumeric concept = Context.getConceptService().getConceptNumeric(obs.getConcept().getId()); - String units = concept.getUnits(); - if (StringUtils.isNotBlank(units)) { - String originalValue = value.toString().trim(); - if (originalValue.endsWith(units)) - value = originalValue.substring(0, originalValue.indexOf(units)).trim(); - else { - //check that that this value has no invalid units - try { - Double.parseDouble(originalValue); - } - catch (NumberFormatException e) { - throw new ResponseException( - originalValue + " has invalid units", e) {}; - } - } - } - } - try { - if (obs.getConcept().getDatatype().getHl7Abbreviation().equals("ZZ")) { - obs.setValueText(value.toString()); - } else { - obs.setValueAsString(value.toString()); - } - } - catch (Exception e) { - throw new ResponseException( - "Unable to convert obs value " + e.getMessage()) {}; - } - } - return obs; - } - - /** - * Creates and saves the orders from the given post - * @param post - * @param encounter - */ - private void createOrdersFromPost(SimpleObject post, Encounter encounter) throws ResponseException { - List orderObjects = (List) post.get("orders"); - for (int i = 0; i < orderObjects.size(); i++) { - //only setting drug orders now - DrugOrder order = new DrugOrder(); - order.setPatient(encounter.getPatient()); - order.setConcept(Context.getConceptService().getConceptByUuid(orderObjects.get(i).get("concept").toString())); - order.setOrderType(Context.getOrderService().getOrderType(OpenmrsConstants.ORDERTYPE_DRUG)); - if (orderObjects.get(i).get("instructions") != null) { - order.setInstructions(orderObjects.get(i).get("instructions").toString()); - } - if (orderObjects.get(i).get("drug") != null) { - order.setDrug(Context.getConceptService().getDrugByUuid(orderObjects.get(i).get("drug").toString())); - } - if (orderObjects.get(i).get("instructions") != null) { - order.setInstructions(orderObjects.get(i).get("instructions").toString()); - } - if (orderObjects.get(i).get("frequency") != null) { - order.setFrequency(orderObjects.get(i).get("frequency").toString()); - } - if (orderObjects.get(i).get("quantity") != null) { - order.setQuantity((Integer) orderObjects.get(i).get("quantity")); - } - if (orderObjects.get(i).get("dose") != null) { - order.setDose((Double) orderObjects.get(i).get("dose")); - } - if (orderObjects.get(i).get("startDate") != null) { - for (int j = 0; j < DATE_FORMATS.length; j++) { - try { - Date date = new SimpleDateFormat(DATE_FORMATS[j]).parse(orderObjects.get(i).get("startDate") - .toString()); - order.setStartDate(date); - } - catch (Exception ex) {} - } - } - if (orderObjects.get(i).get("autoExpireDate") != null) { - for (int j = 0; j < DATE_FORMATS.length; j++) { - try { - Date date = new SimpleDateFormat(DATE_FORMATS[j]).parse(orderObjects.get(i).get("autoExpireDate") - .toString()); - order.setAutoExpireDate(date); - } - catch (Exception ex) {} - } - } - order.setEncounter(encounter); - if (encounter.getProvider() != null) { - order.setOrderer(Context.getAuthenticatedUser()); - } - Context.getOrderService().saveOrder(order); - } - } - - /** - * Get the encounter as FULL representation - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Full representation of Encounter for the uuid path") - @ResponseBody() - public String getEncounterByUuidFull(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initEncounterController(); - Encounter encounter = service.getEncounterByUuid(uuid); - SimpleObject obj = getEncounterAsSimpleObject(encounter); - return gson.toJson(obj); - } - - /** - * Get the encounters by provider - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "provider") - @WSDoc("Gets Full representation of Encounter for the uuid path") - @ResponseBody() - public String getEncountersByProvider(@RequestParam Map params, HttpServletRequest request) - throws ResponseException { - initEncounterController(); - List providers = new ArrayList(); - providers.add(Context.getProviderService().getProviderByUuid(params.get("provider"))); - List encounters = service.getEncounters(null, null, null, null, null, null, providers, null, null, true); - ArrayList results = new ArrayList(); - for (Encounter encounter : encounters) { - results.add(getEncounterAsSimpleObject(encounter)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Returns a SimpleObject containing some fields of Drug - * - * @param drug - * @return - */ - private SimpleObject getEncounterAsSimpleObject(Encounter encounter) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", encounter.getUuid()); - obj.add("display", encounter.toString()); - obj.add("encounterDatetime", encounter.getEncounterDatetime()); - if (encounter.getPatient() != null) { - SimpleObject patientObj = new SimpleObject(); - patientObj.add("uuid", encounter.getPatient().getUuid()); - patientObj.add("display", encounter.getPatient().getPersonName().getFullName()); - obj.add("patient", patientObj); - } - if (encounter.getLocation() != null) { - SimpleObject locationObj = new SimpleObject(); - locationObj.add("uuid", encounter.getLocation().getUuid()); - locationObj.add("display", encounter.getLocation().getDisplayString()); - obj.add("location", locationObj); - } - SimpleObject encounterTypeObj = new SimpleObject(); - encounterTypeObj.add("uuid", encounter.getEncounterType().getUuid()); - encounterTypeObj.add("display", encounter.getEncounterType().getName()); - obj.add("encounterType", encounterTypeObj); - Set obs = encounter.getObs(); - if (!encounter.getObs().isEmpty()) { - ArrayList obsObjects = new ArrayList(); - Iterator obsIter = obs.iterator(); - while (obsIter.hasNext()) { - Obs currentObs = obsIter.next(); - obsObjects.add(createObjectFromObs(currentObs)); - } - obj.add("obs", obsObjects); - } - Set orders = encounter.getOrders(); - if (!orders.isEmpty()) { - ArrayList orderObjects = new ArrayList(); - Iterator orderIter = orders.iterator(); - while (orderIter.hasNext()) { - Order currentOrder = orderIter.next(); - orderObjects.add(createObjectFromOrder(currentOrder)); - } - obj.add("orders", orderObjects); - } - return obj; - } - - /** - * Helper function to add an order to simpleobject for returning over REST - * @param obj - * @param order - * @return - */ - private SimpleObject createObjectFromOrder(Order order) { - SimpleObject newOrderObject = new SimpleObject(); - newOrderObject.add("uuid", order.getUuid()); - if (order.getOrderType() != null) { - SimpleObject orderType = new SimpleObject(); - orderType.add("uuid", order.getOrderType().getUuid()); - orderType.add("display", order.getOrderType().getName()); - newOrderObject.add("orderType", orderType); - } - SimpleObject orderConcept = new SimpleObject(); - orderConcept.add("uuid", order.getConcept().getUuid()); - orderConcept.add("display", order.getConcept().getName().getName()); - newOrderObject.add("concept", orderConcept); - if (order.isDrugOrder()) { - DrugOrder currentDrugOrder = (DrugOrder) order; - newOrderObject.add("instructions", currentDrugOrder.getInstructions()); - newOrderObject.add("startDate", currentDrugOrder.getStartDate().toString()); - newOrderObject.add("autoExpireDate", currentDrugOrder.getAutoExpireDate().toString()); - newOrderObject.add("dose", currentDrugOrder.getDose()); - newOrderObject.add("units", currentDrugOrder.getUnits()); - newOrderObject.add("frequency", currentDrugOrder.getFrequency()); - newOrderObject.add("quantity", currentDrugOrder.getQuantity()); - SimpleObject drugObj = new SimpleObject(); - drugObj.add("uuid", currentDrugOrder.getDrug().getUuid()); - drugObj.add("display", currentDrugOrder.getDrug().getName()); - newOrderObject.add("drug", drugObj); - } - return newOrderObject; - } - - /** - * Helper function to add an obs to simpleobject for returning over REST - * @param obj - * @param order - * @return - */ - private SimpleObject createObjectFromObs(Obs obs) { - SimpleObject newObsObject = new SimpleObject(); - newObsObject.add("uuid", obs.getUuid()); - newObsObject.add("obsDatetime", df.format(obs.getObsDatetime())); - newObsObject.add("value", obs.getValueAsString(Locale.ENGLISH)); - newObsObject.add("comment", obs.getComment()); - if (obs.getOrder() != null) { - newObsObject.add("order", obs.getOrder().getUuid()); - } else { - newObsObject.add("order", null); - } - return newObsObject; - } - -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaLoginController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaLoginController.java deleted file mode 100644 index 0b5dd2a37e..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaLoginController.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Iterator; -import java.util.Set; -import java.util.Date; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Person; -import org.openmrs.PersonAttribute; -import org.openmrs.PersonAttributeType; -import org.openmrs.Provider; -import org.openmrs.ProviderAttribute; -import org.openmrs.Role; -import org.openmrs.User; -import org.openmrs.api.ConceptService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * Controller for REST web service access to the Drug resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/login") -public class RaxaLoginController extends BaseRestController { - - ConceptService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - /** - * Get the login information according to the current user - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get Login information") - @ResponseBody() - public String getLoginInfo(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - SimpleObject obj = new SimpleObject(); - if (Context.isAuthenticated()) { - User u = Context.getAuthenticatedUser(); - Person p = Context.getPersonService().getPersonByUuid(u.getPerson().getUuid()); - Provider provider = Context.getProviderService().getProvidersByPerson(p).iterator().next(); - obj.add("personUuid", p.getUuid()); - if (provider != null) { - obj.add("providerUuid", provider.getUuid()); - ArrayList attributesObj = new ArrayList(); - Iterator attributesIterator = provider.getActiveAttributes().iterator(); - while (attributesIterator.hasNext()) { - SimpleObject attributeObj = new SimpleObject(); - ProviderAttribute pAttribute = attributesIterator.next(); - attributeObj.add("attributeType", pAttribute.getAttributeType().getName()); - attributeObj.add("value", pAttribute.getValue()); - attributesObj.add(attributeObj); - } - obj.add("providerAttributes", attributesObj); - } - obj.add("display", p.getPersonName().getFullName()); - if (p.getAttribute("Health Center") != null) { - obj.add("location", Context.getLocationService().getLocation( - Integer.parseInt(p.getAttribute("Health Center").getValue())).getUuid()); - } - obj.add("roles", u.getAllRoles()); - obj.add("privileges", u.getPrivileges()); - obj.add("serverTime", Calendar.getInstance().getTime()); - return gson.toJson(obj); - } else { - throw new ResponseException( - "Not Authenticated") {}; - } - } - -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientAccessController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientAccessController.java deleted file mode 100644 index 331134faaf..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientAccessController.java +++ /dev/null @@ -1,211 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.lang.reflect.Method; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Person; -import org.openmrs.Relationship; -import org.openmrs.RelationshipType; -import org.openmrs.api.PersonService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the Relationship resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/patientaccess") -public class RaxaPatientAccessController extends BaseRestController { - - PersonService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REQUIRED_FIELDS = { "fromPerson", "toPerson", "relationshipType" }; - - private static final String[] DATE_FORMATS = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", - "EEE MMM d yyyy HH:mm:ss zZzzzz", "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd" }; - - public void initRelationshipController() { - service = Context.getPersonService(); - } - - private void validatePost(SimpleObject post) throws ResponseException { - for (int i = 0; i < REQUIRED_FIELDS.length; i++) { - if (post.get(REQUIRED_FIELDS[i]) == null) { - throw new ResponseException( - "Required field " + REQUIRED_FIELDS[i] + " not found") {}; - } - } - } - - /** - * Create new relationship between 2 persons by POST - * request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and Relationship object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New Relationship") - @ResponseBody - public Object createNewRelationship(@RequestBody SimpleObject post, HttpServletRequest request, - HttpServletResponse response) throws ResponseException { - initRelationshipController(); - validatePost(post); - Relationship relationship = createRelationshipFromPost(post); - relationship = service.saveRelationship(relationship); - return RestUtil.created(response, getRelationshipAsSimpleObject(relationship)); - } - - /** - * Creates an relationship based on fields in the post object - * @param post - * @return - */ - private Relationship createRelationshipFromPost(SimpleObject post) throws ResponseException { - Relationship relationship = new Relationship(); - Person a, b; - try { - Method method = service.getClass().getMethod("getPersonByUuidSafeSearch", String.class); - a = (Person) method.invoke(service, post.get("fromPerson").toString()); - b = (Person) method.invoke(service, post.get("toPerson").toString()); - } - catch (Exception e) { - a = Context.getPersonService().getPersonByUuid(post.get("fromPerson").toString()); - b = Context.getPersonService().getPersonByUuid(post.get("toPerson").toString()); - } - relationship.setPersonA(a); - relationship.setPersonB(b); - relationship.setRelationshipType(Context.getPersonService().getRelationshipTypeByName( - post.get("relationshipType").toString())); - return relationship; - } - - /** - * Get the relationships - * - * @param uuid - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "fromPerson") - @WSDoc("Gets Full representation of Relationships for the given parameters") - @ResponseBody() - public String getRelationships(@RequestParam Map params, HttpServletRequest request) - throws ResponseException { - initRelationshipController(); - Person fromPerson = Context.getPersonService().getPersonByUuid(params.get("fromPerson")); - Person toPerson = Context.getPersonService().getPersonByUuid(params.get("toPerson")); - RelationshipType rType = Context.getPersonService().getRelationshipTypeByName(params.get("relationshipType")); - List relationships = service.getRelationships(fromPerson, toPerson, rType); - ArrayList results = new ArrayList(); - for (Relationship relationship : relationships) { - results.add(getRelationshipAsSimpleObject(relationship)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Get a specific relationship - * - * @param uuid - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) - @WSDoc("Gets Relationship for the uuid path") - @ResponseBody() - public String getRelationshipByUuid(@PathVariable("uuid") String uuid, HttpServletRequest request) - throws ResponseException { - initRelationshipController(); - Relationship relationship = service.getRelationshipByUuid(uuid); - return gson.toJson(getRelationshipAsSimpleObject(relationship)); - } - - /** - * Get all the unretired relationships (as REF representation) in the system - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET) - @WSDoc("Get All Unretired Relationships in the system") - @ResponseBody() - public String getAllRelationships(HttpServletRequest request, HttpServletResponse response) throws ResponseException { - initRelationshipController(); - List allRelationships = service.getAllRelationships(); - ArrayList results = new ArrayList(); - for (Relationship relationship : allRelationships) { - results.add(getRelationshipAsSimpleObject(relationship)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Returns a SimpleObject containing some fields of Relationship - * - * @param relationship - * @return - */ - private SimpleObject getRelationshipAsSimpleObject(Relationship relationship) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", relationship.getUuid()); - if (relationship.getPersonA() != null) { - SimpleObject fromPersonObj = new SimpleObject(); - fromPersonObj.add("uuid", relationship.getPersonA().getUuid()); - fromPersonObj.add("display", relationship.getPersonA().getPersonName().getFullName()); - obj.add("fromPerson", fromPersonObj); - } - if (relationship.getPersonB() != null) { - SimpleObject toPersonObj = new SimpleObject(); - toPersonObj.add("uuid", relationship.getPersonB().getUuid()); - toPersonObj.add("display", relationship.getPersonB().getPersonName().getFullName()); - obj.add("toPerson", toPersonObj); - } - obj.add("relationshipType", relationship.getRelationshipType().getaIsToB() + "/" - + relationship.getRelationshipType().getbIsToA()); - return obj; - } - -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientController.java deleted file mode 100644 index 74cc5a4372..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientController.java +++ /dev/null @@ -1,311 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.common.base.Joiner; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.lang.reflect.Method; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Location; -import org.openmrs.LocationAttribute; -import org.openmrs.Patient; -import org.openmrs.PatientIdentifier; -import org.openmrs.Person; -import org.openmrs.PersonAddress; -import org.openmrs.PersonAttribute; -import org.openmrs.PersonAttributeType; -import org.openmrs.PersonName; -import org.openmrs.User; -import org.openmrs.api.PatientService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -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; - -/** - * Controller for REST web service access to the Drug resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/patient") -public class RaxaPatientController extends BaseRestController { - - PatientService service; - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - private static final String[] REQUIREDFIELDS = { "names", "gender" }; - - private static final String[] REF = { "uuid", "name", "description" }; - - public void initPatientController() { - service = Context.getPatientService(); - } - - private boolean validatePost(SimpleObject post) throws ResponseException { - for (int i = 0; i < REQUIREDFIELDS.length; i++) { - if (post.get(REQUIREDFIELDS[i]) == null) { - throw new ResponseException( - "Required field " + REQUIREDFIELDS[i] + " not found") {}; - } - } - User u = Context.getAuthenticatedUser(); - Person p = Context.getPersonService().getPersonByUuid(u.getPerson().getUuid()); - if (p.getAttribute("Health Center") == null) { - throw new ResponseException( - "Current user needs Health Center attribute") {}; - } - return true; - } - - /** - * Returns the Resource Version - */ - private String getResourceVersion() { - return "1.0"; - } - - /** - * Adds attributes to the given person from the values in the post object - */ - private Person addAttributes(Person p, SimpleObject post) throws ResponseException { - List attributeObjects = (List) post.get("attributes"); - for (int i = 0; i < attributeObjects.size(); i++) { - if (attributeObjects.get(i).get("attributeType") != null && attributeObjects.get(i).get("value") != null) { - PersonAttribute pa = new PersonAttribute(); - PersonAttributeType paType = Context.getPersonService().getPersonAttributeTypeByUuid( - attributeObjects.get(i).get("attributeType").toString()); - if (paType == null) { - throw new ResponseException( - "Person Attribute Type not found") {}; - } - pa.setAttributeType(paType); - String paValue = attributeObjects.get(i).get("value").toString(); - if (paValue == null) { - throw new ResponseException( - "Person Attribute Value cannot be null") {}; - } - pa.setValue(paValue); - p.addAttribute(pa); - } - } - return p; - } - - /** - * Adds names to the given person from the values in the post object - */ - private Person addNames(Person p, SimpleObject post) throws ResponseException { - List nameObjects = (List) post.get("names"); - for (int i = 0; i < nameObjects.size(); i++) { - String first = "", middle = "", last = ""; - if (nameObjects.get(i).get("givenName") != null) { - first = nameObjects.get(i).get("givenName").toString(); - } - if (nameObjects.get(i).get("middleName") != null) { - middle = nameObjects.get(i).get("middleName").toString(); - } - if (nameObjects.get(i).get("familyName") != null) { - last = nameObjects.get(i).get("familyName").toString(); - } - PersonName name = new PersonName(first, middle, last); - if (i == 0) { - name.setPreferred(Boolean.TRUE); - } - p.addName(name); - } - return p; - } - - /** - * Adds the address to the given person from the post object - */ - private Person addAddresses(Person p, SimpleObject post) throws ResponseException { - List addressObjects = (List) post.get("addresses"); - for (int i = 0; i < addressObjects.size(); i++) { - PersonAddress pa = new PersonAddress(); - if (i == 0) { - pa.setPreferred(Boolean.TRUE); - } - if (addressObjects.get(i).get("address1") != null) { - pa.setAddress1(addressObjects.get(i).get("address1").toString()); - } - if (addressObjects.get(i).get("address2") != null) { - pa.setAddress2(addressObjects.get(i).get("address2").toString()); - } - if (addressObjects.get(i).get("address3") != null) { - pa.setAddress3(addressObjects.get(i).get("address3").toString()); - } - if (addressObjects.get(i).get("cityVillage") != null) { - pa.setCityVillage(addressObjects.get(i).get("cityVillage").toString()); - } - if (addressObjects.get(i).get("stateProvince") != null) { - pa.setStateProvince(addressObjects.get(i).get("stateProvince").toString()); - } - p.addAddress(pa); - } - return p; - } - - private Patient savePatient(Person person, SimpleObject post, Location location) { - boolean identifierInUse = true; - String identifier = ""; - Iterator iter = location.getAttributes().iterator(); - String prefix = "NEW"; - while (iter.hasNext()) { - LocationAttribute la = iter.next(); - if (la.getAttributeType().getName().equals("identifierPrefix")) { - prefix = la.getValue().toString(); - } - } - while (identifierInUse) { - //TODO: set this identifier prefix based on location - identifier = prefix + (int) (Math.random() * 100000); - if (service.getPatients(identifier).isEmpty()) { - identifierInUse = false; - } - } - PatientIdentifier pi = new PatientIdentifier(identifier, service - .getPatientIdentifierTypeByName("RaxaEMR Identifier Number"), location); - pi.setPreferred(true); - Patient patient = new Patient(person); - patient.addIdentifier(pi); - return service.savePatient(patient); - } - - /** - * Create new patient by POST'ing at least name and gender property in the - * request body. - * - * @param post the body of the POST request - * @param request - * @param response - * @return 201 response status and Drug object - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Save New Patient") - @ResponseBody - public Object createNewPatient(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initPatientController(); - validatePost(post); - Person person = new Person(); - addNames(person, post); - person.setGender(post.get("gender").toString()); - if (post.get("birthdate") != null) { - if (post.get("time") != null) { - String[] supportedFormats = { "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", - "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }; - for (int i = 0; i < supportedFormats.length; i++) { - try { - Date date = new SimpleDateFormat(supportedFormats[i]).parse(post.get("time").toString()); - person.setBirthdate(date); - person.setBirthdateEstimated(Boolean.FALSE); - } - catch (Exception ex) {} - } - } - } else if (post.get("age") != null) { - person.setBirthdateFromAge(Integer.parseInt(post.get("age").toString()), new Date()); - person.setBirthdateEstimated(Boolean.TRUE); - } - //Location location = Context.getLocationService().getLocationByUuid(post.get("location").toString()); - Integer userLocation = Integer.parseInt(Context.getPersonService().getPersonByUuid( - Context.getAuthenticatedUser().getPerson().getUuid()).getAttribute("Health Center").getValue()); - Location location = Context.getLocationService().getLocation(userLocation); - PersonAttribute locationAttribute = new PersonAttribute(); - locationAttribute.setAttributeType(Context.getPersonService().getPersonAttributeTypeByName("Health Center")); - locationAttribute.setValue(location.getId().toString()); - person.addAttribute(locationAttribute); - if (post.get("attributes") != null) { - addAttributes(person, post); - } - if (post.get("addresses") != null) { - addAddresses(person, post); - } - return RestUtil.created(response, getPatientAsSimpleObject(savePatient(person, post, location))); - } - - /** - * Safe search a patient, bypass security but only show non-sensitive fields - * - * @param safesearch - * @param rep - * @param request - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.GET, params = "safesearch") - @WSDoc("Gets Summarized representation of Patients for the given search") - @ResponseBody() - public String safeSearchPatients(@RequestParam String safesearch, HttpServletRequest request) throws ResponseException { - initPatientController(); - List patients; - try { - Method method = service.getClass().getMethod("getPatientsSafeSearch", String.class); - patients = (List) method.invoke(service, safesearch); - } - catch (Exception e) { - //if openmrs core doesn't have "getPatientsSafeSearch" then use the normal one with security - patients = service.getPatients(safesearch); - return gson.toJson(new SimpleObject().add("nosafesearch", null)); - } - ArrayList results = new ArrayList(); - for (Patient patient : patients) { - results.add(getPatientAsSimpleObject(patient)); - } - return gson.toJson(new SimpleObject().add("results", results)); - } - - /** - * Returns a SimpleObject containing some fields of Patient - * - * @param patient - * @return - */ - private SimpleObject getPatientAsSimpleObject(Patient p) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", p.getUuid()); - obj.add("name", p.getGivenName() + " " + p.getFamilyName()); - obj.add("identifier", p.getPatientIdentifier().getIdentifier()); - return obj; - } - -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaUserController.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaUserController.java deleted file mode 100644 index 27bff488bf..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaUserController.java +++ /dev/null @@ -1,221 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.openmrs.Location; -import org.openmrs.Patient; -import org.openmrs.PatientIdentifier; -import org.openmrs.Person; -import org.openmrs.PersonAttribute; -import org.openmrs.PersonAttributeType; -import org.openmrs.PersonName; -import org.openmrs.Provider; -import org.openmrs.ProviderAttribute; -import org.openmrs.ProviderAttributeType; -import org.openmrs.Role; -import org.openmrs.User; -import org.openmrs.api.ConceptService; -import org.openmrs.api.UserService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RestUtil; -import org.openmrs.module.webservices.rest.web.annotation.WSDoc; -import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; -import org.openmrs.util.OpenmrsConstants; -import org.openmrs.util.OpenmrsUtil; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * Controller for REST web service access to the Drug resource. - */ -@Controller -@RequestMapping(value = "/rest/v1/raxacore/user") -public class RaxaUserController extends BaseRestController { - - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - Gson gson = new GsonBuilder().serializeNulls().create(); - - UserService service; - - private static final String[] TYPE = { "patient", "provider" }; - - private static final String[] REQUIREDFIELDS = { "type", "firstName", "lastName", "gender", "userName", "password", - "location" }; - - public void initUserController() { - service = Context.getUserService(); - } - - private boolean validatePost(SimpleObject post) throws ResponseException { - for (int i = 0; i < REQUIREDFIELDS.length; i++) { - if (post.get(REQUIREDFIELDS[i]) == null) { - throw new ResponseException( - "Required field " + REQUIREDFIELDS[i] + " not found") {}; - } - } - if (service.getUserByUsername(post.get("userName").toString()) != null) { - throw new ResponseException( - "User name must be unique") {}; - } - OpenmrsUtil.validatePassword(post.get("userName").toString(), post.get("password").toString(), null); - for (int j = 0; j < TYPE.length; j++) { - if (post.get("type").equals(TYPE[j])) { - return true; - } - } - throw new ResponseException( - "User type is unsupported") {}; - } - - private Object getUserAsSimpleObject(User u) { - SimpleObject obj = new SimpleObject(); - obj.add("uuid", u.getUuid()); - obj.add("display", u.getDisplayString()); - return obj; - } - - /** - * Get the user information according to the current user - * - * @param request - * @param response - * @return - * @throws ResponseException - */ - @RequestMapping(method = RequestMethod.POST) - @WSDoc("Post user information") - @ResponseBody() - public Object createNewUser(@RequestBody SimpleObject post, HttpServletRequest request, HttpServletResponse response) - throws ResponseException { - initUserController(); - validatePost(post); - Person person = new Person(); - PersonName name = new PersonName(post.get("firstName").toString(), null, post.get("lastName").toString()); - name.setPreferred(true); - person.addName(name); - person.setGender(post.get("gender").toString()); - Location location = Context.getLocationService().getLocationByUuid(post.get("location").toString()); - if (location == null) { - throw new ResponseException( - "Location uuid not found") {}; - } - PersonAttribute locationAttribute = new PersonAttribute(); - locationAttribute.setAttributeType(Context.getPersonService().getPersonAttributeTypeByName("Health Center")); - locationAttribute.setValue(location.getId().toString()); - person.addAttribute(locationAttribute); - if (post.get("email") != null) { - PersonAttribute emailAttribute = new PersonAttribute(); - emailAttribute.setAttributeType(Context.getPersonService().getPersonAttributeTypeByName("Email")); - emailAttribute.setValue(post.get("email").toString()); - person.addAttribute(emailAttribute); - } - if (post.get("phone") != null) { - PersonAttribute phoneAttribute = new PersonAttribute(); - phoneAttribute.setAttributeType(Context.getPersonService().getPersonAttributeTypeByName("Primary Contact")); - phoneAttribute.setValue(post.get("phone").toString()); - person.addAttribute(phoneAttribute); - } - if (post.get("donateOrgans") != null) { - PersonAttribute donateOrgansAttribute = new PersonAttribute(); - donateOrgansAttribute.setAttributeType(Context.getPersonService().getPersonAttributeTypeByName("Donate Organs")); - donateOrgansAttribute.setValue(post.get("donateOrgans").toString()); - person.addAttribute(donateOrgansAttribute); - } - String type = post.get("type").toString(); - if (type.equals(TYPE[0])) { - person = savePatient(person, post, location); - } else if (type.equals(TYPE[1])) { - saveProvider(person, post); - } - User user = new User(person); - user.setUsername(post.get("userName").toString()); - if (type.equals(TYPE[1])) { - user.addRole(Context.getUserService().getRole("System Developer")); - user.addRole(Context.getUserService().getRole("Provider")); - } - User newUser = service.saveUser(user, post.get("password").toString()); - service.setUserProperty(newUser, OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCATION, location.getId().toString()); - return RestUtil.created(response, getUserAsSimpleObject(newUser)); - // return RestUtil.created(response, getDrugAsSimpleObject(drugJustCreated)); - } - - private Person savePatient(Person person, SimpleObject post, Location location) { - // String locationPrefix = l.getAttributes(); - boolean identifierInUse = true; - String identifier = ""; - while (identifierInUse) { - //TODO: set this identifier prefix based on location - identifier = "NEW" + (int) (Math.random() * 100000); - if (Context.getPatientService().getPatients(identifier).isEmpty()) { - identifierInUse = false; - } - } - PatientIdentifier pi = new PatientIdentifier(identifier, Context.getPatientService().getPatientIdentifierTypeByName( - "RaxaEMR Identifier Number"), location); - pi.setPreferred(true); - Patient patient = new Patient(person); - patient.addIdentifier(pi); - System.out.println(patient.getPatientIdentifier()); - int personId = Context.getPatientService().savePatient(patient).getPersonId(); - return (Context.getPersonService().getPerson(personId)); - } - - private void saveProvider(Person person, SimpleObject post) { - boolean identifierInUse = true; - String identifier = ""; - while (identifierInUse) { - identifier = "" + (int) (Math.random() * 100000); - if (Context.getProviderService().getProviderByIdentifier(identifier) == null) { - identifierInUse = false; - } - } - Provider provider = new Provider(); - provider.setPerson(person); - provider.setIdentifier(identifier); - if (post.get("isOutpatientDoctor") == null && post.get("isOutpatientDoctor").equals("true")) { - //Provider service does not allow us to get the provider attribute by name currently, so have to get all.... - Iterator iter = Context.getProviderService().getAllProviderAttributeTypes().iterator(); - while (iter.hasNext()) { - ProviderAttributeType pAttribType = iter.next(); - if (pAttribType.getName().equals("isOutpatientDoctor")) { - ProviderAttribute pAttrib = new ProviderAttribute(); - pAttrib.setValue(true); - pAttrib.setAttributeType(pAttribType); - provider.addAttribute(pAttrib); - break; - } - } - } - Context.getPersonService().savePerson(person); - Context.getProviderService().saveProvider(provider); - - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugGroupResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugGroupResource.java deleted file mode 100644 index 14eac4acc8..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugGroupResource.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import org.openmrs.Drug; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.DrugGroupService; - -/** - * {@link Resource} for DrugGroup, supporting standard CRUD operations This - * resource is currently not used because of serialization issue in OpenMRS core - * (TRUNK-2205) - */ -@Resource("druggroup") -@Handler(supports = DrugGroup.class, order = 0) -public class DrugGroupResource extends MetadataDelegatingCrudResource { - - /** - * Getter for the drugs property on drug group resource - * - * @param drugGroup - * @return - - @PropertyGetter("drugs") - public List getDrugs(DrugGroup drugGroup) { - Set drugs = drugGroup.getDrugs(); - List drugList = new ArrayList(drugs); - return drugList; - } - */ - private DrugGroupService getDrugGroupService() { - return Context.getService(DrugGroupService.class); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#getRepresentationDescription(org.openmrs.module.webservices.rest.web.representation.Representation) - */ - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("drugs", Representation.REF); - description.addProperty("retired"); - description.addSelfLink(); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("drugs", Representation.DEFAULT); - description.addProperty("retired"); - description.addProperty("auditInfo", findMethod("getAuditInfo")); - description.addSelfLink(); - return description; - } - return null; - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getCreatableProperties() - */ - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addRequiredProperty("drug_group_id"); - description.addRequiredProperty("name"); - description.addRequiredProperty("description"); - return description; - } - - /** - * @throws ResourceDoesNotSupportOperationException - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getUpdatableProperties() - */ - @Override - public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("description"); - return description; - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getByUniqueId() - */ - @Override - public DrugGroup getByUniqueId(String uuid) { - return getDrugGroupService().getDrugGroupByUuid(uuid); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#purge() - */ - @Override - public void purge(DrugGroup t, RequestContext rc) throws ResponseException { - getDrugGroupService().deleteDrugGroup(t); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#newDelegate() - */ - @Override - public DrugGroup newDelegate() { - return new DrugGroup(); - } - - /* - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#save() - */ - @Override - public DrugGroup save(DrugGroup drugGroup) { - return getDrugGroupService().saveDrugGroup(drugGroup); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#doGetAll() - * @param context - * @return - * @throws ResponseException - */ - @Override - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(getDrugGroupService().getAllDrugGroup(false), context); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getDisplayString() - * @param delegate - * @return - */ - @Override - public String getDisplayString(DrugGroup delegate) { - if (delegate.getName() == null) { - return ""; - } - return delegate.getName() + " - " + delegate.getDescription(); - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugInfoResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugInfoResource.java deleted file mode 100644 index be9155b77e..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugInfoResource.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.List; -import org.openmrs.Patient; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; - -/** - * {@link Resource} for DrugInfo, supporting standard CRUD operations - * This resource is currently not used because of serialization issue in OpenMRS core (TRUNK-2205) - */ -@Resource("druginfo") -@Handler(supports = DrugInfo.class, order = 0) -public class DrugInfoResource extends MetadataDelegatingCrudResource { - - private DrugInfoService getDrugInfoService() { - return Context.getService(DrugInfoService.class); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#getRepresentationDescription(org.openmrs.module.webservices.rest.web.representation.Representation) - */ - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("price"); - description.addProperty("cost"); - description.addProperty("description"); - description.addProperty("retired"); - description.addSelfLink(); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("price"); - description.addProperty("cost"); - description.addProperty("retired"); - description.addProperty("auditInfo", findMethod("getAuditInfo")); - description.addSelfLink(); - return description; - } - return null; - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getCreatableProperties() - */ - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addRequiredProperty("drug_id"); - description.addRequiredProperty("name"); - description.addRequiredProperty("description"); - return description; - } - - /** - * @throws ResourceDoesNotSupportOperationException - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getUpdatableProperties() - */ - @Override - public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("description"); - return description; - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getByUniqueId() - */ - @Override - public DrugInfo getByUniqueId(String uuid) { - return getDrugInfoService().getDrugInfoByUuid(uuid); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#purge() - */ - @Override - public void purge(DrugInfo t, RequestContext rc) throws ResponseException { - getDrugInfoService().deleteDrugInfo(t); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#newDelegate() - */ - @Override - public DrugInfo newDelegate() { - return new DrugInfo(); - } - - /* - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#save() - */ - @Override - public DrugInfo save(DrugInfo drugInfo) { - return getDrugInfoService().saveDrugInfo(drugInfo); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#doGetAll() - * @param context - * @return - * @throws ResponseException - */ - @Override - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(getDrugInfoService().getAllDrugInfo(false), context); - } - -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugInventoryResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugInventoryResource.java deleted file mode 100644 index 699af2163b..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugInventoryResource.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.List; -import org.openmrs.Patient; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugInventoryService; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; - -/** - * {@link Resource} for PatientList, supporting standard CRUD operations - * This resource is currently not used because of serialization issue in OpenMRS core (TRUNK-2205) - */ -@Resource("druginventory") -@Handler(supports = DrugInventory.class, order = 0) -public class DrugInventoryResource extends MetadataDelegatingCrudResource { - - private DrugInventoryService getDrugInventoryService() { - return Context.getService(DrugInventoryService.class); - } - - @PropertyGetter("druginventory") - public List getAllDrugInventoryList() { - return getDrugInventoryService().getAllDrugInventories(); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - // TODO Auto-generated method stub - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("druId"); - description.addProperty("quantity"); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("drugId"); - description.addProperty("quantity"); - - return description; - } - return null; - } - - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addRequiredProperty("drugId"); - description.addRequiredProperty("quantity"); - return description; - } - - @Override - public DrugInventory newDelegate() { - // TODO Auto-generated method stub - return null; - } - - @Override - public DrugInventory save(DrugInventory drugInventory) { - // TODO Auto-generated method stub - return getDrugInventoryService().saveDrugInventory(drugInventory); - } - - @Override - public DrugInventory getByUniqueId(String uuid) { - return getDrugInventoryService().getDrugInventoryByUuid(uuid); - } - - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(getDrugInventoryService().getAllDrugInventories(), context); - } - - @Override - public void purge(DrugInventory arg0, RequestContext arg1) throws ResponseException { - throw new UnsupportedOperationException("Not supported yet."); - - } - - /** - * Getter for the patients property on patient list resource - * @param patientList - * @return - */ -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugPurchaseOrderResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugPurchaseOrderResource.java deleted file mode 100644 index b8a97af9d5..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/DrugPurchaseOrderResource.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -import java.util.List; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.DrugPurchaseOrderService; - -/** - * {@link Resource} for DrugPurchaseOrder, supporting standard CRUD operations - */ -@Resource("drugpurchaseorder") -@Handler(supports = DrugPurchaseOrder.class, order = 0) -public class DrugPurchaseOrderResource extends MetadataDelegatingCrudResource { - - private DrugPurchaseOrderService getDrugPurchaseOrderService() { - return Context.getService(DrugPurchaseOrderService.class); - } - - @PropertyGetter("drugpurchaseorder") - public DrugPurchaseOrder getDrugPurchaseOrderByUuid(String uuid) { - return getDrugPurchaseOrderService().getDrugPurchaseOrderByUuid(uuid); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("name"); - description.addProperty("providerId"); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("name"); - description.addProperty("providerId"); - - return description; - } - return null; - - } - - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addRequiredProperty("name"); - description.addRequiredProperty("ProviderId"); - return description; - } - - @Override - public DrugPurchaseOrder newDelegate() { - return new DrugPurchaseOrder(); - } - - @Override - public DrugPurchaseOrder save(DrugPurchaseOrder drugOrder) { - return getDrugPurchaseOrderService().saveDrugPurchaseOrder(drugOrder); - } - - public DrugPurchaseOrder getByUniqueId(String uuid) { - return getDrugPurchaseOrderService().getDrugPurchaseOrderByUuid(uuid); - } - - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(getDrugPurchaseOrderService().getAllDrugPurchaseOrders(), context); - } - - @Override - public void purge(DrugPurchaseOrder t, RequestContext rc) throws ResponseException { - throw new UnsupportedOperationException("Not supported yet."); - } - -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/PatientListResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/PatientListResource.java deleted file mode 100644 index 1aa9a992ae..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/PatientListResource.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.List; -import org.openmrs.Patient; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; - -/** - * {@link Resource} for PatientList, supporting standard CRUD operations - * This resource is currently not used because of serialization issue in OpenMRS core (TRUNK-2205) - */ -@Resource("patientlist") -@Handler(supports = PatientList.class, order = 0) -public class PatientListResource extends MetadataDelegatingCrudResource { - - /** - * Getter for the patients property on patient list resource - * @param patientList - * @return - */ - @PropertyGetter("patients") - public List getPatients(PatientList patientList) { - return getPatientListService().getPatientsInPatientList(patientList); - } - - private PatientListService getPatientListService() { - return Context.getService(PatientListService.class); - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#getRepresentationDescription(org.openmrs.module.webservices.rest.web.representation.Representation) - */ - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("searchQuery"); - description.addProperty("patients", Representation.REF); - description.addProperty("retired"); - description.addSelfLink(); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("searchQuery"); - description.addProperty("patients", Representation.DEFAULT); - description.addProperty("retired"); - description.addProperty("auditInfo", findMethod("getAuditInfo")); - description.addSelfLink(); - return description; - } - return null; - } - - /** - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getCreatableProperties() - */ - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addRequiredProperty("name"); - description.addRequiredProperty("description"); - description.addProperty("searchQuery"); - return description; - } - - /** - * @throws ResourceDoesNotSupportOperationException - * @see - * org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getUpdatableProperties() - */ - @Override - public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("description"); - description.addProperty("searchQuery"); - return description; - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getByUniqueId() - */ - @Override - public PatientList getByUniqueId(String uuid) { - return getPatientListService().getPatientListByUuid(uuid); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#purge() - */ - @Override - public void purge(PatientList t, RequestContext rc) throws ResponseException { - getPatientListService().deletePatientList(t); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#newDelegate() - */ - @Override - public PatientList newDelegate() { - return new PatientList(); - } - - /* - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#save() - */ - @Override - public PatientList save(PatientList patientList) { - return getPatientListService().savePatientList(patientList); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#doGetAll() - * @param context - * @return - * @throws ResponseException - */ - @Override - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(getPatientListService().getAllPatientList(false), context); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#doSearch() - * @param query - * @param context - * @return - */ - @Override - protected NeedsPaging doSearch(String query, RequestContext context) { - return new NeedsPaging(getPatientListService().getPatientListByName(query), context); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getDisplayString() - * @param delegate - * @return - */ - @Override - public String getDisplayString(PatientList delegate) { - if (delegate.getName() == null) { - return ""; - } - return delegate.getName() + " - " + delegate.getDescription(); - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/RaxaAlertResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/RaxaAlertResource.java deleted file mode 100644 index c8895f9880..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/RaxaAlertResource.java +++ /dev/null @@ -1,227 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import org.openmrs.Location; -import org.openmrs.Obs; -import org.openmrs.Provider; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.PropertySetter; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ObjectNotFoundException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.raxa.module.raxacore.RaxaAlert; -import org.raxa.module.raxacore.RaxaAlertService; - -/** - * {@link Resource} for {@link Location}, supporting standard CRUD operations - */ -@Resource("raxaalert") -@Handler(supports = RaxaAlert.class, order = 0) -public class RaxaAlertResource extends DataDelegatingCrudResource { - - /** - * @see DelegatingCrudResource#getRepresentationDescription(Representation) - */ - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("patient", Representation.REF); - description.addProperty("seen"); - description.addProperty("alertType"); - description.addProperty("time"); - description.addProperty("defaultTask"); - description.addProperty("providerSent", Representation.REF); - description.addProperty("providerRecipient", Representation.REF); - //cannot add 'voided' property as a bug exists in OpenMRS: tickets.openmrs.org/browse/TRUNK-2205 - //description.addProperty("voided"); - description.addSelfLink(); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("patient"); - description.addProperty("seen"); - description.addProperty("alertType"); - description.addProperty("time"); - description.addProperty("defaultTask"); - description.addProperty("providerSent"); - description.addProperty("providerRecipient"); - //cannot add 'voided' property as a bug exists in OpenMRS: tickets.openmrs.org/browse/TRUNK-2205 - //description.addProperty("voided"); - description.addProperty("auditInfo", findMethod("getAuditInfo")); - description.addSelfLink(); - return description; - } - return null; - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getCreatableProperties() - */ - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - - description.addRequiredProperty("patient"); - description.addRequiredProperty("providerSent"); - description.addRequiredProperty("providerRecipient"); - - description.addProperty("alertType"); - description.addProperty("name"); - description.addProperty("time"); - description.addProperty("defaultTask"); - return description; - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#getUpdatableProperties() - */ - @Override - public DelegatingResourceDescription getUpdatableProperties() { - DelegatingResourceDescription description = getCreatableProperties(); - description.addProperty("seen"); - return description; - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#save(org.openmrs.Encounter) - */ - @Override - public RaxaAlert save(RaxaAlert raxaAlert) { - return Context.getService(RaxaAlertService.class).saveRaxaAlert(raxaAlert); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#getByUniqueId(java.lang.String) - */ - @Override - public RaxaAlert getByUniqueId(String uuid) { - return Context.getService(RaxaAlertService.class).getRaxaAlertByUuid(uuid); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource#doGetAll() - * @param context - * @return - * @throws ResponseException - */ - @Override - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(Context.getService(RaxaAlertService.class).getAllRaxaAlerts(true), context); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#delete(org.openmrs.Encounter, - * java.lang.String, org.openmrs.module.webservices.rest.web.RequestContext) - */ - @Override - public void delete(RaxaAlert raxaAlert, String reason, RequestContext context) throws ResponseException { - if (raxaAlert.isVoided()) { - // DELETE is idempotent, so we return success here - return; - } - Context.getService(RaxaAlertService.class).voidRaxaAlert(raxaAlert, reason); - } - - /** - * @see org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource#purge(org.openmrs.Encounter, - * org.openmrs.module.webservices.rest.web.RequestContext) - */ - @Override - public void purge(RaxaAlert raxaAlert, RequestContext context) throws ResponseException { - if (raxaAlert == null) { - // DELETE is idempotent, so we return success here - return; - } - Context.getService(RaxaAlertService.class).purgeRaxaAlert(raxaAlert); - } - - /** - * @param raxaAlert - * @return encounter type and date - */ - public String getDisplayString(RaxaAlert raxaAlert) { - String ret = "To:"; - ret += raxaAlert.getProviderRecipient() == null ? "?" : raxaAlert.getProviderRecipient().getPerson().getPersonName() - .toString(); - ret += " "; - ret += raxaAlert.getName() == null ? "?" : raxaAlert.getName(); - ret += " "; - ret += raxaAlert.getTime() == null ? "?" : Context.getDateFormat().format(raxaAlert.getTime()); - return ret; - } - - /** - * Gets RaxaAlerts for the given provider (paged according to context if necessary) - * - * @param providerUniqueId - * @see {@link PatientResource#getByUniqueId(String)} for interpretation - * @param context - * @return - * @throws ResponseException - */ - public SimpleObject getRaxaAlertsByProvider(String providerUniqueId, RequestContext context) throws ResponseException { - Provider provider = Context.getProviderService().getProviderByUuid(providerUniqueId); - if (provider == null) { - throw new ObjectNotFoundException(); - } - List raxaAlerts = Context.getService(RaxaAlertService.class).getRaxaAlertByProviderRecipientId( - provider.getId(), false); - return new NeedsPaging(raxaAlerts, context).toSimpleObject(); - } - - @PropertyGetter("providerSent") - public static Object getProviderSent(RaxaAlert instance) { - return Context.getProviderService().getProvider(instance.getProviderSentId()); - } - - @PropertySetter("providerSent") - public static void setProviderSent(RaxaAlert instance, Provider p) { - instance.setProviderSent(p); - instance.setProviderSentId(p.getId()); - } - - /** - * Required for DataDelegatingCrudResource-- we don't have any delegates - * @return - */ - @Override - public RaxaAlert newDelegate() { - throw new UnsupportedOperationException("Not supported yet."); - } -} diff --git a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/RaxaDrugResource.java b/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/RaxaDrugResource.java deleted file mode 100644 index b7082a5936..0000000000 --- a/omod/src/main/java/org/raxa/module/raxacore/web/v1_0/resource/RaxaDrugResource.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -import java.util.List; -import org.openmrs.Patient; -import org.openmrs.annotation.Handler; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.RequestContext; -import org.openmrs.module.webservices.rest.web.RestConstants; -import org.openmrs.module.webservices.rest.web.annotation.PropertyGetter; -import org.openmrs.module.webservices.rest.web.annotation.Resource; -import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; -import org.openmrs.module.webservices.rest.web.representation.FullRepresentation; -import org.openmrs.module.webservices.rest.web.representation.Representation; -import org.openmrs.module.webservices.rest.web.resource.impl.DelegatingResourceDescription; -import org.openmrs.module.webservices.rest.web.resource.impl.MetadataDelegatingCrudResource; -import org.openmrs.module.webservices.rest.web.resource.impl.NeedsPaging; -import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; -import org.openmrs.module.webservices.rest.web.response.ResponseException; -import org.openmrs.api.ConceptService; -import org.openmrs.Drug; - -/** - * {@link Resource} for Drug , supporting standard CRUD operations This resource - * is currently not used because of serialization issue in OpenMRS core - * (TRUNK-2205) - */ -@Resource("drug") -@Handler(supports = Drug.class, order = 0) -public class RaxaDrugResource extends MetadataDelegatingCrudResource { - - private ConceptService getDrugService() { - return Context.getConceptService(); - } - - @Override - public DelegatingResourceDescription getRepresentationDescription(Representation rep) { - if (rep instanceof DefaultRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("price"); - description.addProperty("cost"); - description.addProperty("description"); - description.addProperty("retired"); - description.addSelfLink(); - description.addLink("full", ".?v=" + RestConstants.REPRESENTATION_FULL); - return description; - } else if (rep instanceof FullRepresentation) { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("uuid"); - description.addProperty("display", findMethod("getDisplayString")); - description.addProperty("name"); - description.addProperty("description"); - description.addProperty("price"); - description.addProperty("cost"); - description.addProperty("retired"); - description.addProperty("auditInfo", findMethod("getAuditInfo")); - description.addSelfLink(); - return description; - } - return null; - } - - @Override - public DelegatingResourceDescription getCreatableProperties() { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addRequiredProperty("drug_id"); - description.addRequiredProperty("name"); - description.addRequiredProperty("description"); - return description; - } - - @Override - public DelegatingResourceDescription getUpdatableProperties() throws ResourceDoesNotSupportOperationException { - DelegatingResourceDescription description = new DelegatingResourceDescription(); - description.addProperty("description"); - return description; - } - - @Override - public Drug getByUniqueId(String uuid) { - return getDrugService().getDrugByUuid(uuid); - } - - @Override - public Drug newDelegate() { - return new Drug(); - } - - @Override - public Drug save(Drug drugInfo) { - return getDrugService().saveDrug(drugInfo); - } - - @Override - protected NeedsPaging doGetAll(RequestContext context) throws ResponseException { - return new NeedsPaging(getDrugService().getAllDrugs(false), context); - } - - @Override - public String getDisplayString(Drug delegate) { - if (delegate.getName() == null) { - return ""; - } - return delegate.getName() + " - " + delegate.getDescription(); - } - - @Override - public void purge(Drug t, RequestContext rc) throws ResponseException { - throw new UnsupportedOperationException("Not supported yet."); - } -} diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml deleted file mode 100644 index e0ace629a1..0000000000 --- a/omod/src/main/resources/config.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - @MODULE_ID@ - @MODULE_NAME@ - @MODULE_VERSION@ - @MODULE_PACKAGE@ - Raxa - - Provides core RaxaEMR services - - @MODULE_PACKAGE@.Activator - - https://modules.raxa.org/modules/download/raxacore/update.rdf - - - ${openMRSVersion} - - org.openmrs.module.webservices.rest - - - - - - - - Add Patient Lists - Ability to create patient lists - - - Delete Patient Lists - Ability to delete patient lists - - - Edit Patient Lists - Ability to edit patient lists - - - View Patient Lists - Ability to view patient lists - - - - Add Raxa Alerts - Ability to create raxa alerts - - - Delete Raxa Alerts - Ability to delete raxa alerts - - - Edit Raxa Alerts - Ability to edit raxa alerts - - - View Raxa Alerts - Ability to view raxa alerts - - - - Add Drug Groups - Ability to create Drug Groups - - - Delete Drug Groups - Ability to delete Drug Groups - - - Edit Drug Groups - Ability to edit Drug Groups - - - View Drug Groups - Ability to view Drug Groups - - - - Add Drug Info - Ability to create Drug Info - - - Delete Drug Info - Ability to delete Drug Info - - - Edit Drug Info - Ability to edit Drug Info - - - View Drug Info - Ability to view Drug Info - - - - - - - - - - - en - messages.properties - - - - - RaxacorePatientList.hbm.xml - RaxacoreRaxaAlert.hbm.xml - RaxacoreDrugGroup.hbm.xml - RaxacoreDrugPurchaseOrder.hbm.xml - RaxacoreDrugInventory.hbm.xml - RaxacoreDrugInfo.hbm.xml - - diff --git a/omod/src/main/resources/messages.properties b/omod/src/main/resources/messages.properties deleted file mode 100644 index 1f33c22ea0..0000000000 --- a/omod/src/main/resources/messages.properties +++ /dev/null @@ -1 +0,0 @@ -@MODULE_ID@.title=RaxaEMR Core \ No newline at end of file diff --git a/omod/src/main/resources/webModuleApplicationContext.xml b/omod/src/main/resources/webModuleApplicationContext.xml deleted file mode 100644 index 1b62fcb6a8..0000000000 --- a/omod/src/main/resources/webModuleApplicationContext.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugGroupControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugGroupControllerTest.java deleted file mode 100644 index 659038e063..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugGroupControllerTest.java +++ /dev/null @@ -1,174 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.test.Util; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugGroup; -import org.raxa.module.raxacore.DrugGroupService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class DrugGroupControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private DrugGroupController controller = null; - - private DrugGroupService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new DrugGroupController(); - this.service = Context.getService(DrugGroupService.class); - } - - /** - * @see DrugGroupController#retireDrugGroup(String,String,HttpServletRequest, HttpServletResponse) - * @verifies void a location attribute type - */ - @Test - public void retireDrugGroup_shouldRetireADrugGroup() throws Exception { - DrugGroup dg1 = service.getDrugGroupByUuid(getUuid()); - Assert.assertFalse(dg1.isRetired()); - controller.retireDrugGroup(getUuid(), "testing", request, response); - DrugGroup dg2 = service.getDrugGroupByUuid(getUuid()); - Assert.assertTrue(dg2.isRetired()); - Assert.assertEquals("testing", dg2.getRetireReason()); - } - - /** - * @see DrugGroupController#updateDrugGroup(String, SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void updateDrugGroup_shouldSaveANewDrugGroup() throws Exception { - int before = service.getAllDrugGroup(false).size(); - String json = "{ \"name\":\"Test DrugGroup\",\"description\":\"Test Drug Group\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updateDrugGroup(getUuid(), post, request, response); - Assert.assertEquals(before, service.getAllDrugGroup(false).size()); - String result = controller.getAllDrugGroupByUuid(getUuid(), request); - SimpleObject updatedDrugGroup = SimpleObject.parseJson(result); - Util.log("Updated Drug Group", updatedDrugGroup); - Assert.assertEquals(getUuid(), updatedDrugGroup.get("uuid")); - Assert.assertEquals("Test DrugGroup", updatedDrugGroup.get("name")); - } - - /** - * @see DrugGroupController#createNewDrugGroup(SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void createNewDrugGroup_shouldSaveANewDrugGroup() throws Exception { - int before = service.getAllDrugGroup(false).size(); - String json = "{ \"name\":\"Test DrugGroup\",\"description\":\"Test Drug Group\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object drugGroup = controller.createNewDrugGroup(post, request, response); - Util.log("Created Patient List", drugGroup); - Assert.assertEquals(before + 1, service.getAllDrugGroup(false).size()); - } - - /** - * @see DrugGroupController#getDrugGroupsByName(String,HttpServletRequest) - * @verifies return no results because no matching druggroup name - */ - @Test - public void getDrugGroupsByName_shouldReturnNoResultsIfThereAreNoMatchingDrugGroup() throws Exception { - String results = controller.getDrugGroupsByName("zzzznotype", request); - Assert.assertEquals(0, ((ArrayList) SimpleObject.parseJson(results).get("results")).size()); - } - - /** - * @see DrugGroupController#getDrugGroupsByName(String,HttpServletRequest) - * @verifies find matching patient list - */ - @Test - public void getDrugGroupsByName_shouldFindMatchingDrugGroups() throws Exception { - String results = controller.getDrugGroupsByName("TestDrugGroup2", request); - LinkedHashMap drugGroup = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Util.log("Found DrugGroup(s)", drugGroup); - Assert.assertEquals("68547121-1b70-465e-99ee-c9dfd95e7d30", drugGroup.get("uuid")); - Assert.assertEquals("TestDrugGroup2", drugGroup.get("name")); - Assert.assertNull(drugGroup.get("auditInfo")); - } - - /** - * @see DrugGroupController#getAllDrugGroupByUuidFull(String, String, HttpServletRequest) - * @verifies get the full representation of a patient list by its uuid - */ - @Test - public void getDrugGroupByUuidFull_shouldGetAFullRepresentationOfADrugGroup() throws Exception { - String result = controller.getAllDrugGroupByUuidFull(getUuid(), "full", request); - SimpleObject drugGroup = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Util.log("DrugGroup fetched (full)", result); - Assert.assertEquals("68547121-1b70-465d-99ee-c9dfd95e7d30", drugGroup.get("uuid")); - Assert.assertEquals("TestDrugGroup1", drugGroup.get("name")); - Assert.assertNotNull(drugGroup.get("auditInfo")); - } - - /** - * @see DrugGroupController#getAllDrugGroupByUuid(String, HttpServletRequest) - * @verifies get a default representation of a patient list by its uuid - */ - @Test - public void getDrugGroupByUuid_shouldGetADefaultRepresentationOfADrugGroup() throws Exception { - String result = controller.getAllDrugGroupByUuid(getUuid(), request); - SimpleObject drugGroup = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Util.log("DrugGroup fetched (default)", result); - Assert.assertEquals("68547121-1b70-465d-99ee-c9dfd95e7d30", drugGroup.get("uuid")); - Assert.assertEquals("TestDrugGroup1", drugGroup.get("name")); - Assert.assertNull(drugGroup.get("auditInfo")); - } - - /** - * @see DrugGroupController#getAllDrugGroups(HttpServletRequest, HttpServletResponse) - * @verifies get all the DrugGroup in the system - */ - @Test - public void shouldGetAll() throws Exception { - String allDrugGroups = controller.getAllDrugGroups(request, response); - Util.log("All Drug Groups", allDrugGroups); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allDrugGroups).get("results")).size()); - } - - /** - * @see org.openmrs.module.webservices.rest.web.v1_0.controller.BaseCrudControllerTest#getUuid() - */ - public String getUuid() { - return "68547121-1b70-465d-99ee-c9dfd95e7d30"; - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInfoControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInfoControllerTest.java deleted file mode 100644 index d9575bf076..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInfoControllerTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.raxa.module.raxacore.web.v1_0.controller; - -import java.util.ArrayList; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.test.Util; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugGroupService; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -/** - * - * @author joman - */ -public class DrugInfoControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private DrugInfoController controller = null; - - private DrugInfoService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new DrugInfoController(); - this.service = Context.getService(DrugInfoService.class); - } - - /** - * Test of createNewDrugInfo method, of class DrugInfoController. - */ - @Test - public void createNewDrugInfo_shouldSaveANewDrugInfo() throws Exception { - int before = service.getAllDrugInfo(true).size(); - String json = "{ \"name\":\"Test DrugInfo\",\"description\":\"Test Drug Group\", \"drug\":\"3cfcf118-931c-46f7-8ff6-7b876f0d4202\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object drugInfo = controller.createNewDrugInfo(post, request, response); - Assert.assertEquals(before + 1, service.getAllDrugInfo(false).size()); - } - - /** - * Test of updateDrugInfo method, of class DrugInfoController. - */ - @Test - public void testUpdateDrugInfo_shouldUpdateDrugInfo() throws Exception { - int before = service.getAllDrugInfo(false).size(); - String json = "{ \"name\":\"NameChange\",\"description\":\"Test Drug Info\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updateDrugInfo(getUuid(), post, request, response); - Assert.assertEquals(before, service.getAllDrugInfo(false).size()); - String result = controller.getAllDrugInfoByUuid(getUuid(), request); - SimpleObject updatedDrugGroup = SimpleObject.parseJson(result); - Assert.assertEquals(getUuid(), updatedDrugGroup.get("uuid")); - Assert.assertEquals("NameChange", updatedDrugGroup.get("name")); - } - - /** - * Test of getAllDrugInfo method, of class DrugInfoController. - */ - @Test - public void testGetAllDrugInfo() throws Exception { - String allDrugInfos = controller.getAllDrugInfo(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allDrugInfos).get("results")).size()); - } - - /** - * Test of getAllDrugInfoByUuid method, of class DrugInfoController. - */ - @Test - public void testGetAllDrugInfoByUuid() throws Exception { - String result = controller.getAllDrugInfoByUuid(getUuid(), request); - SimpleObject drugGroup = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals(getUuid(), drugGroup.get("uuid")); - Assert.assertEquals("TestDrugInfo1", drugGroup.get("name")); - Assert.assertNull(drugGroup.get("auditInfo")); - } - - /** - * Test of getAllDrugInfoByUuidFull method, of class DrugInfoController. - */ - @Test - public void testGetAllDrugInfoByUuidFull() throws Exception { - String result = controller.getAllDrugInfoByUuidFull(getUuid(), "full", request); - SimpleObject drugGroup = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals(getUuid(), drugGroup.get("uuid")); - Assert.assertEquals("TestDrugInfo1", drugGroup.get("name")); - Assert.assertNotNull(drugGroup.get("auditInfo")); - } - - /** - * Test of voidDrugInfo method, of class DrugInfoController. - */ - @Test - public void testRetireDrugInfo() throws Exception { - DrugInfo di1 = service.getDrugInfoByUuid(getUuid()); - Assert.assertFalse(di1.isRetired()); - controller.retireDrugInfo(getUuid(), "testing", request, response); - DrugInfo di2 = service.getDrugInfoByUuid(getUuid()); - Assert.assertTrue(di2.isRetired()); - Assert.assertEquals("testing", di2.getRetireReason()); - } - - /** - * Test of purgeDrugInfo method, of class DrugInfoController. - */ - @Test - public void testPurgeDrugInfo() throws Exception { - DrugInfo di1 = service.getDrugInfoByUuid(getUuid()); - Assert.assertFalse(di1.getRetired()); - controller.purgeDrugInfo(getUuid(), request, response); - DrugInfo di2 = service.getDrugInfoByUuid(getUuid()); - Assert.assertNull(di2); - } - - public String getUuid() { - return "68547121-1b70-465d-99ee-dddfd95e7d21"; - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInventoryControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInventoryControllerTest.java deleted file mode 100644 index 3d4da46390..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugInventoryControllerTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.ArrayList; -import java.util.LinkedHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.junit.Assert.*; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.test.Util; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugInventoryService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class DrugInventoryControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private DrugInventoryController controller = null; - - private DrugInventoryService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new DrugInventoryController(); - this.service = Context.getService(DrugInventoryService.class); - } - - /** - * Test of saveDrugInventory method, of class DrugInventoryController. - */ - @Test - public void testSaveDrugInventory() throws Exception { - int before = service.getAllDrugInventories().size(); - String json = "{ \"name\":\"Test Drug Inventory\",\"description\":\"Test drug inventory\", \"drugId\": 2, \"quantity\": 500 }"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.saveDrugInventory(post, request, response); - int after = service.getAllDrugInventories().size(); - Assert.assertEquals(before + 1, after); - - } - - /** - * Test of getDrugInventoryByUuid method, of class DrugInventoryController. - */ - @Test - public void testGetDrugInventoryByUuid() throws Exception { - String uuid = "68547121-1b70-465c-99ee-c9dfd95e7d36"; - String result = controller.getDrugInventoryByUuid(uuid, request); - SimpleObject dI = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - assertEquals(uuid, dI.get("uuid")); - } - - /** - * @see DrugInventoryController#updateDrugInventory(String, SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies updates a drug inv - */ - @Test - public void updateDrugInventory_shouldUpdateDrugInventory() throws Exception { - int before = service.getAllDrugInventories().size(); - String json = "{ \"name\":\"Updated DrugInv\",\"description\":\"Update\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updateDrugInventory("68547121-1b70-465c-99ee-c9dfd95e7d36", post, request, response); - String results = controller.getAllDrugInventories(request, response); - //SimpleObject updatedRaxaAlert = SimpleObject.parseJson(results.substring(12, result.length() - 2)); - LinkedHashMap updatedRaxaAlert = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals("68547121-1b70-465c-99ee-c9dfd95e7d36", updatedRaxaAlert.get("uuid")); - Assert.assertEquals("Updated DrugInv", updatedRaxaAlert.get("name")); - } - - /** - * @see DrugInventoryController#getAllDrugInventories(HttpServletRequest, HttpServletResponse) - * @verifies get all the Drug Invs in the system - */ - @Test - public void shouldGetAll() throws Exception { - String allDIs = controller.getAllDrugInventories(request, response); - Assert.assertEquals(1, ((ArrayList) SimpleObject.parseJson(allDIs).get("results")).size()); - } - - /** - * @see RaxaAlertController#searchByProviderRecipient(String, HttpServeletRequest, HttpServletResponse) - * @throws Exception - */ - @Test - public void searchByLocation_shouldGetInventoriesByLocation() throws Exception { - String results = controller.searchByLocation("dc5c1fcc-0459-4201-bf70-0b90535ba362", request); - LinkedHashMap di = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals("Test drug inventory", di.get("name")); - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugPurchaseOrderControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugPurchaseOrderControllerTest.java deleted file mode 100644 index d18e8c531f..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/DrugPurchaseOrderControllerTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import javax.servlet.http.HttpServletRequest; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.Provider; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugInventory; -import org.raxa.module.raxacore.DrugInventoryService; -import org.raxa.module.raxacore.DrugPurchaseOrder; -import org.raxa.module.raxacore.DrugPurchaseOrderService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class DrugPurchaseOrderControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private DrugPurchaseOrderController controller = null; - - private DrugPurchaseOrderService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new DrugPurchaseOrderController(); - this.service = Context.getService(DrugPurchaseOrderService.class); - } - - /** - * Test of createNewDrugPurchaseOrder method, of class DrugPurchaseOrderController. - */ - @Test - public void testCreateNewDrugPurchaseOrder() throws Exception { - int before = service.getAllDrugPurchaseOrders().size(); - String json = "{ \"name\":\"Test purchase order\",\"description\":\"Test purchase order\", \"provider\": \"68547121-1b70-465e-99ee-c9df45jf9j32\", \"received\": \"true\", \"inventories\": [{\"name\":\"Test inner Drug Inventory\",\"description\":\"Test drug inventory\", \"drug\": \"05ec820a-d297-44e3-be6e-698531d9dd3f\", \"quantity\": 500, \"location\": \"9356400c-a5a2-4532-8f2b-2361b3446eb8\", \"expiryDate\":\"Wed Sep 19 2012 00:00:00 GMT+0530 (India Standard Time)\"}, {\"name\":\"Test inner Drug Inventory 2\",\"description\":\"Test drug inventory2\", \"drug\": \"05ec820a-d297-44e3-be6e-698531d9dd3f\", \"quantity\": 500, \"supplier\": \"test supplier\", \"location\": \"9356400c-a5a2-4532-8f2b-2361b3446eb8\", \"expiryDate\":\"Sep 26, 2012 12:00:00 AM\"}]}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.createNewDrugPurchaseOrder(post, request, response); - int after = service.getAllDrugPurchaseOrders().size(); - Provider p = Context.getProviderService().getProviderByUuid("68547121-1b70-465e-99ee-c9df45jf9j32"); - List dPOs = Context.getService(DrugPurchaseOrderService.class).getDrugPurchaseOrderByProvider( - p.getId()); - List dis = Context.getService(DrugInventoryService.class).getDrugInventoriesByLocation(2); - Assert.assertNotNull(dis); - Assert.assertEquals(2, dis.size()); - Assert.assertEquals("Test inner Drug Inventory", dis.get(0).getName()); - Assert.assertNotNull(dis.get(0).getExpiryDate()); - Assert.assertEquals(dis.get(1).getSupplier(), "test supplier"); - Assert.assertEquals(true, dPOs.get(0).isReceived()); - Assert.assertEquals(before + 1, after); - } - - /** - * Test of getDrugPuchaseOrderByUuid method, of class DrugPurchaseOrderController. - */ - @Test - public void testGetDrugPuchaseOrderByUuid() throws Exception { - String uuid = "68547121-1b70-465c-99ee-c9dfd95e7d41"; - String result = controller.getDrugPuchaseOrderByUuid(uuid, request); - SimpleObject dI = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - assertEquals(uuid, dI.get("uuid")); - } - - /** - * @see DrugPurchaseOrderController#getAllDrugPurchaseOrders(HttpServletRequest, HttpServletResponse) - * @verifies get all the Drug Invs in the system - */ - @Test - public void shouldGetAll() throws Exception { - String allDIs = controller.getAllDrugPurchaseOrders(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allDIs).get("results")).size()); - } - - /** - * @see DrugPurchaseOrderController#searchByStockLocation(String, HttpServeletRequest, HttpServletResponse) - * @throws Exception - */ - @Test - public void searchByStockLocation_shouldGetPurchaseOrdersByStockLocation() throws Exception { - String results = controller.searchByStockLocation("9356400c-a5a2-4532-8f2b-2361b3446eb8", request); - LinkedHashMap di = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals("Test drug PO", di.get("name")); - } - - /** - * @see DrugPurchaseOrderController#updateDrugPurchaseOrder(String, SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void updateDrugPurchaseOrder_shouldUpdateADrugPurchaseOrder() throws Exception { - int before = service.getAllDrugPurchaseOrders().size(); - String json = "{ \"name\":\"Test DrugPurchaseOrder Change\",\"description\":\"Test Alert\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updateDrugPurchaseOrder("68547121-1b70-465c-99ee-c9dfd95e7d41", post, request, response); - Assert.assertEquals(before, service.getAllDrugPurchaseOrders().size()); - String results = controller.getAllDrugPurchaseOrders(request, response); - LinkedHashMap updatedDrugPurchaseOrder = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")) - .get(0); - Assert.assertEquals("Test DrugPurchaseOrder Change", updatedDrugPurchaseOrder.get("name")); - } - -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/PatientListControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/PatientListControllerTest.java deleted file mode 100644 index 9deb8ad47a..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/PatientListControllerTest.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.Encounter; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.module.webservices.rest.test.Util; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class PatientListControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private PatientListController controller = null; - - private PatientListService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new PatientListController(); - this.service = Context.getService(PatientListService.class); - } - - /** - * @see PatientListController#retirePatientList(String,String,HttpServletRequest, HttpServletResponse) - * @verifies void a location attribute type - */ - @Test - public void retirePatientList_shouldRetireAPatientList() throws Exception { - PatientList pl1 = service.getPatientListByUuid(getUuid()); - Assert.assertFalse(pl1.isRetired()); - controller.retirePatientList(getUuid(), "testing", request, response); - PatientList pl2 = service.getPatientListByUuid(getUuid()); - Assert.assertTrue(pl2.isRetired()); - Assert.assertEquals("testing", pl2.getRetireReason()); - } - - /** - * @see PatientListController#getPatientsInPatientList(String, HttpServletRequest) - * @verifies get a default representation of a patient list by its uuid - */ - @Test - public void getPatientsInPatientList_shouldGetPatientsInPatientList() throws Exception { - HashMap hashMap = new HashMap(); - hashMap.put("encounterType", "61ae96f4-6afe-4351-b6f8-cd4fc383cce1"); - hashMap.put("startDate", "2000-01-01T00:00:00.0"); - hashMap.put("endDate", "2012-01-02T00:00:00.0"); - String result = controller.getPatientsInPatientList(hashMap, request); - SimpleObject patientList = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals(3, ((ArrayList) patientList.get("patients")).size()); - } - - /** - * @see PatientListController#updatePatientList(String, SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void updatePatientList_shouldSaveANewPatientList() throws Exception { - int before = service.getAllPatientList(false).size(); - String json = "{ \"name\":\"Test PatientList\",\"description\":\"Test List of Patients\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updatePatientList(getUuid(), post, request, response); - Assert.assertEquals(before, service.getAllPatientList(false).size()); - String result = controller.getAllPatientListByUuid(getUuid(), request); - SimpleObject updatedPatientList = SimpleObject.parseJson(result); - Assert.assertEquals(getUuid(), updatedPatientList.get("uuid")); - Assert.assertEquals("Test PatientList", updatedPatientList.get("name")); - } - - /** - * @see PatientListController#createNewPatientList(SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void createNewPatientList_shouldSaveANewPatientList() throws Exception { - int before = service.getAllPatientList(false).size(); - String json = "{ \"name\":\"Test PatientList\",\"description\":\"Test List of Patients\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object patientList = controller.createNewPatientList(post, request, response); - Assert.assertEquals(before + 1, service.getAllPatientList(false).size()); - } - - @Test - public void getPatientsInPatientListV2_shouldGetPatients() throws Exception { - HashMap hashMap = new HashMap(); - hashMap.put("encounterType", "61ae96f4-6afe-4351-b6f8-cd4fc383cce1"); - hashMap.put("startDate", "2000-01-01T00:00:00"); - hashMap.put("endDate", "2007-01-02T00:00:00"); - hashMap.put("excludeEncounterType", "07000be2-26b6-4cce-8b40-866d8435b613"); - String result = controller.getPatientsInPatientListV2(hashMap, request); - List patientList = (ArrayList) SimpleObject.parseJson(result).get("patients"); - //now checking that notInList works - for (int i = 0; i < patientList.size(); i++) { - System.out.println(patientList.get(i)); - } - Assert.assertEquals(1, patientList.size()); - } - - /** - * @see PatientListController#getPatientListsByName(String,HttpServletRequest) - * @verifies return no results because no matching patientlist name - */ - @Test - public void getPatientListsByName_shouldReturnNoResultsIfThereAreNoMatchingPatientList() throws Exception { - String results = controller.getPatientListsByName("zzzznotype", request); - Assert.assertEquals(0, ((ArrayList) SimpleObject.parseJson(results).get("results")).size()); - } - - /** - * @see PatientListController#getPatientListsByName(String,HttpServletRequest) - * @verifies find matching patient list - */ - @Test - public void getPatientListsByName_shouldFindMatchingPatientList() throws Exception { - String results = controller.getPatientListsByName("TestList2", request); - LinkedHashMap patientList = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals("68547121-1b70-465e-99ee-c9dfd95e7d30", patientList.get("uuid")); - Assert.assertEquals("TestList2", patientList.get("name")); - Assert.assertNull(patientList.get("searchQuery")); - Assert.assertNull(patientList.get("auditInfo")); - } - - /** - * @see PatientListController#getAllPatientListByUuidFull(String, String, HttpServletRequest) - * @verifies get the full representation of a patient list by its uuid - */ - @Test - public void getPatientListByUuidFull_shouldGetAFullRepresentationOfAPatientList() throws Exception { - String result = controller.getAllPatientListByUuidFull(getUuid(), "full", request); - SimpleObject patientList = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals("68547121-1b70-465d-99ee-c9dfd95e7d30", patientList.get("uuid")); - Assert.assertEquals("TestList1", patientList.get("name")); - Assert.assertNotNull(patientList.get("searchQuery")); - Assert.assertNotNull(patientList.get("auditInfo")); - } - - /** - * @see PatientListController#getAllPatientListByUuid(String, HttpServletRequest) - * @verifies get a default representation of a patient list by its uuid - */ - @Test - public void getPatientListByUuid_shouldGetADefaultRepresentationOfAPatientList() throws Exception { - String result = controller.getAllPatientListByUuid(getUuid(), request); - SimpleObject patientList = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals("68547121-1b70-465d-99ee-c9dfd95e7d30", patientList.get("uuid")); - Assert.assertEquals("TestList1", patientList.get("name")); - Assert.assertNull(patientList.get("searchQuery")); - Assert.assertNull(patientList.get("auditInfo")); - } - - /** - * @see PatientListController#getAllPatientLists(HttpServletRequest, HttpServletResponse) - * @verifies get all the PatientList in the system - */ - @Test - public void shouldGetAll() throws Exception { - String allPatientLists = controller.getAllPatientLists(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allPatientLists).get("results")).size()); - } - - /** - * @see org.openmrs.module.webservices.rest.web.v1_0.controller.BaseCrudControllerTest#getUuid() - */ - public String getUuid() { - return "68547121-1b70-465d-99ee-c9dfd95e7d30"; - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaAlertControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaAlertControllerTest.java deleted file mode 100644 index 9295c3da88..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaAlertControllerTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import java.util.ArrayList; -import java.util.LinkedHashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.RaxaAlertService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class RaxaAlertControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaAlertController controller = null; - - private RaxaAlertService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaAlertController(); - this.service = Context.getService(RaxaAlertService.class); - } - - /** - * @see RaxaAlertController#updateRaxaAlert(String, SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void updateRaxaAlert_shouldUpdateARaxaAlert() throws Exception { - int before = service.getAllRaxaAlerts(true).size(); - String json = "{ \"name\":\"Test RaxaAlert\",\"description\":\"Test Alert\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updateRaxaAlert(getUuid(), post, request, response); - Assert.assertEquals(before, service.getAllRaxaAlerts(true).size()); - String results = controller.getAllRaxaAlerts(request, response); - //SimpleObject updatedRaxaAlert = SimpleObject.parseJson(results.substring(12, result.length() - 2)); - LinkedHashMap updatedRaxaAlert = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals(getUuid(), updatedRaxaAlert.get("uuid")); - Assert.assertEquals("Test RaxaAlert", updatedRaxaAlert.get("name")); - } - - /** - * @see RaxaAlertController#createNewRaxaAlert(SimpleObject, HttpServletRequest, HttpServletResponse) - * @verifies a new patient list is created - */ - @Test - public void createNewRaxaAlert_shouldSaveANewRaxaAlert() throws Exception { - int before = service.getAllRaxaAlerts(true).size(); - String json = "{ \"name\":\"Test RaxaAlert\",\"description\":\"Test Alert\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object RaxaAlert = controller.createNewRaxaAlert(post, request, response); - Assert.assertEquals(before + 1, service.getAllRaxaAlerts(true).size()); - } - - /** - * @see RaxaAlertController#getAllRaxaAlertByUuid(String, HttpServletRequest) - * @verifies get a default representation of a patient list by its uuid - */ - @Test - public void getRaxaAlertByUuid_shouldGetADefaultRepresentationOfARaxaAlert() throws Exception { - String result = controller.getRaxaAlertByUuid(getUuid(), request); - SimpleObject RaxaAlert = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals("68547121-1b70-465e-99ee-c9dfd95e7d31", RaxaAlert.get("uuid")); - Assert.assertEquals("TestAlert1", RaxaAlert.get("name")); - } - - /** - * @see RaxaAlertController#getAllRaxaAlerts(HttpServletRequest, HttpServletResponse) - * @verifies get all the RaxaAlert in the system - */ - @Test - public void shouldGetAll() throws Exception { - String allRaxaAlerts = controller.getAllRaxaAlerts(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allRaxaAlerts).get("results")).size()); - } - - /** - * @see RaxaAlertController#searchByProviderRecipient(String, HttpServeletRequest, HttpServletResponse) - * @throws Exception - */ - @Test - public void searchByProviderRecipient_shouldGetAlertsByProvider() throws Exception { - String results = controller.searchByProviderRecipient("68547121-1b70-465e-99ee-c9df45jf9j32", request); - LinkedHashMap raxaAlert = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - System.out.println(Context.getProviderService().getProvider(1).getUuid()); - Assert.assertEquals("TestAlert1", raxaAlert.get("name")); - } - - @Test - public void searchByToLocation_shouldGetAlertsByLocation() throws Exception { - String results = controller.searchByToLocation("9356400c-a5a2-4532-8f2b-2361b3446eb8", request); - LinkedHashMap raxaAlert = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals("TestAlert2", raxaAlert.get("name")); - } - - /** - * @see org.openmrs.module.webservices.rest.web.v1_0.controller.BaseCrudControllerTest#getUuid() - */ - public String getUuid() { - return "68547121-1b70-465e-99ee-c9dfd95e7d31"; - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaDrugControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaDrugControllerTest.java deleted file mode 100644 index 3b5a8ccfac..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaDrugControllerTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.Drug; -import org.openmrs.api.ConceptService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.raxa.module.raxacore.DrugInfo; -import org.raxa.module.raxacore.DrugInfoService; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class RaxaDrugControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaDrugController controller = null; - - private ConceptService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaDrugController(); - this.service = Context.getConceptService(); - } - - /** - * Test of createNewDrug method, of class RaxaDrugController. - */ - @Test - public void createNewDrug_shouldCreateNewDrug() throws Exception { - int before = service.getAllDrugs(true).size(); - String json = "{\"concept\":\"0cbe2ed3-cd5f-4f46-9459-26127c9265ab\",\"name\":\"New Drug name\",\"dosageForm\":\"0cbe2ed3-cd5f-4f46-9459-26127c9265ab\",\"minimumDailyDose\":\"10\",\"maximumDailyDose\":\"100\",\"units\":\"mg\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object drug = controller.createNewDrug(post, request, response); - Assert.assertEquals(before + 1, service.getAllDrugs(true).size()); - } - - /** - * Test of createNewDrug method, of class RaxaDrugController. - */ - @Test - public void createNewDrug_shouldCreateNewDrugInfo() throws Exception { - String json = "{\"concept\":\"0cbe2ed3-cd5f-4f46-9459-26127c9265ab\",\"name\":\"New Drug name\",\"dosageForm\":\"0cbe2ed3-cd5f-4f46-9459-26127c9265ab\",\"minimumDailyDose\":\"10\",\"maximumDailyDose\":\"100\",\"units\":\"mg\", \"drugInfo\":{ \"name\":\"Inner DrugInfo\",\"description\":\"Test Drug Group\", \"drug\":\"3cfcf118-931c-46f7-8ff6-7b876f0d4202\"} }"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object drug = controller.createNewDrug(post, request, response); - List drugInfos = Context.getService(DrugInfoService.class).getAllDrugInfo(true); - Boolean foundNewDrugInfo = false; - for (int i = 0; i < drugInfos.size(); i++) { - DrugInfo di = drugInfos.get(i); - if (di.getName().equals("Inner DrugInfo")) { - foundNewDrugInfo = true; - } - } - Assert.assertEquals(true, foundNewDrugInfo); - } - - /** - * Test of updateDrug method, of class RaxaDrugController. - */ - @Test - public void updateDrug_shouldUpdateADrug() throws Exception { - int before = service.getAllDrugs(true).size(); - String json = "{ \"name\":\"Changed name\",\"description\":\"Test\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.updateDrug(getUuid(), post, request, response); - Assert.assertEquals(before, service.getAllDrugs(true).size()); - String results = controller.getAllDrugs(request, response); - LinkedHashMap updatedDrugs = (LinkedHashMap) ((ArrayList) SimpleObject.parseJson(results).get("results")).get(0); - Assert.assertEquals(getUuid(), updatedDrugs.get("uuid")); - Assert.assertEquals("Changed name", updatedDrugs.get("name")); - } - - /** - * Test of getAllDrug method, of class RaxaDrugController. - */ - @Test - public void getAllDrugs_shouldGetDrugs() throws Exception { - String allDrugs = controller.getAllDrugs(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allDrugs).get("results")).size()); - } - - /** - * Test of getDrugByUuid method, of class RaxaDrugController. - */ - @Test - public void getDrugByUuid_shouldGetDrug() throws Exception { - String result = controller.getDrugByUuid(getUuid(), request); - SimpleObject drug = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals(getUuid(), drug.get("uuid")); - Assert.assertEquals("Triomune-30", drug.get("name")); - } - - /** - * Test of getAllDrugByUuidFull method, of class RaxaDrugController. - */ - @Test - public void getDrugByUuidFull_shouldGetFullDrug() throws Exception { - String result = controller.getDrugByUuidFull(getUuid(), "full", request); - SimpleObject drug = SimpleObject.parseJson(result); - Assert.assertNotNull(result); - Assert.assertEquals(getUuid(), drug.get("uuid")); - Assert.assertEquals(false, drug.get("retired")); - } - - /** - * Test of retireDrug method, of class RaxaDrugController. - */ - @Test - public void testRetireDrug() throws Exception { - Drug drug = service.getDrugByUuid(getUuid()); - Assert.assertFalse(drug.isRetired()); - controller.retireDrug(getUuid(), "testing", request, response); - Drug drug2 = service.getDrugByUuid(getUuid()); - Assert.assertTrue(drug2.isRetired()); - Assert.assertEquals("testing", drug2.getRetireReason()); - } - - private String getUuid() { - return "3cfcf118-931c-46f7-8ff6-7b876f0d4202"; - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaEncounterControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaEncounterControllerTest.java deleted file mode 100644 index 3d94f04ee6..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaEncounterControllerTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.Encounter; -import org.openmrs.api.EncounterService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class RaxaEncounterControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaEncounterController controller = null; - - private EncounterService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaEncounterController(); - this.service = Context.getService(EncounterService.class); - } - - /** - * Test of createNewEncounter method, of class RaxaEncounterController. - */ - @Test - public void testCreateNewEncounter() throws Exception { - String json = "{ \"patient\":\"da7f524f-27ce-4bb2-86d6-6d1d05312bd5\",\"encounterDatetime\":\"2013-01-07T12:40:20Z\", \"encounterType\": \"61ae96f4-6afe-4351-b6f8-cd4fc383cce1\", \"location\": \"9356400c-a5a2-4532-8f2b-2361b3446eb8\", \"obs\": [{\"person\":\"da7f524f-27ce-4bb2-86d6-6d1d05312bd5\",\"concept\":\"4bbbb198-b0af-4681-b5c5-1d3cc6f6e53a\", \"obsDatetime\": \"2013-01-07T12:40:20Z\", \"value\":\"xViii7CyCiiikMKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9k=\", \"location\": \"9356400c-a5a2-4532-8f2b-2361b3446eb8\"}, {\"person\":\"da7f524f-27ce-4bb2-86d6-6d1d05312bd5\",\"concept\":\"b055abd8-a420-4a11-8b98-02ee170a7b54\", \"obsDatetime\": \"2013-01-07T12:40:20Z\", \"value\": \"500\", \"location\": \"9356400c-a5a2-4532-8f2b-2361b3446eb8\"}]}"; - - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - controller.createNewEncounter(post, request, response); - List encs = service.getEncountersByPatient(Context.getPatientService().getPatientByUuid( - "da7f524f-27ce-4bb2-86d6-6d1d05312bd5")); - System.out.println(encs); - } - - /** - * Test of getEncounterByUuidFull method, of class RaxaEncounterController. - */ - @Test - public void testGetEncounterByUuidFull() throws Exception { - String result = controller.getEncounterByUuidFull("6519d653-393b-4118-9c83-a3715b82d4ac", request); - SimpleObject encounter = SimpleObject.parseJson(result); - System.out.println(result); - Assert.assertNotNull(result); - Assert.assertEquals("6519d653-393b-4118-9c83-a3715b82d4ac", encounter.get("uuid")); - } - - /** - * Test of getEncountersByProvider method, of class RaxaEncounterController. - */ - @Test - public void testGetEncountersByProvider() throws Exception { - Map params = new HashMap(); - params.put("provider", "68547121-1b70-465e-99ee-c9df45jf9j32"); - String results = controller.getEncountersByProvider(params, request); - List encounters = (ArrayList) (SimpleObject.parseJson(results).get("results")); - Assert.assertEquals(1, encounters.size()); - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaLoginControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaLoginControllerTest.java deleted file mode 100644 index 527d0c2d3b..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaLoginControllerTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import junit.framework.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -public class RaxaLoginControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaLoginController controller = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaLoginController(); - } - - /** - * Test of getLoginInfo method, of class RaxaLoginController. - */ - @Test - public void testGetLoginInfo() throws Exception { - String result = controller.getLoginInfo(request, response); - SimpleObject loginInfo = SimpleObject.parseJson(result); - Assert.assertEquals("ba1b19c2-3ed6-4f63-b8c0-f762dc8d7562", loginInfo.get("personUuid")); - } - -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientAccessControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientAccessControllerTest.java deleted file mode 100644 index 8b650d763f..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientAccessControllerTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.controller; - -import java.util.ArrayList; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.api.PersonService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -/** - * - * @author joman - */ -public class RaxaPatientAccessControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaPatientAccessController controller = null; - - private PersonService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaPatientAccessController(); - this.service = Context.getPersonService(); - } - - /** - * Test of createNewRelationship method, of class RaxaPatientAccessController. - */ - @Test - public void testCreateNewRelationship() throws Exception { - int before = service.getAllRelationships(true).size(); - String json = "{\"fromPerson\":\"a7e04421-525f-442f-8138-05b619d16def\",\"toPerson\":\"5946f880-b197-400b-9caa-a3c661d23041\",\"relationshipType\":\"Doctor/Patient\"}"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object drug = controller.createNewRelationship(post, request, response); - Assert.assertEquals(before + 1, service.getAllRelationships(true).size()); - } - - /** - * Test of getRelationships method, of class RaxaPatientAccessController. - */ - @Test - public void testGetRelationships() throws Exception { - String allRelationships = controller.getAllRelationships(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allRelationships).get("results")).size()); - } - - /** - * Test of getRelationshipByUuid method, of class RaxaPatientAccessController. - */ - @Test - public void testGetRelationshipByUuid() throws Exception { - String result = controller.getRelationshipByUuid("c18717dd-5d78-4a0e-84fc-ee62c5f0676a", request); - Assert.assertNotNull(result); - } - - /** - * Test of getAllRelationships method, of class RaxaPatientAccessController. - */ - @Test - public void testGetAllRelationships() throws Exception { - String allRelationships = controller.getAllRelationships(request, response); - Assert.assertEquals(2, ((ArrayList) SimpleObject.parseJson(allRelationships).get("results")).size()); - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientControllerTest.java deleted file mode 100644 index 313fb5b0af..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaPatientControllerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.raxa.module.raxacore.web.v1_0.controller; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Assert; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.Patient; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -/** - * - * @author joman - */ -public class RaxaPatientControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaPatientController controller = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaPatientController(); - } - - /** - * Test of createNewPatient method, of class RaxaPatientController. - */ - @Test - public void testCreateNewPatient() throws Exception { - String json = "{\"names\": [{\"givenName\":\"john\",\"familyName\":\"James\"}],\"gender\":\"M\", \"age\":23 }"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - SimpleObject patient = (SimpleObject) (controller.createNewPatient(post, request, response)); - System.out.println(patient); - System.out.println(patient.get("uuid")); - Patient p = Context.getPatientService().getPatientByUuid(patient.get("uuid").toString()); - Assert.assertNotNull(p); - Assert.assertEquals("James", p.getFamilyName()); - Assert.assertTrue(p.getAge() == 23); - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaUserControllerTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaUserControllerTest.java deleted file mode 100644 index fa29d9ffc3..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/controller/RaxaUserControllerTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.raxa.module.raxacore.web.v1_0.controller; - -import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import junit.framework.Assert; -import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Before; -import org.openmrs.Provider; -import org.openmrs.User; -import org.openmrs.api.UserService; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.SimpleObject; -import org.openmrs.test.BaseModuleContextSensitiveTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -/** - * - * @author joman - */ -public class RaxaUserControllerTest extends BaseModuleContextSensitiveTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - private MockHttpServletRequest request = null; - - private MockHttpServletResponse response = null; - - private RaxaUserController controller = null; - - private UserService service = null; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - this.request = new MockHttpServletRequest(); - this.response = new MockHttpServletResponse(); - this.controller = new RaxaUserController(); - this.service = Context.getUserService(); - } - - /** - * Test of createNewUser method, of class RaxaUserController. - */ - @Test - public void testCreateNewPatientUser() throws Exception { - String json = "{\"firstName\":\"john\",\"lastName\":\"James\",\"gender\":\"M\",\"userName\":\"johnJames\",\"password\":\"Hello123\",\"type\":\"patient\",\"location\":\"dc5c1fcc-0459-4201-bf70-0b90535ba362\"} }"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object user = controller.createNewUser(post, request, response); - System.out.println(user); - User u = Context.getUserService().getUserByUsername("johnJames"); - Assert.assertEquals("john", u.getGivenName()); - Assert.assertEquals("1", u.getPerson().getAttribute("Health Center").getValue()); - } - - /** - * Test of createNewUser method, of class RaxaUserController. - */ - @Test - public void testCreateNewProviderUser() throws Exception { - String json = "{\"firstName\":\"Darth\",\"lastName\":\"Vader\",\"gender\":\"M\",\"userName\":\"johnJames\",\"password\":\"Hello123\",\"type\":\"provider\",\"location\":\"dc5c1fcc-0459-4201-bf70-0b90535ba362\"} }"; - SimpleObject post = new ObjectMapper().readValue(json, SimpleObject.class); - Object user = controller.createNewUser(post, request, response); - System.out.println(user); - User u = Context.getUserService().getUserByUsername("johnJames"); - Provider p = Context.getProviderService().getProviders("Darth Vader", null, null, null).iterator().next(); - Assert.assertEquals("Darth Vader", p.getName()); - Assert.assertEquals("1", u.getPerson().getAttribute("Health Center").getValue()); - } -} diff --git a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/resource/PatientListResourceTest.java b/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/resource/PatientListResourceTest.java deleted file mode 100644 index c97de435b1..0000000000 --- a/omod/src/test/java/org/raxa/module/raxacore/web/v1_0/resource/PatientListResourceTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.raxa.module.raxacore.web.v1_0.resource; - -/** - * Copyright 2012, Raxa - * - * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -import org.junit.Before; -import org.openmrs.api.context.Context; -import org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResourceTest; -import org.raxa.module.raxacore.PatientList; -import org.raxa.module.raxacore.PatientListService; - -/* - * Testing the methods in PatientListResource - */ -public class PatientListResourceTest extends BaseDelegatingResourceTest { - - private static final String TEST_DATA_PATH = "org/raxa/module/raxacore/include/"; - - private static final String MODULE_TEST_DATA_XML = TEST_DATA_PATH + "moduleTestData.xml"; - - @Before - public void before() throws Exception { - executeDataSet(MODULE_TEST_DATA_XML); - } - - @Override - public PatientList newObject() { - return Context.getService(PatientListService.class).getPatientListByUuid(getUuidProperty()); - } - - @Override - public void validateRefRepresentation() throws Exception { - super.validateRefRepresentation(); - } - - @Override - public void validateDefaultRepresentation() throws Exception { - super.validateDefaultRepresentation(); - assertPropEquals("name", getObject().getName()); - assertPropEquals("description", getObject().getDescription()); - assertPropEquals("searchQuery", getObject().getSearchQuery()); - assertPropPresent("patients"); - assertPropEquals("retired", getObject().isRetired()); - } - - @Override - public void validateFullRepresentation() throws Exception { - super.validateFullRepresentation(); - assertPropEquals("name", getObject().getName()); - assertPropEquals("description", getObject().getDescription()); - assertPropEquals("searchQuery", getObject().getSearchQuery()); - assertPropPresent("patients"); - assertPropEquals("retired", getObject().isRetired()); - assertPropPresent("auditInfo"); - } - - @Override - public String getDisplayProperty() { - return "TestList1 - First Test List"; - } - - @Override - public String getUuidProperty() { - return "68547121-1b70-465d-99ee-c9dfd95e7d30"; - } - -} diff --git a/omod/src/test/resources/TestingApplicationContext.xml b/omod/src/test/resources/TestingApplicationContext.xml deleted file mode 100644 index 89434bcdef..0000000000 --- a/omod/src/test/resources/TestingApplicationContext.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - classpath:hibernate.cfg.xml - classpath:test-hibernate.cfg.xml - - - - - - - - - - - - - - - org.raxa.module.raxacore.PatientListService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.RaxaAlertService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugGroupService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugInfoService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugInventoryService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.raxa.module.raxacore.DrugPurchaseOrderService - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/omod/src/test/resources/org/raxa/module/raxacore/include/moduleTestData.xml b/omod/src/test/resources/org/raxa/module/raxacore/include/moduleTestData.xml deleted file mode 100644 index fbbf4732d0..0000000000 --- a/omod/src/test/resources/org/raxa/module/raxacore/include/moduleTestData.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/omod/src/test/resources/test-hibernate.cfg.xml b/omod/src/test/resources/test-hibernate.cfg.xml deleted file mode 100644 index 59a7e36907..0000000000 --- a/omod/src/test/resources/test-hibernate.cfg.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/openmrs-elis-atomfeed-client-omod/pom.xml b/openmrs-elis-atomfeed-client-omod/pom.xml new file mode 100644 index 0000000000..bf1ac4e8b1 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/pom.xml @@ -0,0 +1,416 @@ + + 4.0.0 + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + openelis-atomfeed-client-omod + jar + Open-Elis Atom Feed Client + + + elisatomfeedclient + ${project.name} + ${project.version} + ${project.groupId}.${MODULE_ID} + + + + ${project.artifactId}-${project.version} + + + src/main/resources + true + + + src/main/webapp + false + + resources + + web/module + + + src/main/webapp + false + + resources + + web/module + + + + + src/test/resources + true + + + + + + maven-resources-plugin + + true + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.openmrs.maven.plugins + + + maven-openmrs-plugin + + + [1.0.1,) + + + + initialize-module + + + + + + + + + + + org.apache.maven.plugins + + + maven-dependency-plugin + + + [2.4,) + + + + unpack-dependencies + + + + + + + + + + + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.24 + + + BRANCH + COVEREDRATIO + 0.17 + + + + + + + + + + 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.openmrs.api + openmrs-api + ${openMRSVersion} + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + + + org.openmrs.module + webservices.rest-omod + ${openMRSWebServicesVersion} + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + + + org.bahmni.module + auditlog-api + provided + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} + tests + test + + + org.openmrs.module + providermanagement-api + + + org.bahmni.module + bahmni-commons-api + + + org.bahmni.module + bahmnicore-api + ${project.version} + provided + + + rome + rome + + + + + javax.servlet + javax.servlet-api + provided + + + org.openmrs.module + appframework-api + + + org.ict4h + atomfeed-client + ${atomfeed.version} + + + rome + rome + + + + + rome + rome + 1.0 + test + + + org.apache.httpcomponents + httpcore + 4.3.3 + + + org.apache.httpcomponents + httpclient + 4.3.6 + + + joda-time + joda-time + 2.0 + + + org.codehaus.jackson + jackson-mapper-asl + + + commons-codec + commons-codec + 1.4 + + + junit + junit + test + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + org.openmrs.api + openmrs-api + test-jar + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + org.openmrs.test + openmrs-test + pom + test + + + org.bahmni.module + web-clients + ${bahmniJavaUtilsVersion} + + + org.bahmni.module + episodes-api + ${episodes.version} + test + + + + org.ict4h.openmrs + openmrs-atomfeed-common + ${openmrsAtomfeedVersion} + + + org.ict4h.openmrs + openmrs-atomfeed-api + ${openmrsAtomfeedVersion} + test + + + org.openmrs.module + reporting-api + + + org.openmrs.module + calculation-api + + + org.openmrs.module + serialization.xstream-api-2.0 + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + test + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + test + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + test + + + org.openmrs.module + addresshierarchy-api + ${addressHierarchyVersion} + jar + + + org.openmrs.module + addresshierarchy-omod + ${addressHierarchyVersion} + jar + + + org.openmrs.module + legacyui-omod + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + test + + + javax.el + javax.el-api + 2.2.4 + + + org.glassfish.web + javax.el + 2.2.4 + + + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/Activator.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/Activator.java new file mode 100644 index 0000000000..4b9912e32e --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/Activator.java @@ -0,0 +1,22 @@ +package org.bahmni.module.elisatomfeedclient; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.openmrs.module.BaseModuleActivator; + +public class Activator extends BaseModuleActivator { + + private Log log = LogFactory.getLog(this.getClass()); + + @Override + public void started() { + log.info("Started the Open-Elis Atom Feed Client module"); + BahmniCoreProperties.load(); + } + + @Override + public void stopped() { + log.info("Stopped the Open-Elis Atom Feed Client module"); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/Constants.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/Constants.java new file mode 100644 index 0000000000..f31cd06eb6 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/Constants.java @@ -0,0 +1,11 @@ +package org.bahmni.module.elisatomfeedclient.api; + +public class Constants { + public static final String DEFAULT_INVESTIGATION_ENCOUNTER_TYPE = "INVESTIGATION"; + public static final String DEFAULT_LAB_SYSTEM_USERNAME = "Lab System"; + public static final String DEFAULT_LAB_ORDER_TYPE = "Order"; + public static final String DEFAULT_LAB_SYSTEM_IDENTIFIER = "LABSYSTEM"; + public static final String DEFAULT_LAB_RESULT_ENCOUNTER_TYPE = "LAB_RESULT"; + public static final String GP_ALLOW_DISCONTINUE_ORDERS = "elisatomfeedclient.discontinueCancelledOrders"; +} + diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/ElisAtomFeedProperties.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/ElisAtomFeedProperties.java new file mode 100644 index 0000000000..5c46b2a50c --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/ElisAtomFeedProperties.java @@ -0,0 +1,49 @@ +package org.bahmni.module.elisatomfeedclient.api; + +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.ict4h.atomfeed.client.AtomFeedProperties; +import org.springframework.stereotype.Component; + +@Component +public class ElisAtomFeedProperties extends AtomFeedProperties { + + private static final String OPENELIS_URI = "openelis.uri"; + private static final String CONNECT_TIMEOUT = "feed.connectionTimeoutInMilliseconds"; + private static final String MAX_FAILED_EVENTS = "feed.maxFailedEvents"; + private static final String READ_TIMEOUT = "feed.replyTimeoutInMilliseconds"; + private static final String PATIENT_FEED_URI = "patient.feed.uri"; + private static final String OPENELIS_USER = "openelis.user"; + private static final String OPENELIS_PASSWORD = "openelis.password"; + + public String getPatientFeedUri() { + return BahmniCoreProperties.getProperty(PATIENT_FEED_URI); + } + + public String getOpenElisUser() { + return BahmniCoreProperties.getProperty(OPENELIS_USER); + } + + public String getOpenElisPassword() { + return BahmniCoreProperties.getProperty(OPENELIS_PASSWORD); + } + + public String getOpenElisUri() { + return BahmniCoreProperties.getProperty(OPENELIS_URI); + } + + @Override + public int getMaxFailedEvents() { + return Integer.parseInt(BahmniCoreProperties.getProperty(MAX_FAILED_EVENTS)); + } + + @Override + public int getReadTimeout() { + return Integer.parseInt(BahmniCoreProperties.getProperty(READ_TIMEOUT)); + } + + @Override + public int getConnectTimeout() { + return Integer.parseInt(BahmniCoreProperties.getProperty(CONNECT_TIMEOUT)); + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/FailedEventsFeedClient.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/FailedEventsFeedClient.java new file mode 100644 index 0000000000..b8bedac391 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/FailedEventsFeedClient.java @@ -0,0 +1,5 @@ +package org.bahmni.module.elisatomfeedclient.api.client; + +public interface FailedEventsFeedClient { + void processFailedEvents(); +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/FeedClient.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/FeedClient.java new file mode 100644 index 0000000000..235b2900e4 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/FeedClient.java @@ -0,0 +1,5 @@ +package org.bahmni.module.elisatomfeedclient.api.client; + +public interface FeedClient { + void processFeed(); +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisFeedClient.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisFeedClient.java new file mode 100644 index 0000000000..d4f80b3f2d --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisFeedClient.java @@ -0,0 +1,81 @@ +package org.bahmni.module.elisatomfeedclient.api.client; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.webclients.ClientCookies; +import org.bahmni.webclients.ConnectionDetails; +import org.bahmni.webclients.HttpClient; +import org.bahmni.webclients.OpenElisAuthenticator; +import org.ict4h.atomfeed.client.repository.AllFeeds; +import org.ict4h.atomfeed.client.repository.jdbc.AllFailedEventsJdbcImpl; +import org.ict4h.atomfeed.client.repository.jdbc.AllMarkersJdbcImpl; +import org.ict4h.atomfeed.client.service.AtomFeedClient; +import org.ict4h.atomfeed.client.service.EventWorker; +import org.openmrs.module.atomfeed.transaction.support.AtomFeedSpringTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import java.net.URI; +import java.net.URISyntaxException; + +public abstract class OpenElisFeedClient { + protected AtomFeedClient atomFeedClient; + private ElisAtomFeedProperties properties; + private PlatformTransactionManager transactionManager; + private Logger logger = LogManager.getLogger(OpenElisFeedClient.class); + + public OpenElisFeedClient(ElisAtomFeedProperties properties, PlatformTransactionManager transactionManager) { + this.properties = properties; + this.transactionManager = transactionManager; + } + + + /** + * + * @param feedUri + * @return + * @throws java.lang.RuntimeException if feed Uri is invalid + */ + private URI getURIForFeed(String feedUri) { + try { + return new URI(feedUri); + } catch (URISyntaxException e) { + logger.error("openelisatomfeedclient:error instantiating client: {} {}", e.getMessage(), e); + throw new RuntimeException("error for uri:" + feedUri); + } + } + + public org.ict4h.atomfeed.client.service.FeedClient getAtomFeedClient() { + if(atomFeedClient == null) { + createAtomFeedClient(); + } + return atomFeedClient; + } + + public org.ict4h.atomfeed.client.service.FeedClient createAtomFeedClient() { + URI uriForFeed = getURIForFeed(getFeedUri(properties)); + ConnectionDetails connectionDetails = createConnectionDetails(properties); + HttpClient httpClient = new HttpClient(connectionDetails, new OpenElisAuthenticator(connectionDetails)); + ClientCookies cookies = httpClient.getCookies(uriForFeed); + EventWorker openMRSEventWorker = createWorker(httpClient, properties); + AtomFeedSpringTransactionManager txMgr = new AtomFeedSpringTransactionManager(transactionManager); + atomFeedClient = new AtomFeedClient( + new AllFeeds(properties, cookies), + new AllMarkersJdbcImpl(txMgr), + new AllFailedEventsJdbcImpl(txMgr), + properties, + txMgr, + uriForFeed, + openMRSEventWorker); + return atomFeedClient; + } + + protected abstract String getFeedUri(ElisAtomFeedProperties properties); + + private ConnectionDetails createConnectionDetails(ElisAtomFeedProperties properties) { + return new ConnectionDetails(properties.getOpenElisUri(), properties.getOpenElisUser(), + properties.getOpenElisPassword(), properties.getConnectTimeout(), properties.getReadTimeout()); + } + + protected abstract EventWorker createWorker(HttpClient authenticatedWebClient, ElisAtomFeedProperties properties); +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisPatientFailedEventsFeedClient.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisPatientFailedEventsFeedClient.java new file mode 100644 index 0000000000..a8ef14e09e --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisPatientFailedEventsFeedClient.java @@ -0,0 +1,4 @@ +package org.bahmni.module.elisatomfeedclient.api.client; + +public interface OpenElisPatientFailedEventsFeedClient extends FailedEventsFeedClient { +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisPatientFeedClient.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisPatientFeedClient.java new file mode 100644 index 0000000000..a956e62154 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/OpenElisPatientFeedClient.java @@ -0,0 +1,4 @@ +package org.bahmni.module.elisatomfeedclient.api.client; + +public interface OpenElisPatientFeedClient extends FeedClient{ +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/impl/OpenElisPatientFailedEventsFeedClientImpl.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/impl/OpenElisPatientFailedEventsFeedClientImpl.java new file mode 100644 index 0000000000..9e11e67f04 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/impl/OpenElisPatientFailedEventsFeedClientImpl.java @@ -0,0 +1,86 @@ +package org.bahmni.module.elisatomfeedclient.api.client.impl; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.client.OpenElisFeedClient; +import org.bahmni.module.elisatomfeedclient.api.client.OpenElisPatientFailedEventsFeedClient; +import org.bahmni.module.elisatomfeedclient.api.mapper.AccessionHelper; +import org.bahmni.module.elisatomfeedclient.api.worker.OpenElisAccessionEventWorker; +import org.bahmni.module.elisatomfeedclient.api.worker.OpenElisPatientFeedWorker; +import org.bahmni.webclients.HttpClient; +import org.ict4h.atomfeed.client.service.EventWorker; +import org.joda.time.DateTime; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.module.auditlog.service.AuditLogService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.PlatformTransactionManager; + +@Component("openElisPatientFailedEventsFeedClient") +public class OpenElisPatientFailedEventsFeedClientImpl extends OpenElisFeedClient implements OpenElisPatientFailedEventsFeedClient { + private ProviderService providerService; + private ConceptService conceptService; + private BahmniVisitAttributeService bahmniVisitAttributeSaveCommand; + private Logger logger = LogManager.getLogger(OpenElisPatientFailedEventsFeedClientImpl.class); + private AuditLogService auditLogService; + + + @Autowired + public OpenElisPatientFailedEventsFeedClientImpl(ElisAtomFeedProperties properties, + ProviderService providerService, + ConceptService conceptService, + PlatformTransactionManager transactionManager, + BahmniVisitAttributeService bahmniVisitAttributeSaveCommand, + AuditLogService auditLogService) { + super(properties, transactionManager); + this.providerService = providerService; + this.conceptService = conceptService; + this.bahmniVisitAttributeSaveCommand = bahmniVisitAttributeSaveCommand; + this.auditLogService = auditLogService; + } + + @Override + protected String getFeedUri(ElisAtomFeedProperties properties) { + return properties.getPatientFeedUri(); + } + + @Override + protected EventWorker createWorker(HttpClient authenticatedWebClient, ElisAtomFeedProperties properties) { + EncounterService encounterService = Context.getService(EncounterService.class); + OpenElisAccessionEventWorker accessionEventWorker = new OpenElisAccessionEventWorker( + properties, + authenticatedWebClient, + encounterService, + conceptService, + new AccessionHelper(properties), + providerService, bahmniVisitAttributeSaveCommand, auditLogService); + return new OpenElisPatientFeedWorker(accessionEventWorker); + } + + @Override + public void processFailedEvents() { + try { + logger.info("openelisatomfeedclient:processing failed events {}", DateTime.now()); + getAtomFeedClient().processFailedEvents(); + } catch (Exception e) { + try { + if (e != null && ExceptionUtils.getStackTrace(e).contains("HTTP response code: 401")) { + getAtomFeedClient(); + }else{ + throw e; + } + + } catch (Exception ex) { + logger.error("openelis atomfeedclient:failed feed execution while running failed events {}", ex, e); + throw new RuntimeException(ex); + } + } + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/impl/OpenElisPatientFeedClientImpl.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/impl/OpenElisPatientFeedClientImpl.java new file mode 100644 index 0000000000..21633c34ed --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/client/impl/OpenElisPatientFeedClientImpl.java @@ -0,0 +1,82 @@ +package org.bahmni.module.elisatomfeedclient.api.client.impl; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.client.OpenElisFeedClient; +import org.bahmni.module.elisatomfeedclient.api.client.OpenElisPatientFeedClient; +import org.bahmni.module.elisatomfeedclient.api.mapper.AccessionHelper; +import org.bahmni.module.elisatomfeedclient.api.worker.OpenElisAccessionEventWorker; +import org.bahmni.module.elisatomfeedclient.api.worker.OpenElisPatientFeedWorker; +import org.bahmni.webclients.HttpClient; +import org.ict4h.atomfeed.client.service.EventWorker; +import org.joda.time.DateTime; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.module.auditlog.service.AuditLogService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.PlatformTransactionManager; + +@Component("openElisPatientFeedClient") +public class OpenElisPatientFeedClientImpl extends OpenElisFeedClient implements OpenElisPatientFeedClient { + private BahmniVisitAttributeService bahmniVisitAttributeSaveCommand; + private AuditLogService auditLogService; + private Logger logger = LogManager.getLogger(OpenElisPatientFeedClientImpl.class); + + + @Autowired + public OpenElisPatientFeedClientImpl(ElisAtomFeedProperties properties, + PlatformTransactionManager transactionManager, + BahmniVisitAttributeService bahmniVisitAttributeSaveCommand, + AuditLogService auditLogService) { + super(properties, transactionManager); + this.bahmniVisitAttributeSaveCommand = bahmniVisitAttributeSaveCommand; + this.auditLogService = auditLogService; + } + + @Override + protected String getFeedUri(ElisAtomFeedProperties properties) { + return properties.getPatientFeedUri(); + } + + @Override + protected EventWorker createWorker(HttpClient authenticatedWebClient, ElisAtomFeedProperties properties) { + EncounterService encounterService = Context.getService(EncounterService.class); + ConceptService conceptService = Context.getService(ConceptService.class); + ProviderService providerService = Context.getProviderService(); + + OpenElisAccessionEventWorker accessionEventWorker = new OpenElisAccessionEventWorker(properties, + authenticatedWebClient, encounterService, conceptService, new AccessionHelper(properties), + providerService, bahmniVisitAttributeSaveCommand, auditLogService); + return new OpenElisPatientFeedWorker(accessionEventWorker); + } + + @Override + public void processFeed() { + try { + logger.info("openelisatomfeedclient:processing feed {}", DateTime.now()); + getAtomFeedClient().processEvents(); + } catch (Exception e) { + try { + if (e != null && isUnauthorised(e)) { + createAtomFeedClient(); + } + } catch (Exception ex) { + logger.error("openelisatomfeedclient:failed feed execution {}", e); + throw new RuntimeException(ex); + } + } + } + + private boolean isUnauthorised(Exception e) { + return ExceptionUtils.getStackTrace(e).contains("HTTP response code: 401") + || ExceptionUtils.getStackTrace(e).contains("HTTP response code: 403") + || ExceptionUtils.getStackTrace(e).contains("User not authorized"); + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/AccessionDiff.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/AccessionDiff.java new file mode 100644 index 0000000000..4fd53068e3 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/AccessionDiff.java @@ -0,0 +1,44 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +public class AccessionDiff { + private Set addedTestDetails = new HashSet<>(); + private Set removedTestDetails = new HashSet<>(); + + public ArrayList getAccessionNotesToBeAdded() { + return accessionNotesToBeAdded; + } + + public void setAccessionNotesToBeAdded(ArrayList accessionNotesToBeAdded) { + this.accessionNotesToBeAdded = accessionNotesToBeAdded; + } + + private ArrayList accessionNotesToBeAdded = new ArrayList<>(); + + public Set getAddedTestDetails() { + return addedTestDetails; + } + + public void addAddedTestDetail(OpenElisTestDetail testDetail) { + addedTestDetails.add(testDetail); + } + + public Set getRemovedTestDetails() { + return removedTestDetails; + } + + public void addRemovedTestDetails(OpenElisTestDetail testDetail) { + removedTestDetails.add(testDetail); + } + + public boolean hasDifference() { + return (getRemovedTestDetails().size() > 0 || getAddedTestDetails().size() > 0); + } + + public boolean hasDifferenceInAccessionNotes(){ + return getAccessionNotesToBeAdded().size() > 0; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccession.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccession.java new file mode 100644 index 0000000000..83d488cdca --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccession.java @@ -0,0 +1,181 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.elisatomfeedclient.api.worker.ProviderHelper; +import org.joda.time.DateTime; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Provider; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class OpenElisAccession { + private String accessionUuid; + private String labLocationUuid; + private String patientUuid; + private String patientFirstName; + private String patientLastName; + private String dateTime; + private String patientIdentifier; + private List accessionNotes; + private Set testDetails = new HashSet<>(); + + public String getLabLocationUuid() { + return labLocationUuid; + } + + public void setLabLocationUuid(String labLocationUuid) { + this.labLocationUuid = labLocationUuid; + } + + public void addTestDetail(OpenElisTestDetail testDetail) { + getTestDetails().add(testDetail); + } + + public AccessionDiff getDiff(Encounter previousEncounter) { + AccessionDiff accessionDiff = new AccessionDiff(); + for (OpenElisTestDetail testDetail : testDetails) { + String orderableUuid = StringUtils.isBlank(testDetail.getPanelUuid()) ? testDetail.getTestUuid() : testDetail.getPanelUuid(); + if (testDetail.isCancelled()) { + if (hasOrderByUuid(previousEncounter.getOrders(), orderableUuid)) { + accessionDiff.addRemovedTestDetails(testDetail); + } + } else { + Order order = getOrderByTestUuid(previousEncounter.getOrders(), orderableUuid); + if (order == null) { + accessionDiff.addAddedTestDetail(testDetail); + } + } + } + + return accessionDiff; + } + + private boolean hasOrderByUuid(Set orders, String testUuid) { + for (Order order : orders) { + if (!order.getVoided() && order.getConcept() != null && order.getConcept().getUuid().equals(testUuid)) + return true; + } + return false; + } + + private Order getOrderByTestUuid(Set orders, String testUuid) { + for (Order order : orders) { + if (order.getConcept() != null && order.getConcept().getUuid().equals(testUuid)) + return order; + } + return null; + } + + public Date fetchDate() { + return dateTime == null ? null : DateTime.parse(dateTime).toDate(); + } + + public String getHealthCenter() { + return patientIdentifier.substring(0, 3); + } + + public AccessionDiff getAccessionNoteDiff(Set encounters, Concept labManagerNoteConcept, + Provider defaultLabManagerProvider) { + AccessionDiff accessionNotesDiff = new AccessionDiff(); + if (accessionNotes != null) { + ArrayList accessionNotesCopy = new ArrayList<>(accessionNotes); + if (encounters != null) { + for (Encounter labManagerEncounter : encounters) { + filterOutAlreadyAddedAccessionNotes(labManagerEncounter, labManagerNoteConcept, + accessionNotesCopy, defaultLabManagerProvider); + } + } + accessionNotesDiff.setAccessionNotesToBeAdded(accessionNotesCopy); + } + return accessionNotesDiff; + } + + private void filterOutAlreadyAddedAccessionNotes(Encounter encounter, Concept labManagerNoteConcept, ArrayList accessionNotesCopy, Provider defaultLabManagerProvider) { + Set encObs = encounter.getObs(); + for (Obs obs : encObs) { + if (obs.getConcept().equals(labManagerNoteConcept)) { + for (OpenElisAccessionNote accessionNote : accessionNotes) { + if (shouldMatchNoteInEncounter(encounter, defaultLabManagerProvider, obs, accessionNote)) { + accessionNotesCopy.remove(accessionNote); + } + } + } + } + } + + private boolean shouldMatchNoteInEncounter(Encounter encounter, Provider defaultLabManagerProvider, Obs obs, OpenElisAccessionNote accessionNote) { + return accessionNote.getNote().equals(obs.getValueText()) && + (accessionNote.isProviderInEncounter(encounter) || ProviderHelper.getProviderFrom(encounter).equals(defaultLabManagerProvider)); + } + + public String getAccessionUuid() { + return accessionUuid; + } + + public void setAccessionUuid(String accessionUuid) { + this.accessionUuid = accessionUuid; + } + + public String getPatientUuid() { + return patientUuid; + } + + public void setPatientUuid(String patientUuid) { + this.patientUuid = patientUuid; + } + + public String getPatientFirstName() { + return patientFirstName; + } + + public void setPatientFirstName(String patientFirstName) { + this.patientFirstName = patientFirstName; + } + + public String getPatientLastName() { + return patientLastName; + } + + public void setPatientLastName(String patientLastName) { + this.patientLastName = patientLastName; + } + + public String getDateTime() { + return dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public String getPatientIdentifier() { + return patientIdentifier; + } + + public void setPatientIdentifier(String patientIdentifier) { + this.patientIdentifier = patientIdentifier; + } + + public List getAccessionNotes() { + return accessionNotes; + } + + public void setAccessionNotes(List accessionNotes) { + this.accessionNotes = accessionNotes; + } + + public Set getTestDetails() { + return testDetails; + } + + public void setTestDetails(Set testDetails) { + this.testDetails = testDetails; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccessionNote.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccessionNote.java new file mode 100644 index 0000000000..2aba83dcd1 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccessionNote.java @@ -0,0 +1,79 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.openmrs.Encounter; +import org.openmrs.Provider; + +import java.text.ParseException; +import java.util.Date; +import java.util.Locale; + +public class OpenElisAccessionNote { + private String note; + private String providerUuid; + private String dateTime; + + public OpenElisAccessionNote() { + } + + public OpenElisAccessionNote(String note, String providerUuid, String dateTime) { + this.note = note; + this.providerUuid = providerUuid; + this.dateTime = dateTime; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + + public String getProviderUuid() { + return providerUuid; + } + + public void setProviderUuid(String providerUuid) { + this.providerUuid = providerUuid; + } + + + public String getDateTime() { + return dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public boolean isProviderInEncounter(Encounter encounter){ + return encounter.getEncounterProviders().iterator().next().getProvider().getUuid().equals(providerUuid); + } + + public boolean matchesProvider(Provider provider){ + return providerUuid.equals(provider.getUuid()); + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + OpenElisAccessionNote that = (OpenElisAccessionNote) o; + return (note != null && note.equals(that.note) && + providerUuid != null && providerUuid.equals(that.providerUuid)); + + } + + @Override + public int hashCode() { + int result = note != null ? note.hashCode() : 0; + result = 31 * result + (providerUuid != null ? providerUuid.hashCode() : 0); + return result; + } + + public Date getDateTimeAsDate() throws ParseException { + return DateUtils.parseDateStrictly(dateTime.toString(), Locale.US, DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.getPattern()); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatient.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatient.java new file mode 100644 index 0000000000..358024f863 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatient.java @@ -0,0 +1,161 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import org.joda.time.DateTime; + +import java.util.Date; +import java.util.List; + +public class OpenElisPatient { + private String patientIdentifier; + private String firstName; + private String lastName; + private String gender; + private String address1; + private String address2; + private String address3; + private String cityVillage; + private String countyDistrict; + private String stateProvince; + private String dateOfBirth; + private String healthCenter; + private String patientUUID; + + private List attributes; + + public OpenElisPatient() { + } + + public OpenElisPatient(String patientIdentifier, String firstName, String lastName, String gender, String address1, String address2, String address3, String cityVillage, String countyDistrict, String stateProvince, String dateOfBirth, String healthCenter, String patientUUID, List attributes) { + this.patientIdentifier = patientIdentifier; + this.firstName = firstName; + this.lastName = lastName; + this.gender = gender; + this.address1 = address1; + this.address2 = address2; + this.address3 = address3; + this.cityVillage = cityVillage; + this.countyDistrict = countyDistrict; + this.stateProvince = stateProvince; + this.dateOfBirth = dateOfBirth; + this.healthCenter = healthCenter; + this.patientUUID = patientUUID; + this.attributes = attributes; + } + + public Date getDateOfBirthAsDate() { + return dateOfBirth == null ? null : DateTime.parse(dateOfBirth).toDate(); + } + + public String getPatientIdentifier() { + return patientIdentifier; + } + + public void setPatientIdentifier(String patientIdentifier) { + this.patientIdentifier = patientIdentifier; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getAddress1() { + return address1; + } + + public void setAddress1(String address1) { + this.address1 = address1; + } + + public String getAddress2() { + return address2; + } + + public void setAddress2(String address2) { + this.address2 = address2; + } + + public String getAddress3() { + return address3; + } + + public void setAddress3(String address3) { + this.address3 = address3; + } + + public String getCityVillage() { + return cityVillage; + } + + public void setCityVillage(String cityVillage) { + this.cityVillage = cityVillage; + } + + public String getCountyDistrict() { + return countyDistrict; + } + + public void setCountyDistrict(String countyDistrict) { + this.countyDistrict = countyDistrict; + } + + public String getStateProvince() { + return stateProvince; + } + + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + + public String getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(String dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public String getHealthCenter() { + return healthCenter; + } + + public void setHealthCenter(String healthCenter) { + this.healthCenter = healthCenter; + } + + public String getPatientUUID() { + return patientUUID; + } + + public void setPatientUUID(String patientUUID) { + this.patientUUID = patientUUID; + } + + public List getAttributes() { + return attributes; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } +} + diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatientAttribute.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatientAttribute.java new file mode 100644 index 0000000000..174e2c7478 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatientAttribute.java @@ -0,0 +1,30 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +public class OpenElisPatientAttribute { + private String name; + private String value; + + public OpenElisPatientAttribute() { + } + + public OpenElisPatientAttribute(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisTestDetail.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisTestDetail.java new file mode 100644 index 0000000000..a097fc197a --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisTestDetail.java @@ -0,0 +1,180 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.joda.time.DateTime; + +import java.util.Date; + +public class OpenElisTestDetail { + private String testName; + private String testUnitOfMeasurement; + private String testUuid; + private String panelUuid; + private Double minNormal; + private Double maxNormal; + private String result; + private String resultUuid; + private String notes; + private String resultType; + private String providerUuid; + private String dateTime; + private String status; + private Boolean abnormal; + private String uploadedFileName; + + public OpenElisTestDetail() { + } + + public OpenElisTestDetail(String testName, String testUnitOfMeasurement, String testUuid, String panelUuid, Double minNormal, Double maxNormal, String result, String resultUuid, String notes, String resultType, String providerUuid, String dateTime, String status, Boolean abnormal, String uploadedFileName) { + this.testName = testName; + this.testUnitOfMeasurement = testUnitOfMeasurement; + this.testUuid = testUuid; + this.panelUuid = panelUuid; + this.minNormal = minNormal; + this.maxNormal = maxNormal; + this.result = result; + this.resultUuid = resultUuid; + this.notes = notes; + this.resultType = resultType; + this.providerUuid = providerUuid; + this.dateTime = dateTime; + this.status = status; + this.abnormal = abnormal; + this.uploadedFileName = uploadedFileName; + } + + @JsonIgnore + public boolean isCancelled() { + return "Canceled".equals(status); + } + + public Date fetchDate() { + return dateTime == null ? null : DateTime.parse(dateTime).toDate(); + } + + @JsonIgnore + public boolean isReferredOut() { + return status != null && (status.equalsIgnoreCase("referred out") || status.equalsIgnoreCase("Finalized RO")); + } + + public String getTestName() { + + return testName; + } + + public void setTestName(String testName) { + this.testName = testName; + } + + public String getTestUnitOfMeasurement() { + return testUnitOfMeasurement; + } + + public void setTestUnitOfMeasurement(String testUnitOfMeasurement) { + this.testUnitOfMeasurement = testUnitOfMeasurement; + } + + public String getTestUuid() { + return testUuid; + } + + public void setTestUuid(String testUuid) { + this.testUuid = testUuid; + } + + public String getPanelUuid() { + return panelUuid; + } + + public void setPanelUuid(String panelUuid) { + this.panelUuid = panelUuid; + } + + public Double getMinNormal() { + return minNormal; + } + + public void setMinNormal(Double minNormal) { + this.minNormal = minNormal; + } + + public Double getMaxNormal() { + return maxNormal; + } + + public void setMaxNormal(Double maxNormal) { + this.maxNormal = maxNormal; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getResultUuid() { + return resultUuid; + } + + public void setResultUuid(String resultUuid) { + this.resultUuid = resultUuid; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public String getResultType() { + return resultType; + } + + public void setResultType(String resultType) { + this.resultType = resultType; + } + + public String getProviderUuid() { + return providerUuid; + } + + public void setProviderUuid(String providerUuid) { + this.providerUuid = providerUuid; + } + + public String getDateTime() { + return dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Boolean getAbnormal() { + return abnormal; + } + + public void setAbnormal(Boolean abnormal) { + this.abnormal = abnormal; + } + + public String getUploadedFileName() { + return uploadedFileName; + } + + public void setUploadedFileName(String uploadedFileName) { + this.uploadedFileName = uploadedFileName; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/elisFeedInterceptor/ElisFeedAccessionInterceptor.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/elisFeedInterceptor/ElisFeedAccessionInterceptor.java new file mode 100644 index 0000000000..c9608ff932 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/elisFeedInterceptor/ElisFeedAccessionInterceptor.java @@ -0,0 +1,7 @@ +package org.bahmni.module.elisatomfeedclient.api.elisFeedInterceptor; + +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; + +public interface ElisFeedAccessionInterceptor { + void run(OpenElisAccession openElisAccession); +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/elisFeedInterceptor/ElisFeedEncounterInterceptor.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/elisFeedInterceptor/ElisFeedEncounterInterceptor.java new file mode 100644 index 0000000000..f5855dd5b9 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/elisFeedInterceptor/ElisFeedEncounterInterceptor.java @@ -0,0 +1,9 @@ +package org.bahmni.module.elisatomfeedclient.api.elisFeedInterceptor; + +import org.openmrs.Encounter; + +import java.util.Set; + +public interface ElisFeedEncounterInterceptor { + void run(Set encounters); +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/exception/OpenElisFeedException.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/exception/OpenElisFeedException.java new file mode 100644 index 0000000000..ab628f8109 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/exception/OpenElisFeedException.java @@ -0,0 +1,11 @@ +package org.bahmni.module.elisatomfeedclient.api.exception; + +public class OpenElisFeedException extends RuntimeException { + public OpenElisFeedException(String message, Exception e) { + super(message, e); + } + + public OpenElisFeedException(String message) { + super(message); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/AccessionHelper.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/AccessionHelper.java new file mode 100644 index 0000000000..82df55220b --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/AccessionHelper.java @@ -0,0 +1,274 @@ +package org.bahmni.module.elisatomfeedclient.api.mapper; + +import org.apache.commons.lang.time.DateUtils; +import org.bahmni.module.elisatomfeedclient.api.Constants; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.domain.AccessionDiff; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.joda.time.DateTime; +import org.openmrs.CareSetting; +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.EncounterType; +import org.openmrs.Location; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.UserService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.service.VisitIdentificationHelper; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import static org.bahmni.module.elisatomfeedclient.api.Constants.DEFAULT_INVESTIGATION_ENCOUNTER_TYPE; + +public class AccessionHelper { + private final EncounterService encounterService; + private final PatientService patientService; + private final VisitService visitService; + private final ConceptService conceptService; + private final AdministrationService administrationService; + private User labUser; + private OrderService orderService; + protected ElisAtomFeedProperties properties; + private final UserService userService; + private final ProviderService providerService; + private BahmniVisitLocationService bahmniVisitLocationService; + private OrderType labOrderType; + + public AccessionHelper(ElisAtomFeedProperties properties) { + this(Context.getService(EncounterService.class), Context.getService(PatientService.class), + Context.getService(VisitService.class), Context.getService(ConceptService.class), + Context.getService(UserService.class), Context.getService(ProviderService.class), + Context.getService(OrderService.class), properties, Context.getService(BahmniVisitLocationService.class), + Context.getService(AdministrationService.class)); + } + + AccessionHelper(EncounterService encounterService, PatientService patientService, VisitService visitService, ConceptService conceptService, + UserService userService, ProviderService providerService, OrderService orderService, + ElisAtomFeedProperties properties, BahmniVisitLocationService bahmniVisitLocationService) { + this.encounterService = encounterService; + this.patientService = patientService; + this.visitService = visitService; + this.conceptService = conceptService; + this.orderService = orderService; + this.properties = properties; + this.userService = userService; + this.providerService = providerService; + this.bahmniVisitLocationService = bahmniVisitLocationService; + this.administrationService = Context.getService(AdministrationService.class); + } + + AccessionHelper(EncounterService encounterService, PatientService patientService, VisitService visitService, ConceptService conceptService, + UserService userService, ProviderService providerService, OrderService orderService, + ElisAtomFeedProperties properties, BahmniVisitLocationService bahmniVisitLocationService, AdministrationService administrationService) { + this.encounterService = encounterService; + this.patientService = patientService; + this.visitService = visitService; + this.conceptService = conceptService; + this.orderService = orderService; + this.properties = properties; + this.userService = userService; + this.providerService = providerService; + this.bahmniVisitLocationService = bahmniVisitLocationService; + this.administrationService = administrationService; + } + + public Encounter mapToNewEncounter(OpenElisAccession openElisAccession, String visitType) { + Patient patient = patientService.getPatientByUuid(openElisAccession.getPatientUuid()); + if (labUser == null) { + labUser = userService.getUserByUsername(Constants.DEFAULT_LAB_SYSTEM_USERNAME); + } + + Provider labSystemProvider = getLabSystemProvider(); + EncounterType encounterType = encounterService.getEncounterType(DEFAULT_INVESTIGATION_ENCOUNTER_TYPE); + + Date accessionDate = openElisAccession.fetchDate(); + Visit visit = new VisitIdentificationHelper(visitService, bahmniVisitLocationService).getVisitFor(patient, visitType, accessionDate, null, null, openElisAccession.getLabLocationUuid()); + Location location = Context.getLocationService().getLocationByUuid(openElisAccession.getLabLocationUuid()); + + Encounter encounter = newEncounterInstance(visit, patient, labSystemProvider, encounterType, accessionDate, location); + encounter.setUuid(openElisAccession.getAccessionUuid()); + + Set groupedOrders = groupOrders(openElisAccession.getTestDetails()); + + Set orders = createOrders(openElisAccession, groupedOrders, patient); + addOrdersToEncounter(encounter, orders); + visit.addEncounter(encounter); + return encounter; + } + + private Encounter newEncounterInstance(Visit visit, Patient patient, Provider labSystemProvider, EncounterType encounterType, Date date, Location labLocation) { + Encounter encounter = new Encounter(); + encounter.setEncounterType(encounterType); + encounter.setPatient(patient); + encounter.setEncounterDatetime(date); + EncounterRole encounterRole = encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID); + encounter.setProvider(encounterRole, labSystemProvider); + encounter.setVisit(visit); + encounter.setLocation(labLocation); + return encounter; + } + + public Encounter addOrDiscontinueOrderDifferences(OpenElisAccession openElisAccession, AccessionDiff diff, + Encounter previousEncounter) { + if (diff.getAddedTestDetails().size() > 0) { + Set addedOrders = groupOrders(diff.getAddedTestDetails()); + Set newOrders = createOrders(openElisAccession, addedOrders, previousEncounter.getPatient()); + addOrdersToEncounter(previousEncounter, newOrders); + } + + Boolean shouldAllowDiscontinueOrdersIfCancelled = administrationService.getGlobalPropertyValue(Constants.GP_ALLOW_DISCONTINUE_ORDERS, Boolean.TRUE); + + if (shouldAllowDiscontinueOrdersIfCancelled && diff.getRemovedTestDetails().size() > 0) { + Set removedOrders = groupOrders(diff.getRemovedTestDetails()); + discontinueOrders(previousEncounter, removedOrders); + } + + return previousEncounter; + } + + private void addOrdersToEncounter(Encounter encounter, Set orders) { + for (Order order : orders) { + encounter.addOrder(order); + } + } + + private Set createOrders(OpenElisAccession openElisAccession, Set orderConceptUuids, Patient patient) { + Set orders = new HashSet<>(); + if (labUser == null) { + labUser = userService.getUserByUsername(Constants.DEFAULT_LAB_SYSTEM_USERNAME); + } + for (String orderConceptUuid : orderConceptUuids) { + Order order = new Order(); + order.setConcept(conceptService.getConceptByUuid(orderConceptUuid)); + order.setAccessionNumber(openElisAccession.getAccessionUuid()); + order.setCreator(labUser); + order.setPatient(patient); + order.setOrderType(getLabOrderType()); + order.setOrderer(getLabSystemProvider()); + order.setCareSetting(orderService.getCareSettingByName(CareSetting.CareSettingType.OUTPATIENT.toString())); + orders.add(order); + } + return orders; + } + + private OrderType getLabOrderType() { + if (labOrderType == null) { + labOrderType = orderService.getOrderTypeByName(Constants.DEFAULT_LAB_ORDER_TYPE); + } + return labOrderType; + } + + private void discontinueOrders(Encounter previousEncounter, Set removedOrders) { + List newOrdersForDiscontinue = new ArrayList<>(); + for (String removedOrder : removedOrders) { + for (Order order : previousEncounter.getOrders()) { + if (!order.getAction().equals(Order.Action.DISCONTINUE) + && order.isActive() + && removedOrder.equals(order.getConcept().getUuid())) { + Order newOrder = order.cloneForDiscontinuing(); + newOrder.setOrderer(order.getOrderer()); + newOrdersForDiscontinue.add(newOrder); + } + } + } + for (Order order : newOrdersForDiscontinue) { + previousEncounter.addOrder(order); + } + } + + private Set groupOrders(Set openElisAccessionTestDetails) { + Set orderConceptUuids = new HashSet<>(); + for (OpenElisTestDetail testDetail : openElisAccessionTestDetails) { + String uuid = testDetail.getPanelUuid() != null ? testDetail.getPanelUuid() : testDetail.getTestUuid(); + orderConceptUuids.add(uuid); + } + return orderConceptUuids; + } + + private Provider getLabSystemProvider() { + Collection labSystemProviders = providerService.getProvidersByPerson(labUser.getPerson()); + return labSystemProviders == null ? null : labSystemProviders.iterator().next(); + } + + public Visit findOrInitializeVisit(Patient patient, Date visitDate, String visitType) { + Visit applicableVisit = getVisitForPatientWithinDates(patient, visitDate); + if (applicableVisit != null) { + return applicableVisit; + } + Visit visit = new Visit(); + visit.setPatient(patient); + visit.setVisitType(getVisitTypeByName(visitType)); + visit.setStartDatetime(visitDate); + visit.setEncounters(new HashSet()); + visit.setUuid(UUID.randomUUID().toString()); + + Visit nextVisit = getVisitForPatientForNearestStartDate(patient, visitDate); + DateTime startTime = new DateTime(visitDate); + if (nextVisit == null) { + if (!DateUtils.isSameDay(visitDate, new Date())) { + Date stopTime = startTime.withTime(23, 59, 59, 000).toDate(); + visit.setStopDatetime(stopTime); + } + } else { + DateTime nextVisitStartTime = new DateTime(nextVisit.getStartDatetime()); + DateTime visitStopDate = startTime.withTime(23, 59, 59, 000); + boolean isEndTimeBeforeNextVisitStart = visitStopDate.isBefore(nextVisitStartTime); + if (!isEndTimeBeforeNextVisitStart) { + visitStopDate = nextVisitStartTime.minusSeconds(1); + } + visit.setStopDatetime(visitStopDate.toDate()); + } + return visit; + } + + protected Visit getVisitForPatientWithinDates(Patient patient, Date startTime) { + List visits = visitService.getVisits(null, Collections.singletonList(patient), null, null, null, startTime, startTime, null, null, true, false); + return visits.isEmpty() ? null : visits.get(0); + } + + protected Visit getVisitForPatientForNearestStartDate(Patient patient, Date startTime) { + List visits = visitService.getVisits(null, Collections.singletonList(patient), null, null, startTime, null, null, null, null, true, false); + if (visits.isEmpty()) { + return null; + } + Collections.sort(visits, new Comparator() { + @Override + public int compare(Visit v1, Visit v2) { + return v1.getStartDatetime().compareTo(v2.getStartDatetime()); + } + }); + return visits.get(0); + } + + private VisitType getVisitTypeByName(String visitTypeName) { + List visitTypes = visitService.getVisitTypes(visitTypeName); + return visitTypes.isEmpty() ? null : visitTypes.get(0); + } + + public boolean shouldIgnoreAccession(OpenElisAccession openElisAccession) { + return patientService.getPatientByUuid(openElisAccession.getPatientUuid()) == null; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/BahmniPatientMapper.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/BahmniPatientMapper.java new file mode 100644 index 0000000000..a4a8f24462 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/BahmniPatientMapper.java @@ -0,0 +1,59 @@ +package org.bahmni.module.elisatomfeedclient.api.mapper; + +import org.bahmni.module.bahmnicore.model.BahmniAddress; +import org.bahmni.module.bahmnicore.model.BahmniName; +import org.bahmni.module.bahmnicore.model.BahmniPatient; +import org.bahmni.module.bahmnicore.model.BahmniPersonAttribute; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisPatient; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisPatientAttribute; +import org.joda.time.DateTime; +import org.openmrs.PersonAttributeType; + +import java.util.List; + + +public class BahmniPatientMapper { + + private List allPersonAttributeTypes; + + public BahmniPatientMapper(List allPersonAttributeTypes) { + this.allPersonAttributeTypes = allPersonAttributeTypes; + } + + public BahmniPatient map(OpenElisPatient openElisPatient) { + BahmniPatient bahmniPatient = new BahmniPatient(); + bahmniPatient.setGender(openElisPatient.getGender()); + bahmniPatient.setPersonDateCreated(DateTime.now().toDate()); + bahmniPatient.addName(new BahmniName(openElisPatient.getFirstName(), openElisPatient.getLastName())); + bahmniPatient.setBirthDate(openElisPatient.getDateOfBirthAsDate()); + + BahmniAddress bahmniAddress = new BahmniAddress(); + bahmniAddress.setAddress1(openElisPatient.getAddress1()); + bahmniAddress.setAddress2(openElisPatient.getAddress2()); + bahmniAddress.setAddress3(openElisPatient.getAddress3()); + bahmniAddress.setCityVillage(openElisPatient.getCityVillage()); + bahmniAddress.setCountyDistrict(openElisPatient.getCountyDistrict()); + bahmniAddress.setStateProvince(openElisPatient.getStateProvince()); + bahmniPatient.addAddress(bahmniAddress); + bahmniPatient.setUuid(openElisPatient.getPatientUUID()); + bahmniPatient.setIdentifier(openElisPatient.getPatientIdentifier()); + bahmniPatient.setCenter(openElisPatient.getHealthCenter()); + + mapCutomAttributes(openElisPatient, bahmniPatient); + + return bahmniPatient; + } + + private void mapCutomAttributes(OpenElisPatient openElisPatient, BahmniPatient bahmniPatient) { + for (OpenElisPatientAttribute openElisPatientAttribute : openElisPatient.getAttributes()) { + String name = openElisPatientAttribute.getName(); + for (PersonAttributeType attributeType : allPersonAttributeTypes) { + if (attributeType.getName().toUpperCase().equals(name) && attributeType.getFormat().equals("java.lang.String")) { + bahmniPatient.addAttribute(new BahmniPersonAttribute(attributeType.getUuid(), openElisPatientAttribute.getValue())); + break; + } + } + } + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/OpenElisTestDetailMapper.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/OpenElisTestDetailMapper.java new file mode 100644 index 0000000000..fad2dae2f6 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/mapper/OpenElisTestDetailMapper.java @@ -0,0 +1,44 @@ +package org.bahmni.module.elisatomfeedclient.api.mapper; + +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.joda.time.DateTime; +import org.openmrs.Concept; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; + +public class OpenElisTestDetailMapper { + + public LabOrderResult map(OpenElisTestDetail testDetail, Concept concept) { + LabOrderResult labOrderResult = new LabOrderResult(); + labOrderResult.setPanelUuid(testDetail.getPanelUuid()); + labOrderResult.setTestUuid(testDetail.getTestUuid()); + labOrderResult.setTestName(testDetail.getTestName()); + labOrderResult.setResultUuid(testDetail.getResultUuid()); + labOrderResult.setResult(getValue(testDetail.getResult(), concept)); + labOrderResult.setResultDateTime(DateTime.parse(testDetail.getDateTime()).toDate()); + labOrderResult.setTestUnitOfMeasurement(testDetail.getTestUnitOfMeasurement()); + labOrderResult.setReferredOut(testDetail.isReferredOut()); + labOrderResult.setAbnormal(testDetail.getAbnormal()); + labOrderResult.setMinNormal(testDetail.getMinNormal()); + labOrderResult.setMaxNormal(testDetail.getMaxNormal()); + labOrderResult.setAccessionDateTime(DateTime.parse(testDetail.getDateTime()).toDate()); + labOrderResult.setUploadedFileName(testDetail.getUploadedFileName()); + labOrderResult.setNotes(testDetail.getNotes()); + return labOrderResult; + } + + private String getValue(String value, Concept concept) { + if (value == null || value.isEmpty()) return null; + if(concept.isNumeric()) { + return getNumericResultValue(value); + } + return value; + } + + private String getNumericResultValue(String value) { + try { + return Double.valueOf(value).toString(); + } catch (NumberFormatException e) { + return null; + } + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/task/OpenElisPatientFeedFailedEventsTask.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/task/OpenElisPatientFeedFailedEventsTask.java new file mode 100644 index 0000000000..3e3e257d94 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/task/OpenElisPatientFeedFailedEventsTask.java @@ -0,0 +1,15 @@ +package org.bahmni.module.elisatomfeedclient.api.task; + +import org.bahmni.module.elisatomfeedclient.api.client.FailedEventsFeedClient; +import org.bahmni.module.elisatomfeedclient.api.client.OpenElisPatientFailedEventsFeedClient; +import org.openmrs.api.context.Context; +import org.openmrs.scheduler.tasks.AbstractTask; + +public class OpenElisPatientFeedFailedEventsTask extends AbstractTask { + + @Override + public void execute() { + FailedEventsFeedClient feedClient = Context.getService(OpenElisPatientFailedEventsFeedClient.class); + feedClient.processFailedEvents(); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/task/OpenElisPatientFeedTask.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/task/OpenElisPatientFeedTask.java new file mode 100644 index 0000000000..e554890eb7 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/task/OpenElisPatientFeedTask.java @@ -0,0 +1,15 @@ +package org.bahmni.module.elisatomfeedclient.api.task; + +import org.bahmni.module.elisatomfeedclient.api.client.FeedClient; +import org.bahmni.module.elisatomfeedclient.api.client.OpenElisPatientFeedClient; +import org.openmrs.api.context.Context; +import org.openmrs.scheduler.tasks.AbstractTask; + +public class OpenElisPatientFeedTask extends AbstractTask { + + @Override + public void execute() { + FeedClient feedClient = Context.getService(OpenElisPatientFeedClient.class); + feedClient.processFeed(); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/EncounterHelper.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/EncounterHelper.java new file mode 100644 index 0000000000..e76ab2369f --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/EncounterHelper.java @@ -0,0 +1,112 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.EncounterType; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class EncounterHelper { + private EncounterService encounterService; + + public EncounterHelper(EncounterService encounterService) { + this.encounterService = encounterService; + } + + public Set getEncountersForAccession(String accessionUuid, EncounterType encounterType, Visit visit) { + List encounters = filterEncountersByType(visit.getEncounters(),encounterType); + Set matchedEncounters = new HashSet<>(); + if (encounters != null && !encounters.isEmpty()) { + for (Encounter encounter : encounters) { + if (encounterContainsObsPointingToAccession(encounter, accessionUuid)) { + matchedEncounters.add(encounter); + } + } + } + return matchedEncounters; + } + + private boolean encounterContainsObsPointingToAccession(Encounter encounter, String accessionUuid) { + Set observations = encounter.getObs(); + for (Obs obs : observations) { + if(obs.getValueText().equals(accessionUuid) && + obs.getConcept().getName().getName().equals(OpenElisAccessionEventWorker.ACCESSION_UUID_CONCEPT)){ + return true; + } + } + return false; + } + + public Encounter createNewEncounter(Visit visit, EncounterType encounterType, Date encounterDate, Patient patient, Provider provider, Location location) { + Encounter encounter = new Encounter(); + encounter.setPatient(patient); + EncounterRole encounterRole = encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID); + encounter.addProvider(encounterRole, provider); + encounter.setEncounterType(encounterType); + encounter.setEncounterDatetime(encounterDate); + encounter.setVisit(visit); + encounter.setLocation(location); + return encounter; + + } + + public boolean hasObservationWithText(String observationText, Encounter encounter) { + Set observations = encounter.getObs(); + if(!observations.isEmpty()){ + for (Obs observation : observations) { + if(observation.getValueText().equals(observationText)){ + return true; + } + } + } + return false; + } + + public boolean hasSameEncounterType(EncounterType encounterType, Encounter encounter) { + return encounter.getEncounterType().getUuid().equals(encounterType.getUuid()); + } + + public boolean hasSameProvider(Provider provider, Encounter encounter) { + if (encounter.getEncounterProviders().size() > 0) { + return encounter.getEncounterProviders().iterator().next().getProvider().getUuid().equals(provider.getUuid()); + } + return false; + } + + public Encounter getEncounterByProviderAndEncounterType(Provider provider, EncounterType encounterType, Set encounters) { + for (Encounter encounter : encounters) { + if (hasSameEncounterType(encounterType, encounter) && hasSameProvider(provider, encounter)) { + return encounter; + } + } + return null; + } + + public Encounter findOrInitializeEncounter(Visit visit, Provider testProvider, EncounterType encounterType, Date encounterDate, Location location) { + Encounter encounter = getEncounterByProviderAndEncounterType(testProvider, encounterType, visit.getEncounters()); + if (encounter == null) { + encounter = createNewEncounter(visit, encounterType, encounterDate, visit.getPatient(), testProvider, location); + } + return encounter; + } + + public List filterEncountersByType(Set encounters,EncounterType encounterType){ + List matchedEncounters = new ArrayList<>(); + for(Encounter encounter: encounters){ + if(hasSameEncounterType(encounterType,encounter)){ + matchedEncounters.add(encounter); + } + } + return matchedEncounters; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/IgnoreEventWorker.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/IgnoreEventWorker.java new file mode 100644 index 0000000000..7cb32b9c50 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/IgnoreEventWorker.java @@ -0,0 +1,26 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.ict4h.atomfeed.client.domain.Event; +import org.ict4h.atomfeed.client.service.EventWorker; + +public class IgnoreEventWorker implements EventWorker { + + private static Logger logger = LogManager.getLogger(IgnoreEventWorker.class); + private String message; + + public IgnoreEventWorker(String message) { + this.message = message; + } + + @Override + public void process(Event event) { + logger.warn(message); + } + + @Override + public void cleanUp(Event event) { + + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java new file mode 100644 index 0000000000..0f35f094df --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorker.java @@ -0,0 +1,415 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import groovy.lang.GroovyClassLoader; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bahmni.module.elisatomfeedclient.api.Constants; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.domain.AccessionDiff; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccessionNote; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.bahmni.module.elisatomfeedclient.api.elisFeedInterceptor.ElisFeedAccessionInterceptor; +import org.bahmni.module.elisatomfeedclient.api.elisFeedInterceptor.ElisFeedEncounterInterceptor; +import org.bahmni.module.elisatomfeedclient.api.exception.OpenElisFeedException; +import org.bahmni.module.elisatomfeedclient.api.mapper.AccessionHelper; +import org.bahmni.webclients.HttpClient; +import org.ict4h.atomfeed.client.domain.Event; +import org.ict4h.atomfeed.client.service.EventWorker; +import org.joda.time.DateTime; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterType; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Provider; +import org.openmrs.Visit; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.module.auditlog.service.AuditLogService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.openmrs.util.OpenmrsUtil; + +import java.io.File; +import java.io.IOException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +public class OpenElisAccessionEventWorker implements EventWorker { + public static final String LAB_VISIT = "LAB VISIT"; + public static final String LAB_MANAGER_NOTES = "Lab Manager Notes"; + public static final String LAB_MANAGER_IDENTIFIER = "LABMANAGER"; + public static final String ACCESSION_UUID_CONCEPT = "Accession Uuid"; + private static final String ACCESSION_NOTE_ENCOUNTER_TYPE = "VALIDATION NOTES"; + private static Logger logger = LogManager.getLogger(OpenElisAccessionEventWorker.class); + private final EncounterHelper encounterHelper; + private final ProviderHelper providerHelper; + private ElisAtomFeedProperties atomFeedProperties; + private HttpClient httpClient; + private EncounterService encounterService; + private ConceptService conceptService; + private AccessionHelper accessionHelper; + private ProviderService providerService; + private BahmniVisitAttributeService bahmniVisitAttributeSaveCommand; + private AuditLogService auditLogService; + + + //TODO : add the new service classes to bean initialization + public OpenElisAccessionEventWorker(ElisAtomFeedProperties atomFeedProperties, + HttpClient httpClient, + EncounterService encounterService, + ConceptService conceptService, + AccessionHelper accessionHelper, + ProviderService providerService, + BahmniVisitAttributeService bahmniVisitAttributeSaveCommand, + AuditLogService auditLogService) { + + this.atomFeedProperties = atomFeedProperties; + this.httpClient = httpClient; + this.encounterService = encounterService; + this.conceptService = conceptService; + this.accessionHelper = accessionHelper; + this.providerService = providerService; + this.bahmniVisitAttributeSaveCommand = bahmniVisitAttributeSaveCommand; + this.encounterHelper = new EncounterHelper(encounterService); + this.providerHelper = new ProviderHelper(providerService); + this.auditLogService = auditLogService; + } + + @Override + public void process(Event event) { + String accessionUrl = atomFeedProperties.getOpenElisUri() + event.getContent(); + logger.info("Processing event : {}", accessionUrl); + try { + OpenElisAccession openElisAccession = httpClient.get(accessionUrl, OpenElisAccession.class); + if (accessionHelper.shouldIgnoreAccession(openElisAccession)) { + logger.warn(String.format("Ignoring accession event. Patient with UUID %s is not present in OpenMRS.", openElisAccession.getPatientUuid())); + return; + } + runInterceptor(ElisFeedAccessionInterceptor.class, openElisAccession); + + for(OpenElisTestDetail openElisTestDetail : openElisAccession.getTestDetails()) { + if(openElisTestDetail.getTestUuid() == null) { + throw new RuntimeException("Concept for lab test'"+openElisTestDetail.getTestName()+"' not found in openmrs"); + } + } + Encounter orderEncounter = encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid()); + + boolean shouldSaveOrderEncounter = false; + if (orderEncounter != null) { + AccessionDiff diff = openElisAccession.getDiff(orderEncounter); + if (diff.hasDifference()) { + logger.info("updating encounter for accession : {}" , accessionUrl); + accessionHelper.addOrDiscontinueOrderDifferences(openElisAccession, diff, orderEncounter); + shouldSaveOrderEncounter = true; + } + } else { + logger.info("creating new encounter for accession : {}" , accessionUrl); + orderEncounter = accessionHelper.mapToNewEncounter(openElisAccession, LAB_VISIT); + shouldSaveOrderEncounter = true; + } + + if (shouldSaveOrderEncounter) { + //will save new visit as well + Encounter encounter = encounterService.saveEncounter(orderEncounter); + bahmniVisitAttributeSaveCommand.save(encounter); + logEncounter(encounter); + } + if (openElisAccession.getAccessionNotes() != null && !openElisAccession.getAccessionNotes().isEmpty()) { + processAccessionNotes(openElisAccession, orderEncounter); + } + Set updatedEncounters = associateTestResultsToOrder(openElisAccession); + runInterceptor(ElisFeedEncounterInterceptor.class, updatedEncounters); + + saveUpdatedEncounters(updatedEncounters); + } catch (IOException e) { + logger.error("openelisatomfeedclient:error processing event : {} {} {}", accessionUrl , e.getMessage(), e); + throw new OpenElisFeedException("could not read accession data", e); + } catch (ParseException pe) { + logger.error("openelisatomfeedclient:error processing lab results. Invalid result data type : " + accessionUrl + pe.getMessage(), pe); + throw new OpenElisFeedException("could not read accession data. Invalid result data type.", pe); + } + } + + void runInterceptor(Class className, Object object) { + GroovyClassLoader gcl = new GroovyClassLoader(); + String applicationDataDirectory = OpenmrsUtil.getApplicationDataDirectory(); + if (!applicationDataDirectory.endsWith(File.separator)) { + applicationDataDirectory += File.separator; + } + File directory = new File(applicationDataDirectory + "elisFeedInterceptor"); + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + Class clazz; + try { + clazz = gcl.parseClass(file); + if (className.equals(ElisFeedEncounterInterceptor.class) + && ElisFeedEncounterInterceptor.class.isAssignableFrom(clazz)) { + logger.info("BahmniEncounterTransactionUpdateAdvice : Using rules in {}" , clazz.getName()); + ElisFeedEncounterInterceptor elisFeedEncounterInterceptor = (ElisFeedEncounterInterceptor) clazz.newInstance(); + Set encounters = (HashSet) object; + elisFeedEncounterInterceptor.run(encounters); + logger.info("BahmniEncounterTransactionUpdateAdvice : Done"); + } else if (className.equals(ElisFeedAccessionInterceptor.class) + && ElisFeedAccessionInterceptor.class.isAssignableFrom(clazz)) { + logger.info("BahmniEncounterTransactionUpdateAdvice : Using rules in {}" , clazz.getName()); + ElisFeedAccessionInterceptor elisFeedAccessionInterceptor = (ElisFeedAccessionInterceptor) clazz.newInstance(); + elisFeedAccessionInterceptor.run((OpenElisAccession) object); + logger.info("BahmniEncounterTransactionUpdateAdvice : Done"); + } + } catch (IOException | IllegalAccessException | InstantiationException e) { + logger.error(e); + } + } + } + + } + + private void saveUpdatedEncounters(Set updatedEncounters) { + for (Encounter updatedEncounter : updatedEncounters) { + Encounter savedEncounter = encounterService.saveEncounter(updatedEncounter); + logEncounter(savedEncounter); + } + } + + private void logEncounter(Encounter savedEncounter) { + Boolean isAuditLogEnabled = Boolean.valueOf(Context.getAdministrationService().getGlobalProperty("bahmni.enableAuditLog")); + if (isAuditLogEnabled) { + Map params = new HashMap<>(); + params.put("encounterUuid", savedEncounter.getUuid()); + params.put("encounterType", savedEncounter.getEncounterType().getName()); + auditLogService.createAuditLog(savedEncounter.getPatient().getUuid(), "EDIT_ENCOUNTER", "EDIT_ENCOUNTER_MESSAGE", params, "OpenElis"); + } + } + + private void processAccessionNotes(OpenElisAccession openElisAccession, Encounter orderEncounter) throws ParseException { + + EncounterType labNotesEncounterType = getLabNotesEncounterType(); + Provider defaultLabManagerProvider = providerService.getProviderByIdentifier(LAB_MANAGER_IDENTIFIER); + + Concept labNotesConcept = getLabNotesConcept(); + Concept accessionConcept = getAccessionConcept(); + Set encountersForAccession = encounterHelper.getEncountersForAccession(openElisAccession.getAccessionUuid(), labNotesEncounterType, orderEncounter.getVisit()); + AccessionDiff accessionNoteDiff = openElisAccession.getAccessionNoteDiff(encountersForAccession, labNotesConcept, defaultLabManagerProvider); + if (accessionNoteDiff.hasDifferenceInAccessionNotes()) { + for (OpenElisAccessionNote note : accessionNoteDiff.getAccessionNotesToBeAdded()) { + Encounter noteEncounter = getEncounterForNote(note, encountersForAccession, labNotesEncounterType, orderEncounter); + if (!encounterHelper.hasObservationWithText(openElisAccession.getAccessionUuid(), noteEncounter)) { + noteEncounter.addObs(createObsWith(openElisAccession.getAccessionUuid(), accessionConcept, note.getDateTimeAsDate())); + } + noteEncounter.addObs(createObsWith(note.getNote(), labNotesConcept, note.getDateTimeAsDate())); + Encounter newEncounter = encounterService.saveEncounter(noteEncounter); + logEncounter(newEncounter); + encountersForAccession.add(newEncounter); + } + } + } + + private Encounter getEncounterForNote(OpenElisAccessionNote note, Set encountersForAccession, EncounterType encounterType, Encounter orderEncounter) { + Provider provider = providerHelper.getProviderByUuidOrReturnDefault(note.getProviderUuid(), LAB_MANAGER_IDENTIFIER); + Encounter encounterWithDefaultProvider = null; + + if (encountersForAccession != null) { + for (Encounter encounter : encountersForAccession) { + if (note.isProviderInEncounter(encounter)) { + return encounter; + } else if (ProviderHelper.getProviderFrom(encounter).equals(provider)) { + encounterWithDefaultProvider = encounter; + } + } + } + return encounterWithDefaultProvider != null ? encounterWithDefaultProvider : encounterHelper.createNewEncounter(orderEncounter.getVisit(), encounterType, orderEncounter.getEncounterDatetime(), orderEncounter.getPatient(), provider, orderEncounter.getLocation()); + } + + private Concept getAccessionConcept() { + return conceptService.getConcept(ACCESSION_UUID_CONCEPT); + } + + private Concept getLabNotesConcept() { + return conceptService.getConcept(LAB_MANAGER_NOTES); + } + + private EncounterType getLabNotesEncounterType() { + return encounterService.getEncounterType(ACCESSION_NOTE_ENCOUNTER_TYPE); + } + + private Obs createObsWith(String textValue, Concept concept, Date obsDateTime) { + Obs observation = new Obs(); + observation.setConcept(concept); + observation.setValueText(textValue); + observation.setObsDatetime(obsDateTime); + return observation; + } + + protected Set associateTestResultsToOrder(OpenElisAccession openElisAccession) throws ParseException { + Encounter orderEncounter = encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid()); + + if (!orderEncounter.getOrders().isEmpty()) { + for (OpenElisTestDetail testDetail : openElisAccession.getTestDetails()) { + if (testDetail == null || testDetail.getStatus() == null) { + continue; + } + for (Order order : orderEncounter.getOrders()) { + if (testDetail.getTestUuid().equals(order.getConcept().getUuid()) || order.getConcept().getUuid().equals(testDetail.getPanelUuid())) { + if ("Canceled".equals(testDetail.getStatus())) { + continue; + } + order.setAccessionNumber(openElisAccession.getAccessionUuid()); + } + } + } + } + + final EncounterType labResultEncounterType = getLabResultEncounterType(); + final Set allTests = openElisAccession.getTestDetails(); + + List labResultEncounters = findVisitEncountersOfType(orderEncounter.getVisit(), labResultEncounterType); + HashSet resultEncounters = new HashSet<>(labResultEncounters); + Set updatedEncounters = new HashSet<>(); + ResultObsHelper resultObsHelper = new ResultObsHelper(conceptService); + List labResultProviders = new ArrayList<>(); + Visit resultVisit = orderEncounter.getVisit(); + for (OpenElisTestDetail testDetail : allTests) { + if (testDetail.isReferredOut() && StringUtils.isBlank(testDetail.getDateTime())) { + testDetail.setDateTime(openElisAccession.getDateTime()); + } + if (StringUtils.isNotBlank(testDetail.getDateTime())) { + Order testOrder = identifyOrder(orderEncounter, testDetail); + Encounter resultEncounterForTest = identifyResultEncounter(resultEncounters, testDetail, testOrder); + Provider testProvider = getProviderForResults(labResultProviders, testDetail.getProviderUuid()); + boolean isResultUpdated = true; + + Date testDate = DateTime.parse(testDetail.getDateTime()).toDate(); + if (resultEncounterForTest != null) { + Obs prevObs = identifyResultObs(resultEncounterForTest, testDetail, testOrder); + isResultUpdated = prevObs.getObsDatetime().getTime() < testDate.getTime(); + if (isResultUpdated) { + resultObsHelper.voidObs(prevObs, testDate); + } + } + + if (isResultUpdated) { + resultEncounterForTest = encounterHelper.findOrInitializeEncounter(resultVisit, testProvider, + labResultEncounterType, orderEncounter.getEncounterDatetime(), orderEncounter.getLocation()); + resultEncounterForTest.addObs(resultObsHelper.createNewObsForOrder(testDetail, testOrder, resultEncounterForTest)); + resultVisit.addEncounter(resultEncounterForTest); + updatedEncounters.add(resultEncounterForTest); + labResultEncounters.add(resultEncounterForTest); + } + } + } + return updatedEncounters; + } + + private List findVisitEncountersOfType(Visit visit, EncounterType encounterType) { + List encounters = new ArrayList<>(); + for (Encounter encounter : visit.getEncounters()) { + if (encounter.getEncounterType().equals(encounterType)) { + encounters.add(encounter); + } + } + return encounters; + } + + private EncounterType getLabResultEncounterType() { + return encounterService.getEncounterType(Constants.DEFAULT_LAB_RESULT_ENCOUNTER_TYPE); + } + + /** + * For a given test/panel result, there ought to be only one encounter containing non voided corresponding observation + * + * @param labResultEncounters + * @param testDetail + * @param testOrder + * @return + */ + private Encounter identifyResultEncounter(HashSet labResultEncounters, OpenElisTestDetail testDetail, Order testOrder) { + for (Encounter encounter : labResultEncounters) { + final Obs resultObs = identifyResultObs(encounter, testDetail, testOrder); + if (resultObs != null) { + return encounter; + } + } + return null; + } + + /** + * This method currenly checks at the topLevel Obs. + * if its a panel, then it goes through the next level and identifes a test by the concept at the next level + * If its a test, then it just checks at the top level concept + *

+ * However, for future multi-value tests, in both the cases (panel and indiv test), it would need go to one more + * level down and return the matching observation. + * + * @param resultEncounter + * @param testDetail + * @param testOrder + * @return + */ + private Obs identifyResultObs(Encounter resultEncounter, OpenElisTestDetail testDetail, Order testOrder) { + boolean isPanel = StringUtils.isNotBlank(testDetail.getPanelUuid()); + final Set obsAtTopLevel = resultEncounter.getObsAtTopLevel(false); + for (Obs obs : obsAtTopLevel) { + if (isPanel && obs.getConcept().getUuid().equals(testDetail.getPanelUuid()) && obs.getOrder().getId().equals(testOrder.getId())) { + for (Obs member : obs.getGroupMembers()) { + if (member.getConcept().getUuid().equals(testDetail.getTestUuid()) + && member.getOrder().getId().equals(testOrder.getId())) { + return member; + } + } + } else if (obs.getConcept().getUuid().equals(testDetail.getTestUuid()) + && obs.getOrder().getId().equals(testOrder.getId())) { + return obs; + } + } + return null; + } + + private Order identifyOrder(Encounter orderEncounter, OpenElisTestDetail testDetail) { + for (Order order : orderEncounter.getOrders()) { + String testConceptUuid = StringUtils.isBlank(testDetail.getPanelUuid()) ? testDetail.getTestUuid() : testDetail.getPanelUuid(); + if (order.getConcept() != null && order.getConcept().getUuid().equals(testConceptUuid)) { + return order; + } + } + return null; //this should never be the case. + } + + private Provider getProviderForResults(List labResultProviders, String providerUuid) { + for (Provider labResultProvider : labResultProviders) { + if (labResultProvider.getUuid().equals(providerUuid)) { + return labResultProvider; + } + } + + Provider provider = null; + if (StringUtils.isNotBlank(providerUuid)) { + provider = providerService.getProviderByUuid(providerUuid); + } + + //the lab results provider may not be register as provider in MRS, + //hence instead of failing, toString the system provider + if (provider == null) { + provider = providerService.getProviderByIdentifier(Constants.DEFAULT_LAB_SYSTEM_IDENTIFIER); + } + + labResultProviders.add(provider); + return provider; + } + + @Override + public void cleanUp(Event event) { + + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisPatientFeedWorker.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisPatientFeedWorker.java new file mode 100644 index 0000000000..44b1be309d --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisPatientFeedWorker.java @@ -0,0 +1,33 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.ict4h.atomfeed.client.domain.Event; +import org.ict4h.atomfeed.client.service.EventWorker; + +import java.util.HashMap; + +public class OpenElisPatientFeedWorker implements EventWorker { + public HashMap workers = new HashMap<>(); + + public OpenElisPatientFeedWorker(OpenElisAccessionEventWorker accessionEventWorker) { + workers.put("accession", accessionEventWorker); + } + + @Override + public void process(Event event) { + getEventWorker(event).process(event); + } + + @Override + public void cleanUp(Event event) { + getEventWorker(event).cleanUp(event); + } + + private EventWorker getEventWorker(Event event) { + return workerFor(event); + } + + private EventWorker workerFor(Event event) { + Object worker = workers.get(event.getTitle()); + return worker == null? new IgnoreEventWorker("No worker found for event: " + event): (EventWorker) worker; + } +} \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/ProviderHelper.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/ProviderHelper.java new file mode 100644 index 0000000000..c8833153f5 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/ProviderHelper.java @@ -0,0 +1,29 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.openmrs.Encounter; +import org.openmrs.Provider; +import org.openmrs.api.ProviderService; + +public class ProviderHelper { + private ProviderService providerService; + + public ProviderHelper(ProviderService providerService) { + this.providerService = providerService; + } + + public static Provider getProviderFrom(Encounter encounter) { + return encounter.getEncounterProviders().iterator().next().getProvider(); + } + + public Provider getProviderByUuidOrReturnDefault(String providerUuid, String defaultProviderIdentifier) { + Provider provider = providerService.getProviderByUuid(providerUuid); + if (provider != null) { + return provider; + } + if (defaultProviderIdentifier != null) { + return providerService.getProviderByIdentifier(defaultProviderIdentifier); + } + return null; + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/ResultObsHelper.java b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/ResultObsHelper.java new file mode 100644 index 0000000000..053b4435a4 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/java/org/bahmni/module/elisatomfeedclient/api/worker/ResultObsHelper.java @@ -0,0 +1,75 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.bahmni.module.elisatomfeedclient.api.mapper.OpenElisTestDetailMapper; +import org.joda.time.DateTime; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.api.ConceptService; +import org.openmrs.module.bahmniemrapi.laborder.contract.LabOrderResult; +import org.openmrs.module.bahmniemrapi.laborder.mapper.LabOrderResultMapper; + +import java.text.ParseException; +import java.util.Date; +import java.util.Set; + +public class ResultObsHelper { + public static final String VOID_REASON = "updated since by lab technician"; + + private final ConceptService conceptService; + + public ResultObsHelper(ConceptService conceptService) { + this.conceptService = conceptService; + } + + public Obs createNewObsForOrder(OpenElisTestDetail testDetail, Order testOrder, Encounter resultEncounter) throws ParseException { + Date obsDate = DateTime.parse(testDetail.getDateTime()).toDate(); + if(testDetail.getPanelUuid() != null) { + Obs panelObs = createOrFindPanelObs(testDetail, testOrder, resultEncounter, obsDate); + Concept testConcept = conceptService.getConceptByUuid(testDetail.getTestUuid()); + panelObs.addGroupMember(createObsForTest(testDetail, testOrder, testConcept)); + return panelObs; + } else { + return createObsForTest(testDetail, testOrder, testOrder.getConcept()); + } + } + + public void voidObs(Obs obs, Date testDate) { + obs.setVoided(true); + obs.setVoidReason(VOID_REASON); + obs.setDateVoided(testDate); + final Set groupMembers = obs.getGroupMembers(); + if ((groupMembers != null) && (groupMembers.size() > 0)) { + for (Obs member : groupMembers) { + voidObs(member, testDate); + } + } + } + + private Obs createObsForTest(OpenElisTestDetail testDetail, Order order, Concept testConcept) { + LabOrderResult labOrderResult = new OpenElisTestDetailMapper().map(testDetail, testConcept); + return new LabOrderResultMapper(conceptService).map(labOrderResult, order, testConcept); + } + + private Obs createOrFindPanelObs(OpenElisTestDetail testDetail, Order testOrder, Encounter resultEncounter, Date obsDate) { + Obs panelObs = null; + for (Obs obs : resultEncounter.getObsAtTopLevel(false)) { + if(obs.getConcept().getUuid().equals(testDetail.getPanelUuid()) && obs.getOrder().getId().equals(testOrder.getId())){ + panelObs = obs; + break; + } + } + return panelObs != null ? panelObs : newObs(testOrder, testOrder.getConcept(), obsDate); + } + + private Obs newObs(Order order, Concept concept, Date obsDate) { + Obs labObs = new Obs(); + labObs.setConcept(concept); + labObs.setOrder(order); + labObs.setObsDatetime(obsDate); + return labObs; + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_44__AddingSchedulerTaskToProcessOpenElisPatientFeed.sql b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_44__AddingSchedulerTaskToProcessOpenElisPatientFeed.sql new file mode 100644 index 0000000000..f35c53cb96 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_44__AddingSchedulerTaskToProcessOpenElisPatientFeed.sql @@ -0,0 +1,2 @@ +INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval, start_on_startup, started, created_by, date_created, uuid) +VALUES ('OpenElis Atom Feed Client', 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisAtomFeedTask', now(), 'MM/dd/yyyy HH:mm:ss', 60, 1, 1, 1, curdate(), uuid()); \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_45__UpdatingOpenElisAtomFeedSchedulerTaskToNotStartUpAutomatically.sql b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_45__UpdatingOpenElisAtomFeedSchedulerTaskToNotStartUpAutomatically.sql new file mode 100644 index 0000000000..15a5cebd88 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_45__UpdatingOpenElisAtomFeedSchedulerTaskToNotStartUpAutomatically.sql @@ -0,0 +1 @@ +UPDATE scheduler_task_config SET start_on_startup = 0 WHERE name = 'OpenElis Atom Feed Client'; \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_50__UpdatingOpenElisAtomFeedSchedulerTaskToRunEvery15Seconds.sql b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_50__UpdatingOpenElisAtomFeedSchedulerTaskToRunEvery15Seconds.sql new file mode 100644 index 0000000000..6afb0609db --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_50__UpdatingOpenElisAtomFeedSchedulerTaskToRunEvery15Seconds.sql @@ -0,0 +1 @@ +UPDATE scheduler_task_config SET repeat_interval = 15 WHERE name = 'OpenElis Atom Feed Client'; \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_52__StartOpenElisAtomFeedSchedulerTaskToStartAutomatically.sql b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_52__StartOpenElisAtomFeedSchedulerTaskToStartAutomatically.sql new file mode 100644 index 0000000000..e94b1f17ae --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_52__StartOpenElisAtomFeedSchedulerTaskToStartAutomatically.sql @@ -0,0 +1 @@ +UPDATE scheduler_task_config SET start_on_startup = 1 WHERE name = 'OpenElis Atom Feed Client'; \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_64__AddLabResultFeedScheduler.sql b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_64__AddLabResultFeedScheduler.sql new file mode 100644 index 0000000000..d59d659014 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/V1_64__AddLabResultFeedScheduler.sql @@ -0,0 +1,7 @@ +UPDATE scheduler_task_config SET + schedulable_class="org.bahmni.module.elisatomfeedclient.api.task.OpenElisPatientFeedTask", + name = "OpenElis Patient Atom Feed Task" +where schedulable_class = "org.bahmni.module.elisatomfeedclient.api.task.OpenElisAtomFeedTask"; + +INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval, start_on_startup, started, created_by, date_created, uuid) +VALUES ('OpenElis Lab Result Atom Feed Task', 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisLabResultFeedTask', now(), 'MM/dd/yyyy HH:mm:ss', 15, 1, 1, 1, curdate(), uuid()); \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/config.xml b/openmrs-elis-atomfeed-client-omod/src/main/resources/config.xml new file mode 100644 index 0000000000..70ad934754 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/config.xml @@ -0,0 +1,52 @@ + + + + + + + @MODULE_ID@ + @MODULE_NAME@ + @MODULE_VERSION@ + @MODULE_PACKAGE@ + Bahmni + + Atom feed client for OpenElis + + @MODULE_PACKAGE@.Activator + + https://example.com/modules/download/elisatomfeedclient/update.rdf + + + ${openMRSRuntimeVersion} + + org.bahmni.module.bahmnicore + org.ict4h.openmrs.openmrs-atomfeed + org.openmrs.module.auditlog + + + + + + + + Add Patient Lists + Ability to create patient lists + + + Delete Patient Lists + Ability to delete patient lists + + + Edit Patient Lists + Ability to edit patient lists + + + View Patient Lists + Ability to view patient lists + + + + en + messages.properties + + diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/liquibase.xml b/openmrs-elis-atomfeed-client-omod/src/main/resources/liquibase.xml new file mode 100644 index 0000000000..2aec2ca68b --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/liquibase.xml @@ -0,0 +1,120 @@ + + + + rel2 + + + + rel2 + + + + rel2 + + + + rel2 + + + + rel3 + + + + Add failed events job for Openelis lab result processing + + INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval, start_on_startup, started, created_by, date_created, uuid) + VALUES ('OpenElis Lab Result Atom Feed Failed Event Task', 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisLabResultFeedFailedEventsTask', now(), 'MM/dd/yyyy HH:mm:ss', 15, 1, 1, 1, curdate(), uuid()); + + + + Add failed events job for Openelis patient processing + + INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval, start_on_startup, started, created_by, date_created, uuid) + VALUES ('OpenElis Patient Atom Feed Failed Event Task', 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisPatientFeedFailedEventsTask', now(), 'MM/dd/yyyy HH:mm:ss', 15, 0, 0, 1, curdate(), uuid()); + + + + Don't start the patient feed on startup + + UPDATE scheduler_task_config SET start_on_startup = 0 WHERE name = 'OpenElis Patient Atom Feed Task'; + + + + + set @puuid = uuid(); + + insert into person(birthdate_estimated, dead, creator, date_created, uuid) + values(0, 0, 1, now(), @puuid); + + insert into users(system_id, creator, date_created, person_id, uuid, username) + values ('Lab System', 1, now(),(select person_id from person where uuid = @puuid) , uuid(), 'Lab System'); + + insert into provider (person_id, identifier, creator, date_created, uuid, name) values ((select person_id from person where uuid = @puuid), 'LABSYSTEM', 1, now(), uuid(), 'Lab System'); + + + + + + select count(*) from liquibasechangelog where author='elisatomfeedclient' and id='100'; + + + + INSERT INTO `liquibasechangelog` (`ID`,`AUTHOR`,`FILENAME`,`DATEEXECUTED`,`MD5SUM`,`DESCRIPTION`,`COMMENTS`,`TAG`,`LIQUIBASE`,`EXECTYPE`,`ORDEREXECUTED`) + VALUES ('100','ict4h','sql/db_migrations.xml',now(),'3:8ee36a0313cda559247cbb2729fe6e76','Create Table (x2)','',NULL,'2.0.5','EXECUTED','100') ON DUPLICATE KEY UPDATE EXECTYPE = 'EXECUTED'; + + + + + + select count(*) from liquibasechangelog where author='tw' and id='elis-atomfeed-9'; + + + + INSERT INTO `liquibasechangelog` (`ID`,`AUTHOR`,`FILENAME`,`DATEEXECUTED`,`MD5SUM`,`DESCRIPTION`,`COMMENTS`,`TAG`,`LIQUIBASE`,`EXECTYPE`,`ORDEREXECUTED`) + VALUES ('101','ict4h','sql/db_migrations.xml',now(),'3:29f59eb61eb39a9dee52d81f4026d642','Add Column','',NULL,'2.0.5','EXECUTED','101') ON DUPLICATE KEY UPDATE EXECTYPE = 'EXECUTED'; + + + + + update scheduler_task_config set start_on_startup='1' where name in ('OpenElis Patient Atom Feed Task','OpenElis Patient Atom Feed Failed Event Task'); + + + + Remove scheduled job to process failed Openelis lab results + + DELETE FROM scheduler_task_config WHERE schedulable_class = 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisLabResultFeedFailedEventsTask'; + + + + Remove scheduled job to process Openelis lab results, as this is now part of accession worker + + DELETE FROM scheduler_task_config WHERE schedulable_class = 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisLabResultFeedTask'; + + + + + select count(*) from visit_type where name = 'LAB VISIT' + + Creating new visit type LAB VISIT + + INSERT INTO visit_type (name, description, creator, uuid, date_created) VALUES ('LAB VISIT', 'Visits for lab visit by patient when the tests are not ordered through OpenMRS', 1, uuid(), curdate()); + + + + + + + select count(*) from scheduler_task_config where schedulable_class= "org.bahmni.module.elisatomfeedclient.api.task.OpenElisPatientFeedTask" and name = "OpenElis Patient Atom Feed Task"; + + + rel3 + + INSERT INTO scheduler_task_config(name, schedulable_class, start_time, start_time_pattern, repeat_interval, start_on_startup, started, created_by, date_created, uuid) + VALUES ('OpenElis Patient Atom Feed Task', 'org.bahmni.module.elisatomfeedclient.api.task.OpenElisPatientFeedTask', now(), 'MM/dd/yyyy HH:mm:ss', 15, 1, 1, 1, curdate(), uuid()); + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/messages.properties b/openmrs-elis-atomfeed-client-omod/src/main/resources/messages.properties new file mode 100644 index 0000000000..53ce10512e --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/messages.properties @@ -0,0 +1 @@ +@MODULE_ID@.title=Open-Elis Atom Feed Client \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/main/resources/moduleApplicationContext.xml b/openmrs-elis-atomfeed-client-omod/src/main/resources/moduleApplicationContext.xml new file mode 100644 index 0000000000..6e2140d395 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/main/resources/moduleApplicationContext.xml @@ -0,0 +1,28 @@ + + + + + + + + + org.bahmni.module.elisatomfeedclient.api.client.OpenElisPatientFeedClient + + + + + + + + org.bahmni.module.elisatomfeedclient.api.client.OpenElisPatientFailedEventsFeedClient + + + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/builder/OpenElisAccessionBuilder.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/builder/OpenElisAccessionBuilder.java new file mode 100644 index 0000000000..9353d59d51 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/builder/OpenElisAccessionBuilder.java @@ -0,0 +1,55 @@ +package org.bahmni.module.elisatomfeedclient.api.builder; + + +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccessionNote; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; + +import java.util.Arrays; +import java.util.Set; + +public class OpenElisAccessionBuilder { + + private OpenElisAccession openElisAccession; + + public OpenElisAccessionBuilder() { + openElisAccession = new OpenElisAccession(); + openElisAccession.setAccessionUuid("1234"); + openElisAccession.addTestDetail(new OpenElisTestDetailBuilder().build()); + openElisAccession.setPatientIdentifier("GAN12345"); + openElisAccession.setLabLocationUuid("be69741b-29e9-49a1-adc9-2a726e6610e4"); + } + + public OpenElisAccession build() { + return openElisAccession; + } + + public OpenElisAccessionBuilder withTestDetails(Set testDetails) { + openElisAccession.setTestDetails(testDetails); + return this; + } + + public OpenElisAccessionBuilder withDateTime(String dateTime) { + openElisAccession.setDateTime(dateTime); + return this; + } + + public OpenElisAccessionBuilder withPatientUuid(String uuid) { + openElisAccession.setPatientUuid(uuid); + return this; + } + public OpenElisAccessionBuilder withAccessionNotes(OpenElisAccessionNote... accessionNotes) { + openElisAccession.setAccessionNotes(Arrays.asList(accessionNotes)); + return this; + } + + public OpenElisAccessionBuilder withLabLocationUuid(String labLocationUuid) { + openElisAccession.setLabLocationUuid(labLocationUuid); + return this; + } + + public OpenElisAccessionBuilder withPatientIdentifier(String patientIdentifier) { + openElisAccession.setPatientIdentifier(patientIdentifier); + return this; + } +} \ No newline at end of file diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/builder/OpenElisTestDetailBuilder.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/builder/OpenElisTestDetailBuilder.java new file mode 100644 index 0000000000..172b9f9ae8 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/builder/OpenElisTestDetailBuilder.java @@ -0,0 +1,72 @@ +package org.bahmni.module.elisatomfeedclient.api.builder; + +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; + +public class OpenElisTestDetailBuilder { + + private final OpenElisTestDetail testDetail; + + public OpenElisTestDetailBuilder() { + testDetail = new OpenElisTestDetail(); + testDetail.setTestUuid("Test123"); + } + + public OpenElisTestDetail build() { + return testDetail; + } + + public OpenElisTestDetailBuilder withTestUuid(String testUuid) { + testDetail.setTestUuid(testUuid); + return this; + } + + public OpenElisTestDetailBuilder withStatus(String status) { + testDetail.setStatus(status); + return this; + } + + public OpenElisTestDetailBuilder withPanelUuid(String panelUuid) { + testDetail.setPanelUuid(panelUuid); + return this; + } + + public OpenElisTestDetailBuilder withResult(String result) { + testDetail.setResult(result); + return this; + } + + public OpenElisTestDetailBuilder withProviderUuid(String providerUuid) { + testDetail.setProviderUuid(providerUuid); + return this; + } + + public OpenElisTestDetailBuilder withDateTime(String dateTime) { + testDetail.setDateTime(dateTime); + return this; + } + + public OpenElisTestDetailBuilder withMinNormal(String minNormalValue) { + testDetail.setMinNormal(Double.valueOf(minNormalValue)); + return this; + } + + public OpenElisTestDetailBuilder withMaxNormal(String maxNormalValue) { + testDetail.setMaxNormal(Double.valueOf(maxNormalValue)); + return this; + } + + public OpenElisTestDetailBuilder withAbnormal(String value) { + testDetail.setAbnormal(Boolean.valueOf(value)); + return this; + } + + public OpenElisTestDetailBuilder withResultType(String resultType) { + testDetail.setResultType(resultType); + return this; + } + + public OpenElisTestDetailBuilder withUploadedFileName(String uploadedFileName) { + testDetail.setUploadedFileName(uploadedFileName); + return this; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccessionTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccessionTest.java new file mode 100644 index 0000000000..e47fa70abe --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisAccessionTest.java @@ -0,0 +1,287 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisAccessionBuilder; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisTestDetailBuilder; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class OpenElisAccessionTest { + private HashSet accessionNotesEncounters; + private Concept accessionNotesConcept; + private OpenElisAccession openElisAccessionWithNotes; + private Provider defaultLabManagerProvider; + + @Test + public void shouldGetDiffWhenAccessionHasNewOrder() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2))).build(); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(1, diff.getAddedTestDetails().size()); + assertEquals(test2, diff.getAddedTestDetails().toArray()[0]); + } + + @Test + public void shouldGetDiffWhenAccessionHasRemovedOrderFromPreviousEncounter() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1", "test2", "test3"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").withStatus("Canceled").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + Set removedTestDetails = diff.getRemovedTestDetails(); + + assertEquals(1, removedTestDetails.size()); + assertEquals(test3, removedTestDetails.toArray()[0]); + + } + + @Test + public void shouldGetDiffWhenAccessionHasAddedTestToPreviousEncounterAndRemovedTestWithinElis() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").withStatus("Canceled").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(1, diff.getAddedTestDetails().size()); + assertEquals(test2, diff.getAddedTestDetails().toArray()[0]); + assertEquals(0, diff.getRemovedTestDetails().size()); + } + + @Test + public void shouldNotDiffIfThereAreNoAddedOrRemovedTests() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1", "test2"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(0, diff.getAddedTestDetails().size()); + assertEquals(0, diff.getRemovedTestDetails().size()); + + } + + @Test + public void shouldNotDiffIfThereAreTestsRemovedOnBothSides() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1", "test2"); + getOrderByName(previousEncounter, "test1").setVoided(true); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").withStatus("Canceled").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(0, diff.getAddedTestDetails().size()); + assertEquals(0, diff.getRemovedTestDetails().size()); + } + + @Test + @Ignore + //This testcase has other consequences. For example + // Doctor orders a test, it gets synced to elis. The sample is collected and now the doctor cancels it from MRS (voided=1). + // The cancel is dropped as the sample is already collected. Now, when it syncs back, we do not want the original order to be un-voided. Refer #2341 + public void shouldGetDiffIfCancelledTestIsReordered() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1", "test2"); + getOrderByName(previousEncounter, "test1").setVoided(true); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").withStatus("Canceled").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail test1ReOrdered = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test1ReOrdered))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(1, diff.getAddedTestDetails().size()); + assertEquals(test1ReOrdered, diff.getAddedTestDetails().toArray()[0]); + } + + @Test + public void shouldGetDiffIfNewPanelAreAdded() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").withPanelUuid("panel1").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").withPanelUuid("panel1").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(2, diff.getAddedTestDetails().size()); + Assert.assertThat(diff.getAddedTestDetails(), hasItem(test2)); + Assert.assertThat(diff.getAddedTestDetails(), hasItem(test3)); + } + + @Test + public void shouldGetDiffIfPanelAreRemoved() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("test1", "panel1"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").withStatus("Canceled").withPanelUuid("panel1").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").withStatus("Canceled").withPanelUuid("panel1").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(2, diff.getRemovedTestDetails().size()); + Assert.assertThat(diff.getRemovedTestDetails(), hasItem(test2)); + Assert.assertThat(diff.getRemovedTestDetails(), hasItem(test3)); + } + + @Test + public void shouldNotGetDiffIfThereArePanelsRemovedOnBothSides() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("panel1", "test2"); + getOrderByName(previousEncounter, "panel1").setVoided(true); + OpenElisTestDetail panel1 = new OpenElisTestDetailBuilder().withTestUuid("test1").withPanelUuid("panel1").withStatus("Canceled").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(panel1, test2))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(0, diff.getAddedTestDetails().size()); + assertEquals(0, diff.getRemovedTestDetails().size()); + } + + @Test + @Ignore + public void shouldGetDiffIfCancelledPanelIsReordered() throws Exception { + Encounter previousEncounter = getEncounterWithOrders("panel1", "test2"); + getOrderByName(previousEncounter, "panel1").setVoided(true); + OpenElisTestDetail panel1 = new OpenElisTestDetailBuilder().withTestUuid("test1").withPanelUuid("panel1").withStatus("Canceled").build(); + OpenElisTestDetail panel2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail panel1ReOrdered = new OpenElisTestDetailBuilder().withTestUuid("test1").withPanelUuid("panel1").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(panel1, panel2, panel1ReOrdered))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + + AccessionDiff diff = openElisAccession.getDiff(previousEncounter); + + assertEquals(1, diff.getAddedTestDetails().size()); + assertEquals(panel1ReOrdered, diff.getAddedTestDetails().toArray()[0]); + } + + public void accessionNotesTestSetup() { + PowerMockito.mockStatic(Context.class); + when(Context.getAuthenticatedUser()).thenReturn(new User()); + + accessionNotesEncounters = new HashSet<>(); + Encounter encounter1 = createEncounterWithProviderAndObservations("e1","p1","c1","note1"); + Encounter encounter2 =createEncounterWithProviderAndObservations("e2","p2","c1","note2","note3"); + accessionNotesEncounters.add(encounter1); + accessionNotesEncounters.add(encounter2); + defaultLabManagerProvider = new Provider(); + defaultLabManagerProvider.setUuid("default"); + accessionNotesConcept = new Concept(); + accessionNotesConcept.setUuid("c1"); + } + + private Encounter createEncounterWithProviderAndObservations(String encUuid,String providerUuid,String conceptUuid,String... observations) { + Encounter encounter1 = new Encounter(); + encounter1.setUuid(encUuid); + Provider provider1 = new Provider(); + provider1.setUuid(providerUuid); + encounter1.addProvider(new EncounterRole(1), provider1); + Concept concept = new Concept(); + concept.setUuid(conceptUuid); + + for(String observation : observations){ + Obs obs = new Obs(); + obs.setConcept(concept); + obs.setValueText(observation); + encounter1.addObs(obs); + } + return encounter1; + } + + + @Test + public void shouldUpdateTheAccessionNotesToBeAdded() { + accessionNotesTestSetup(); + openElisAccessionWithNotes = new OpenElisAccessionBuilder().withAccessionNotes( + new OpenElisAccessionNote("note1","p1", "2014-01-30T11:50:18+0530"), + new OpenElisAccessionNote("note2","p2", "2014-01-30T11:50:18+0530"), + new OpenElisAccessionNote("note3","p2", "2014-01-30T11:50:18+0530"), + new OpenElisAccessionNote("note4","p1", "2014-01-30T11:50:18+0530")).build(); + + AccessionDiff diff = openElisAccessionWithNotes.getAccessionNoteDiff(accessionNotesEncounters, accessionNotesConcept,defaultLabManagerProvider); + assertNotNull(diff); + assertEquals(1, diff.getAccessionNotesToBeAdded().size()); + assertEquals("note4", diff.getAccessionNotesToBeAdded().get(0).getNote()); + assertEquals("p1", diff.getAccessionNotesToBeAdded().get(0).getProviderUuid()); + } + + @Test + public void shouldntReturnDiffWhenNotesAlreadyExist() { + accessionNotesTestSetup(); + openElisAccessionWithNotes = new OpenElisAccessionBuilder().withAccessionNotes( + new OpenElisAccessionNote("note1","p1", "2014-01-30T11:50:18+0530"), + new OpenElisAccessionNote("note2","p2", "2014-01-30T11:50:18+0530"), + new OpenElisAccessionNote("note3","p2", "2014-01-30T11:50:18+0530")).build(); + AccessionDiff diff = openElisAccessionWithNotes.getAccessionNoteDiff(accessionNotesEncounters, accessionNotesConcept,defaultLabManagerProvider); + assertNotNull(diff); + assertEquals(0, diff.getAccessionNotesToBeAdded().size()); + } + + @Test + public void shouldntReturnDiffWhenNotesAreAddedAndNoNotesExist() { + accessionNotesTestSetup(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().build(); + AccessionDiff diff = openElisAccession.getAccessionNoteDiff(accessionNotesEncounters, accessionNotesConcept, defaultLabManagerProvider); + assertNotNull(diff); + assertEquals(0, diff.getAccessionNotesToBeAdded().size()); + } + + private Order getOrderByName(Encounter encounter, String testUuid) { + for (Order order : encounter.getOrders()) { + if (order.getConcept().getUuid().equals(testUuid)) + return order; + } + return null; + } + + private Encounter getEncounterWithOrders(String... testUuids) { + Encounter encounter = new Encounter(); + for (String testUuid : testUuids) { + Order order = new Order(); + Concept concept = new Concept(); + concept.setUuid(testUuid); + order.setConcept(concept); + encounter.addOrder(order); + } + return encounter; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatientTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatientTest.java new file mode 100644 index 0000000000..23c634d3a3 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/domain/OpenElisPatientTest.java @@ -0,0 +1,19 @@ +package org.bahmni.module.elisatomfeedclient.api.domain; + +import org.joda.time.LocalDate; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +public class OpenElisPatientTest { + + @Test + public void shouldReturnBirthDateAsDate() throws Exception { + OpenElisPatient openElisPatient = new OpenElisPatient(); + LocalDate today = LocalDate.now(); + openElisPatient.setDateOfBirth(today.toString("yyyy-MM-dd")); + + assertEquals(today.toDate(), openElisPatient.getDateOfBirthAsDate()); + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/mapper/AccessionHelperTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/mapper/AccessionHelperTest.java new file mode 100644 index 0000000000..4c41b873da --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/mapper/AccessionHelperTest.java @@ -0,0 +1,314 @@ +package org.bahmni.module.elisatomfeedclient.api.mapper; + +import org.bahmni.module.elisatomfeedclient.api.Constants; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisAccessionBuilder; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisTestDetailBuilder; +import org.bahmni.module.elisatomfeedclient.api.domain.AccessionDiff; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterRole; +import org.openmrs.EncounterType; +import org.openmrs.Order; +import org.openmrs.OrderType; +import org.openmrs.Patient; +import org.openmrs.Person; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.LocationService; +import org.openmrs.api.OrderService; +import org.openmrs.api.PatientService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.UserService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.bahmni.module.bahmnicommons.api.visitlocation.BahmniVisitLocationService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyCollection; +import static org.mockito.Mockito.anyMap; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) + +public class AccessionHelperTest { + @Mock + EncounterService encounterService; + @Mock + PatientService patientService; + @Mock + VisitService visitService; + @Mock + ConceptService conceptService; + + @Mock + BahmniVisitLocationService bahmniVisitLocationService; + + @Mock + private ElisAtomFeedProperties feedProperties; + @Mock + private UserService userService; + @Mock + private ProviderService providerService; + @Mock + private OrderService orderService; + @Mock + private LocationService locationService; + @Mock + private AdministrationService administrationService; + + private AccessionHelper accessionHelper; + private static final String VISIT_START_DATE = "2014-01-15 15:25:43+0530"; + private static final String ENCOUNTER_START_DATE = "2014-01-17T17:25:43Z"; + private static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ"; + private SimpleDateFormat simpleDateFormat; + + + @Before + public void setUp() { + initMocks(this); + accessionHelper = new AccessionHelper(encounterService, patientService, visitService, conceptService, userService, providerService, orderService, feedProperties,bahmniVisitLocationService, administrationService); + simpleDateFormat = new SimpleDateFormat(DATE_FORMAT); + } + + @Test + public void shouldMapToNewEncounter() throws ParseException { + OpenElisTestDetail panel1 = new OpenElisTestDetailBuilder().withPanelUuid("panel1").withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + HashSet testDetails = new HashSet<>(); + + testDetails.add(panel1); + testDetails.add(test2); + Patient patient = new Patient(); + List visits = createVisits(1); + + User provider = new User(); + + when(patientService.getPatientByUuid(any(String.class))).thenReturn(patient); + when(encounterService.getEncounterType("Consultation")).thenReturn(new EncounterType()); + when(conceptService.getConceptByUuid("panel1")).thenReturn(getConceptByUuid("panel1")); + when(conceptService.getConceptByUuid("test2")).thenReturn(getConceptByUuid("test2")); + when(visitService.saveVisit(any(Visit.class))).thenReturn(visits.get(0)); + when(visitService.getVisitTypes("LAB_RESULTS")).thenReturn(Arrays.asList(visits.get(0).getVisitType())); + when(visitService.getVisits(anyCollection(), anyCollection(), anyCollection(), anyCollection(), any(Date.class), any(Date.class), any(Date.class), any(Date.class), anyMap(), anyBoolean(), anyBoolean())).thenReturn(visits); + when(userService.getUserByUsername(anyString())).thenReturn(provider); + when(providerService.getProvidersByPerson(eq(null))).thenReturn(Arrays.asList(new Provider())); + when(encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID)).thenReturn(new EncounterRole()); + when(orderService.getOrderTypes(true)).thenReturn(Arrays.asList(getOrderType())); + PowerMockito.mockStatic(Context.class); + when(Context.getAuthenticatedUser()).thenReturn(provider); + when(Context.getLocationService()).thenReturn(locationService); + when(locationService.getLocationByUuid(anyString())).thenReturn(null); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(testDetails).build(); + openElisAccession.setDateTime(ENCOUNTER_START_DATE); + Encounter encounter = accessionHelper.mapToNewEncounter(openElisAccession, "LAB_RESULTS"); + + Set orders = encounter.getOrders(); + Assert.assertEquals(2, orders.size()); + verify(conceptService, never()).getConceptByUuid("test1"); + + for (Order order : orders) { + Assert.assertTrue(order.getConcept().getUuid().equals("panel1") || order.getConcept().getUuid().equals("test2")); + } + } + + @Test + public void shouldFindProperVisitAndMapToNewEncounter() throws ParseException { + OpenElisTestDetail panel1 = new OpenElisTestDetailBuilder().withPanelUuid("panel1").withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + HashSet testDetails = new HashSet<>(); + testDetails.add(panel1); + testDetails.add(test2); + Patient patient = new Patient(); + List visits = createVisits(3); + User provider = new User(); + + when(patientService.getPatientByUuid(any(String.class))).thenReturn(patient); + when(encounterService.getEncounterType("Consultation")).thenReturn(new EncounterType()); + when(conceptService.getConceptByUuid("panel1")).thenReturn(getConceptByUuid("panel1")); + when(conceptService.getConceptByUuid("test2")).thenReturn(getConceptByUuid("test2")); + when(visitService.getVisitTypes("LAB_RESULTS")).thenReturn(Arrays.asList(visits.get(0).getVisitType())); + when(visitService.getVisits(anyCollection(), anyCollection(), anyCollection(), anyCollection(), any(Date.class), any(Date.class), any(Date.class), any(Date.class), anyMap(), anyBoolean(), anyBoolean())).thenReturn(visits); + when(userService.getUserByUsername(anyString())).thenReturn(provider); + when(providerService.getProvidersByPerson(eq(null))).thenReturn(Arrays.asList(new Provider())); + when(encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID)).thenReturn(new EncounterRole()); + when(orderService.getOrderTypes(true)).thenReturn(Arrays.asList(getOrderType())); + when(visitService.saveVisit(any(Visit.class))).thenReturn(visits.get(0)); + PowerMockito.mockStatic(Context.class); + when(Context.getAuthenticatedUser()).thenReturn(provider); + when(Context.getLocationService()).thenReturn(locationService); + when(locationService.getLocationByUuid(anyString())).thenReturn(null); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(testDetails).build(); + openElisAccession.setDateTime(ENCOUNTER_START_DATE); + Encounter encounter = accessionHelper.mapToNewEncounter(openElisAccession, "LAB_RESULTS"); + + Date startDatetime = encounter.getVisit().getStartDatetime(); + Assert.assertTrue("Encounter should be before or after visit start", encounter.getEncounterDatetime().compareTo(startDatetime) >= 0); + Set orders = encounter.getOrders(); + Assert.assertEquals(2, orders.size()); + verify(conceptService, never()).getConceptByUuid("test1"); + + for (Order order : orders) { + Assert.assertTrue(order.getConcept().getUuid().equals("panel1") || order.getConcept().getUuid().equals("test2")); + } + } + + @Test + public void shouldMapNewOrdersToExistingEncounter() { + Encounter previousEncounter = new Encounter(); + Order panel = getOrderWithConceptUuid("panel"); + Order test = getOrderWithConceptUuid("test"); + HashSet orders = new HashSet<>(); + orders.add(panel); + orders.add(test); + previousEncounter.setOrders(orders); + when(userService.getUserByUsername(anyString())).thenReturn(new User()); + when(providerService.getProvidersByPerson(eq(null))).thenReturn(Arrays.asList(new Provider())); + when(administrationService.getGlobalPropertyValue(Constants.GP_ALLOW_DISCONTINUE_ORDERS, Boolean.TRUE)).thenReturn(Boolean.TRUE); + AccessionDiff diff = new AccessionDiff(); + diff.addAddedTestDetail(new OpenElisTestDetailBuilder().withTestUuid("test2").build()); + diff.addAddedTestDetail(new OpenElisTestDetailBuilder().withTestUuid("panel1").build()); + + Encounter encounter = accessionHelper.addOrDiscontinueOrderDifferences(new OpenElisAccessionBuilder().build(), diff, previousEncounter); + + Assert.assertEquals(4, encounter.getOrders().size()); + } + + @Test + public void shouldMapDeletedOrdersToExistingEncounter() { + Encounter previousEncounter = new Encounter(); + Order panel = getOrderWithConceptUuid("panel1"); + Order test = getOrderWithConceptUuid("test2"); + HashSet orders = new HashSet<>(); + orders.add(panel); + orders.add(test); + previousEncounter.setOrders(orders); + + AccessionDiff diff = new AccessionDiff(); + diff.addRemovedTestDetails(new OpenElisTestDetailBuilder().withTestUuid("test2").withStatus("Cancelled").build()); + when(administrationService.getGlobalPropertyValue(Constants.GP_ALLOW_DISCONTINUE_ORDERS, Boolean.TRUE)).thenReturn(Boolean.TRUE); + + Encounter encounter = accessionHelper.addOrDiscontinueOrderDifferences(new OpenElisAccessionBuilder().build(), diff, previousEncounter); + + Set result = encounter.getOrders(); + Assert.assertEquals(3, result.size()); + for (Order order : result) { + if (order.getAction().equals(Order.Action.DISCONTINUE)) { + Assert.assertTrue(order.getPreviousOrder().getConcept().getUuid().endsWith(order.getConcept().getUuid())); + } + } + } + + @Test + public void shouldNotMapDeletedOrdersToExistingEncounter() { + Encounter previousEncounter = new Encounter(); + Order panel = getOrderWithConceptUuid("panel2"); + Order test = getOrderWithConceptUuid("test3"); + HashSet orders = new HashSet<>(); + orders.add(panel); + orders.add(test); + previousEncounter.setOrders(orders); + + AccessionDiff diff = new AccessionDiff(); + diff.addRemovedTestDetails(new OpenElisTestDetailBuilder().withTestUuid("test3").withStatus("Cancelled").build()); + when(administrationService.getGlobalPropertyValue(Constants.GP_ALLOW_DISCONTINUE_ORDERS, Boolean.TRUE)).thenReturn(Boolean.FALSE); + + Encounter encounter = accessionHelper.addOrDiscontinueOrderDifferences(new OpenElisAccessionBuilder().build(), diff, previousEncounter); + + Set result = encounter.getOrders(); + Assert.assertEquals(2, result.size()); + for (Order order : result) { + Assert.assertEquals(order.getAction(), Order.Action.NEW); + } + } + + @Test + public void shouldReturnTrueIfPatientWithTheGivenUuidIsNotPresent() { + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withPatientUuid("uuid1").build(); + when(patientService.getPatientByUuid("uuid1")).thenReturn(new Patient()); + assertThat(accessionHelper.shouldIgnoreAccession(openElisAccession), is(false)); + } + + @Test + public void shouldReturnFalseIfPatientWithTheGivenUuidIsNotPresent() { + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withPatientUuid("uuid2").build(); + assertThat(accessionHelper.shouldIgnoreAccession(openElisAccession), is(true)); + } + + private Order getOrderWithConceptUuid(String conceptUuid) { + Order order = new Order(); + Concept concept = new Concept(); + concept.setUuid(conceptUuid); + order.setConcept(concept); + order.setDateActivated(new Date()); + return order; + } + + private Concept getConceptByUuid(String uuid) { + Concept concept = new Concept(); + concept.setUuid(uuid); + return concept; + } + + private List createVisits(int i) throws ParseException { + List visits = new ArrayList<>(); + + for(int j = 0;j attributeTypes = new ArrayList() {{ + this.add(new PersonAttributeType() {{ + setName("occupation"); + setFormat("org.openmrs.Concept"); + }}); + this.add(new PersonAttributeType() {{ + setName("primaryRelative"); + setFormat("java.lang.String"); + }}); + }}; + + BahmniPatientMapper bahmniPatientMapper = new BahmniPatientMapper(attributeTypes); + final List attributes = new ArrayList() {{ + add( new OpenElisPatientAttribute("OCCUPATION", "Tailor")); + add( new OpenElisPatientAttribute("PRIMARYRELATIVE", "Milka Singh")); + }}; + + OpenElisPatient openElisPatient = new OpenElisPatient() {{ + setAttributes(attributes); + }}; + + BahmniPatient bahmniPatient = bahmniPatientMapper.map(openElisPatient); + assertEquals(1, bahmniPatient.getAttributes().size()); + assertEquals("Milka Singh", bahmniPatient.getAttributes().get(0).getValue()); + } + + @Test + public void shouldMapPatientUUID() throws Exception { + List attributeTypes = new ArrayList() {{ + this.add(new PersonAttributeType() {{ + setName("occupation"); + setFormat("org.openmrs.Concept"); + }}); + this.add(new PersonAttributeType() {{ + setName("primaryRelative"); + setFormat("java.lang.String"); + }}); + }}; + + BahmniPatientMapper bahmniPatientMapper = new BahmniPatientMapper(attributeTypes); + final List attributes = new ArrayList() {{ + add( new OpenElisPatientAttribute("OCCUPATION", "Tailor")); + add( new OpenElisPatientAttribute("PRIMARYRELATIVE", "Milka Singh")); + }}; + + OpenElisPatient openElisPatient = new OpenElisPatient() {{ + setAttributes(attributes); + }}; + openElisPatient.setPatientUUID("UUID"); + BahmniPatient bahmniPatient = bahmniPatientMapper.map(openElisPatient); + assertEquals("UUID", bahmniPatient.getUuid()); + + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/EncounterHelperTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/EncounterHelperTest.java new file mode 100644 index 0000000000..9ecc3145e7 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/EncounterHelperTest.java @@ -0,0 +1,121 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterType; +import org.openmrs.Form; +import org.openmrs.Location; +import org.openmrs.Obs; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.User; +import org.openmrs.Visit; +import org.openmrs.VisitType; +import org.openmrs.api.EncounterService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class EncounterHelperTest { + private EncounterType encounterType; + @Mock + EncounterService encounterService; + @Mock + VisitService visitService; + private EncounterHelper encounterHelper; + private Provider provider; + private Patient patient; + + @Before + public void setUp() throws ParseException { + initMocks(this); + encounterType = new EncounterType("TestEncounter", "Encounter for test"); + when(encounterService.getEncounters(any(Patient.class), any(Location.class), any(Date.class), any(Date.class), + anyListOf(Form.class), anyListOf(EncounterType.class), anyListOf(Provider.class), + anyListOf(VisitType.class), anyListOf(Visit.class), anyBoolean())).thenReturn(getEncounters()); + encounterHelper = new EncounterHelper(encounterService); + provider = new Provider(333); + patient = new Patient(444); + PowerMockito.mockStatic(Context.class); + when(Context.getAuthenticatedUser()).thenReturn(new User()); + } + + @Test + public void shouldCreateEncounterWithGivenParameters() throws Exception { + Visit visit = new Visit(); + visit.setEncounters(new HashSet<>(getEncounters())); + Encounter newEncounter = encounterHelper.createNewEncounter(visit, encounterType, new Date(), patient, provider, null); + assertEquals(encounterType, newEncounter.getEncounterType()); + assertEquals(provider.getIdentifier(), newEncounter.getEncounterProviders().iterator().next().getProvider().getIdentifier()); + assertEquals(patient.getId(), newEncounter.getPatient().getId()); + } + + public List getEncounterWithObs() { + List encounters = new ArrayList<>(); + Encounter encounter = new Encounter(1); + encounter.setObs(createObs("10", "20", "30")); + encounters.add(encounter); + encounters.add(new Encounter(2)); + encounters.add(new Encounter(3)); + return encounters; + } + + private Set createObs(String... obsUuids) { + HashSet observations = new HashSet<>(); + Order order = createOrders("30").iterator().next(); + Concept concept = new Concept(); + concept.setUuid("c1"); + for (String obsUuid : obsUuids) { + Obs obs = new Obs(); + obs.setUuid(obsUuid); + obs.setOrder(order); + obs.setConcept(concept); + observations.add(obs); + } + return observations; + } + + public List getEncounters() { + ArrayList encounters = new ArrayList(); + encounters.add(new Encounter(1)); + encounters.add(new Encounter(2)); + encounters.add(new Encounter(3)); + encounters.get(2).setOrders(createOrders("10", "20", "30")); + encounters.get(0).setOrders(createOrders("40", "50", "60")); + return encounters; + } + + private Set createOrders(String... orderUuids) { + HashSet orders = new HashSet(); + for (String orderUuid : orderUuids) { + Order order = new Order(); + order.setUuid(orderUuid); + orders.add(order); + } + return orders; + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerIT.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerIT.java new file mode 100644 index 0000000000..f15ca4d256 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerIT.java @@ -0,0 +1,1214 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import org.bahmni.module.bahmnicore.properties.BahmniCoreProperties; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisAccessionBuilder; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisTestDetailBuilder; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccessionNote; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.bahmni.module.elisatomfeedclient.api.mapper.AccessionHelper; +import org.bahmni.webclients.HttpClient; +import org.ict4h.atomfeed.client.domain.Event; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import static org.mockito.Mockito.when; +import org.mockito.MockitoAnnotations; +import org.openmrs.Encounter; +import org.openmrs.EncounterType; +import org.openmrs.Obs; +import org.openmrs.Visit; +import org.openmrs.api.EncounterService; +import org.openmrs.api.VisitService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class OpenElisAccessionEventWorkerIT extends BaseModuleWebContextSensitiveTest { + + public static final String ENCOUNTER_TYPE_LAB_RESULT = "LAB_RESULT"; + public static final String VALIDATION_NOTES = "VALIDATION NOTES"; + @Mock + HttpClient httpClient; + @Autowired + private ElisAtomFeedProperties properties; + @Autowired + private BahmniVisitAttributeService bahmniVisitAttributeSaveCommand; + private OpenElisAccessionEventWorker openElisAccessionEventWorker; + private String openElisUrl = "http://localhost:8080/"; + private Event event = new Event("id", "openelis/accession/12-34-56-78", "title", "feedUri", new Date()); + + @Before + public void setUp() throws Exception { + executeDataSet("labResult.xml"); + InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("test-bahmnicore.properties"); + Properties properties = new Properties(); + properties.load(resourceAsStream); + BahmniCoreProperties.initalize(properties); + executeDataSet("visitAttributeDataSet.xml"); + MockitoAnnotations.initMocks(this); + this.openElisAccessionEventWorker = new OpenElisAccessionEventWorker(this.properties, httpClient, + Context.getEncounterService(), Context.getConceptService(), new AccessionHelper(this.properties), + Context.getProviderService(), + bahmniVisitAttributeSaveCommand, null); + } + + @Test + public void shouldCreateResultEncounterAndObsForTestWithResultAndOtherValues() throws Exception { + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withTestUuid("7923d0e0-8734-11e3-baa7-0800200c9a66") + .withResult("10.5") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .withUploadedFileName("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg") + .build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530").withTestDetails(new HashSet<>(Arrays.asList(test1))).build(); + openElisAccession.setAccessionUuid("6d0af4567-707a-4629-9850-f15206e63ab0"); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.associateTestResultsToOrder(openElisAccession); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set topLevelObs = labEncounter.getAllObs(); + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(4, resultMembers.size()); + } + + @Test + public void shouldCreateResultObsWhenTestIsReferredOut() throws Exception { + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withTestUuid("7923d0e0-8734-11e3-baa7-0800200c9a66") + .withStatus("referred out") + .build(); + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withPatientUuid(patientUuid).withTestDetails(new HashSet<>(Arrays.asList(test1))).build(); + String accessionUuid = "6d0af4567-707a-4629-9850-f15206e63ab0"; + openElisAccession.setAccessionUuid(accessionUuid); + + Event event = new Event("id", "openelis/accession/" + accessionUuid, "title", "feedUri", new Date()); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.process(event); + + Context.flushSession(); + Context.clearSession(); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set topLevelObs = labEncounter.getObsAtTopLevel(false); + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(1, resultMembers.size()); + Obs status = resultMembers.iterator().next(); + assertEquals("Ensure the concept is Referred Out", status.getConcept(), Context.getConceptService().getConcept(108)); + assertTrue(status.getValueBoolean()); + } + + @Test + public void shouldCreateResultEncounterWithSystemProvider() throws Exception { + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withTestUuid("7923d0e0-8734-11e3-baa7-0800200c9a66") + .withResult("10.5") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withTestDetails(new HashSet<>(Arrays.asList(test1))).build(); + openElisAccession.setAccessionUuid("6d0af4567-707a-4629-9850-f15206e63ab0"); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.associateTestResultsToOrder(openElisAccession); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + assertEquals("LABSYSTEM", labEncounter.getEncounterProviders().iterator().next().getProvider().getIdentifier()); + + Set topLevelObs = labEncounter.getAllObs(); + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + } + + @Test + public void shouldCreateResultEncounterAndObsForPanelWithOnetestWithResultAndOtherValues() throws Exception { + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .withUploadedFileName("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg") + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withTestDetails(new HashSet<>(Arrays.asList(test1))).build(); + openElisAccession.setAccessionUuid("6d0af4567-707a-4629-9850-f15206e63ab0"); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.associateTestResultsToOrder(openElisAccession); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); + + Set topLevelObs = panel1ResultMembers; + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(4, resultMembers.size()); + + Obs testResultObs = getObsByConceptUuid(testLevelObs, haemoglobinConceptUuid); + assertNotNull(testResultObs); + assertEquals(4, testResultObs.getGroupMembers().size()); + + } + + @Test + public void shouldCreateResultEncounterAndObsForPanelWithOnetestWithOnlyUploadedFileName() throws Exception { + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + final String documentConceptUuid = "a5909c8e-332e-464c-a0d7-ca36828672d6"; + + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .withUploadedFileName("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg") + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withTestDetails(new HashSet<>(Arrays.asList(test1))).build(); + openElisAccession.setAccessionUuid("6d0af4567-707a-4629-9850-f15206e63ab0"); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.associateTestResultsToOrder(openElisAccession); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); + + Set topLevelObs = panel1ResultMembers; + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + + Obs testResultObs = getObsByConceptUuid(testLevelObs, haemoglobinConceptUuid); + assertNotNull(testResultObs); + assertEquals(3, testResultObs.getGroupMembers().size()); + + Obs documentUploadedObs = getObsByConceptUuid(resultMembers, documentConceptUuid); + assertNotNull(documentUploadedObs); + assertEquals("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg", documentUploadedObs.getValueText()); + + } + + @Test + public void shouldCreateResultEncounterAndObsForPanelWithMoreThanOnetestWithResultAndOtherValues() throws Exception { + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + String providerUuid = "331c6bf8-7846-11e3-a96a-09xD371c1b75"; + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .withUploadedFileName("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg") + .build(); + + String esrConceptUuid = "a04c36be-3f90-11e3-968c-0800271c1b75"; + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(esrConceptUuid) + .withResult("16") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withTestDetails(new HashSet<>(Arrays.asList(test1, test2))) + .withDateTime("2014-01-30T11:50:18+0530").build(); + openElisAccession.setAccessionUuid("6d0af4567-707a-4629-9850-f15206e63ab0"); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.associateTestResultsToOrder(openElisAccession); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(2, panel1ResultMembers.size()); + + Obs haemoglobinTestResultObs = getObsByConceptUuid(panel1ResultMembers, haemoglobinConceptUuid); + assertNotNull(haemoglobinTestResultObs); + Set testLevelObs = haemoglobinTestResultObs.getGroupMembers(); + assertEquals(1, testLevelObs.size()); + Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(4, resultMembers.size()); + + Obs esrTestResultObs = getObsByConceptUuid(panel1ResultMembers, esrConceptUuid); + assertNotNull(esrTestResultObs); + testLevelObs = esrTestResultObs.getGroupMembers(); + assertEquals(1, testLevelObs.size()); + resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + } + + @Test + public void shouldCreateResultEncounterForPanelAndTest() throws Exception { + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + String providerUuid = "331c6bf8-7846-11e3-a96a-09xD371c1b75"; + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + + final String nitroUreaConceptUuid = "7923d0e0-8734-11e3-baa7-0800200c9a66"; + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder() + .withTestUuid(nitroUreaConceptUuid) + .withResult("10.5") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withTestDetails(new HashSet<>(Arrays.asList(test1, test2))) + .withDateTime("2014-01-30T11:50:18+0530").build(); + openElisAccession.setAccessionUuid("6d0af4567-707a-4629-9850-f15206e63ab0"); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + + openElisAccessionEventWorker.associateTestResultsToOrder(openElisAccession); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set obs = labEncounter.getAllObs(); + assertEquals(2, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); + + Obs haemoglobinTestResultObs = getObsByConceptUuid(panel1ResultMembers, haemoglobinConceptUuid); + assertNotNull(haemoglobinTestResultObs); + Set testLevelObs = haemoglobinTestResultObs.getGroupMembers(); + assertEquals(1, testLevelObs.size()); + Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + + Obs nirtoTestResultObs = getObsByConceptUuid(obs, nitroUreaConceptUuid); + assertNotNull(nitroUreaConceptUuid); + testLevelObs = nirtoTestResultObs.getGroupMembers(); + assertEquals(1, testLevelObs.size()); + resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + } + + @Test + public void shouldUpdateValueAndUploadedFileNameForAlreadyExistingTestResult() throws Exception { + final String nitroUreaConceptUuid = "7923d0e0-8734-11e3-baa7-0800200c9a66"; + final String accessionUuid = "6d0af4567-707a-4629-9850-f15206e63ab0"; + final String documentConceptUuid = "a5909c8e-332e-464c-a0d7-ca36828672d6"; + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + + Visit visit = Context.getVisitService().getVisit(2); + int encounterBeforeSize = visit.getEncounters().size(); + + + OpenElisTestDetail initialTestResult = new OpenElisTestDetailBuilder() + .withTestUuid(nitroUreaConceptUuid) + .withResult("10") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .withUploadedFileName("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample.jpeg") + .build(); + OpenElisAccession initialAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withPatientUuid(patientUuid).withTestDetails(new HashSet<>(Arrays.asList(initialTestResult))).build(); + initialAccession.setAccessionUuid(accessionUuid); + + Event event = new Event("id", "openelis/accession/" + accessionUuid, "title", "feedUri", new Date()); + + // on update of value new openElisAccession response + OpenElisTestDetail updatedTest = new OpenElisTestDetailBuilder() + .withTestUuid(nitroUreaConceptUuid) + .withResult("20") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:55:18+0530") //date changed + .withResultType("N") + .withUploadedFileName("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample1.jpeg") + .build(); + OpenElisAccession updatedAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withPatientUuid(patientUuid).withTestDetails(new HashSet<>(Arrays.asList(updatedTest))).build(); + updatedAccession.setAccessionUuid(accessionUuid); + + when(httpClient.get(properties.getOpenElisUri() + event.getContent(), OpenElisAccession.class)) + .thenReturn(initialAccession) + .thenReturn(updatedAccession); + openElisAccessionEventWorker.process(event); //first time + Context.flushSession(); + Context.clearSession(); + + openElisAccessionEventWorker.process(event);// second time + Context.flushSession(); + Context.clearSession(); + + visit = Context.getVisitService().getVisit(2); + Set encounters = visit.getEncounters(); + Encounter labEncounter = encounters.stream() + .filter(encounter -> encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) + .findFirst().get(); + + assertEquals(encounterBeforeSize+1, encounters.size()); + assertNotNull(labEncounter); + final Set obsAtTopLevel = labEncounter.getObsAtTopLevel(true); + assertEquals(2, obsAtTopLevel.size()); + final Set allObs = labEncounter.getAllObs(true); + assertEquals(12, allObs.size()); + + ArrayList voidedObservations = getVoidedObservations(allObs); + assertEquals(6, voidedObservations.size()); + + Set nonVoidedObs = labEncounter.getObsAtTopLevel(false); + assertEquals(1, nonVoidedObs.size()); + + Obs nitroTestResultObs = getObsByConceptUuid(nonVoidedObs, nitroUreaConceptUuid); + assertNotNull(nitroTestResultObs); + + Set testLevelObs = nitroTestResultObs.getGroupMembers(); + assertEquals(1, testLevelObs.size()); + Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(4, resultMembers.size()); + Obs resultObs = getObsByConceptUuid(resultMembers, nitroUreaConceptUuid); + assertEquals(new Double(20.0), resultObs.getValueNumeric()); + + Obs uploadedFileObs = getObsByConceptUuid(resultMembers, documentConceptUuid); + assertEquals("8834dedb-dc15-4afe-a491-ea3ca4150bce_sample1.jpeg", uploadedFileObs.getValueText()); + } + + @Test + public void shouldUpdateResultForPanelWithMultipleTests() throws Exception { + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + String esrConceptUuid = "a04c36be-3f90-11e3-968c-0800271c1b75"; + String providerUuid = "331c6bf8-7846-11e3-a96a-09xD371c1b75"; + String accessionUuid = "6d0af4567-707a-4629-9850-f15206e63ab0"; + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + + + OpenElisTestDetail hbTest = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + + OpenElisTestDetail esrTest = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(esrConceptUuid) + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withTestDetails(new HashSet<>(Arrays.asList(hbTest, esrTest))).withDateTime("2014-01-30T11:50:18+0530") + .withPatientUuid(patientUuid).build(); + openElisAccession.setAccessionUuid(accessionUuid); + + + OpenElisTestDetail hbTestUpdated = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("9.0") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("true") + .withDateTime("2014-01-30T12:50:18+0530") + .withResultType("N") + .build(); + + OpenElisTestDetail esrTestUpdated = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(esrConceptUuid) + .withResult("16") + .withProviderUuid(providerUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T12:50:18+0530") + .withResultType("N") + .build(); + + OpenElisAccession openElisAccessionUpdated = new OpenElisAccessionBuilder() + .withTestDetails(new HashSet<>(Arrays.asList(hbTestUpdated, esrTestUpdated))) + .withPatientUuid(patientUuid).withDateTime("2014-01-30T11:50:18+0530").build(); + openElisAccessionUpdated.setAccessionUuid(accessionUuid); + + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)) + .thenReturn(openElisAccession) //when called first time + .thenReturn(openElisAccessionUpdated); //when called second time + + openElisAccessionEventWorker.process(event); //first time + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); //only one test has results + + + openElisAccessionEventWorker.process(event); //second time + + visit = Context.getVisitService().getVisit(2); + labEncounter = null; + encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set allObs = labEncounter.getAllObs(true); + assertEquals(17, allObs.size()); + Obs panelObs = getObsByConceptUuid(allObs, panelConceptUuid); + final Set testObservations = panelObs.getGroupMembers(true); + assertEquals(3, testObservations.size()); //one voided, 1 updated, 1 new + assertEquals(1, getVoidedObservations(testObservations).size()); + final Set unvoidedObservations = panelObs.getGroupMembers(false); + assertEquals(2, unvoidedObservations.size()); + final Obs resultsForHaemoglobin = getObsByConceptUuid(unvoidedObservations, haemoglobinConceptUuid); + assertEquals(new Double(9.0), getConceptResultObs(resultsForHaemoglobin.getGroupMembers(), haemoglobinConceptUuid).getValueNumeric()); + + } + + @Test + public void shouldUpdateResultForPanelWithMultipleTestsWithDiffProviders() throws Exception { + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + String labTechProviderUuid = "331c6bf8-7846-11e3-a96a-09xD371c1b75"; + String systemProviderUuid = "331c6bf8-7846-11e3-a96a-0909871c1b75"; + + OpenElisTestDetail hbTest = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid(labTechProviderUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + + String esrConceptUuid = "a04c36be-3f90-11e3-968c-0800271c1b75"; + OpenElisTestDetail esrTest = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(esrConceptUuid) + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withTestDetails(new HashSet<>(Arrays.asList(hbTest, esrTest))) + .withDateTime("2014-01-30T11:50:18+0530") + .withPatientUuid("75e04d42-3ca8-11e3-bf2b-0800271c1b75").build(); + String accessionUuid = "6d0af4567-707a-4629-9850-f15206e63ab0"; + openElisAccession.setAccessionUuid(accessionUuid); + + Event firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + + openElisAccessionEventWorker.process(firstEvent); + + Visit visit = Context.getVisitService().getVisit(2); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(2, encounters.size()); + assertNotNull(labEncounter); + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); + assertNotNull(getObsByConceptUuid(panel1ResultMembers, haemoglobinConceptUuid)); + + + OpenElisTestDetail hbTestUpdated = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("9.0") + .withProviderUuid(systemProviderUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("true") + .withDateTime("2014-01-30T12:50:18+0530") + .withResultType("N") + .build(); + + OpenElisTestDetail esrTestUpdated = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(esrConceptUuid) + .withResult("16") + .withProviderUuid(systemProviderUuid) + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T12:50:18+0530") + .withResultType("N") + .build(); + + openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(hbTestUpdated, esrTestUpdated))).withDateTime("2014-01-30T11:50:18+0530").withPatientUuid("75e04d42-3ca8-11e3-bf2b-0800271c1b75").build(); + openElisAccession.setAccessionUuid(accessionUuid); + firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + + visit = Context.getVisitService().getVisit(2); + List labEncounters = new ArrayList<>(); + encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounters.add(encounter); + } + } + + assertEquals(3, encounters.size()); + assertEquals(2, labEncounters.size()); + + List encountersByLabTech = findEncountersForProvider(labEncounters, labTechProviderUuid); + assertEquals(1, encountersByLabTech.size()); + final Set panelObsByLabTech = encountersByLabTech.get(0).getAllObs(true); + assertEquals(1, panelObsByLabTech.size()); + Set topLevelTestsByLabTech = panelObsByLabTech.iterator().next().getGroupMembers(true); + assertEquals(1, topLevelTestsByLabTech.size()); + final ArrayList voidedObservations = getVoidedObservations(topLevelTestsByLabTech); + assertEquals(1, voidedObservations.size()); + final Set testObs = voidedObservations.get(0).getGroupMembers(true); + assertEquals(1, testObs.size()); + final Set testResults = testObs.iterator().next().getGroupMembers(true); + for (Obs testOb : testResults) { + assertTrue(testOb.getVoided()); + } + + List encountersBySystem = findEncountersForProvider(labEncounters, systemProviderUuid); + assertEquals(1, encountersBySystem.size()); + final Set panelObsBySystem = encountersBySystem.get(0).getAllObs(true); + assertEquals(1, panelObsBySystem.size()); + Set topLevelPanelTestsBySystem = panelObsBySystem.iterator().next().getGroupMembers(true); + assertEquals(2, topLevelPanelTestsBySystem.size()); + assertEquals(0, getVoidedObservations(topLevelPanelTestsBySystem).size()); + } + + @Test + public void shouldNotVoidObsIfTimeDidntChange() throws Exception { + String patientUuid = "75e04d42-3ca8-11e3-bf2b-0800271c1b75"; + int beforeEncounterSize = Context.getVisitService().getVisit(2).getEncounters().size(); + OpenElisTestDetail initialTestResult = new OpenElisTestDetailBuilder() + .withTestUuid("7923d0e0-8734-11e3-baa7-0800200c9a66") + .withResult("10") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withDateTime("2014-01-30T11:50:18+0530") + .withPatientUuid(patientUuid).withTestDetails(new HashSet<>(Arrays.asList(initialTestResult))).build(); + String accessionUuid = "6d0af4567-707a-4629-9850-f15206e63ab0"; + openElisAccession.setAccessionUuid(accessionUuid); + + //first time + Event event = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(event); + Context.flushSession(); + Context.clearSession(); + + Visit visit = Context.getVisitService().getVisit(2); + Set encounters = visit.getEncounters(); + Encounter labEncounter = encounters.stream() + .filter(encounter -> encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) + .findFirst().get(); + + assertEquals(beforeEncounterSize+1, encounters.size()); + assertNotNull(labEncounter); + Set obs = labEncounter.getAllObs(); + assertEquals(5, obs.size()); + + //second time + openElisAccessionEventWorker.process(event); + Context.flushSession(); + Context.clearSession(); + visit = Context.getVisitService().getVisit(2); + encounters = visit.getEncounters(); + labEncounter = encounters.stream() + .filter(encounter -> encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) + .findFirst().get(); + + assertEquals(beforeEncounterSize+1, encounters.size()); + assertNotNull(labEncounter); + obs = labEncounter.getAllObs(true); + assertEquals(0, getVoidedObservations(obs).size()); + assertEquals(5, obs.size()); + } + + @Test + public void shouldCreateOrderEncounterAndAssociateResultsAndLabNotesForNewAccession() throws Exception { + EncounterService encounterService = Context.getEncounterService(); + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + String accessionUuid = "6xfe4567-707a-4629-9850-f15206e9b0eX"; + String patientUuidWithNoOrders = "75e04d42-3ca8-11e3-bf2b-ab87271c1b75"; + + assertNull(encounterService.getEncounterByUuid(accessionUuid)); + + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18") + .withResultType("N") + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withDateTime("2014-01-30T11:50:18") + .withTestDetails(new HashSet<>(Arrays.asList(test1))) + .withPatientUuid(patientUuidWithNoOrders) + .withAccessionNotes(new OpenElisAccessionNote("Note1", "aa1c6bf8-7846-11e3-a96a-09xD371c1b75", "2014-01-30T11:50:18"), + new OpenElisAccessionNote("Note2", "aa1c6bf8-7846-11e3-a96a-09xD371c1b75", "2014-01-30T11:50:18")) + .build(); + openElisAccession.setAccessionUuid(accessionUuid); + + Event firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + Encounter orderEncounter = encounterService.getEncounterByUuid(accessionUuid); + assertNotNull(orderEncounter); + Visit visit = orderEncounter.getVisit(); + Encounter labEncounter = null; + Encounter notesEncounter = null; + List encounters = encounterService.getEncountersByPatient(visit.getPatient()); + + + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } else if (encounter.getEncounterType().getName().equals(VALIDATION_NOTES)) { + notesEncounter = encounter; + } + } + + assertEquals(3, encounters.size()); + + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); + + Set topLevelObs = panel1ResultMembers; + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + + Obs testResultObs = getObsByConceptUuid(testLevelObs, haemoglobinConceptUuid); + assertNotNull(testResultObs); + assertEquals(3, testResultObs.getGroupMembers().size()); + assertNotNull(notesEncounter); + assertEquals("aa1c6bf8-7846-11e3-a96a-09xD371c1b75", ProviderHelper.getProviderFrom(notesEncounter).getUuid()); + Set notesObservations = notesEncounter.getObs(); + + assertEquals(3, notesObservations.size()); + boolean containsAccessionUuidObservation = false; + for (Obs notesObservation : notesObservations) { + + if (notesObservation.getConcept().getName().getName().equals(OpenElisAccessionEventWorker.ACCESSION_UUID_CONCEPT)) { + containsAccessionUuidObservation = true; + assertEquals("6xfe4567-707a-4629-9850-f15206e9b0eX", notesObservation.getValueText()); + } else { + assertEquals(OpenElisAccessionEventWorker.LAB_MANAGER_NOTES, notesObservation.getConcept().getName().getName()); + assertTrue(Arrays.asList("Note1", "6xfe4567-707a-4629-9850-f15206e9b0eX", "Note2").contains(notesObservation.getValueText())); + } + } + assertTrue(containsAccessionUuidObservation); + + } + + @Test + public void shouldUpdateLabNotesForAccession() throws Exception { + EncounterService encounterService = Context.getEncounterService(); + String accessionUuid = "6g0bf6767-707a-4329-9850-f15206e63ab0"; + String patientUuidWithAccessionNotes = "86e04d42-3ca8-11e3-bf2b-0x7009861b97"; + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18") + .withResultType("N") + .build(); + + String providerUuid = "aa1c6bf8-7846-11e3-a96a-09xD371c1b75"; + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withDateTime("2014-01-30T11:50:18") + .withTestDetails(new HashSet<>(Arrays.asList(test1))) + .withPatientUuid(patientUuidWithAccessionNotes) + .withAccessionNotes(new OpenElisAccessionNote("Note1", providerUuid, "2014-01-30T11:50:18"), + new OpenElisAccessionNote("Note2", providerUuid, "2014-01-30T11:50:18")) + .withLabLocationUuid("be69741b-29e9-49a1-adc9-2a726e6610e4") + .build(); + openElisAccession.setAccessionUuid(accessionUuid); + Encounter notesEncounter1 = encounterService.getEncounter(36); + Set encounters = notesEncounter1.getVisit().getEncounters(); + assertEquals(2, encounters.size()); + + assertEquals(2, notesEncounter1.getObs().size()); + Event firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + encounters = notesEncounter1.getVisit().getEncounters(); + notesEncounter1 = encounterService.getEncounter(36); + assertEquals(4, encounters.size()); + assertEquals(3, notesEncounter1.getObs().size()); + } + + @Test + public void shouldMatchLabNotesForAccessionWithDefaultProvider() throws Exception { + EncounterService encounterService = Context.getEncounterService(); + String accessionUuid = "6g0bf6767-707a-4329-9850-f15206e63ab0"; + String patientUuidWithAccessionNotes = "86e04d42-3ca8-11e3-bf2b-0x7009861b97"; + + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18") + .withResultType("N") + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withDateTime("2014-01-30T11:50:18") + .withTestDetails(new HashSet<>(Arrays.asList(test1))) + .withPatientUuid(patientUuidWithAccessionNotes) + .withAccessionNotes(new OpenElisAccessionNote("Note1", "non-existent-provider", "2014-01-30T11:50:18"), + new OpenElisAccessionNote("Note1", "aa1c6bf8-7846-11e3-a96a-09xD371c1b75", "2014-01-30T11:50:18")) + .withLabLocationUuid("be69741b-29e9-49a1-adc9-2a726e6610e4") + .build(); + openElisAccession.setAccessionUuid(accessionUuid); + Encounter notesEncounter1 = encounterService.getEncounter(36); + Encounter notesEncounter2 = encounterService.getEncounter(38); + + Set encounters = notesEncounter1.getVisit().getEncounters(); + assertEquals(2, encounters.size()); + + assertEquals(2, notesEncounter1.getObs().size()); + assertEquals(1, notesEncounter2.getObs().size()); + + Event firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + + encounters = notesEncounter1.getVisit().getEncounters(); + notesEncounter1 = encounterService.getEncounter(36); + notesEncounter2 = encounterService.getEncounter(38); + assertEquals(4, encounters.size()); + assertEquals(2, notesEncounter1.getObs().size()); + assertEquals(2, notesEncounter2.getObs().size()); + } + + @Test + public void shouldCreateNewLabNotesEncounterForAccessionWithExistingProvider() throws Exception { + + + EncounterService encounterService = Context.getEncounterService(); + VisitService visitService = Context.getVisitService(); + + String accessionUuid = "6g0bf6767-707a-4329-9850-f15206e63ab0"; + String patientUuidWithAccessionNotes = "86e04d42-3ca8-11e3-bf2b-0x7009861b97"; + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withDateTime("2014-01-30T11:50:18") + .withTestDetails(new HashSet()) + .withPatientUuid(patientUuidWithAccessionNotes) + .withAccessionNotes(new OpenElisAccessionNote("Note1", "331c6bf8-7846-11e3-a96a-09xD371c1b75", "2014-01-30T11:50:18"), + new OpenElisAccessionNote("Note1", "aa1c6bf8-7846-11e3-a96a-09xD371c1b75", "2014-01-30T11:50:18")) + .withLabLocationUuid("be69741b-29e9-49a1-adc9-2a726e6610e4") + .build(); + openElisAccession.setAccessionUuid(accessionUuid); + Encounter notesEncounter1 = encounterService.getEncounter(36); + + List encounters = encounterService.getEncountersByPatientId(3); + assertEquals(2, encounters.size()); + assertEquals(2, notesEncounter1.getObs().size()); + + Event firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + List visitsByPatient = visitService.getVisitsByPatient(notesEncounter1.getPatient()); + assertEquals(1, visitsByPatient.size()); + + encounters = encounterService.getEncountersByPatientId(3); + notesEncounter1 = encounterService.getEncounter(36); + assertEquals(4, encounters.size()); + assertEquals(2, notesEncounter1.getObs().size()); + + Encounter newNoteEncounter = null; + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(VALIDATION_NOTES) && encounter.getId() != 36 && encounter.getId() != 38) { + newNoteEncounter = encounter; + break; + } + } + assertNotNull(newNoteEncounter); + assertEquals((Integer) 23, ProviderHelper.getProviderFrom(newNoteEncounter).getId()); + assertEquals(2, newNoteEncounter.getObs().size()); + for (Obs obs : newNoteEncounter.getObs()) { + assertTrue(Arrays.asList("Note1", "6g0bf6767-707a-4329-9850-f15206e63ab0").contains(obs.getValueText())); + } + + } + + @Test + public void shouldCreateOrderEncounterAndAssociateResultsForNewAccessionWhenTheVisitToOrderEncounterIsClosed() throws Exception { + + EncounterService encounterService = Context.getEncounterService(); + + String panelConceptUuid = "cfc5056c-3f8e-11e3-968c-0800271c1b75"; + String haemoglobinConceptUuid = "7f7379ba-3ca8-11e3-bf2b-0800271c1b75"; + String accessionUuid = "6xfe4567-707a-4629-9850-f15206e9b0eX"; + String patientUuidWithNoOrders = "75e04d42-3ca8-11e3-bf2b-ab87271c1b75"; + + assertNull(encounterService.getEncounterByUuid(accessionUuid)); + + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .build(); + + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder() + .withDateTime("2014-01-30T11:50:18+0530") + .withTestDetails(new HashSet<>(Arrays.asList(test1))) + .withPatientUuid(patientUuidWithNoOrders) + .build(); + openElisAccession.setAccessionUuid(accessionUuid); + + Event firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + + Visit visit = encounterService.getEncounterByUuid(accessionUuid).getVisit(); + Encounter labEncounter = null; + Set encounters = visit.getEncounters(); + for (Encounter encounter : encounters) { + if (encounter.getEncounterType().getName().equals(ENCOUNTER_TYPE_LAB_RESULT)) { + labEncounter = encounter; + } + } + + assertEquals(1, encounters.size()); + assertNull(labEncounter); + + visit.setStopDatetime(new Date()); + Context.getVisitService().saveVisit(visit); + + test1 = new OpenElisTestDetailBuilder() + .withPanelUuid(panelConceptUuid) + .withTestUuid(haemoglobinConceptUuid) + .withResult("10.5") + .withProviderUuid("331c6bf8-7846-11e3-a96a-09xD371c1b75") + .withMinNormal("10") + .withMaxNormal("20.2") + .withAbnormal("false") + .withDateTime("2014-01-30T11:50:18+0530") + .withResultType("N") + .build(); + + openElisAccession = new OpenElisAccessionBuilder() + .withDateTime("2014-01-30T11:50:18+0530") + .withTestDetails(new HashSet<>(Arrays.asList(test1))) + .withPatientUuid(patientUuidWithNoOrders) + .build(); + openElisAccession.setAccessionUuid(accessionUuid); + + firstEvent = stubHttpClientToGetOpenElisAccession(accessionUuid, openElisAccession); + openElisAccessionEventWorker.process(firstEvent); + + Encounter orderEncounter = encounterService.getEncounterByUuid(accessionUuid); + labEncounter = null; + EncounterType labResultEncounterType = encounterService.getEncounterType(ENCOUNTER_TYPE_LAB_RESULT); + + List encounterList = encounterService.getEncounters(orderEncounter.getPatient(), + null, orderEncounter.getEncounterDatetime(), null, null, + Arrays.asList(labResultEncounterType), + null, null, null, false); + + assertEquals(1, encounterList.size()); + labEncounter = encounterList.get(0); + assertNotNull(labEncounter); + + Set obs = labEncounter.getAllObs(); + assertEquals(1, obs.size()); + Obs panelResultObs = getObsByConceptUuid(obs, panelConceptUuid); + assertNotNull(panelResultObs); + Set panel1ResultMembers = panelResultObs.getGroupMembers(); + assertEquals(1, panel1ResultMembers.size()); + + Set topLevelObs = panel1ResultMembers; + assertEquals(1, topLevelObs.size()); + final Set testLevelObs = getGroupMembersForObs(topLevelObs); + assertEquals(1, testLevelObs.size()); + final Set resultMembers = getGroupMembersForObs(testLevelObs); + assertEquals(3, resultMembers.size()); + + Obs testResultObs = getObsByConceptUuid(testLevelObs, haemoglobinConceptUuid); + assertNotNull(testResultObs); + assertEquals(3, testResultObs.getGroupMembers().size()); + + } + + private Event stubHttpClientToGetOpenElisAccession(String accessionUuid, OpenElisAccession openElisAccession) throws java.io.IOException { + Event firstEvent = new Event("id", "openelis/accession/" + accessionUuid, "title", "feedUri", new Date()); + when(httpClient.get(properties.getOpenElisUri() + firstEvent.getContent(), OpenElisAccession.class)).thenReturn(openElisAccession); + return firstEvent; + } + + private Obs getObsByConceptUuid(Set panel1ResultMembers, String conceptUuid) { + return panel1ResultMembers.stream().filter(obs -> obs.getConcept().getUuid().equals(conceptUuid)) + .findFirst().get(); + } + + private List findEncountersForProvider(List labEncounters, String providerUuid) { + List encounters = new ArrayList<>(); + for (Encounter encounter : labEncounters) { + String encProviderUuid = encounter.getEncounterProviders().iterator().next().getProvider().getUuid(); + if (encProviderUuid.equals(providerUuid)) { + encounters.add(encounter); + } + } + return encounters; + } + + private Obs getConceptResultObs(Set members, String conceptUuid) { + Obs obs = getObsByConceptUuid(members, conceptUuid); + return getObsByConceptUuid(obs.getGroupMembers(), conceptUuid); + } + + private ArrayList getVoidedObservations(Set allObs) { + ArrayList voidedObs = new ArrayList(); + for (Obs obs : allObs) { + if (obs.isVoided()) { + //for individual test + voidedObs.add(obs); + } else if (obs.getConcept().isSet()) { + //for tests in panel + for (Obs member : obs.getGroupMembers()) { + if (member.isVoided()) { + voidedObs.add(member); + } + } + } + } + return voidedObs; + } + + private Set getGroupMembersForObs(Set obs) { + Obs testObs = obs.iterator().next(); + return testObs.getGroupMembers(); + } + + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java new file mode 100644 index 0000000000..5192bd818d --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisAccessionEventWorkerTest.java @@ -0,0 +1,282 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.bahmni.module.elisatomfeedclient.api.Constants; +import org.bahmni.module.elisatomfeedclient.api.ElisAtomFeedProperties; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisAccessionBuilder; +import org.bahmni.module.elisatomfeedclient.api.builder.OpenElisTestDetailBuilder; +import org.bahmni.module.elisatomfeedclient.api.domain.AccessionDiff; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisAccession; +import org.bahmni.module.elisatomfeedclient.api.domain.OpenElisTestDetail; +import org.bahmni.module.elisatomfeedclient.api.mapper.AccessionHelper; +import org.bahmni.webclients.HttpClient; +import org.ict4h.atomfeed.client.domain.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.Encounter; +import org.openmrs.EncounterType; +import org.openmrs.Order; +import org.openmrs.Patient; +import org.openmrs.Visit; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.EncounterService; +import org.openmrs.api.ProviderService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.auditlog.service.AuditLogService; +import org.openmrs.module.bahmniemrapi.encountertransaction.command.impl.BahmniVisitAttributeService; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import org.openmrs.util.OpenmrsUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest({Context.class, OpenmrsUtil.class}) +public class OpenElisAccessionEventWorkerTest { + @Mock + private HttpClient httpClient; + @Mock + private EncounterService encounterService; + @Mock + private AccessionHelper accessionMapper; + @Mock + private ElisAtomFeedProperties feedProperties; + @Mock + private ConceptService conceptService; + @Mock + private ProviderService providerService; + @Mock + private BahmniVisitAttributeService bahmniVisitAttributeSaveCommand; + @Mock + private AuditLogService auditLogService; + @Mock + private AdministrationService administrationService; + @Mock + private UserContext userContext; + + private OpenElisAccessionEventWorker accessionEventWorker; + private String openElisUrl; + private Event event; + + @Before + public void setUp() { + initMocks(this); + PowerMockito.mockStatic(Context.class); + accessionEventWorker = new OpenElisAccessionEventWorker(feedProperties, httpClient, encounterService, + conceptService, accessionMapper, providerService, bahmniVisitAttributeSaveCommand, auditLogService); + openElisUrl = "http://localhost:8080"; + event = new Event("id", "/openelis/accession/12-34-56-78", "title", "feedUri", new Date()); + when(feedProperties.getOpenElisUri()).thenReturn(openElisUrl); + when(administrationService.getGlobalProperty("bahmni.enableAuditLog")).thenReturn("true"); + when(Context.getAdministrationService()).thenReturn(administrationService); + PowerMockito.mockStatic(OpenmrsUtil.class); + PowerMockito.when(OpenmrsUtil.getApplicationDataDirectory()).thenReturn(getClass().getClassLoader().getResource("").getPath()); + } + + @Test + public void shouldSaveEncounterWhenEncounterForGivenAccessionDoesNotExists() throws Exception { + final Encounter encounter = getEncounterWithTests("test1"); + EncounterType encounterType = new EncounterType(Constants.DEFAULT_INVESTIGATION_ENCOUNTER_TYPE, "OpenElis Order Encounter"); + encounter.setEncounterType(encounterType); + final Visit visit = new Visit(); + visit.setId(1); + encounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Arrays.asList(encounter))); + final OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().build(); + stubAccession(openElisAccession); + + // first time when it calls it should return null as there is no encounter at that point + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(null).thenReturn(encounter); + when(accessionMapper.mapToNewEncounter(any(OpenElisAccession.class), any(String.class))).thenReturn(encounter); + when(accessionMapper.findOrInitializeVisit(any(Patient.class), any(Date.class), any(String.class))).thenReturn(visit); + when(encounterService.saveEncounter(encounter)).thenReturn(encounter); + accessionEventWorker.process(event); + + verify(encounterService).saveEncounter(encounter); + verify(bahmniVisitAttributeSaveCommand).save(encounter); + Map params = new HashMap<>(); + params.put("encounterUuid", encounter.getUuid()); + params.put("encounterType", encounter.getEncounterType().getName()); + verify(auditLogService).createAuditLog(encounter.getPatient().getUuid(),"EDIT_ENCOUNTER", "EDIT_ENCOUNTER_MESSAGE", params, "OpenElis"); + } + + @Test + public void shouldUpdateEncounterWhenAccessionHasNewOrder() throws Exception { + Encounter previousEncounter = getEncounterWithTests("test1"); + Encounter encounterFromAccession = getEncounterWithTests("test1", "test2"); + final Visit visit = new Visit(); + visit.setId(1); + previousEncounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Arrays.asList(previousEncounter))); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2))).build(); + stubAccession(openElisAccession); + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(previousEncounter); + when(accessionMapper.addOrDiscontinueOrderDifferences(any(OpenElisAccession.class), any(AccessionDiff.class), any(Encounter.class))).thenReturn(encounterFromAccession); + when(accessionMapper.findOrInitializeVisit(any(Patient.class), any(Date.class), any(String.class))).thenReturn(visit); + when(encounterService.saveEncounter(previousEncounter)).thenReturn(previousEncounter); + accessionEventWorker.process(event); + + verify(encounterService, times(2)).getEncounterByUuid(openElisAccession.getAccessionUuid()); + verify(encounterService).saveEncounter(previousEncounter); + verify(bahmniVisitAttributeSaveCommand).save(previousEncounter); + } + + @Test + public void shouldUpdateEncounterWithAccessionNumberWhenItsGenerated() throws Exception { + Encounter orderEncounter = getEncounterWithTests("test1", "test2", "test3"); + final Visit visit = new Visit(); + visit.setId(1); + orderEncounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Arrays.asList(orderEncounter))); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").build(); + test1.setStatus("Not started"); + test2.setStatus("Canceled"); + test3.setStatus("Not started"); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + + stubAccession(openElisAccession); + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(orderEncounter); + when(accessionMapper.findOrInitializeVisit(any(Patient.class), any(Date.class), any(String.class))).thenReturn(visit); + when(encounterService.saveEncounter(orderEncounter)).thenReturn(orderEncounter); + accessionEventWorker.associateTestResultsToOrder(openElisAccession); + + List orderAccessionNumbers = orderEncounter.getOrders().stream() + .map(Order::getAccessionNumber) + .collect(Collectors.toList()); + + verify(encounterService, times(1)).getEncounterByUuid(openElisAccession.getAccessionUuid()); + + assertEquals("1234", orderAccessionNumbers.get(0)); + assertNotEquals("1234", orderAccessionNumbers.get(1)); + assertEquals("1234", orderAccessionNumbers.get(2)); + } + + @Test + public void shouldUpdateEncounterWhenAccessionHasRemovedOrderFromPreviousEncounter() throws Exception { + Encounter previousEncounter = getEncounterWithTests("test1", "test2", "test3"); + Encounter encounterFromAccession = getEncounterWithTests("test1", "test2", "test3"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisTestDetail test3 = new OpenElisTestDetailBuilder().withTestUuid("test3").withStatus("Canceled").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2, test3))).build(); + stubAccession(openElisAccession); + + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(previousEncounter); + AccessionDiff accessionDiff = new AccessionDiff(); + accessionDiff.addRemovedTestDetails(test3); + when(accessionMapper.addOrDiscontinueOrderDifferences(any(OpenElisAccession.class), any(AccessionDiff.class), any(Encounter.class))).thenReturn(encounterFromAccession); + final Visit visit = new Visit(); + visit.setId(1); + previousEncounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Arrays.asList(previousEncounter))); + when(accessionMapper.findOrInitializeVisit(any(Patient.class), any(Date.class), any(String.class))).thenReturn(visit); + when(encounterService.saveEncounter(previousEncounter)).thenReturn(previousEncounter); + + accessionEventWorker.process(event); + + verify(encounterService, times(2)).getEncounterByUuid(openElisAccession.getAccessionUuid()); + verify(accessionMapper, never()).mapToNewEncounter(any(OpenElisAccession.class), any(String.class)); + verify(accessionMapper).addOrDiscontinueOrderDifferences(any(OpenElisAccession.class), any(AccessionDiff.class), any(Encounter.class)); + verify(encounterService).saveEncounter(previousEncounter); + verify(bahmniVisitAttributeSaveCommand).save(previousEncounter); + } + + @Test + public void shouldNotUpdateEncounterWhenAccessionHasSameOrdersAsPreviousEncounter() throws Exception { + Encounter previousEncounter = getEncounterWithTests("test1", "test2"); + OpenElisTestDetail test1 = new OpenElisTestDetailBuilder().withTestUuid("test1").build(); + OpenElisTestDetail test2 = new OpenElisTestDetailBuilder().withTestUuid("test2").build(); + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().withTestDetails(new HashSet<>(Arrays.asList(test1, test2))).build(); + previousEncounter.setUuid(openElisAccession.getAccessionUuid()); + stubAccession(openElisAccession); + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(previousEncounter); + final Visit visit = new Visit(); + visit.setId(1); + previousEncounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Arrays.asList(previousEncounter))); + when(accessionMapper.findOrInitializeVisit(any(Patient.class), any(Date.class), any(String.class))).thenReturn(visit); + + accessionEventWorker.process(event); + + verify(encounterService, times(2)).getEncounterByUuid(openElisAccession.getAccessionUuid()); + verify(encounterService, never()).saveEncounter(previousEncounter); + } + + @Test + public void shouldIgnoreAccessionEventIfPatientIsNotPresentInOpenMRS() throws IOException { + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().build(); + when(accessionMapper.shouldIgnoreAccession(openElisAccession)).thenReturn(true); + stubAccession(openElisAccession); + + accessionEventWorker.process(event); + + verify(encounterService, times(0)).saveEncounter(any(Encounter.class)); + } + + @Test + public void shouldNotIgnoreAccessionEventIfPatientIsPresentInOpenMRS() throws IOException { + OpenElisAccession openElisAccession = new OpenElisAccessionBuilder().build(); + Encounter encounter = getEncounterWithTests("test1"); + Visit visit = new Visit(); + visit.setId(1); + encounter.setVisit(visit); + visit.setEncounters(new HashSet<>(Collections.singletonList(encounter))); + stubAccession(openElisAccession); + when(accessionMapper.shouldIgnoreAccession(openElisAccession)).thenReturn(false); + when(encounterService.getEncounterByUuid(openElisAccession.getAccessionUuid())).thenReturn(encounter); + when(encounterService.saveEncounter(any(Encounter.class))).thenReturn(encounter); + + accessionEventWorker.process(event); + + verify(encounterService, times(1)).saveEncounter(any(Encounter.class)); + } + + private Encounter getEncounterWithTests(String... testUuids) { + Encounter encounter = new Encounter(); + for (String testUuid : testUuids) { + Order order = new Order(); + Concept concept = new Concept(); + concept.setId(123); + concept.setUuid(testUuid); + order.setConcept(concept); + order.setAccessionNumber(null); + encounter.addOrder(order); + encounter.setEncounterType(new EncounterType()); + Patient patient = new Patient(); + patient.setUuid("patientUuid"); + encounter.setPatient(patient); + } + return encounter; + } + + private void stubAccession(OpenElisAccession accession) throws IOException { + when(httpClient.get(openElisUrl + event.getContent(), OpenElisAccession.class)).thenReturn(accession); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisPatientFeedWorkerTest.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisPatientFeedWorkerTest.java new file mode 100644 index 0000000000..d90b7a2b6a --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/OpenElisPatientFeedWorkerTest.java @@ -0,0 +1,50 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.ict4h.atomfeed.client.domain.Event; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import java.util.Date; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +public class OpenElisPatientFeedWorkerTest { + + @Mock + private OpenElisAccessionEventWorker accessionEventWorker; + + @Before + public void before() { + initMocks(this); + } + + @Test + public void shouldCallAccessionEventWorkerWhenEventTitleIsAccession() { + OpenElisPatientFeedWorker openElisPatientFeedWorker = new OpenElisPatientFeedWorker(accessionEventWorker); + Event event = createEvent(); + event.setTitle("accession"); + + openElisPatientFeedWorker.process(event); + + verify(accessionEventWorker, times(1)).process(event); + } + + @Test + public void shouldNotFailWhenNoEventWorkerFound() { + OpenElisPatientFeedWorker openElisPatientFeedWorker = new OpenElisPatientFeedWorker(accessionEventWorker); + Event event = createEvent(); + event.setTitle("newAccession"); + + openElisPatientFeedWorker.process(event); + + verify(accessionEventWorker, never()).process(event); + } + + private Event createEvent() { + return new Event("tag:atomfeed.ict4h.org:22617bda-71ac-45c0-832b-c945b4881334", "/openelis/ws/rest/accession/4e85095d-b08e-444b-8970-0d5c2210791b","patient", "http://localhost:8080/openelis/ws/feed/patient/recent",new Date()); + } +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/TransactionMgrIT.java b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/TransactionMgrIT.java new file mode 100644 index 0000000000..b3217ea020 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/java/org/bahmni/module/elisatomfeedclient/api/worker/TransactionMgrIT.java @@ -0,0 +1,84 @@ +package org.bahmni.module.elisatomfeedclient.api.worker; + +import org.ict4h.atomfeed.transaction.AFTransactionWork; +import org.ict4h.atomfeed.transaction.AFTransactionWorkWithoutResult; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.module.atomfeed.transaction.support.AtomFeedSpringTransactionManager; +import org.openmrs.web.test.BaseModuleWebContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.transaction.PlatformTransactionManager; + +import java.sql.Connection; +import java.util.concurrent.atomic.AtomicInteger; + +@ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +@Ignore +public class TransactionMgrIT extends BaseModuleWebContextSensitiveTest { + + @Autowired + private PlatformTransactionManager transactionManager; + + @Test + public void shouldNestTransactionWithSpring() { + final AtomFeedSpringTransactionManager txMgr = new AtomFeedSpringTransactionManager(transactionManager); + try { + txMgr.executeWithTransaction(new AFTransactionWorkWithoutResult() { + + @Override + public PropagationDefinition getTxPropagationDefinition() { + return PropagationDefinition.PROPAGATION_REQUIRES_NEW; + } + + @Override + protected void doInTransaction() { + try { + Connection outerCon1 = txMgr.getConnection(); + System.out.println("outer connection outer 1st time:" + outerCon1); + } catch (Exception e1) { + System.out.println("connection fetch outer 1st time :" + e1); + } + + for (int i=1; i <= 2; i++) { + System.out.println("********** Exec counter "+i); + final AtomicInteger loopCounter = new AtomicInteger(i); + try { + txMgr.executeWithTransaction(new AFTransactionWork() { + @Override + public Object execute() { + try { + if (loopCounter.get() == 2) { + throw new Exception("Throw exception for 2nd iteration"); + } + Connection innerCon = txMgr.getConnection(); + System.out.println("inner connection:" + innerCon); + } catch(Exception e2) { + System.out.println("connection fetch inner :" + e2); + } + return null; + } + public PropagationDefinition getTxPropagationDefinition() { + return PropagationDefinition.PROPAGATION_REQUIRES_NEW; + } + }); + } catch (Exception innerTxEx) { + System.out.println("********** Exec counter "+ i); + System.out.println("inner Tx :" + innerTxEx); + } + } + + try { + Connection outerCon2 = txMgr.getConnection(); + System.out.println("outer connection outer 2nd time:" + outerCon2); + } catch (Exception e3) { + System.out.println("connection fetch outer 2nd time :" + e3); + } + } + }); + } catch (Exception outerEx) { + System.out.println("Outer Exception:" + outerEx); + } + } + +} diff --git a/openmrs-elis-atomfeed-client-omod/src/test/resources/TestingApplicationContext.xml b/openmrs-elis-atomfeed-client-omod/src/test/resources/TestingApplicationContext.xml new file mode 100644 index 0000000000..04e33a497f --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/resources/TestingApplicationContext.xml @@ -0,0 +1,7 @@ + + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/test/resources/labOrderEncounter.xml b/openmrs-elis-atomfeed-client-omod/src/test/resources/labOrderEncounter.xml new file mode 100644 index 0000000000..4f3d27de12 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/resources/labOrderEncounter.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/test/resources/labResult.xml b/openmrs-elis-atomfeed-client-omod/src/test/resources/labResult.xml new file mode 100644 index 0000000000..1640fb3a40 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/resources/labResult.xml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/test/resources/labResultForOldVisits.xml b/openmrs-elis-atomfeed-client-omod/src/test/resources/labResultForOldVisits.xml new file mode 100644 index 0000000000..e16f0222b3 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/resources/labResultForOldVisits.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openmrs-elis-atomfeed-client-omod/src/test/resources/test-bahmnicore.properties b/openmrs-elis-atomfeed-client-omod/src/test/resources/test-bahmnicore.properties new file mode 100644 index 0000000000..d157f7ec34 --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/resources/test-bahmnicore.properties @@ -0,0 +1,6 @@ +openelis.uri=http://localhost:8080/ +patient.feed.uri=http://localhost:8080/openelis/ws/feed/patient/recent +feed.maxFailedEvents=10000 +feed.connectionTimeoutInMilliseconds=10000 +feed.replyTimeoutInMilliseconds=20000 + diff --git a/openmrs-elis-atomfeed-client-omod/src/test/resources/visitAttributeDataSet.xml b/openmrs-elis-atomfeed-client-omod/src/test/resources/visitAttributeDataSet.xml new file mode 100644 index 0000000000..9a3a3bf17d --- /dev/null +++ b/openmrs-elis-atomfeed-client-omod/src/test/resources/visitAttributeDataSet.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index da95b55534..8f16b17f7a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,53 +1,282 @@ - 4.0.0 - org.raxa.module - raxacore - 0.2-SNAPSHOT + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT pom - RaxaEMR Core - Parent project for the RaxaEMR Core Module - + Bahmni EMR Core + https://github.com/Bahmni/bahmni-core.git + Bahmni core modules + + + GNU AFFERO GENERAL PUBLIC LICENSE + https://www.gnu.org/licenses/agpl-3.0.txt + + - Raxa developers + Bahmni + info@bahmni.org + Bahmni + https://github.com/Bahmni - - - Raxa - http://raxa.org - - - http://raxaemr.atlassian.net/wiki - - scm:git:git@github.com:Raxa/raxacore.git - scm:git:git@github.com:Raxa/raxacore.git - https://github.com/Raxa/raxacore.git + scm:git:git@github.com:Bahmni/bahmni-core.git + scm:git:git@github.com:Bahmni/bahmni-core.git + https://github.com/Bahmni/bahmni-core - api - omod + bahmni-emr-api + bahmnicore-api + openmrs-elis-atomfeed-client-omod + bahmnicore-omod + reference-data + admin + vagrant-deploy + bahmni-mapping + obs-relation + bahmni-test-commons + bahmnicore-ui + + UTF-8 + 2.5.12 + 2.39.0 + 5.2.14.RELEASE + 1.10.1 + 2.14.2 + 1.23.0 + 1.3.0 + 0.2.15 + 1.35.0-SNAPSHOT + 1.5.0 + 2.6.3 + 1.18.20 + 4.7.0 + 1.13.0 + 1.1.0 + 1.3.0 + 1.3.0 + 1.0.0 + 0.94.4-SNAPSHOT + 4.0.1 + 2.17.1 + 1.4.0 + 2.13.0 + 1.6.2 + 1.1.0-SNAPSHOT + + + 4.13 + 2.0.7 + 1.3 + 3.5.11 + -Xmx1024m + + + + + IT + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.17 + + + + integration-test + verify + + + -Xmx512m + + **/*IT.java + + + + + + + + + + release-sign-artifacts + + + performRelease + true + + + + + nexus-sonatype + https://oss.sonatype.org/content/repositories/snapshots + + + nexus-sonatype + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + nexus-sonatype + + true + + + + nexus-sonatype + https://oss.sonatype.org/content/repositories/snapshots + + + nexus-sonatype + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + + + mybahmni-s3 + + + repo.mybahmni.org + bahmni-artifactory-snapshots + s3://repo.mybahmni.org/artifactory/snapshot + + + + + + + org.bahmni.module + bahmni-mapping + ${project.version} + + + org.bahmni.module + bahmni-emr-api + ${project.version} + + + org.bahmni.module + openelis-atomfeed-client-omod + ${project.version} + + + org.bahmni.module + admin + ${project.parent.version} + + + org.hamcrest + hamcrest-all + ${hamcrestVersion} + test + + + org.bahmni.module + bahmnicore-omod + ${project.version} + + + org.bahmni.module + auditlog-api + ${auditLogVersion} + + + + + org.apache.velocity + velocity + provided + ${velocityVersion} + + + commons-httpclient + commons-httpclient + 3.1 + org.openmrs.api openmrs-api ${openMRSVersion} jar provided + + + javax.servlet + servlet-api + + org.openmrs.web openmrs-web ${openMRSVersion} jar + + + javax.servlet + servlet-api + + + provided + + + org.bahmni.module + bahmni-commons-api + jar + ${bahmniCommons.version} provided @@ -56,6 +285,12 @@ ${openMRSVersion} test-jar test + + + javax.servlet + servlet-api + + org.openmrs.web @@ -63,6 +298,12 @@ ${openMRSVersion} test-jar test + + + javax.servlet + servlet-api + + org.openmrs.test @@ -71,6 +312,12 @@ pom test + + com.github.stefanbirkner + system-rules + 1.19.0 + test + org.openmrs.tools openmrs-tools @@ -80,44 +327,277 @@ org.openmrs.module - webservices.rest-api - 1.1 + webservices.rest-omod + ${openMRSWebServicesVersion} + jar + provided + + + org.bahmni.module + bahmni-migrator + ${bahmniJavaUtilsVersion} jar provided org.openmrs.module - webservices.rest-omod - 1.1 + webservices.rest-omod-common + ${openMRSWebServicesVersion} jar provided org.openmrs.module - webservices.rest-omod - 1.1 + appframework-api + 2.15.0 + test + + + org.openmrs.module + reporting-api + ${reportingModuleVersion} + test + + + + + + + + + org.openmrs.module + calculation-api + ${calculationModuleVersion} + test + + + org.openmrs.module + serialization.xstream-api-2.0 + ${serializationXstreamModuleVersion} + test + + + org.openmrs.module + webservices.rest-omod-common + ${openMRSWebServicesVersion} tests test - org.openmrs.module - webservices.rest19ext-api - 1.0-SNAPSHOT + idgen-api + ${idgenVersion} + provided + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + provided + + + org.hamcrest + hamcrest-library + + + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + provided + + + org.hamcrest + hamcrest-library + + + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + provided + + + org.hamcrest + hamcrest-library + + + + + org.openmrs.module + emrapi-omod + ${emrapi-omod.version} + test-jar + test + + + org.openmrs.module + providermanagement-api + ${providermanagementVersion} + test + + + org.apache.xmlrpc + xmlrpc-client + 3.1.3 + + + org.apache.logging.log4j + log4j-api + ${log4jVersion} + provided + + + org.apache.logging.log4j + log4j-core + ${log4jVersion} + provided + + + org.apache.logging.log4j + log4j-1.2-api + ${log4jVersion} + provided + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4jVersion} + provided + + + javax.servlet + javax.servlet-api + ${javaxServletVersion} + provided + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + provided + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + provided + + + org.bahmni.module + file-uploader + ${bahmniJavaUtilsVersion} + + + org.openmrs.module + addresshierarchy-api + ${addressHierarchyVersion} + jar + provided org.openmrs.module - webservices.rest19ext-omod - 1.0-SNAPSHOT + addresshierarchy-omod + ${addressHierarchyVersion} + jar + provided + + + org.openmrs.module + legacyui-omod + ${legacyuiVersion} + jar + provided + + + org.jcodec + jcodec + 0.2.1 + + + org.jcodec + jcodec-javase + 0.2.1 + + + + + + + + javax.el + javax.el-api + 2.2.4 + provided + + + + + junit + junit + ${junitVersion} + test + + + org.powermock + powermock-module-junit4 + ${powerMockVersion} + test + + + org.powermock + powermock-api-mockito + ${powerMockVersion} + + + mockito-all + org.mockito + + + test + + + org.mockito + mockito-all + ${mockitoVersion} + + + org.hamcrest + hamcrest-core + + + test + + + org.mockito + mockito-core + ${mockitoVersion} + test + + + org.bahmni.module + communication-api + 1.2.0-SNAPSHOT + jar + provided + + + cglib + cglib + 2.2.2 + test + + + org.projectlombok + lombok + ${lombokVersion} + provided - - UTF-8 - 1.9.0 - - @@ -125,8 +605,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 @@ -152,39 +632,194 @@ - com.googlecode.maven-java-formatter-plugin - maven-java-formatter-plugin - 0.3.1 + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + + prepare-agent + + + + * + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.10 - ${javaCompilerVersion} - ${javaCompilerVersion} - ${javaCompilerVersion} - ../OpenMRSFormatter.xml - true - CRLF + + **/*Test.java + + + **/BaseIntegrationTest.java + + + true + + + + org.kuali.maven.wagons + maven-s3-wagon + 1.2.1 + + + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots + + false + + + true + interval:10080 + + + + sonatype-nexus-releases + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/releases + + true + + + false + + + + central + https://repo1.maven.org/maven2 + Repository for dependencies + + true + interval:10080 + + + + spring-maven-release + Spring Maven Release Repository + https://maven.springframework.org/release + + interval:10080 + + + + apache-maven-release + Apache Maven Release Repository + https://repository.apache.org/content/repositories/releases + + interval:10080 + + + + JBoss + The "public-jboss" repository group provides a combined view all JBoss community project artifacts + + default + https://repository.jboss.org/nexus/content/groups/public-jboss + + interval:10080 + + + + spring-repo + Spring Maven Repository + https://maven.springframework.org/milestone + + interval:10080 + + + interval:10080 + + openmrs-repo OpenMRS Nexus Repository - http://mavenrepo.openmrs.org/nexus/content/repositories/public + https://mavenrepo.openmrs.org/nexus/content/repositories/public + + always + + + repo.mybahmni.org + bahmni-artifactory-snapshots + https://repo.mybahmni.org.s3.amazonaws.com/artifactory/snapshot + + always + + + + repo.mybahmni.org-release + bahmni-artifactory-release + https://repo.mybahmni.org.s3.amazonaws.com/artifactory/release + - + + central + https://repo1.maven.org/maven2 + Repository for plugins + + + spring-maven-release + Spring Maven Release Repository + https://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + https://maven.springframework.org/milestone + openmrs-repo OpenMRS Nexus Repository - http://mavenrepo.openmrs.org/nexus/content/repositories/public + https://mavenrepo.openmrs.org/nexus/content/repositories/public false - diff --git a/reference-data/api/pom.xml b/reference-data/api/pom.xml new file mode 100644 index 0000000000..dccf8ecc3e --- /dev/null +++ b/reference-data/api/pom.xml @@ -0,0 +1,106 @@ + + + + reference-data + org.bahmni.module + 1.2.0-SNAPSHOT + + 4.0.0 + + ${project.parent.artifactId}-api + Reference Data API + + + org.openmrs.api + openmrs-api + jar + + + org.openmrs.web + openmrs-web + jar + + + org.openmrs.api + openmrs-api + test-jar + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + org.openmrs.test + openmrs-test + pom + test + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.bahmni.module + bahmni-emr-api + ${project.version} + provided + + + + + + + src/main/resources + true + + + + + src/test/resources + true + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.04 + + + BRANCH + COVEREDRATIO + 0.03 + + + + + + + + + + + + diff --git a/reference-data/api/src/main/java/feed/FeedActivator.java b/reference-data/api/src/main/java/feed/FeedActivator.java new file mode 100644 index 0000000000..fd6831daa1 --- /dev/null +++ b/reference-data/api/src/main/java/feed/FeedActivator.java @@ -0,0 +1,35 @@ +package feed; + +import org.openmrs.module.ModuleActivator; + +public class FeedActivator implements ModuleActivator { + @Override + public void willRefreshContext() { + + } + + @Override + public void contextRefreshed() { + + } + + @Override + public void willStart() { + + } + + @Override + public void started() { + + } + + @Override + public void willStop() { + + } + + @Override + public void stopped() { + + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/contract/ConceptDetails.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/contract/ConceptDetails.java new file mode 100644 index 0000000000..791d3d8f7f --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/contract/ConceptDetails.java @@ -0,0 +1,85 @@ +package org.bahmni.module.referencedata.contract; + +import java.util.HashMap; +import java.util.Map; + +public class ConceptDetails { + private String name; + private String fullName; + private String units; + private Double hiNormal; + private Double lowNormal; + private Map attributes = new HashMap<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUnits() { + return units; + } + + public void setUnits(String units) { + this.units = units; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConceptDetails that = (ConceptDetails) o; + + return fullName != null ? fullName.equals(that.fullName) : that.fullName == null; + + } + + @Override + public int hashCode() { + return name != null ? name.hashCode() : 0; + } + + public Double getHiNormal() { + return hiNormal; + } + + public void setHiNormal(Double hiNormal) { + this.hiNormal = hiNormal; + } + + public Double getLowNormal() { + return lowNormal; + } + + public void setLowNormal(Double lowNormal) { + this.lowNormal = lowNormal; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public Map getAttributes() { + return attributes; + } + + public Object getAttribute(String key) { + return attributes.get(key); + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + public void addAttribute(String key, Object value) { + this.attributes.put(key, value); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/contract/ConceptName.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/contract/ConceptName.java new file mode 100644 index 0000000000..48976b4b9f --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/contract/ConceptName.java @@ -0,0 +1,50 @@ +package org.bahmni.module.referencedata.contract; + +public class ConceptName { + private String fullySpecifiedName; + private String shortName; + + public ConceptName(String fullySpecifiedName, String shortName) { + this.fullySpecifiedName = fullySpecifiedName; + this.shortName = shortName; + } + + public ConceptName() { + + } + + public String getFullySpecifiedName() { + return fullySpecifiedName; + } + + public void setFullySpecifiedName(String fullySpecifiedName) { + this.fullySpecifiedName = fullySpecifiedName; + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConceptName that = (ConceptName) o; + + if (fullySpecifiedName != null ? !fullySpecifiedName.equals(that.fullySpecifiedName) : that.fullySpecifiedName != null) + return false; + return shortName != null ? shortName.equals(that.shortName) : that.shortName == null; + } + + @Override + public int hashCode() { + int result = fullySpecifiedName != null ? fullySpecifiedName.hashCode() : 0; + result = 31 * result + (shortName != null ? shortName.hashCode() : 0); + return result; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/helper/ConceptHelper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/helper/ConceptHelper.java new file mode 100644 index 0000000000..51d6a3654b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/helper/ConceptHelper.java @@ -0,0 +1,199 @@ +package org.bahmni.module.referencedata.helper; + +import java.util.Locale; +import org.apache.commons.collections.CollectionUtils; +import org.bahmni.module.referencedata.contract.ConceptDetails; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.bahmniemrapi.encountertransaction.mapper.ETObsToBahmniObsMapper; +import org.openmrs.module.emrapi.utils.HibernateLazyLoader; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +@Component +public class ConceptHelper { + private ConceptService conceptService; + + @Autowired + public ConceptHelper(ConceptService conceptService) { + this.conceptService = conceptService; + } + + + public List getConceptsForNames(Collection conceptNames) { + List concepts = new ArrayList<>(); + if (conceptNames != null) { + for (String conceptName : conceptNames) { + List conceptsByName = conceptService.getConceptsByName(conceptName.replaceAll("%20", " ")); + if (CollectionUtils.isNotEmpty(conceptsByName)) { + for (Concept concept : conceptsByName) { + for (ConceptName conceptNameObj : concept.getNames()) { + if (conceptNameObj.getName().equalsIgnoreCase(conceptName) && conceptNameObj.isFullySpecifiedName()) { + concepts.add(concept); + break; + } + } + } + } + } + } + return concepts; + } + + public Set getLeafConceptDetails(List obsConcepts, boolean withoutAttributes) { + if (obsConcepts != null && !obsConcepts.isEmpty()) { + Set leafConcepts = new LinkedHashSet<>(); + for (Concept concept : obsConcepts) { + addLeafConcepts(concept, null, leafConcepts, withoutAttributes); + } + return leafConcepts; + } + return Collections.EMPTY_SET; + } + + protected void addLeafConcepts(Concept rootConcept, Concept parentConcept, Set leafConcepts, boolean withoutAttributes) { + if (rootConcept != null) { + if (rootConcept.isSet()) { + for (Concept setMember : rootConcept.getSetMembers()) { + addLeafConcepts(setMember, rootConcept, leafConcepts, withoutAttributes); + } + } else if (!shouldBeExcluded(rootConcept)) { + Concept conceptToAdd = rootConcept; + if (parentConcept != null && !withoutAttributes && hasConceptDetailsClass(parentConcept)) { + conceptToAdd = parentConcept; + } + ConceptDetails conceptDetails = createConceptDetails(conceptToAdd); + addAttributes(conceptDetails, parentConcept); + leafConcepts.add(conceptDetails); + } + } + } + + private void addAttributes(ConceptDetails conceptDetails, Concept parentConcept) { + if (parentConcept != null && hasConceptDetailsClass(parentConcept)) { + for (Concept concept : parentConcept.getSetMembers()) { + if ("Unknown".equals(concept.getConceptClass().getName())) { + conceptDetails.addAttribute("Unknown Concept", getConceptName(concept, ConceptNameType.FULLY_SPECIFIED)); + } + if ("Abnormal".equals(concept.getConceptClass().getName())) { + conceptDetails.addAttribute("Abnormal Concept", getConceptName(concept, ConceptNameType.FULLY_SPECIFIED)); + } + } + } + + } + + private boolean hasConceptDetailsClass(Concept parentConcept) { + return ETObsToBahmniObsMapper.CONCEPT_DETAILS_CONCEPT_CLASS.equals(parentConcept.getConceptClass().getName()); + } + + private ConceptDetails createConceptDetails(Concept conceptToAdd) { + Concept concept = new HibernateLazyLoader().load(conceptToAdd); + String fullNameInLocale = getConceptNameInLocale(concept, ConceptNameType.FULLY_SPECIFIED, false); + String shortNameInLocale = getConceptNameInLocale(concept, ConceptNameType.SHORT, false); + String conceptFullName = (fullNameInLocale != null) ? fullNameInLocale : getConceptNameInLocale(concept, ConceptNameType.FULLY_SPECIFIED, true); + String conceptShortName = (shortNameInLocale != null) ? shortNameInLocale : fullNameInLocale; + if (conceptShortName == null) { + String defaultLocaleShortName = getConceptNameInLocale(concept, ConceptNameType.SHORT, true); + conceptShortName = (defaultLocaleShortName != null) ? defaultLocaleShortName : conceptFullName; + } + ConceptDetails conceptDetails = new ConceptDetails(); + conceptDetails.setName(conceptShortName); + conceptDetails.setFullName(conceptFullName); + if (concept.isNumeric()) { + ConceptNumeric numericConcept = (ConceptNumeric) concept; + conceptDetails.setUnits(numericConcept.getUnits()); + conceptDetails.setHiNormal(numericConcept.getHiNormal()); + conceptDetails.setLowNormal(numericConcept.getLowNormal()); + } + return conceptDetails; + } + + private String getConceptName(Concept concept, ConceptNameType conceptNameType){ + String conceptNameInLocale = getConceptNameInLocale(concept, conceptNameType, false); + return (conceptNameInLocale != null) ? conceptNameInLocale : getConceptNameInLocale(concept, conceptNameType, true); + } + + private String getConceptNameInLocale(Concept concept, ConceptNameType conceptNameType, boolean isDefaultLocale) { + Locale locale; + locale = isDefaultLocale ? LocaleUtility.getDefaultLocale() : + LocaleUtility.fromSpecification(Context.getAuthenticatedUser().getUserProperty("defaultLocale")); + ConceptName conceptName = concept.getName(locale, conceptNameType, null); + return (conceptName != null) ? conceptName.getName() : null; + } + + private boolean shouldBeExcluded(Concept rootConcept) { + return ETObsToBahmniObsMapper.ABNORMAL_CONCEPT_CLASS.equals(rootConcept.getConceptClass().getName()) || + ETObsToBahmniObsMapper.DURATION_CONCEPT_CLASS.equals(rootConcept.getConceptClass().getName()) || + ETObsToBahmniObsMapper.UNKNOWN_CONCEPT_CLASS.equals(rootConcept.getConceptClass().getName()); + } + + public Set getConceptDetails(List conceptNames) { + Set conceptDetails = new LinkedHashSet<>(); + for (Concept concept : conceptNames) { + if (concept != null) { + conceptDetails.add(createConceptDetails(concept)); + } + } + return conceptDetails; + } + + public Set getConceptIds(List conceptNames) { + Set conceptIds = new LinkedHashSet<>(); + for (Concept concept : conceptNames) { + if (concept != null) { + conceptIds.add(concept.getConceptId()); + } + } + return conceptIds; + } + + public List getParentConcepts(Concept concept) { + return conceptService.getConceptsByAnswer(concept); + } + + public Set getChildConceptNames(List conceptsForNames) { + Set conceptDetails = new LinkedHashSet<>(); + getConceptNames(conceptDetails, conceptsForNames); + return conceptDetails; + } + + private void getConceptNames(Set conceptDetails, List concepts) { + for (Concept concept : concepts) { + if (!concept.isRetired()) { + conceptDetails.add(getConceptName(concept, ConceptNameType.FULLY_SPECIFIED)); + } + getConceptNames(conceptDetails, concept.getSetMembers()); + } + } + + public Set getLeafConceptNames(List concepts) { + Set leafConcepts = new LinkedHashSet<>(); + getLeafConceptName(leafConcepts, concepts); + return leafConcepts; + } + + private void getLeafConceptName(Set leafConcepts, List concepts) { + for (Concept concept : concepts) { + if (!concept.isSet() && !concept.isRetired()) { + String fullySpecifiedName = getConceptName(concept, ConceptNameType.FULLY_SPECIFIED); + String shortName = getConceptName(concept, ConceptNameType.SHORT); + leafConcepts.add(new org.bahmni.module.referencedata.contract.ConceptName(fullySpecifiedName, shortName)); + } else if (concept.isSet() && !concept.isRetired()) { + getLeafConceptName(leafConcepts, concept.getSetMembers()); + } + } + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/AllSamples.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/AllSamples.java new file mode 100644 index 0000000000..75834e1681 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/AllSamples.java @@ -0,0 +1,29 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.ArrayList; +import java.util.List; + +public class AllSamples extends Resource { + private String description; + private List samples = new ArrayList<>(); + public static final String ALL_SAMPLES = "Lab Samples"; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getSamples() { + return samples; + } + + public void addSample(Sample sample) { + if (sample != null) { + this.samples.add(sample); + } + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/AllTestsAndPanels.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/AllTestsAndPanels.java new file mode 100644 index 0000000000..384c9da154 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/AllTestsAndPanels.java @@ -0,0 +1,25 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +public class AllTestsAndPanels extends Resource { + public static final String ALL_TESTS_AND_PANELS = "All_Tests_and_Panels"; + + private String description; + + private TestsAndPanels testsAndPanels; + + public TestsAndPanels getTestsAndPanels() { + return testsAndPanels; + } + + public void setTestsAndPanels(TestsAndPanels testsAndPanels) { + this.testsAndPanels = testsAndPanels; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/CodedTestAnswer.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/CodedTestAnswer.java new file mode 100644 index 0000000000..d72b66a424 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/CodedTestAnswer.java @@ -0,0 +1,31 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + + +public class CodedTestAnswer { + private String name; + private String uuid; + + public CodedTestAnswer() { + } + + public CodedTestAnswer(String name, String uuid) { + this.name = name; + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Concept.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Concept.java new file mode 100644 index 0000000000..f83b107ee4 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Concept.java @@ -0,0 +1,75 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +import java.util.ArrayList; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Concept extends ConceptCommon { + private List answers; + private List synonyms; + private String units; + private String hiNormal; + private String lowNormal; + private String allowDecimal; + + public Concept() { + } + + public Concept(String uuid, String name, String conceptDescription, String conceptClass, String conceptShortname, + List conceptReferenceTermList, List conceptSynonyms, List conceptAnswers, String datatype) { + super(uuid, name, conceptDescription, conceptClass, conceptShortname, conceptReferenceTermList, datatype); + this.answers = conceptAnswers; + this.synonyms = conceptSynonyms; + } + + public List getAnswers() { + return answers; + } + + public void setAnswers(List answers) { + this.answers = answers; + } + + public List getSynonyms() { + return synonyms == null ? new ArrayList() : synonyms; + } + + public void setSynonyms(List synonyms) { + this.synonyms = synonyms; + } + + + public String getUnits() { + return units; + } + + public void setUnits(String units) { + this.units = units; + } + + public void setHiNormal(String hiNormal) { + this.hiNormal = hiNormal; + } + + public String getHiNormal() { + return hiNormal; + } + + public void setLowNormal(String lowNormal) { + this.lowNormal = lowNormal; + } + + public String getLowNormal() { + return lowNormal; + } + + public String getAllowDecimal() { + return allowDecimal; + } + + public void setAllowDecimal(String allowDecimal) { + this.allowDecimal = allowDecimal; + } +} \ No newline at end of file diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptCommon.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptCommon.java new file mode 100644 index 0000000000..7e8b1e04ef --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptCommon.java @@ -0,0 +1,98 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import org.apache.commons.lang3.StringUtils; + +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; + +public class ConceptCommon { + private String uniqueName; + private String displayName; + private String description; + private String className; + private String dataType; + private String locale; + private List conceptReferenceTermsList = new ArrayList<>(); + private String uuid; + + public ConceptCommon(String uuid, String name, String conceptDescription, String conceptClass, String conceptShortname, List conceptReferenceTermsList, String dataType) { + this.uuid = uuid; + this.uniqueName = name; + this.description = conceptDescription; + this.className = conceptClass; + this.displayName = conceptShortname; + this.dataType = dataType; + this.conceptReferenceTermsList = conceptReferenceTermsList; + } + + public ConceptCommon() { + + } + + public List getConceptReferenceTermsList() { + return conceptReferenceTermsList; + } + + public void setConceptReferenceTermsList(List conceptReferenceTermsList) { + this.conceptReferenceTermsList = conceptReferenceTermsList; + } + + @NotNull + public String getUniqueName() { + return uniqueName; + } + + public void setUniqueName(String uniqueName) { + this.uniqueName = uniqueName; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @NotNull + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getDataType() { + return StringUtils.isEmpty(dataType) ? "N/A" : dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setLocale(String locale) { + this.locale = locale; + } + + public String getLocale() { + return locale; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptReferenceTerm.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptReferenceTerm.java new file mode 100644 index 0000000000..075133d5e3 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptReferenceTerm.java @@ -0,0 +1,79 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +public class ConceptReferenceTerm { + + private String referenceTermName; + private String referenceTermCode; + private String referenceTermRelationship; + private String referenceTermSource; + + private String referenceDescription; + private String referenceVersion; + + public ConceptReferenceTerm() { + } + + public ConceptReferenceTerm(String conceptReferenceTermCode, String conceptReferenceTermRelationship, String conceptReferenceTermSource) { + this.referenceTermCode = conceptReferenceTermCode; + this.referenceTermRelationship = conceptReferenceTermRelationship; + this.referenceTermSource = conceptReferenceTermSource; + } + + public ConceptReferenceTerm(String conceptReferenceTermCode, String conceptReferenceTermName, String conceptReferenceTermRelationship, String conceptReferenceTermSource, String conceptReferenceDescription, String conceptReferenceVersion) { + this.referenceTermCode = conceptReferenceTermCode; + this.referenceTermName = conceptReferenceTermName; + this.referenceTermRelationship = conceptReferenceTermRelationship; + this.referenceTermSource = conceptReferenceTermSource; + this.referenceDescription = conceptReferenceDescription; + this.referenceVersion = conceptReferenceVersion; + } + + public String getReferenceTermName() { + return referenceTermName; + } + + public void setReferenceTermName(String referenceTermName) { + this.referenceTermName = referenceTermName; + } + + public String getReferenceTermCode() { + return referenceTermCode; + } + + public void setReferenceTermCode(String referenceTermCode) { + this.referenceTermCode = referenceTermCode; + } + + public String getReferenceTermRelationship() { + return referenceTermRelationship; + } + + public void setReferenceTermRelationship(String referenceTermRelationship) { + this.referenceTermRelationship = referenceTermRelationship; + } + + public String getReferenceTermSource() { + return referenceTermSource; + } + + public void setReferenceTermSource(String referenceTermSource) { + this.referenceTermSource = referenceTermSource; + } + + public String getReferenceDescription() { + return referenceDescription; + } + + public void setReferenceDescription(String referenceDescription) { + this.referenceDescription = referenceDescription; + } + + public String getReferenceVersion() { + return referenceVersion; + } + + public void setReferenceVersion(String referenceVersion) { + this.referenceVersion = referenceVersion; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptSet.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptSet.java new file mode 100644 index 0000000000..fc3be38dc7 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ConceptSet.java @@ -0,0 +1,25 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.ArrayList; +import java.util.List; + +public class ConceptSet extends ConceptCommon { + private List children; + + public ConceptSet() { + super(); + } + + public ConceptSet(String uuid, String name, String conceptDescription, String conceptClass, String conceptShortname, List referenceTerms, List children) { + super(uuid, name, conceptDescription, conceptClass, conceptShortname, referenceTerms, "N/A"); + this.children = children; + } + + public List getChildren() { + return children == null ? new ArrayList() : children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Concepts.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Concepts.java new file mode 100644 index 0000000000..ac7ee4a311 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Concepts.java @@ -0,0 +1,24 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.List; + +public class Concepts { + private List conceptList; + private List conceptSetList; + + public List getConceptList() { + return conceptList; + } + + public void setConceptList(List conceptList) { + this.conceptList = conceptList; + } + + public List getConceptSetList() { + return conceptSetList; + } + + public void setConceptSetList(List conceptSetList) { + this.conceptSetList = conceptSetList; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Department.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Department.java new file mode 100644 index 0000000000..27b2b388b7 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Department.java @@ -0,0 +1,28 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.List; + +public class Department extends Resource { + private String description; + private List tests; + + public static final String DEPARTMENT_PARENT_CONCEPT_NAME = "Lab Departments"; + public static final String DEPARTMENT_CONCEPT_CLASS = "Department"; + + public List getTests() { + return tests; + } + + public void setTests(List tests) { + this.tests = tests; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Drug.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Drug.java new file mode 100644 index 0000000000..93deed2c61 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Drug.java @@ -0,0 +1,102 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; + +import javax.validation.constraints.NotNull; + +public class Drug { + private String uuid; + @NotNull + private String name; + @NotNull + private String genericName; + private Boolean combination; + private String strength; + private String dosageForm; + private String minimumDose; + private String maximumDose; + private String shortName; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGenericName() { + return genericName; + } + + public void setGenericName(String genericName) { + this.genericName = genericName; + } + + public void setCombination(Boolean combination) { + this.combination = combination; + } + + public Boolean isCombination() { + return BooleanUtils.toBoolean(combination); + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getStrength() { + return strength; + } + + public void setDosageForm(String dosageForm) { + this.dosageForm = dosageForm; + } + + public String getDosageForm() { + return dosageForm; + } + + public void setMinimumDose(String minimumDose) { + this.minimumDose = minimumDose; + } + + public String getMinimumDose() { + return minimumDose; + } + + public void setMaximumDose(String maximumDose) { + this.maximumDose = maximumDose; + } + + public String getMaximumDose() { + return maximumDose; + } + + + public Double doubleMaximumDose() { + return StringUtils.isBlank(maximumDose) ? null : Double.valueOf(maximumDose); + } + + public Double doubleMinimumDose() { + return StringUtils.isBlank(minimumDose) ? null : Double.valueOf(minimumDose); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java new file mode 100644 index 0000000000..c71f37da25 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/LabTest.java @@ -0,0 +1,66 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import org.openmrs.ConceptAnswer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class LabTest extends Resource { + private String description; + private String resultType; + private String testUnitOfMeasure; + private Double sortOrder; + + public static final List LAB_TEST_CONCEPT_CLASSES = Arrays.asList("LabTest","Test"); + + private Collection codedTestAnswer; + + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getResultType() { + return resultType; + } + + public void setResultType(String resultType) { + this.resultType = resultType; + } + + public String getTestUnitOfMeasure() { + return testUnitOfMeasure; + } + + public void setTestUnitOfMeasure(String testUnitOfMeasure) { + this.testUnitOfMeasure = testUnitOfMeasure; + } + + public void setSortOrder(Double sortOrder) { + this.sortOrder = sortOrder; + } + + public Double getSortOrder() { + return sortOrder; + } + + public void setCodedTestAnswer(Collection conceptAnswers) { + codedTestAnswer = new ArrayList<>(); + for (ConceptAnswer conceptAnswer : conceptAnswers) { + CodedTestAnswer ans = new CodedTestAnswer(); + ans.setName(conceptAnswer.getAnswerConcept().getName().getName()); + ans.setUuid(conceptAnswer.getAnswerConcept().getUuid()); + codedTestAnswer.add(ans); + } + } + + public Collection getCodedTestAnswer() { + return codedTestAnswer; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Panel.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Panel.java new file mode 100644 index 0000000000..716759147b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Panel.java @@ -0,0 +1,34 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.List; + +public class Panel extends Resource { + private String description; + private List tests; + private Double sortOrder; + public static final String LAB_SET_CONCEPT_CLASS = "LabSet"; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getTests() { + return tests; + } + + public void setTests(List tests) { + this.tests = tests; + } + + public void setSortOrder(Double sortOrder) { + this.sortOrder = sortOrder; + } + + public Double getSortOrder() { + return sortOrder; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java new file mode 100644 index 0000000000..fba0a3c334 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/RadiologyTest.java @@ -0,0 +1,9 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.Arrays; +import java.util.List; + +public class RadiologyTest extends Resource { + public static final List RADIOLOGY_TEST_CONCEPT_CLASSES = Arrays.asList("Radiology", "Radiology/Imaging Procedure"); + public static final String RADIOLOGY_TEST_PARENT_CONCEPT_NAME = "Radiology"; +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Resource.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Resource.java new file mode 100644 index 0000000000..7290225910 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Resource.java @@ -0,0 +1,69 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openmrs.module.emrapi.utils.CustomJsonDateSerializer; + +import java.util.Date; +import java.util.HashMap; + +public class Resource { + private String id; + private Date dateCreated; + private Date lastUpdated; + private String name; + private Boolean isActive; + + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + private HashMap properties; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getDateCreated() { + return dateCreated; + } + + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + @JsonSerialize(using = CustomJsonDateSerializer.class) + public Date getLastUpdated() { + return lastUpdated; + } + + public void setLastUpdated(Date lastUpdated) { + this.lastUpdated = lastUpdated; + } + + public HashMap getProperties() { + return properties; + } + + public void setProperties(HashMap properties) { + this.properties = properties; + } + +} \ No newline at end of file diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ResourceReference.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ResourceReference.java new file mode 100644 index 0000000000..1fe1dcd44c --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/ResourceReference.java @@ -0,0 +1,30 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +public class ResourceReference { + private String name; + private String uuid; + + public ResourceReference() { + } + + public ResourceReference(String uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java new file mode 100644 index 0000000000..f2b5c8728b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/Sample.java @@ -0,0 +1,43 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.List; + +public class Sample extends Resource { + private String shortName; + public static final String SAMPLE_CONCEPT_CLASS = "Sample"; + private Double sortOrder; + private List tests; + private List panels; + + public List getTests() { + return tests; + } + + public void setTests(List tests) { + this.tests = tests; + } + + public List getPanels() { + return panels; + } + + public void setPanels(List panels) { + this.panels = panels; + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public Double getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Double sortOrder) { + this.sortOrder = sortOrder; + } +} \ No newline at end of file diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/TestsAndPanels.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/TestsAndPanels.java new file mode 100644 index 0000000000..b890f5d9f8 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/contract/TestsAndPanels.java @@ -0,0 +1,39 @@ +package org.bahmni.module.referencedata.labconcepts.contract; + +import java.util.HashSet; +import java.util.Set; + +public class TestsAndPanels extends Resource { + private Set tests; + private Set panels; + + public Set getTests() { + if (tests == null) { + tests = new HashSet<>(); + } + return tests; + } + + public void setTests(Set tests) { + this.tests = tests; + } + + public Set getPanels() { + if (panels == null) { + panels = new HashSet<>(); + } + return panels; + } + + public void setPanels(Set panels) { + this.panels = panels; + } + + public void addTest(LabTest labTest) { + getTests().add(labTest); + } + + public void addPanel(Panel panel) { + getPanels().add(panel); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java new file mode 100644 index 0000000000..d033492f03 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllSamplesMapper.java @@ -0,0 +1,28 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.openmrs.Concept; + +import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; + + +public class AllSamplesMapper extends ResourceMapper { + public AllSamplesMapper() { + super(null); + } + + @Override + public AllSamples map(Concept allSamplesConcept) { + AllSamples allSamples = new AllSamples(); + allSamples = mapResource(allSamples, allSamplesConcept); + allSamples.setDescription(ConceptExtension.getDescription(allSamplesConcept)); + + for (Concept setMember : allSamplesConcept.getSetMembers()) { + if (ConceptExtension.isOfConceptClass(setMember, SAMPLE_CONCEPT_CLASS)) { + SampleMapper sampleMapper = new SampleMapper(); + allSamples.addSample(sampleMapper.map(setMember)); + } + } + return allSamples; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllTestsAndPanelsMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllTestsAndPanelsMapper.java new file mode 100644 index 0000000000..f1231925e9 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AllTestsAndPanelsMapper.java @@ -0,0 +1,19 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.openmrs.Concept; + +public class AllTestsAndPanelsMapper extends ResourceMapper { + public AllTestsAndPanelsMapper() { + super(null); + } + + @Override + public AllTestsAndPanels map(Concept testsAndPanelsConcept) { + AllTestsAndPanels allTestsAndPanels = new AllTestsAndPanels(); + allTestsAndPanels = mapResource(allTestsAndPanels, testsAndPanelsConcept); + allTestsAndPanels.setDescription(ConceptExtension.getDescription(testsAndPanelsConcept)); + allTestsAndPanels.setTestsAndPanels(new TestAndPanelMapper().map(testsAndPanelsConcept)); + return allTestsAndPanels; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AttributableResourceMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AttributableResourceMapper.java new file mode 100644 index 0000000000..43ef93aab1 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/AttributableResourceMapper.java @@ -0,0 +1,27 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.openmrs.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.Resource; + +import java.util.HashMap; + +public class AttributableResourceMapper extends ResourceMapper { + + public AttributableResourceMapper() {super(null);} + + protected AttributableResourceMapper(String parentConceptName) { + super(parentConceptName); + } + + @Override + public Resource map(Concept concept) { + Resource resource = new Resource(); + mapResource(resource, concept); + HashMap properties = new HashMap<>(); + concept.getActiveAttributes().stream().forEach(a -> properties.put(a.getAttributeType().getName(), a.getValueReference())); + if (!properties.isEmpty()) { + resource.setProperties(properties); + } + return resource; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptAnswerMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptAnswerMapper.java new file mode 100644 index 0000000000..213cb0094c --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptAnswerMapper.java @@ -0,0 +1,39 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.api.context.Context; + +import java.util.Collection; +import java.util.List; + +public class ConceptAnswerMapper { + + public Concept map(Concept concept, List answers) { + double sortWeight = 0.0; + removeConceptAnswers(concept); + for (ConceptAnswer answer : answers) { + sortWeight++; + addAnswer(concept, answer, sortWeight); + } + return concept; + } + + private org.openmrs.Concept addAnswer(org.openmrs.Concept concept, ConceptAnswer answer, double sortWeight) { + for (ConceptAnswer conceptAnswer : concept.getAnswers()) { + if (conceptAnswer.getAnswerConcept().getName(Context.getLocale()).getName().equals(answer.getAnswerConcept().getName(Context.getLocale()).getName())) { + return concept; + } + } + answer.setSortWeight(sortWeight); + concept.addAnswer(answer); + return concept; + } + + private void removeConceptAnswers(org.openmrs.Concept concept) { + Collection answers = concept.getAnswers(); + answers.clear(); + concept.setAnswers(answers); + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptCommonMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptCommonMapper.java new file mode 100644 index 0000000000..0d2fe8ae61 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptCommonMapper.java @@ -0,0 +1,53 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptCommon; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.openmrs.Concept; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; + +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.addConceptName; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.constructDescription; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getConceptName; + +public class ConceptCommonMapper { + + public org.openmrs.Concept map(ConceptCommon conceptCommon, ConceptMetaData conceptMetaData) { + org.openmrs.Concept openmrsConcept = new org.openmrs.Concept(); + if (conceptMetaData.getExistingConcept() != null) { + openmrsConcept = conceptMetaData.getExistingConcept(); + } else if (StringUtils.isNotBlank(conceptCommon.getUuid())){ + openmrsConcept.setUuid(conceptCommon.getUuid()); + } + String displayName = conceptCommon.getDisplayName(); + openmrsConcept = addConceptName(openmrsConcept, getConceptName(conceptCommon.getUniqueName(), ConceptNameType.FULLY_SPECIFIED, conceptMetaData.getLocale())); + if (displayName != null) { + openmrsConcept = addConceptName(openmrsConcept, getConceptName(conceptCommon.getDisplayName(), ConceptNameType.SHORT, conceptMetaData.getLocale())); + } + + if (!StringUtils.isBlank(conceptCommon.getDescription())) { + setDescriptionWithLocale(conceptCommon.getDescription(), conceptMetaData.getLocale(), openmrsConcept); + } + openmrsConcept.setConceptClass(conceptMetaData.getConceptClass()); + return openmrsConcept; + } + + + private void setDescriptionWithLocale(String description, Locale locale, Concept concept) { + if (descriptionAlreadyExistsInLocale(concept, locale)) { + concept.getDescription(locale).setDescription(description); + } else { + concept.addDescription(constructDescription(description, locale)); + } + } + + private boolean descriptionAlreadyExistsInLocale(Concept concept, Locale locale) { + locale = (locale != null ? locale: Context.getLocale()); + if (concept.getDescription(locale) == null) + return false; + return concept.getDescription(locale).getLocale().equals(locale); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java new file mode 100644 index 0000000000..657d7f4a13 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptExtension.java @@ -0,0 +1,148 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.referencedata.labconcepts.contract.ResourceReference; +import org.openmrs.Concept; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptName; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class ConceptExtension { + public static String getDescription(Concept concept) { + ConceptDescription description = concept.getDescription(); + if (description != null) { + return description.getDescription(); + } + return null; + } + + public static String getDescriptionOrName(Concept concept) { + ConceptDescription description = concept.getDescription(); + if (description != null) { + return description.getDescription(); + } + return concept.getName(Context.getLocale()).getName(); + } + + public static ConceptDescription constructDescription(String description, Locale locale) { + if (StringUtils.isBlank(description)) return null; + if (locale == null) { + locale = Context.getLocale(); + } + ConceptDescription conceptDescription = new ConceptDescription(description, locale); + return conceptDescription; + } + + + public static ConceptName getConceptName(String name) { + ConceptName conceptName = new ConceptName(); + conceptName.setName(name); + conceptName.setLocale(Context.getLocale()); + return conceptName; + } + + public static ConceptName getConceptName(String name, Locale locale) { + ConceptName conceptName = new ConceptName(); + conceptName.setName(name); + conceptName.setLocale(locale != null ? locale: Context.getLocale()); + return conceptName; + } + + public static ConceptName getConceptName(String name, ConceptNameType conceptNameType) { + ConceptName conceptName = getConceptName(name); + conceptName.setConceptNameType(conceptNameType); + return conceptName; + } + + public static ConceptName getConceptName(String name, ConceptNameType conceptNameType, Locale locale) { + ConceptName conceptName = getConceptName(name, conceptNameType); + conceptName.setConceptNameType(conceptNameType); + conceptName.setLocale(locale != null ? locale: Context.getLocale()); + return conceptName; + } + + public static String getUnits(Concept concept) { + ConceptNumeric conceptNumeric = Context.getConceptService().getConceptNumeric(concept.getConceptId()); + return conceptNumeric == null ? null : conceptNumeric.getUnits(); + } + + public static boolean isActive(Concept setMember) { + return !setMember.isRetired(); + } + + public static org.openmrs.Concept addConceptName(org.openmrs.Concept concept, ConceptName conceptName) { + if (conceptName.getName() == null) return concept; + for (ConceptName name : concept.getNames()) { + if (isFullySpecifiedName(conceptName) && isFullySpecifiedName(name) && !name.getName().equals(conceptName.getName()) && name.getLocale().equals(conceptName.getLocale())) { + name.setName(conceptName.getName()); + return concept; + } else if (isShortName(conceptName) && isShortName(name) && !name.getName().equals(conceptName.getName()) && name.getLocale().equals(conceptName.getLocale())) { + name.setName(conceptName.getName()); + return concept; + } else if (name.getName().equals(conceptName.getName()) && name.getLocale().equals(conceptName.getLocale())) { + return concept; + } + } + concept.addName(conceptName); + return concept; + } + + private static boolean isShortName(ConceptName conceptName) { + return ObjectUtils.equals(conceptName.getConceptNameType(), ConceptNameType.SHORT); + } + + private static boolean isFullySpecifiedName(ConceptName conceptName) { + return ObjectUtils.equals(conceptName.getConceptNameType(), ConceptNameType.FULLY_SPECIFIED); + } + + private static boolean containsClassName(String conceptClassName, List classNames){ + for (String className : classNames) { + if (className.equalsIgnoreCase(conceptClassName)) { + return true; + } + } + return false; + } + + public static boolean isOfConceptClass(Concept concept, String conceptClassName) { + return concept.getConceptClass() != null && concept.getConceptClass().getName() != null && concept.getConceptClass().getName().equals(conceptClassName); + } + + public static boolean isOfAnyConceptClass(Concept concept, List conceptClassNames) { + return concept.getConceptClass() != null && concept.getConceptClass().getName() != null && containsClassName(concept.getConceptClass().getName(),conceptClassNames); + } + + public static boolean isOfConceptClassByUUID(Concept concept, String conceptClassUUID) { + return concept.getConceptClass() != null && concept.getConceptClass().getUuid().equals(conceptClassUUID); + } + + public static List getResourceReferencesOfConceptClass(List setMembers, String conceptClass) { + ResourceReferenceMapper resourceReferenceMapper = new ResourceReferenceMapper(); + List resourceReferences = new ArrayList<>(); + for (Concept setMember : setMembers) { + if (isOfConceptClass(setMember, conceptClass)) { + resourceReferences.add(resourceReferenceMapper.map(setMember)); + } + } + return resourceReferences; + } + + public static List getResourceReferencesOfConceptClasses(List setMembers, List conceptClasses) { + ResourceReferenceMapper resourceReferenceMapper = new ResourceReferenceMapper(); + List resourceReferences = new ArrayList<>(); + for (Concept setMember : setMembers) { + if (isOfAnyConceptClass(setMember, conceptClasses)) { + resourceReferences.add(resourceReferenceMapper.map(setMember)); + } + } + return resourceReferences; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptMapper.java new file mode 100644 index 0000000000..407035d690 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptMapper.java @@ -0,0 +1,109 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + + +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.openmrs.ConceptAnswer; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptName; +import org.openmrs.api.context.Context; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.addConceptName; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getConceptName; + +public class ConceptMapper { + + private final ConceptAnswerMapper conceptAnswerMapper; + private final ConceptNumericMapper conceptNumericMapper; + private final ConceptCommonMapper conceptCommonMapper; + + public ConceptMapper() { + conceptAnswerMapper = new ConceptAnswerMapper(); + conceptNumericMapper = new ConceptNumericMapper(); + conceptCommonMapper = new ConceptCommonMapper(); + } + + public org.openmrs.Concept map(Concept conceptData, ConceptMetaData conceptMetaData, List answers) { + org.openmrs.Concept concept = conceptCommonMapper.map(conceptData, conceptMetaData); + for (String conceptName : conceptData.getSynonyms()) { + concept = addConceptName(concept, getConceptName(conceptName, conceptMetaData.getLocale())); + } + if (conceptMetaData.getConceptDatatype().isNumeric()) { + concept = conceptNumericMapper.map(concept, conceptData, conceptMetaData.getExistingConcept()); + } + concept.setDatatype(conceptMetaData.getConceptDatatype()); + concept = conceptAnswerMapper.map(concept, answers); + return concept; + } + + public org.openmrs.Concept addConceptMap(org.openmrs.Concept mappedConcept, ConceptMap conceptMap) { + if (conceptMap == null) return mappedConcept; + for (ConceptMap existingMap : mappedConcept.getConceptMappings()) { + if (existingMap.getConceptReferenceTerm().equals(conceptMap.getConceptReferenceTerm())) { + return mappedConcept; + } + } + mappedConcept.addConceptMapping(conceptMap); + return mappedConcept; + } + + public Concept map(org.openmrs.Concept concept) { + String conceptDescription = null; + String conceptShortname = null; + String name = concept.getName(Context.getLocale()).getName(); + ConceptDescription description = concept.getDescription(Context.getLocale()); + if (description != null) { + conceptDescription = description.getDescription(); + } + ConceptName shortName = concept.getShortNameInLocale(Context.getLocale()); + if (shortName != null) { + conceptShortname = shortName.getName(); + } + String conceptClass = concept.getConceptClass().getName(); + String conceptDatatype = concept.getDatatype().getName(); + List conceptSynonyms = getSynonyms(concept); + List conceptAnswers = getAnswers(concept); + Collection conceptMappings = concept.getConceptMappings(); + + List referenceTerms = new ArrayList<>(); + for (ConceptMap conceptMapping : conceptMappings) { + org.openmrs.ConceptReferenceTerm term = conceptMapping.getConceptReferenceTerm(); + referenceTerms.add(new ConceptReferenceTerm(term.getCode(), conceptMapping.getConceptMapType().getName(), term.getConceptSource().getName())); + } + + String uuid = concept.getUuid(); + return new Concept(uuid, name, conceptDescription, conceptClass, conceptShortname, referenceTerms, conceptSynonyms, conceptAnswers, conceptDatatype); + } + + private List getAnswers(org.openmrs.Concept concept) { + List answers = new ArrayList<>(); + for (ConceptAnswer conceptAnswer : concept.getAnswers()) { + answers.add(conceptAnswer.getAnswerConcept().getName(Context.getLocale()).getName()); + } + return answers; + } + + private List getSynonyms(org.openmrs.Concept concept) { + List synonyms = new ArrayList<>(); + for (ConceptName synonym : concept.getSynonyms()) { + synonyms.add(synonym.getName()); + } + return synonyms; + } + + public List mapAll(org.openmrs.Concept concept) { + List conceptList = new ArrayList<>(); + for (ConceptAnswer conceptAnswer : concept.getAnswers()) { + conceptList.addAll(mapAll(conceptAnswer.getAnswerConcept())); + } + conceptList.add(map(concept)); + return conceptList; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptNumericMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptNumericMapper.java new file mode 100644 index 0000000000..d1c3f1b338 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptNumericMapper.java @@ -0,0 +1,45 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.Concept; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptNumeric; + +public class ConceptNumericMapper { + + public Concept map(Concept concept, org.bahmni.module.referencedata.labconcepts.contract.Concept conceptData, Concept existingConcept) { + ConceptNumeric conceptNumeric = null; + if (existingConcept == null || !existingConcept.getDatatype().getUuid().equals(ConceptDatatype.NUMERIC_UUID)) { + conceptNumeric = new ConceptNumeric(concept); + } else if (existingConcept.getDatatype().getUuid().equals(ConceptDatatype.NUMERIC_UUID)) { + conceptNumeric = (ConceptNumeric) (concept); + } + if (conceptNumeric != null) { + conceptNumeric.setUnits(conceptData.getUnits()); + setHiNormal(conceptData, conceptNumeric); + setLowNormal(conceptData, conceptNumeric); + setAllowDecimal(conceptData, conceptNumeric); + } + return conceptNumeric; + } + + private void setLowNormal(org.bahmni.module.referencedata.labconcepts.contract.Concept conceptData, ConceptNumeric conceptNumeric) { + String lowNormal = conceptData.getLowNormal(); + if (!StringUtils.isBlank(lowNormal)) { + conceptNumeric.setLowNormal(Double.valueOf(lowNormal)); + } + } + + private void setHiNormal(org.bahmni.module.referencedata.labconcepts.contract.Concept conceptData, ConceptNumeric conceptNumeric) { + String hiNormal = conceptData.getHiNormal(); + if (!StringUtils.isBlank(hiNormal)) { + conceptNumeric.setHiNormal(Double.valueOf(hiNormal)); + } + } + private void setAllowDecimal(org.bahmni.module.referencedata.labconcepts.contract.Concept conceptData, ConceptNumeric conceptNumeric) { + String allowDecimal = conceptData.getAllowDecimal(); + if (!StringUtils.isBlank(allowDecimal)) { + conceptNumeric.setAllowDecimal(Boolean.valueOf(allowDecimal)); + } + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptSetMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptSetMapper.java new file mode 100644 index 0000000000..a7bd15c622 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptSetMapper.java @@ -0,0 +1,91 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.contract.Concepts; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.openmrs.Concept; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptName; +import org.openmrs.api.context.Context; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ConceptSetMapper { + + private final ConceptMapper conceptMapper; + private final ConceptCommonMapper conceptCommonMapper; + private final SetMemberMapper setMemberMapper; + + public ConceptSetMapper() { + conceptMapper = new ConceptMapper(); + conceptCommonMapper = new ConceptCommonMapper(); + setMemberMapper = new SetMemberMapper(); + } + + public Concept map(ConceptSet conceptSet, List childConcepts, ConceptMetaData conceptMetaData) { + Concept concept = conceptCommonMapper.map(conceptSet, conceptMetaData); + concept.setSet(true); + concept.setDatatype(conceptMetaData.getConceptDatatype()); + concept = setMemberMapper.map(concept, childConcepts); + return concept; + } + + + public ConceptSet map(Concept concept) { + String conceptDescription = null; + String conceptShortname = null; + String name = concept.getName(Context.getLocale()).getName(); + ConceptDescription description = concept.getDescription(Context.getLocale()); + if (description != null) { + conceptDescription = description.getDescription(); + } + ConceptName shortName = concept.getShortNameInLocale(Context.getLocale()); + if (shortName != null) { + conceptShortname = shortName.getName(); + } + String conceptClass = concept.getConceptClass().getName(); + List children = getSetMembers(concept); + Collection conceptMappings = concept.getConceptMappings(); + + + List referenceTerms = new ArrayList<>(); + for (ConceptMap conceptMapping : conceptMappings) { + org.openmrs.ConceptReferenceTerm term = conceptMapping.getConceptReferenceTerm(); + referenceTerms.add(new org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm(term.getCode(), conceptMapping.getConceptMapType().getName(), term.getConceptSource().getName())); + } + + String uuid = concept.getUuid(); + ConceptSet conceptSet = new ConceptSet(uuid, name, conceptDescription, conceptClass, conceptShortname, referenceTerms, children); + return conceptSet; + } + + private List getSetMembers(Concept concept) { + List setMembers = new ArrayList<>(); + for (Concept setMember : concept.getSetMembers()) { + setMembers.add(setMember.getName(Context.getLocale()).getName()); + } + return setMembers; + } + + public Concepts mapAll(Concept concept) { + List conceptSetList = new ArrayList<>(); + List conceptList = new ArrayList<>(); + for (Concept setMember : concept.getSetMembers()) { + if (setMember.isSet()) { + Concepts concepts = mapAll(setMember); + conceptSetList.addAll(concepts.getConceptSetList()); + conceptList.addAll(concepts.getConceptList()); + } else { + conceptList.addAll(conceptMapper.mapAll(setMember)); + } + } + conceptSetList.add(map(concept)); + Concepts concepts = new Concepts(); + concepts.setConceptList(conceptList); + concepts.setConceptSetList(conceptSetList); + return concepts; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java new file mode 100644 index 0000000000..22fe234cf6 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DepartmentMapper.java @@ -0,0 +1,23 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Department; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.openmrs.Concept; + +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClasses; + +public class DepartmentMapper extends ResourceMapper { + + public DepartmentMapper() { + super(Department.DEPARTMENT_PARENT_CONCEPT_NAME); + } + + @Override + public Department map(Concept departmentConcept) { + Department department = new Department(); + department = mapResource(department, departmentConcept); + department.setDescription(ConceptExtension.getDescriptionOrName(departmentConcept)); + department.setTests(getResourceReferencesOfConceptClasses(departmentConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASSES)); + return department; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMapper.java new file mode 100644 index 0000000000..08b4919cac --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMapper.java @@ -0,0 +1,62 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.openmrs.Concept; +import org.openmrs.api.ConceptNameType; +import org.openmrs.api.context.Context; +import org.springframework.util.Assert; + +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getConceptName; + +public class DrugMapper { + + private final DrugMetaDataMapper drugMetaDataMapper; + + public DrugMapper() { + drugMetaDataMapper = new DrugMetaDataMapper(); + } + + public org.openmrs.Drug map(Drug drug, DrugMetaData drugMetaData) { + Assert.notNull(drugMetaData.getDosageForm(),"The dosage form should not be null"); + Assert.notNull(drugMetaData.getDrugConcept(),"The drug concept should not be null"); + + org.openmrs.Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + conceptDrug.setName(drug.getName()); + ConceptExtension.addConceptName(conceptDrug.getConcept(), getConceptName(drug.getGenericName(), ConceptNameType.FULLY_SPECIFIED)); + conceptDrug.setCombination(drug.isCombination()); + conceptDrug.setStrength(drug.getStrength()); + conceptDrug.setMaximumDailyDose(drug.doubleMaximumDose()); + conceptDrug.setMinimumDailyDose(drug.doubleMinimumDose()); + return conceptDrug; + } + + + public Drug map(org.openmrs.Drug conceptDrug) { + Drug drug = new Drug(); + drug.setName(conceptDrug.getName()); + drug.setShortName(getShortNameFrom(conceptDrug.getConcept())); + drug.setGenericName(getNameFrom(conceptDrug.getConcept())); + drug.setDosageForm(getNameFrom(conceptDrug.getDosageForm())); + drug.setStrength(conceptDrug.getStrength()); + drug.setUuid(conceptDrug.getUuid()); + drug.setCombination(conceptDrug.getCombination()); + drug.setMaximumDose(conceptDrug.getMaximumDailyDose()==null?"":conceptDrug.getMaximumDailyDose().toString()); + drug.setMinimumDose(conceptDrug.getMinimumDailyDose()==null?"":conceptDrug.getMinimumDailyDose().toString()); + return drug; + } + + private String getShortNameFrom(Concept concept) { + if (concept != null && concept.getShortNameInLocale(Context.getLocale()) != null) { + return concept.getShortNameInLocale(Context.getLocale()).getName(); + } + return null; + } + + private String getNameFrom(Concept concept) { + if (concept != null && concept.getName(Context.getLocale()) != null) { + return concept.getName(Context.getLocale()).getName(); + } + return null; + } +} \ No newline at end of file diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMetaDataMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMetaDataMapper.java new file mode 100644 index 0000000000..312950f6da --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMetaDataMapper.java @@ -0,0 +1,21 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.openmrs.Drug; + +public class DrugMetaDataMapper { + + public org.openmrs.Drug map(DrugMetaData drugMetaData) { + Drug drug = null; + + if (drugMetaData.getExistingDrug() != null) { + drug = drugMetaData.getExistingDrug(); + } else { + drug = new Drug(); + } + + drug.setDosageForm(drugMetaData.getDosageForm()); + drug.setConcept(drugMetaData.getDrugConcept()); + return drug; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/LabTestMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/LabTestMapper.java new file mode 100644 index 0000000000..a08f1f8fcb --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/LabTestMapper.java @@ -0,0 +1,25 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.openmrs.Concept; + +public class LabTestMapper extends ResourceMapper { + public LabTestMapper() { + super(AllTestsAndPanels.ALL_TESTS_AND_PANELS); + } + + @Override + public LabTest map(Concept testConcept) { + LabTest test = new LabTest(); + test = mapResource(test, testConcept); + test.setDescription(ConceptExtension.getDescriptionOrName(testConcept)); + test.setResultType(testConcept.getDatatype().getName()); + test.setTestUnitOfMeasure(ConceptExtension.getUnits(testConcept)); + test.setSortOrder(getSortWeight(testConcept)); + test.setCodedTestAnswer(testConcept.getAnswers()); + return test; + } + + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java new file mode 100644 index 0000000000..9555e65a52 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/PanelMapper.java @@ -0,0 +1,22 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Panel; +import org.openmrs.Concept; + +public class PanelMapper extends ResourceMapper { + public PanelMapper() { + super(AllTestsAndPanels.ALL_TESTS_AND_PANELS); + } + + @Override + public Panel map(Concept panelConcept) { + Panel panel = new Panel(); + panel = mapResource(panel, panelConcept); + panel.setTests(ConceptExtension.getResourceReferencesOfConceptClasses(panelConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASSES)); + panel.setSortOrder(getSortWeight(panelConcept)); + panel.setDescription(ConceptExtension.getDescriptionOrName(panelConcept)); + return panel; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/RadiologyTestMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/RadiologyTestMapper.java new file mode 100644 index 0000000000..75ee670aed --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/RadiologyTestMapper.java @@ -0,0 +1,17 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest; +import org.openmrs.Concept; + +public class RadiologyTestMapper extends ResourceMapper { + public RadiologyTestMapper() { + super(RadiologyTest.RADIOLOGY_TEST_PARENT_CONCEPT_NAME); + } + + @Override + public RadiologyTest map(Concept testConcept) { + return mapResource(new RadiologyTest(), testConcept); + } + + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ResourceMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ResourceMapper.java new file mode 100644 index 0000000000..bbf72478db --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ResourceMapper.java @@ -0,0 +1,41 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Resource; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.context.Context; + +import java.util.List; + +public abstract class ResourceMapper { + public static final double DEFAULT_SORT_ORDER = 999.0; + String parentConceptName; + + protected ResourceMapper(String parentConceptName) { + this.parentConceptName = parentConceptName; + } + + public abstract T map(Concept concept); + + + R mapResource(R resource, Concept concept) { + resource.setName(concept.getName(Context.getLocale()).getName()); + resource.setIsActive(!concept.isRetired()); + resource.setId(concept.getUuid()); + resource.setDateCreated(concept.getDateCreated()); + resource.setLastUpdated(concept.getDateChanged()); + return (R) resource; + } + + Double getSortWeight(Concept concept) { + List conceptSets = Context.getConceptService().getSetsContainingConcept(concept); + if (conceptSets == null) return DEFAULT_SORT_ORDER; + for (ConceptSet conceptSet : conceptSets) { + if (conceptSet.getConceptSet().getName(Context.getLocale()).getName().equals(parentConceptName)) { + return conceptSet.getSortWeight() != null ? conceptSet.getSortWeight() : DEFAULT_SORT_ORDER; + } + } + return DEFAULT_SORT_ORDER; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ResourceReferenceMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ResourceReferenceMapper.java new file mode 100644 index 0000000000..17e0cfea32 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/ResourceReferenceMapper.java @@ -0,0 +1,11 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.ResourceReference; +import org.openmrs.Concept; +import org.openmrs.api.context.Context; + +public class ResourceReferenceMapper { + public ResourceReference map(Concept concept) { + return new ResourceReference(concept.getUuid(), concept.getName(Context.getLocale()).getName()); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java new file mode 100644 index 0000000000..4dab4563c0 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SampleMapper.java @@ -0,0 +1,29 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Panel; +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.openmrs.Concept; +import org.openmrs.api.context.Context; + +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClass; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.getResourceReferencesOfConceptClasses; + +public class SampleMapper extends ResourceMapper { + public SampleMapper() { + super(AllSamples.ALL_SAMPLES); + } + + @Override + public Sample map(Concept sampleConcept) { + Sample sample = new Sample(); + sample = mapResource(sample, sampleConcept); + sample.setShortName(sampleConcept.getShortestName(Context.getLocale(), false).getName()); + sample.setSortOrder(getSortWeight(sampleConcept)); + sample.setTests(getResourceReferencesOfConceptClasses(sampleConcept.getSetMembers(), LabTest.LAB_TEST_CONCEPT_CLASSES)); + sample.setPanels(getResourceReferencesOfConceptClass(sampleConcept.getSetMembers(), Panel.LAB_SET_CONCEPT_CLASS)); + return sample; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SetMemberMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SetMemberMapper.java new file mode 100644 index 0000000000..324e73470d --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/SetMemberMapper.java @@ -0,0 +1,40 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.context.Context; + +import java.util.Collection; +import java.util.List; + +public class SetMemberMapper { + + public Concept map(Concept concept, List childConcepts) { + removeAllSetMembers(concept); + for (int i = 0; i < childConcepts.size(); i++) { + addSetMember(concept, childConcepts.get(i), i); + } + return concept; + } + + private void removeAllSetMembers(Concept concept) { + Collection conceptSets = concept.getConceptSets(); + conceptSets.clear(); + concept.setConceptSets(conceptSets); + } + + private org.openmrs.Concept addSetMember(Concept concept, Concept childConcept, Integer sortWeight) { + if (ifChildExists(concept, childConcept)) return concept; + concept.addSetMember(childConcept, sortWeight); + return concept; + } + + private boolean ifChildExists(Concept concept, Concept childConcept) { + for (Concept child : concept.getSetMembers()) { + if (child.getName(Context.getLocale()).getName().equals(childConcept.getName(Context.getLocale()).getName())) { + return true; + } + } + return false; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java new file mode 100644 index 0000000000..5789fba58a --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/mapper/TestAndPanelMapper.java @@ -0,0 +1,41 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Panel; +import org.bahmni.module.referencedata.labconcepts.contract.TestsAndPanels; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; + +import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.*; + +public class TestAndPanelMapper extends ResourceMapper { + + private final LabTestMapper labTestMapper; + private PanelMapper panelMapper; + + public TestAndPanelMapper() { + super(null); + labTestMapper = new LabTestMapper(); + panelMapper = new PanelMapper(); + } + + @Override + public TestsAndPanels map(Concept sampleConcept) { + TestsAndPanels testsAndPanels = new TestsAndPanels(); + for (Concept concept : sampleConcept.getSetMembers()) { + if (ConceptExtension.isActive(concept)) addConcept(testsAndPanels, concept); + } + return testsAndPanels; + } + + private void addConcept(TestsAndPanels testsAndPanels, Concept concept) { + if (isOfAnyConceptClass(concept, LAB_TEST_CONCEPT_CLASSES)) { + LabTest test = labTestMapper.map(concept); + testsAndPanels.addTest(test); + } else if (isOfConceptClassByUUID(concept, ConceptClass.LABSET_UUID)) { + Panel panel = panelMapper.map(concept); + testsAndPanels.addPanel(panel); + } + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/model/ConceptMetaData.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/model/ConceptMetaData.java new file mode 100644 index 0000000000..a37405926b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/model/ConceptMetaData.java @@ -0,0 +1,54 @@ +package org.bahmni.module.referencedata.labconcepts.model; + +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; + +import java.util.Locale; + +public class ConceptMetaData { + private Concept existingConcept; + private ConceptDatatype conceptDatatype; + private ConceptClass conceptClass; + private Locale locale; + + public ConceptMetaData(Concept existingConcept, ConceptDatatype conceptDatatype, ConceptClass conceptClass, Locale locale) { + this.existingConcept = existingConcept; + this.conceptDatatype = conceptDatatype; + this.conceptClass = conceptClass; + this.locale = locale; + } + + public Concept getExistingConcept() { + return existingConcept; + } + + public void setExistingConcept(Concept existingConcept) { + this.existingConcept = existingConcept; + } + + public ConceptDatatype getConceptDatatype() { + return conceptDatatype; + } + + public void setConceptDatatype(ConceptDatatype conceptDatatype) { + this.conceptDatatype = conceptDatatype; + } + + public ConceptClass getConceptClass() { + return conceptClass; + } + + public void setConceptClass(ConceptClass conceptClass) { + this.conceptClass = conceptClass; + } + + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/model/DrugMetaData.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/model/DrugMetaData.java new file mode 100644 index 0000000000..687a58a5bd --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/model/DrugMetaData.java @@ -0,0 +1,53 @@ +package org.bahmni.module.referencedata.labconcepts.model; + +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.Drug; + +public class DrugMetaData { + private Concept drugConcept; + private Concept dosageForm; + private ConceptClass drugConceptClass; + private Drug existingDrug; + public DrugMetaData() { + } + + public DrugMetaData(Drug existingDrug, Concept drugConcept, Concept dosageFormConcept, ConceptClass drugConceptClass) { + this.existingDrug = existingDrug; + this.drugConcept = drugConcept; + this.dosageForm = dosageFormConcept; + this.drugConceptClass = drugConceptClass; + } + + public Concept getDrugConcept() { + return drugConcept; + } + + public void setDrugConcept(Concept drugConcept) { + this.drugConcept = drugConcept; + } + + public Concept getDosageForm() { + return dosageForm; + } + + public void setDosageForm(Concept dosageForm) { + this.dosageForm = dosageForm; + } + + public ConceptClass getDrugConceptClass() { + return drugConceptClass; + } + + public void setDrugConceptClass(ConceptClass drugConceptClass) { + this.drugConceptClass = drugConceptClass; + } + + public Drug getExistingDrug() { + return existingDrug; + } + + public void setExistingDrug(Drug existingDrug) { + this.existingDrug = existingDrug; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ConceptMetaDataService.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ConceptMetaDataService.java new file mode 100644 index 0000000000..6278976d3f --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ConceptMetaDataService.java @@ -0,0 +1,8 @@ +package org.bahmni.module.referencedata.labconcepts.service; + +import org.bahmni.module.referencedata.labconcepts.contract.ConceptCommon; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; + +public interface ConceptMetaDataService { + public ConceptMetaData getConceptMetaData(ConceptCommon conceptCommon); +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/DrugMetaDataService.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/DrugMetaDataService.java new file mode 100644 index 0000000000..0e6352af8d --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/DrugMetaDataService.java @@ -0,0 +1,7 @@ +package org.bahmni.module.referencedata.labconcepts.service; + +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; + +public interface DrugMetaDataService { + public DrugMetaData getDrugMetaData(org.bahmni.module.referencedata.labconcepts.contract.Drug drug); +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataConceptReferenceTermService.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataConceptReferenceTermService.java new file mode 100644 index 0000000000..49f05f601b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataConceptReferenceTermService.java @@ -0,0 +1,12 @@ +package org.bahmni.module.referencedata.labconcepts.service; + +import org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm; +import org.openmrs.ConceptMap; + +public interface ReferenceDataConceptReferenceTermService { + public org.openmrs.ConceptReferenceTerm getConceptReferenceTerm(String referenceTermCode, String referenceTermSource); + + public ConceptMap getConceptMap(org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm conceptReferenceTermData); + + public org.openmrs.ConceptReferenceTerm saveOrUpdate(ConceptReferenceTerm conceptReferenceTerm); +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataConceptService.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataConceptService.java new file mode 100644 index 0000000000..78a1d0ff3d --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataConceptService.java @@ -0,0 +1,12 @@ +package org.bahmni.module.referencedata.labconcepts.service; + +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; + +public interface ReferenceDataConceptService { + public org.openmrs.Concept saveConcept(Concept concept); + + public org.openmrs.Concept saveConcept(ConceptSet conceptSet); + + public org.bahmni.module.referencedata.labconcepts.contract.Concepts getConcept(String conceptName); +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataDrugService.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataDrugService.java new file mode 100644 index 0000000000..abf59562b1 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/ReferenceDataDrugService.java @@ -0,0 +1,8 @@ +package org.bahmni.module.referencedata.labconcepts.service; + + +import org.bahmni.module.referencedata.labconcepts.contract.Drug; + +public interface ReferenceDataDrugService { + public org.openmrs.Drug saveDrug(Drug drug); +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ConceptMetaDataServiceImpl.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ConceptMetaDataServiceImpl.java new file mode 100644 index 0000000000..fff490f183 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ConceptMetaDataServiceImpl.java @@ -0,0 +1,75 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptCommon; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.bahmni.module.referencedata.labconcepts.service.ConceptMetaDataService; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Locale; + +@Service +public class ConceptMetaDataServiceImpl implements ConceptMetaDataService { + + @Autowired + private ConceptService conceptService; + + + @Override + public ConceptMetaData getConceptMetaData(ConceptCommon conceptCommon) { + ConceptClass conceptClass = conceptService.getConceptClassByName(conceptCommon.getClassName()); + org.openmrs.Concept existingConcept = getExistingConcept(conceptCommon.getUniqueName(), conceptCommon.getUuid()); + ConceptDatatype conceptDatatype = conceptService.getConceptDatatypeByName(conceptCommon.getDataType()); + return new ConceptMetaData(existingConcept, conceptDatatype, conceptClass, getLocale(conceptCommon.getLocale())); + } + + private org.openmrs.Concept getExistingConcept(String uniqueName, String uuid) { + if (uuid != null) { + return conceptService.getConceptByUuid(uuid); + } + + Concept conceptByName = conceptService.getConceptByName(uniqueName); + if (conceptByName != null) { + return conceptByName; + } + + AdministrationService administrationService = Context.getAdministrationService(); + List locales = administrationService.getAllowedLocales(); + List conceptSearchResults = conceptService.getConcepts(uniqueName, locales, false, null, null, null, null, null, null, null); + if (conceptSearchResults.isEmpty()) + return null; + return getMatchingConcept(conceptSearchResults,uniqueName); + } + + private org.openmrs.Concept getMatchingConcept(List conceptSearchResults, String uniqueName) { + for(ConceptSearchResult conceptSearchResult : conceptSearchResults) { + if (conceptSearchResult.getConcept().getName().toString().equalsIgnoreCase(uniqueName)) { + return conceptSearchResult.getConcept(); + } + } + return null; + } + + private Locale getLocale(String locale) { + if (StringUtils.isEmpty(locale)) { + return Context.getLocale(); + } + + Locale locale1 = LocaleUtility.fromSpecification(locale); + if (!LocaleUtility.isValid(locale1)) { + throw new IllegalArgumentException("The locale " + locale + " is not valid"); + } + return locale1; + } + +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/DrugMetaDataServiceImpl.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/DrugMetaDataServiceImpl.java new file mode 100644 index 0000000000..b023cda42e --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/DrugMetaDataServiceImpl.java @@ -0,0 +1,54 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.bahmni.module.referencedata.labconcepts.service.DrugMetaDataService; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.Drug; +import org.openmrs.api.ConceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class DrugMetaDataServiceImpl implements DrugMetaDataService { + + private final ConceptService conceptService; + + @Autowired + public DrugMetaDataServiceImpl(ConceptService conceptService) { + this.conceptService = conceptService; + } + + @Override + public DrugMetaData getDrugMetaData(org.bahmni.module.referencedata.labconcepts.contract.Drug drug) { + Concept dosageFormConcept = conceptService.getConceptByName(drug.getDosageForm()); + Drug existingDrug = getExistingDrug(drug, dosageFormConcept); + + Concept drugConcept = conceptService.getConceptByName(drug.getGenericName()); + ConceptClass drugConceptClass = conceptService.getConceptClassByUuid(ConceptClass.DRUG_UUID); + return new DrugMetaData(existingDrug, drugConcept, dosageFormConcept, drugConceptClass); + } + + private Drug getExistingDrug(org.bahmni.module.referencedata.labconcepts.contract.Drug drug,Concept dosageFormConcept) { + if (!StringUtils.isBlank(drug.getUuid())) { + return conceptService.getDrugByUuid(drug.getUuid()); + } + + if(dosageFormConcept == null){ + return null; + } + + List drugs = conceptService.getDrugs(drug.getName()); + for(Drug mrsDrug: drugs){ + if(mrsDrug.getStrength().equals(drug.getStrength()) && + mrsDrug.getDosageForm().getConceptId().equals(dosageFormConcept.getConceptId()) && + mrsDrug.getName().equals(drug.getName())){ + return mrsDrug; + } + } + return null; + } +} \ No newline at end of file diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImpl.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImpl.java new file mode 100644 index 0000000000..2a7c4dd598 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImpl.java @@ -0,0 +1,89 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptReferenceTermService; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptMapType; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.ConceptSource; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ReferenceDataConceptReferenceTermServiceImpl implements ReferenceDataConceptReferenceTermService { + + @Autowired + private ConceptService conceptService; + + @Override + public ConceptReferenceTerm getConceptReferenceTerm(String referenceTermCode, String referenceTermSource) { + ConceptSource conceptReferenceSource = conceptService.getConceptSourceByName(referenceTermSource); + ConceptReferenceTerm conceptReferenceTerm = conceptService.getConceptReferenceTermByCode(referenceTermCode, conceptReferenceSource); + validate(conceptReferenceSource, conceptReferenceTerm); + return conceptReferenceTerm; + } + + @Override + public ConceptMap getConceptMap(org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm conceptReferenceTermData) { + ConceptMap conceptMap = null; + if (conceptReferenceTermData != null && hasReferenceTermAndSource(conceptReferenceTermData)) { + ConceptReferenceTerm conceptReferenceTerm = getConceptReferenceTerm(conceptReferenceTermData.getReferenceTermCode(), conceptReferenceTermData.getReferenceTermSource()); + String mapType = conceptReferenceTermData.getReferenceTermRelationship(); + ConceptMapType conceptMapType = conceptService.getConceptMapTypeByName(mapType); + if (conceptMapType == null) { + conceptMapType = conceptService.getConceptMapTypeByUuid(ConceptMapType.SAME_AS_MAP_TYPE_UUID); + } + conceptMap = new ConceptMap(conceptReferenceTerm, conceptMapType); + } + return conceptMap; + } + + @Override + public ConceptReferenceTerm saveOrUpdate(org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm conceptReferenceTerm) { + ConceptReferenceTerm openmrsConceptReferenceTerm = fetchConceptReferenceTerm(conceptReferenceTerm.getReferenceTermSource(), conceptReferenceTerm.getReferenceTermCode()); + if(openmrsConceptReferenceTerm == null) { + ConceptSource conceptSource = conceptService.getConceptSourceByName(conceptReferenceTerm.getReferenceTermSource()); + openmrsConceptReferenceTerm = new ConceptReferenceTerm(conceptSource, conceptReferenceTerm.getReferenceTermCode(), conceptReferenceTerm.getReferenceTermName()); + } else { + openmrsConceptReferenceTerm.setName(conceptReferenceTerm.getReferenceTermName()); + } + openmrsConceptReferenceTerm.setVersion(conceptReferenceTerm.getReferenceVersion()); + openmrsConceptReferenceTerm.setDescription(conceptReferenceTerm.getReferenceDescription()); + return conceptService.saveConceptReferenceTerm(openmrsConceptReferenceTerm); + } + + + private ConceptReferenceTerm fetchConceptReferenceTerm(String referenceTermSource, String referenceTermCode) { + ConceptSource conceptReferenceSource = conceptService.getConceptSourceByName(referenceTermSource); + if(conceptReferenceSource == null) { + throw new APIException(String.format("Concept reference source %s does not exists.", referenceTermSource)); + } + return conceptService.getConceptReferenceTermByCode(referenceTermCode, conceptReferenceSource); + } + + private boolean hasReferenceTermAndSource(org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm conceptReferenceTerm) { + return !(StringUtils.isEmpty(conceptReferenceTerm.getReferenceTermCode()) || StringUtils.isEmpty(conceptReferenceTerm.getReferenceTermSource())); + } + + private void validate(ConceptSource referenceTermSource, ConceptReferenceTerm referenceTerm) { + StringBuilder errors = new StringBuilder(); + if (referenceTermSource == null) { + errors.append("Concept reference source not found\n"); + } + if (referenceTerm == null) { + errors.append("Concept reference term code not found\n"); + } else if (!referenceTerm.getConceptSource().equals(referenceTermSource)) { + errors.append("Concept reference term not mapped to the given source\n"); + } + throwExceptionIfExists(errors); + } + + private void throwExceptionIfExists(StringBuilder errors) { + String message = errors.toString(); + if (!StringUtils.isBlank(message)) { + throw new APIException(message); + } + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptServiceImpl.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptServiceImpl.java new file mode 100644 index 0000000000..2f47da198b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptServiceImpl.java @@ -0,0 +1,130 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptCommon; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.contract.Concepts; +import org.bahmni.module.referencedata.labconcepts.mapper.ConceptMapper; +import org.bahmni.module.referencedata.labconcepts.mapper.ConceptSetMapper; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.bahmni.module.referencedata.labconcepts.service.ConceptMetaDataService; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptReferenceTermService; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.bahmni.module.referencedata.labconcepts.validator.ConceptValidator; +import org.openmrs.ConceptAnswer; +import org.openmrs.ConceptMap; +import org.openmrs.api.ConceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Service +public class ReferenceDataConceptServiceImpl implements ReferenceDataConceptService { + private final ConceptMetaDataService conceptMetaDataService; + private ConceptService conceptService; + private ReferenceDataConceptReferenceTermService referenceDataConceptReferenceTermService; + private ConceptMapper conceptMapper; + private ConceptSetMapper conceptSetMapper; + private final ConceptValidator conceptValidator; + private List notFound; + + @Autowired + public ReferenceDataConceptServiceImpl(ConceptService conceptService, ReferenceDataConceptReferenceTermService referenceDataConceptReferenceTermService, ConceptMetaDataService conceptMetaDataService) { + this.conceptMapper = new ConceptMapper(); + this.conceptSetMapper = new ConceptSetMapper(); + this.conceptService = conceptService; + this.referenceDataConceptReferenceTermService = referenceDataConceptReferenceTermService; + this.conceptMetaDataService = conceptMetaDataService; + conceptValidator = new ConceptValidator(); + + } + + @Override + public org.openmrs.Concept saveConcept(Concept conceptData) { + ConceptMetaData conceptMetaData = conceptMetaDataService.getConceptMetaData(conceptData); + org.openmrs.Concept mappedConcept = getConcept(conceptData, conceptMetaData); + return conceptService.saveConcept(mappedConcept); + } + + + @Override + public org.openmrs.Concept saveConcept(ConceptSet conceptSet) { + ConceptMetaData conceptMetaData = conceptMetaDataService.getConceptMetaData(conceptSet); + org.openmrs.Concept mappedConceptSet = getConceptSet(conceptSet, conceptMetaData); + return conceptService.saveConcept(mappedConceptSet); + } + + + @Override + public Concepts getConcept(String conceptName) { + org.openmrs.Concept concept = conceptService.getConceptByName(conceptName); + if (concept == null) { + return null; + } + Concepts concepts = conceptSetMapper.mapAll(concept); + return concepts; + } + + private org.openmrs.Concept getConceptSet(ConceptSet conceptSet, ConceptMetaData conceptMetaData) { + List setMembers = getSetMembers(conceptSet.getChildren()); + conceptValidator.validate(conceptSet, conceptMetaData.getConceptClass(), conceptMetaData.getConceptDatatype(), notFound); + org.openmrs.Concept mappedConceptSet = conceptSetMapper.map(conceptSet, setMembers,conceptMetaData); + clearAndAddConceptMappings(conceptSet, mappedConceptSet); + return mappedConceptSet; + } + + private org.openmrs.Concept getConcept(Concept conceptData, ConceptMetaData conceptMetaData) { + List conceptAnswers = getConceptAnswers(conceptData.getAnswers()); + conceptValidator.validate(conceptData, conceptMetaData.getConceptClass(), conceptMetaData.getConceptDatatype(), notFound); + org.openmrs.Concept mappedConcept = conceptMapper.map(conceptData, conceptMetaData, conceptAnswers); + clearAndAddConceptMappings(conceptData, mappedConcept); + return mappedConcept; + } + + private void clearAndAddConceptMappings(ConceptCommon conceptData, org.openmrs.Concept mappedConcept) { + Collection conceptMappings = mappedConcept.getConceptMappings(); + conceptMappings.clear(); + mappedConcept.setConceptMappings(conceptMappings); + + for(ConceptReferenceTerm conceptReferenceTerm : conceptData.getConceptReferenceTermsList()) { + conceptMapper.addConceptMap(mappedConcept, referenceDataConceptReferenceTermService.getConceptMap(conceptReferenceTerm)); + } + } + + private List getConceptAnswers(List answers) { + List conceptAnswers = new ArrayList<>(); + notFound = new ArrayList<>(); + if (answers == null) return conceptAnswers; + for (String answer : answers) { + org.openmrs.Concept answerConcept = conceptService.getConceptByName(answer); + if (answerConcept == null) { + notFound.add(answer); + } + conceptAnswers.add(constructConceptAnswer(answerConcept)); + } + return conceptAnswers; + } + + private List getSetMembers(List children) { + List setMembers = new ArrayList<>(); + notFound = new ArrayList<>(); + if (children == null) return setMembers; + for (String child : children) { + org.openmrs.Concept childConcept = conceptService.getConceptByName(child); + if (childConcept == null) { + notFound.add(child); + } + setMembers.add(childConcept); + } + return setMembers; + } + + private ConceptAnswer constructConceptAnswer(org.openmrs.Concept answerConcept) { + ConceptAnswer conceptAnswer = new ConceptAnswer(answerConcept); + return conceptAnswer; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImpl.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImpl.java new file mode 100644 index 0000000000..94e0cc3858 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImpl.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.labconcepts.mapper.DrugMapper; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.bahmni.module.referencedata.labconcepts.service.DrugMetaDataService; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataDrugService; +import org.bahmni.module.referencedata.labconcepts.validator.DrugValidator; +import org.openmrs.Drug; +import org.openmrs.api.ConceptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ReferenceDataDrugServiceImpl implements ReferenceDataDrugService { + + private final DrugValidator drugValidator; + private final ConceptService conceptService; + private final DrugMetaDataService drugMetaDataService; + private DrugMapper drugMapper; + + + @Autowired + public ReferenceDataDrugServiceImpl(ConceptService conceptService, DrugMetaDataService drugMetaDataService) { + drugValidator = new DrugValidator(); + this.conceptService = conceptService; + this.drugMapper = new DrugMapper(); + this.drugMetaDataService = drugMetaDataService; + } + + @Override + public Drug saveDrug(org.bahmni.module.referencedata.labconcepts.contract.Drug drug) { + DrugMetaData drugMetaData = drugMetaDataService.getDrugMetaData(drug); + drugValidator.validate(drug, drugMetaData); + Drug conceptDrug = drugMapper.map(drug, drugMetaData); + return conceptService.saveDrug(conceptDrug); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/ConceptValidator.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/ConceptValidator.java new file mode 100644 index 0000000000..e8351fbde8 --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/ConceptValidator.java @@ -0,0 +1,45 @@ +package org.bahmni.module.referencedata.labconcepts.validator; + +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptCommon; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; + +import java.util.ArrayList; +import java.util.List; + +public class ConceptValidator extends Validator { + + public void validate(Concept conceptData, ConceptClass conceptClassName, ConceptDatatype conceptDatatype, List notFound) { + List errors = validateConceptCommon(conceptData, conceptClassName, conceptDatatype, notFound); + if (conceptDatatype != null && !conceptDatatype.isCoded() && hasAnswers(conceptData)) { + errors.add("Cannot create answers for concept " + conceptData.getUniqueName() + " having datatype " + conceptData.getDataType()); + } + throwExceptionIfExists(errors); + } + + public void validate(ConceptSet conceptSet, ConceptClass conceptClass, ConceptDatatype conceptDatatype, List notFound) { + List errors = validateConceptCommon(conceptSet, conceptClass, conceptDatatype, notFound); + throwExceptionIfExists(errors); + } + + private List validateConceptCommon(ConceptCommon conceptData, ConceptClass conceptClassName, ConceptDatatype conceptDatatype, List notFound) { + List errors = new ArrayList<>(); + if (conceptClassName == null) { + errors.add("Concept Class " + conceptData.getClassName() + " not found"); + } + if (conceptDatatype == null) { + errors.add("Concept Datatype " + conceptData.getDataType() + " not found"); + } + for (String notFoundItem : notFound) { + errors.add(notFoundItem + " Concept/ConceptAnswer not found"); + } + return errors; + } + + + private boolean hasAnswers(Concept conceptData) { + return conceptData.getAnswers() != null && conceptData.getAnswers().size() > 0; + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/DrugMetaDataValidator.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/DrugMetaDataValidator.java new file mode 100644 index 0000000000..92ec0198bf --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/DrugMetaDataValidator.java @@ -0,0 +1,26 @@ +package org.bahmni.module.referencedata.labconcepts.validator; + +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.openmrs.ConceptClass; + +import java.util.ArrayList; +import java.util.List; + +public class DrugMetaDataValidator extends Validator { + public void validate(DrugMetaData drugMetaData) { + List errors = new ArrayList<>(); + if (drugMetaData.getDrugConcept() != null && drugMetaData.getDrugConcept().getConceptClass() !=null && !drugMetaData.getDrugConcept().getConceptClass().getUuid().equals(ConceptClass.DRUG_UUID)) { + errors.add("There is an existing concept linked to the drug, which does not belong to concept class drug"); + } + + if(drugMetaData.getDrugConcept()==null){ + errors.add("There is no concept available with the provided generic name."); + } + + if(drugMetaData.getDosageForm() == null){ + errors.add("There is no concept available with the provided dosage form."); + } + + throwExceptionIfExists(errors); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/DrugValidator.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/DrugValidator.java new file mode 100644 index 0000000000..20f873450e --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/DrugValidator.java @@ -0,0 +1,32 @@ +package org.bahmni.module.referencedata.labconcepts.validator; + +import org.apache.commons.lang3.StringUtils; +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; + +import java.util.ArrayList; +import java.util.List; + +public class DrugValidator extends Validator{ + + private final DrugMetaDataValidator drugMetaDataValidator; + + public DrugValidator() { + drugMetaDataValidator = new DrugMetaDataValidator(); + } + + public void validate(Drug drug, DrugMetaData drugMetaData) { + drugMetaDataValidator.validate(drugMetaData); + List errors = new ArrayList<>(); + if(StringUtils.isNotBlank(drug.getUuid()) && drugMetaData.getExistingDrug() == null){ + errors.add("Drug with provided Uuid does not exist"); + } + if (StringUtils.isBlank(drug.getName())){ + errors.add("Drug name is mandatory"); + } + if (StringUtils.isBlank(drug.getGenericName())){ + errors.add("Drug generic name is mandatory"); + } + throwExceptionIfExists(errors); + } +} diff --git a/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/Validator.java b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/Validator.java new file mode 100644 index 0000000000..f511d2b64b --- /dev/null +++ b/reference-data/api/src/main/java/org/bahmni/module/referencedata/labconcepts/validator/Validator.java @@ -0,0 +1,15 @@ +package org.bahmni.module.referencedata.labconcepts.validator; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.api.APIException; + +import java.util.List; + +public class Validator { + public void throwExceptionIfExists(List errors) { + String message = StringUtils.join(errors, "\n"); + if (!StringUtils.isBlank(message)) { + throw new APIException(message); + } + } +} diff --git a/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ConceptMetaDataServiceImplTest.java b/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ConceptMetaDataServiceImplTest.java new file mode 100644 index 0000000000..9da7298e0d --- /dev/null +++ b/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ConceptMetaDataServiceImplTest.java @@ -0,0 +1,185 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.labconcepts.contract.ConceptCommon; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptName; +import org.openmrs.ConceptSearchResult; +import org.openmrs.api.AdministrationService; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({org.openmrs.util.LocaleUtility.class, Context.class}) +public class ConceptMetaDataServiceImplTest { + + @Mock + ConceptService conceptService; + + @Mock + org.openmrs.ConceptClass conceptClass; + + @Mock + org.openmrs.ConceptDatatype conceptDataType; + + @Mock + AdministrationService administrationService; + + @Mock + Concept concept; + + @InjectMocks + ConceptMetaDataServiceImpl conceptMetaDataService; + + @Before + public void setup(){ + initMocks(this); + PowerMockito.mockStatic(org.openmrs.util.LocaleUtility.class); + PowerMockito.mockStatic(Context.class); + ConceptName conceptName = new ConceptName(); + conceptName.setName("ConceptA"); + when(concept.getName()).thenReturn(conceptName); + } + + @Test + public void testGetConceptMetaDataWhenUuidIsPassed() throws Exception { + ConceptCommon conceptCommon = new ConceptCommon(); + conceptCommon.setClassName("ConceptClass"); + conceptCommon.setDataType("N/A"); + conceptCommon.setLocale("en"); + conceptCommon.setUniqueName("ConceptA"); + conceptCommon.setUuid("123"); + + when(conceptService.getConceptClassByName("ConceptClass")).thenReturn(conceptClass); + when(conceptService.getConceptDatatypeByName("N/A")).thenReturn(conceptDataType); + when(conceptService.getConceptByUuid("123")).thenReturn(concept); + Locale locale = new Locale("en"); + when(org.openmrs.util.LocaleUtility.fromSpecification("en")).thenReturn(locale); + when(org.openmrs.util.LocaleUtility.isValid(locale)).thenReturn(true); + + ConceptMetaData conceptMetadata = conceptMetaDataService.getConceptMetaData(conceptCommon); + + Assert.assertEquals(concept, conceptMetadata.getExistingConcept()); + Assert.assertEquals(conceptClass, conceptMetadata.getConceptClass()); + Assert.assertEquals(conceptDataType, conceptMetadata.getConceptDatatype()); + + } + + @Test + public void testGetConceptMetaDataWhenLocaleIsPassedAndThereAreNoResults() throws Exception { + ConceptCommon conceptCommon = new ConceptCommon(); + + conceptCommon.setClassName("ConceptClass"); + conceptCommon.setDataType("N/A"); + conceptCommon.setUniqueName("ConceptA"); + conceptCommon.setLocale("en"); + + List locales = new ArrayList<>(); + + when(Context.getAdministrationService()).thenReturn(administrationService); + when(conceptService.getConceptClassByName("ConceptClass")).thenReturn(conceptClass); + when(conceptService.getConceptDatatypeByName("N/A")).thenReturn(conceptDataType); + when(administrationService.getAllowedLocales()).thenReturn(locales); + Locale locale = new Locale("en"); + when(org.openmrs.util.LocaleUtility.fromSpecification("en")).thenReturn(locale); + when(org.openmrs.util.LocaleUtility.isValid(locale)).thenReturn(true); + + ConceptMetaData conceptMetadata = conceptMetaDataService.getConceptMetaData(conceptCommon); + + Assert.assertNull(conceptMetadata.getExistingConcept()); + Assert.assertEquals(conceptClass, conceptMetadata.getConceptClass()); + Assert.assertEquals(conceptDataType, conceptMetadata.getConceptDatatype()); + } + + @Test + public void testGetConceptMetaDataWhenLocaleIsNotPassed() throws Exception { + ConceptCommon conceptCommon = new ConceptCommon(); + conceptCommon.setClassName("ConceptClass"); + conceptCommon.setDataType("N/A"); + conceptCommon.setUniqueName("ConceptA"); + + List locales = new ArrayList<>(); + List conceptSearchResults = new ArrayList<>(); + ConceptSearchResult conceptSearchResult = new ConceptSearchResult(); + conceptSearchResult.setConcept(concept); + conceptSearchResults.add(conceptSearchResult); + + when(Context.getAdministrationService()).thenReturn(administrationService); + when(conceptService.getConceptClassByName("ConceptClass")).thenReturn(conceptClass); + when(conceptService.getConceptDatatypeByName("N/A")).thenReturn(conceptDataType); + when(administrationService.getAllowedLocales()).thenReturn(locales); + when(conceptService.getConcepts("ConceptA", locales, false, null, null, null, null, null, null, null)).thenReturn(conceptSearchResults); + + + ConceptMetaData conceptMetadata = conceptMetaDataService.getConceptMetaData(conceptCommon); + + Assert.assertEquals(concept, conceptMetadata.getExistingConcept()); + Assert.assertEquals(conceptClass, conceptMetadata.getConceptClass()); + Assert.assertEquals(conceptDataType, conceptMetadata.getConceptDatatype()); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetConceptMetaDataWhenLocaleIsInvalid() { + ConceptCommon conceptCommon = new ConceptCommon(); + conceptCommon.setUniqueName("ConceptA"); + conceptCommon.setLocale("en"); + + List locales = new ArrayList<>(); + List conceptSearchResults = new ArrayList<>(); + ConceptSearchResult conceptSearchResult = new ConceptSearchResult(); + conceptSearchResult.setConcept(concept); + conceptSearchResults.add(conceptSearchResult); + + Locale locale = new Locale("en"); + when(Context.getAdministrationService()).thenReturn(administrationService); + when(org.openmrs.util.LocaleUtility.fromSpecification("en")).thenReturn(locale); + when(org.openmrs.util.LocaleUtility.isValid(locale)).thenReturn(false); + when(administrationService.getAllowedLocales()).thenReturn(locales); + when(conceptService.getConcepts("ConceptA", locales, false, null, null, null, null, null, null, null)).thenReturn(conceptSearchResults); + + conceptMetaDataService.getConceptMetaData(conceptCommon); + } + + @Test + public void testGetConceptMetaDataWhenLocaleIsPassed() throws Exception { + ConceptCommon conceptCommon = new ConceptCommon(); + conceptCommon.setUniqueName("ConceptA"); + conceptCommon.setLocale("en"); + + List conceptSearchResults = new ArrayList<>(); + ConceptSearchResult conceptSearchResult = new ConceptSearchResult(); + conceptSearchResult.setConcept(concept); + conceptSearchResults.add(conceptSearchResult); + + + List locales = new ArrayList<>(); + Locale locale = new Locale("en"); + + when(Context.getAdministrationService()).thenReturn(administrationService); + when(org.openmrs.util.LocaleUtility.fromSpecification("en")).thenReturn(locale); + when(org.openmrs.util.LocaleUtility.isValid(locale)).thenReturn(true); + when(administrationService.getAllowedLocales()).thenReturn(locales); + when(conceptService.getConcepts("ConceptA", locales, false, null, null, null, null, null, null, null)).thenReturn(conceptSearchResults); + + + ConceptMetaData conceptMetadata = conceptMetaDataService.getConceptMetaData(conceptCommon); + + Assert.assertEquals(concept, conceptMetadata.getExistingConcept()); + } +} diff --git a/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/DrugMetaDataServiceImplTest.java b/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/DrugMetaDataServiceImplTest.java new file mode 100644 index 0000000000..3a55d302c6 --- /dev/null +++ b/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/DrugMetaDataServiceImplTest.java @@ -0,0 +1,116 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.api.ConceptService; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +public class DrugMetaDataServiceImplTest { + + @Mock + ConceptService conceptService; + + private static Integer DRUG_CONCEPT = 1; + private static Integer DOSAGE_FORM_CONCEPT = 2; + + @Before + public void setup() { + initMocks(this); + } + + @Test + public void ensureDrugMetadataIsProperWithAllValid(){ + Drug drug = new Drug(); + drug.setUuid("uuid"); + drug.setGenericName("genericName"); + drug.setDosageForm("dosageForm"); + + org.openmrs.Drug drugInDb1 = new org.openmrs.Drug(); + drugInDb1.setUuid("uuid"); + + org.openmrs.Drug drugInDb2 = new org.openmrs.Drug(); + drugInDb2.setUuid("uuid"); + + org.openmrs.Drug mrsDrug = new org.openmrs.Drug(1234); + + when(conceptService.getConceptByName("genericName")).thenReturn(new Concept(DRUG_CONCEPT)); + when(conceptService.getConceptByName("dosageForm")).thenReturn(new Concept(DOSAGE_FORM_CONCEPT)); + when(conceptService.getDrugByUuid("uuid")).thenReturn(mrsDrug); + when(conceptService.getConceptClassByUuid(ConceptClass.DRUG_UUID)).thenReturn(null); + when(conceptService.getConceptDatatypeByUuid(ConceptDatatype.N_A_UUID)).thenReturn(null); + + DrugMetaDataServiceImpl drugMetaDataService = new DrugMetaDataServiceImpl(conceptService); + DrugMetaData drugMetaData = drugMetaDataService.getDrugMetaData(drug); + + assertNotNull(drugMetaData); + assertNotNull(drugMetaData.getExistingDrug()); + assertEquals(DOSAGE_FORM_CONCEPT, drugMetaData.getDosageForm().getId()); + assertEquals(DRUG_CONCEPT,drugMetaData.getDrugConcept().getId()); + + } + + @Test + public void existingDrugIsNullWhenUuidIsInvalid(){ + Drug drug = new Drug(); + drug.setUuid("uuid"); + drug.setGenericName("genericName"); + drug.setDosageForm("dosageForm"); + + org.openmrs.Drug drugInDb1 = new org.openmrs.Drug(); + drugInDb1.setUuid("uuid"); + + org.openmrs.Drug drugInDb2 = new org.openmrs.Drug(); + drugInDb2.setUuid("uuid"); + + new org.openmrs.Drug(1234); + + when(conceptService.getConceptByName("genericName")).thenReturn(new Concept(DRUG_CONCEPT)); + when(conceptService.getConceptByName("dosageForm")).thenReturn(null); + when(conceptService.getDrugByUuid("uuid")).thenReturn(null); + when(conceptService.getConceptClassByUuid(ConceptClass.DRUG_UUID)).thenReturn(null); + when(conceptService.getConceptDatatypeByUuid(ConceptDatatype.N_A_UUID)).thenReturn(null); + + DrugMetaDataServiceImpl drugMetaDataService = new DrugMetaDataServiceImpl(conceptService); + DrugMetaData drugMetaData = drugMetaDataService.getDrugMetaData(drug); + + assertNotNull(drugMetaData); + assertNull(drugMetaData.getExistingDrug()); + assertEquals(DRUG_CONCEPT,drugMetaData.getDrugConcept().getId()); + } + + @Test + public void newDrugWithInvalidDosageForm(){ + Drug drug = new Drug(); + drug.setGenericName("genericName"); + drug.setDosageForm("dosageForm"); + + new org.openmrs.Drug(1234); + + when(conceptService.getConceptByName("genericName")).thenReturn(new Concept(DRUG_CONCEPT)); + when(conceptService.getConceptByName("dosageForm")).thenReturn(null); + when(conceptService.getDrugByUuid("uuid")).thenReturn(null); + when(conceptService.getConceptClassByUuid(ConceptClass.DRUG_UUID)).thenReturn(null); + when(conceptService.getConceptDatatypeByUuid(ConceptDatatype.N_A_UUID)).thenReturn(null); + + DrugMetaDataServiceImpl drugMetaDataService = new DrugMetaDataServiceImpl(conceptService); + DrugMetaData drugMetaData = drugMetaDataService.getDrugMetaData(drug); + + assertNotNull(drugMetaData); + assertNull(drugMetaData.getExistingDrug()); + assertNull(drugMetaData.getDosageForm()); + assertEquals(DRUG_CONCEPT,drugMetaData.getDrugConcept().getId()); + } + + +} diff --git a/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/validator/DrugMetaDataValidatorTest.java b/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/validator/DrugMetaDataValidatorTest.java new file mode 100644 index 0000000000..084f3b643c --- /dev/null +++ b/reference-data/api/src/test/java/org/bahmni/module/referencedata/labconcepts/validator/DrugMetaDataValidatorTest.java @@ -0,0 +1,36 @@ +package org.bahmni.module.referencedata.labconcepts.validator; + +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.Drug; +import org.openmrs.api.APIException; + +public class DrugMetaDataValidatorTest { + + @Test(expected = APIException.class) + public void ensureDrugConceptIsNotNull() { + DrugMetaData drugMetaData = new DrugMetaData(new Drug(), null, new Concept(), new ConceptClass()); + DrugMetaDataValidator validator = new DrugMetaDataValidator(); + validator.validate(drugMetaData); + } + + @Test(expected = APIException.class) + public void ensureDosageFormIsNotNull(){ + DrugMetaData drugMetaData = new DrugMetaData(new Drug(),new Concept(), null, new ConceptClass()); + DrugMetaDataValidator validator = new DrugMetaDataValidator(); + validator.validate(drugMetaData); + } + + @Test + public void ensureDosageFormAndDrugConceptValid(){ + DrugMetaData drugMetaData = new DrugMetaData(new Drug(),new Concept(), new Concept(), new ConceptClass()); + DrugMetaDataValidator validator = new DrugMetaDataValidator(); + validator.validate(drugMetaData); + //No error + + } + + +} diff --git a/reference-data/omod/pom.xml b/reference-data/omod/pom.xml new file mode 100644 index 0000000000..3d7a3df678 --- /dev/null +++ b/reference-data/omod/pom.xml @@ -0,0 +1,267 @@ + + + + reference-data + org.bahmni.module + 1.2.0-SNAPSHOT + + 4.0.0 + + ${project.parent.artifactId}-omod + Reference Data Omod + + + + org.openmrs.module + webservices.rest-omod + provided + + + org.openmrs.api + openmrs-api + jar + + + org.openmrs.web + openmrs-web + jar + + + javax.servlet + servlet-api + + + + + org.openmrs.api + openmrs-api + test-jar + test + + + org.openmrs.web + openmrs-web + test-jar + test + + + org.openmrs.test + openmrs-test + pom + test + + + org.ict4h.openmrs + openmrs-atomfeed-common + ${openmrsAtomfeedVersion} + provided + + + org.ict4h.openmrs + openmrs-atomfeed-omod + ${openmrsAtomfeedVersion} + provided + + + org.ict4h.openmrs + openmrs-atomfeed-api + ${openmrsAtomfeedVersion} + provided + + + org.ict4h + atomfeed-server + ${atomfeed.version} + provided + + + org.ict4h + atomfeed-commons + ${atomfeed.version} + provided + + + ${project.parent.groupId} + ${project.parent.artifactId}-api + ${project.parent.version} + + + org.openmrs.module + emrapi-api + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-1.12 + ${emrapi-omod.version} + + + org.openmrs.module + emrapi-api-2.2 + ${emrapi-omod.version} + + + org.openmrs.module + reporting-api + test + + + org.openmrs.module + calculation-api + test + + + org.openmrs.module + serialization.xstream-api-2.0 + test + + + org.openmrs.module + providermanagement-api + test + + + org.apache.httpcomponents + httpclient + 4.2.5 + test + + + org.bahmni.test + bahmni-test-commons + ${project.parent.version} + test-jar + test + + + org.openmrs.module + addresshierarchy-api + ${addressHierarchyVersion} + + + org.openmrs.module + addresshierarchy-omod + ${addressHierarchyVersion} + + + org.openmrs.module + legacyui-omod + + + javax.servlet + javax.servlet-api + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + test + + + + + ${project.parent.artifactId}-${project.parent.version} + + + src/main/resources + true + + + + + src/test/resources + true + + + + + + maven-resources-plugin + + true + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.5.201505241946 + + + check + + report + check + + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.14 + + + BRANCH + COVEREDRATIO + 0.13 + + + + + + + + + + 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 + + + + + + + + + diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/addresshierarchy/AddressHierarchyEntryEventInterceptor.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/addresshierarchy/AddressHierarchyEntryEventInterceptor.java new file mode 100644 index 0000000000..13db333ac7 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/addresshierarchy/AddressHierarchyEntryEventInterceptor.java @@ -0,0 +1,86 @@ +package org.bahmni.module.referencedata.addresshierarchy; + +import org.ict4h.atomfeed.server.repository.AllEventRecordsQueue; +import org.ict4h.atomfeed.server.repository.jdbc.AllEventRecordsQueueJdbcImpl; +import org.ict4h.atomfeed.server.service.Event; +import org.ict4h.atomfeed.server.service.EventService; +import org.ict4h.atomfeed.server.service.EventServiceImpl; +import org.ict4h.atomfeed.transaction.AFTransactionWorkWithoutResult; +import java.time.LocalDateTime; +import org.openmrs.api.context.Context; +import org.openmrs.module.addresshierarchy.AddressHierarchyEntry; +import org.openmrs.module.atomfeed.transaction.support.AtomFeedSpringTransactionManager; +import org.springframework.aop.AfterReturningAdvice; +import org.springframework.transaction.PlatformTransactionManager; + +import java.lang.reflect.Method; +import java.net.URI; +import java.util.List; +import java.util.UUID; + +import static java.util.Arrays.asList; + +public class AddressHierarchyEntryEventInterceptor implements AfterReturningAdvice { + + private final AtomFeedSpringTransactionManager atomFeedSpringTransactionManager; + private final EventService eventService; + + private static final List SAVE_ADDRESS_HIERARCY_ENTRY_METHODS = asList("saveAddressHierarchyEntries", "saveAddressHierarchyEntry"); + private static final String TEMPLATE = "/openmrs/ws/rest/v1/addressHierarchy/%s"; + private static final String CATEGORY = "addressHierarchy"; + private static final String TITLE = "addressHierarchy"; + + public AddressHierarchyEntryEventInterceptor() { + atomFeedSpringTransactionManager = new AtomFeedSpringTransactionManager(getSpringPlatformTransactionManager()); + AllEventRecordsQueue allEventRecordsQueue = new AllEventRecordsQueueJdbcImpl(atomFeedSpringTransactionManager); + this.eventService = new EventServiceImpl(allEventRecordsQueue); + } + + @Override + public void afterReturning(Object returnValue, Method method, Object[] arguments, Object target) throws Exception { + if (SAVE_ADDRESS_HIERARCY_ENTRY_METHODS.contains(method.getName())) { + createEvents(arguments); + } + } + + private void createEvents(Object[] arguments) { + if (arguments == null) { + return; + } + if (arguments[0] instanceof List) { + List entries = (List) arguments[0]; + for (AddressHierarchyEntry entry : entries) { + createAndNotifyEvent(entry); + } + return; + } + createAndNotifyEvent((AddressHierarchyEntry) arguments[0]); + } + + private void createAndNotifyEvent(AddressHierarchyEntry entry) { + if (entry == null) { + return; + } + String contents = String.format(TEMPLATE, entry.getUuid()); + final Event event = new Event(UUID.randomUUID().toString(), TITLE, LocalDateTime.now(), (URI) null, contents, CATEGORY); + + atomFeedSpringTransactionManager.executeWithTransaction( + new AFTransactionWorkWithoutResult() { + @Override + protected void doInTransaction() { + eventService.notify(event); + } + + @Override + public PropagationDefinition getTxPropagationDefinition() { + return PropagationDefinition.PROPAGATION_REQUIRED; + } + } + ); + } + + private PlatformTransactionManager getSpringPlatformTransactionManager() { + List platformTransactionManagers = Context.getRegisteredComponents(PlatformTransactionManager.class); + return platformTransactionManagers.get(0); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptor.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptor.java new file mode 100644 index 0000000000..b31f966e2a --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptor.java @@ -0,0 +1,71 @@ +package org.bahmni.module.referencedata.labconcepts.advice; + +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.ict4h.atomfeed.server.repository.AllEventRecordsQueue; +import org.ict4h.atomfeed.server.repository.jdbc.AllEventRecordsQueueJdbcImpl; +import org.ict4h.atomfeed.server.service.Event; +import org.ict4h.atomfeed.server.service.EventService; +import org.ict4h.atomfeed.server.service.EventServiceImpl; +import org.ict4h.atomfeed.transaction.AFTransactionWorkWithoutResult; +import org.openmrs.api.context.Context; +import org.openmrs.module.atomfeed.transaction.support.AtomFeedSpringTransactionManager; +import org.springframework.aop.AfterReturningAdvice; +import org.springframework.transaction.PlatformTransactionManager; + +import java.lang.reflect.Method; +import java.util.List; + +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; + +public class ConceptServiceEventInterceptor implements AfterReturningAdvice { + private AtomFeedSpringTransactionManager atomFeedSpringTransactionManager; + private EventService eventService; + + public ConceptServiceEventInterceptor() { + atomFeedSpringTransactionManager = createTransactionManager(); + this.eventService = createService(atomFeedSpringTransactionManager); + } + + public ConceptServiceEventInterceptor(AtomFeedSpringTransactionManager atomFeedSpringTransactionManager, EventService eventService) { + this.atomFeedSpringTransactionManager = atomFeedSpringTransactionManager; + this.eventService = eventService; + } + + private AtomFeedSpringTransactionManager createTransactionManager() { + PlatformTransactionManager platformTransactionManager = getSpringPlatformTransactionManager(); + return new AtomFeedSpringTransactionManager(platformTransactionManager); + } + + private EventServiceImpl createService(AtomFeedSpringTransactionManager atomFeedSpringTransactionManager) { + AllEventRecordsQueue allEventRecordsQueue = new AllEventRecordsQueueJdbcImpl(atomFeedSpringTransactionManager); + return new EventServiceImpl(allEventRecordsQueue); + } + + @Override + public void afterReturning(Object returnValue, Method method, Object[] arguments, Object conceptService) throws Throwable { + Operation operation = new Operation(method); + final List events = operation.apply(arguments); + if (isNotEmpty(events)) { + atomFeedSpringTransactionManager.executeWithTransaction( + new AFTransactionWorkWithoutResult() { + @Override + protected void doInTransaction() { + for (Event event : events) { + eventService.notify(event); + } + } + + @Override + public PropagationDefinition getTxPropagationDefinition() { + return PropagationDefinition.PROPAGATION_REQUIRED; + } + } + ); + } + } + + private PlatformTransactionManager getSpringPlatformTransactionManager() { + List platformTransactionManagers = Context.getRegisteredComponents(PlatformTransactionManager.class); + return platformTransactionManagers.get(0); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/Operation.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/Operation.java new file mode 100644 index 0000000000..a7ef51a32b --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/Operation.java @@ -0,0 +1,50 @@ +package org.bahmni.module.referencedata.labconcepts.model; + +import org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceOperationEvent; +import org.ict4h.atomfeed.server.service.Event; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.apache.commons.collections.CollectionUtils.addIgnoreNull; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.allTestsAndPanelsConceptSetEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.departmentEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.drugEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.labConceptSetEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.panelEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.radiologyTestEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.sampleEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.testEvent; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.saleableTypeEvent; + +public class Operation { + + private String name; + private static final List events = asList( + sampleEvent(), + departmentEvent(), + testEvent(), + panelEvent(), + labConceptSetEvent(), + allTestsAndPanelsConceptSetEvent(), + drugEvent(), + radiologyTestEvent(), + saleableTypeEvent() + ); + + public Operation(Method method) { + this.name = method.getName(); + } + + public List apply(Object[] arguments) throws Exception { + List atomFeedEvents = new ArrayList<>(); + for (ConceptServiceOperationEvent event : events) { + if (event.isApplicable(name, arguments)) { + addIgnoreNull(atomFeedEvents, event.asAtomFeedEvent(arguments)); + } + } + return atomFeedEvents; + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/AllLabSamplesEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/AllLabSamplesEvent.java new file mode 100644 index 0000000000..ae22db4ec5 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/AllLabSamplesEvent.java @@ -0,0 +1,22 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.openmrs.Concept; +import org.openmrs.api.context.Context; + +public class AllLabSamplesEvent extends ConceptOperationEvent { + + public AllLabSamplesEvent(String conceptUrl, String labCategory, String title) { + super(conceptUrl, labCategory, title); + } + + @Override + public boolean isResourceConcept(Concept concept) { + return isLabSamplesConcept(concept); + } + + + private boolean isLabSamplesConcept(Concept concept) { + return concept.getName(Context.getLocale()) != null && concept.getName(Context.getLocale()).getName().equals(AllSamples.ALL_SAMPLES); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEvent.java new file mode 100644 index 0000000000..eb72b4c325 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEvent.java @@ -0,0 +1,24 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.openmrs.Concept; +import org.openmrs.api.context.Context; + +public class AllTestsPanelsConceptSetEvent extends ConceptOperationEvent { + + + public AllTestsPanelsConceptSetEvent(String url, String category, String title) { + super(url, category, title); + } + + @Override + public boolean isResourceConcept(Concept concept) { + return isAllTestAndPanelConcept(concept); + } + + private boolean isAllTestAndPanelConcept(Concept concept) { + return concept.getName(Context.getLocale()) != null && + concept.getName(Context.getLocale()).getName().equals(AllTestsAndPanels.ALL_TESTS_AND_PANELS); + } + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptOperationEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptOperationEvent.java new file mode 100644 index 0000000000..beebde3e2f --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptOperationEvent.java @@ -0,0 +1,58 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.ict4h.atomfeed.server.service.Event; +import java.time.LocalDateTime; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.context.Context; + +import java.net.URISyntaxException; +import java.util.List; +import java.util.UUID; + +import static java.util.Arrays.asList; + +public abstract class ConceptOperationEvent implements ConceptServiceOperationEvent { + protected String url; + protected String category; + protected String title; + + public ConceptOperationEvent(String url, String category, String title) { + this.url = url; + this.category = category; + this.title = title; + } + + public ConceptOperationEvent() { + } + + public abstract boolean isResourceConcept(Concept argument); + + @Override + public Boolean isApplicable(String operation, Object[] arguments) { + return this.operations().contains(operation) && isResourceConcept((Concept) arguments[0]); + } + + + private List operations() { + return asList("saveConcept", "updateConcept", "retireConcept", "purgeConcept"); + } + + @Override + public Event asAtomFeedEvent(Object[] arguments) throws URISyntaxException { + Concept concept = (Concept) arguments[0]; + String url = String.format(this.url, title, concept.getUuid()); + return new Event(UUID.randomUUID().toString(), title, LocalDateTime.now(), url, url, category); + } + + public static boolean isChildOf(Concept concept, String parentConceptName) { + List conceptSets = Context.getConceptService().getSetsContainingConcept(concept); + if (conceptSets == null) return false; + for (ConceptSet conceptSet : conceptSets) { + if (conceptSet.getConceptSet().getName(Context.getLocale()).getName().equals(parentConceptName)) { + return true; + } + } + return false; + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptServiceEventFactory.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptServiceEventFactory.java new file mode 100644 index 0000000000..b979f61cc8 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptServiceEventFactory.java @@ -0,0 +1,46 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +public class ConceptServiceEventFactory { + public static final String CONCEPT_URL = "/openmrs/ws/rest/v1/reference-data/%s/%s"; + public static final String LAB = "lab"; + public static final String LAB_SAMPLE = "all-samples"; + public static final String SAMPLE = "sample"; + public static final String DEPARTMENT = "department"; + public static final String TEST = "test"; + public static final String PANEL = "panel"; + public static final String TESTS_AND_PANEL = "all-tests-and-panels"; + public static final String DRUG = "drug"; + public static final String RADIOLOGY = "radiology"; + public static final String SALEABLE = "saleable"; + + public static ConceptServiceOperationEvent sampleEvent() { + return new SampleEvent(CONCEPT_URL, LAB, SAMPLE); + } + + public static ConceptServiceOperationEvent labConceptSetEvent() { return new AllLabSamplesEvent(CONCEPT_URL, LAB, LAB_SAMPLE); } + + public static ConceptServiceOperationEvent allTestsAndPanelsConceptSetEvent() { return new AllTestsPanelsConceptSetEvent(CONCEPT_URL, LAB, TESTS_AND_PANEL); } + + public static ConceptServiceOperationEvent departmentEvent() { + return new DepartmentEvent(CONCEPT_URL, LAB, DEPARTMENT); + } + + public static ConceptServiceOperationEvent panelEvent() { + return new PanelEvent(CONCEPT_URL, LAB, PANEL); + } + + public static ConceptServiceOperationEvent testEvent() { + return new LabTestEvent(CONCEPT_URL, LAB, TEST); + } + + public static ConceptServiceOperationEvent drugEvent() { + return new DrugEvent(CONCEPT_URL, DRUG, DRUG); + } + public static ConceptServiceOperationEvent radiologyTestEvent() { + return new RadiologyTestEvent(CONCEPT_URL, LAB, RADIOLOGY); + } + + public static ConceptServiceOperationEvent saleableTypeEvent() { + return new SaleableTypeEvent(CONCEPT_URL, SALEABLE); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptServiceOperationEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptServiceOperationEvent.java new file mode 100644 index 0000000000..d3ec128025 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptServiceOperationEvent.java @@ -0,0 +1,10 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.ict4h.atomfeed.server.service.Event; + +import java.net.URISyntaxException; + +public interface ConceptServiceOperationEvent { + public Event asAtomFeedEvent(Object[] arguments) throws URISyntaxException; + public Boolean isApplicable(String operation, Object[] arguments); +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/DepartmentEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/DepartmentEvent.java new file mode 100644 index 0000000000..b5f61f6ebd --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/DepartmentEvent.java @@ -0,0 +1,19 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.openmrs.Concept; + +import static org.bahmni.module.referencedata.labconcepts.contract.Department.DEPARTMENT_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClass; + +public class DepartmentEvent extends ConceptOperationEvent { + + public DepartmentEvent(String url, String category, String title) { + super(url, category, title); + } + + @Override + public boolean isResourceConcept(Concept concept) { + return isOfConceptClass(concept, DEPARTMENT_CONCEPT_CLASS); + } + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/DrugEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/DrugEvent.java new file mode 100644 index 0000000000..c1d9813797 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/DrugEvent.java @@ -0,0 +1,48 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.ict4h.atomfeed.server.service.Event; +import java.time.LocalDateTime; +import org.openmrs.Drug; + +import java.net.URISyntaxException; +import java.util.List; +import java.util.UUID; + +import static java.util.Arrays.asList; + +public class DrugEvent implements ConceptServiceOperationEvent { + protected String url; + protected String category; + protected String title; + + public DrugEvent(String url, String category, String title) { + this.url = url; + this.category = category; + this.title = title; + } + + public DrugEvent() { + } + + + List operations() { + return asList("saveDrug", "purgeDrug"); + } + + private boolean isValid(Object[] arguments) { + return arguments != null && arguments.length > 0; + } + + @Override + public Boolean isApplicable(String operation, Object[] arguments) { + return this.operations().contains(operation) && isValid(arguments) && arguments[0] instanceof Drug; + } + + @Override + public Event asAtomFeedEvent(Object[] arguments) throws URISyntaxException { + Drug drug = (Drug) arguments[0]; + String url = String.format(this.url, title, drug.getUuid()); + return new Event(UUID.randomUUID().toString(), title, LocalDateTime.now(), url, url, category); + } + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java new file mode 100644 index 0000000000..06926f13d2 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEvent.java @@ -0,0 +1,48 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.helper.ConceptHelper; +import org.ict4h.atomfeed.server.service.Event; +import java.time.LocalDateTime; +import org.openmrs.Concept; +import org.openmrs.api.context.Context; + +import java.net.URISyntaxException; +import java.util.List; +import java.util.UUID; + +import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfAnyConceptClass; + +public class LabTestEvent extends ConceptOperationEvent { + + public LabTestEvent(String url, String category, String title) { + super(url, category, title); + } + + public boolean isResourceConcept(Concept concept) { + return isOfAnyConceptClass(concept, LAB_TEST_CONCEPT_CLASSES) || (getParentOfTypeLabTest(concept) != null); + } + + private Concept getParentOfTypeLabTest(Concept concept) { + ConceptHelper conceptHelper = new ConceptHelper(Context.getConceptService()); + List parentConcepts = conceptHelper.getParentConcepts(concept); + for (Concept parentConcept : parentConcepts) { + if (isOfAnyConceptClass(parentConcept, LAB_TEST_CONCEPT_CLASSES)) { + return parentConcept; + } + } + return null; + } + + @Override + public Event asAtomFeedEvent(Object[] arguments) throws URISyntaxException { + Concept concept = (Concept) arguments[0]; + if (!isOfAnyConceptClass(concept, LAB_TEST_CONCEPT_CLASSES)) { + concept = getParentOfTypeLabTest(concept); + } + String url = String.format(this.url, title, concept.getUuid()); + return new Event(UUID.randomUUID().toString(), title, LocalDateTime.now(), url, url, category); + } + + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/PanelEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/PanelEvent.java new file mode 100644 index 0000000000..8c0c5dc775 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/PanelEvent.java @@ -0,0 +1,19 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.openmrs.Concept; +import org.openmrs.ConceptClass; + +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClassByUUID; + +public class PanelEvent extends ConceptOperationEvent { + + public PanelEvent(String url, String category, String title) { + super(url, category, title); + } + + @Override + public boolean isResourceConcept(Concept concept) { + return isOfConceptClassByUUID(concept, ConceptClass.LABSET_UUID); + } + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java new file mode 100644 index 0000000000..2f98ab8207 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEvent.java @@ -0,0 +1,21 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.openmrs.Concept; + +import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfAnyConceptClass; + +public class RadiologyTestEvent extends ConceptOperationEvent { + + public RadiologyTestEvent(String url, String category, String title) { + super(url, category, title); + } + + + @Override + public boolean isResourceConcept(Concept concept) { + return isOfAnyConceptClass(concept, RADIOLOGY_TEST_CONCEPT_CLASSES); + } + + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java new file mode 100644 index 0000000000..6f884a6cd7 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEvent.java @@ -0,0 +1,76 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.ict4h.atomfeed.server.service.Event; +import java.time.LocalDateTime; +import org.openmrs.Concept; +import org.openmrs.ConceptAttribute; +import org.openmrs.ConceptName; +import org.openmrs.api.context.Context; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.*; + +import static org.bahmni.module.referencedata.labconcepts.contract.AllSamples.ALL_SAMPLES; +import static org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels.ALL_TESTS_AND_PANELS; +import static org.bahmni.module.referencedata.labconcepts.contract.Department.DEPARTMENT_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.contract.LabTest.LAB_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.contract.Panel.LAB_SET_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES; +import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; + +public class SaleableTypeEvent implements ConceptServiceOperationEvent { + + public static final String RESOURCE_TITLE = "reference data"; + public static final String SALEABLE_ATTR_NAME = "saleable"; + public static final String RESOURCES = "resources"; + private final String url; + private final String category; + private List supportedOperations = Arrays.asList("saveConcept", "updateConcept", "retireConcept", "purgeConcept"); + + private List unhandledClasses = new ArrayList(){{ + addAll(Arrays.asList(LAB_SET_CONCEPT_CLASS, SAMPLE_CONCEPT_CLASS, DEPARTMENT_CONCEPT_CLASS)); + addAll(LAB_TEST_CONCEPT_CLASSES); + addAll(RADIOLOGY_TEST_CONCEPT_CLASSES); + }}; + private List unhandledConcepsByName = Arrays.asList(ALL_SAMPLES, ALL_TESTS_AND_PANELS); + + public SaleableTypeEvent(String url, String category) { + this.url = url; + this.category = category; + } + + @Override + public Event asAtomFeedEvent(Object[] arguments) throws URISyntaxException { + Concept concept = (Concept) arguments[0]; + String url = String.format(this.url, RESOURCES, concept.getUuid()); + return new Event(UUID.randomUUID().toString(), RESOURCE_TITLE, LocalDateTime.now(), new URI(url), url, this.category); + } + + @Override + public Boolean isApplicable(String operation, Object[] arguments) { + if (supportedOperations.contains(operation) + && arguments.length > 0 && arguments[0] instanceof Concept) { + Concept concept = (Concept) arguments[0]; + if (!shouldRaiseEvent(concept)) { + return false; + } + Collection activeAttributes = concept.getActiveAttributes(); + return activeAttributes.stream().filter(a -> a.getAttributeType().getName().equalsIgnoreCase(SALEABLE_ATTR_NAME)).findFirst().isPresent(); + } + return false; + } + + private boolean shouldRaiseEvent(Concept concept) { + boolean result = unhandledClasses.stream().anyMatch(concept.getConceptClass().getName()::equalsIgnoreCase); + if (result) { + return false; + } + ConceptName conceptName = concept.getName(Context.getLocale()); + if (conceptName != null) { + return !unhandledConcepsByName.stream().anyMatch(conceptName.getName()::equalsIgnoreCase); + } + + return true; + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java new file mode 100644 index 0000000000..1191423631 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEvent.java @@ -0,0 +1,21 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.openmrs.Concept; + +import static org.bahmni.module.referencedata.labconcepts.contract.Sample.SAMPLE_CONCEPT_CLASS; +import static org.bahmni.module.referencedata.labconcepts.mapper.ConceptExtension.isOfConceptClass; + +public class SampleEvent extends ConceptOperationEvent { + + public SampleEvent(String url, String category, String title) { + super(url, category, title); + } + + + @Override + public boolean isResourceConcept(Concept concept) { + return isOfConceptClass(concept, SAMPLE_CONCEPT_CLASS); + } + + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/AllSamplesController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/AllSamplesController.java new file mode 100644 index 0000000000..53bfae9951 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/AllSamplesController.java @@ -0,0 +1,38 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.mapper.AllSamplesMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/all-samples") +public class AllSamplesController extends BaseRestController { + private ConceptService conceptService; + private final AllSamplesMapper allSamplesMapper; + + @Autowired + public AllSamplesController(ConceptService conceptService) { + this.conceptService = conceptService; + this.allSamplesMapper = new AllSamplesMapper(); + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public AllSamples getAllTestsAndPanels(@PathVariable("uuid") String uuid) { + final Concept allSamples = conceptService.getConceptByUuid(uuid); + if (allSamples == null) { + throw new ConceptNotFoundException("All tests and panels concept set not found with uuid " + uuid); + } + return allSamplesMapper.map(allSamples); + } + +} \ No newline at end of file diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/AllTestsAndPanelsController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/AllTestsAndPanelsController.java new file mode 100644 index 0000000000..0ae0afc100 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/AllTestsAndPanelsController.java @@ -0,0 +1,39 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.mapper.AllTestsAndPanelsMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/all-tests-and-panels") +public class AllTestsAndPanelsController extends BaseRestController { + + private ConceptService conceptService; + private final AllTestsAndPanelsMapper allTestsAndPanelsMapper; + + @Autowired + public AllTestsAndPanelsController(ConceptService conceptService) { + this.conceptService = conceptService; + this.allTestsAndPanelsMapper = new AllTestsAndPanelsMapper(); + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public AllTestsAndPanels getAllTestsAndPanels(@PathVariable("uuid") String uuid) { + final Concept allTestsAndPanelsConceptSet = conceptService.getConceptByUuid(uuid); + if (allTestsAndPanelsConceptSet == null) { + throw new ConceptNotFoundException("All tests and panels concept set not found with uuid " + uuid); + } + return allTestsAndPanelsMapper.map(allTestsAndPanelsConceptSet); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptController.java new file mode 100644 index 0000000000..497627642b --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptController.java @@ -0,0 +1,36 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.mapper.ConceptMapper; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class ConceptController extends BaseRestController { + @Autowired + private ReferenceDataConceptService referenceDataConceptService; + private final ConceptMapper conceptMapper; + + public ConceptController() { + conceptMapper = new ConceptMapper(); + } + + @RequestMapping(value = "/rest/v1/reference-data/concept", method = RequestMethod.POST) + @ResponseBody + public ResponseEntity create(@RequestBody Concept concept) { + try { + org.openmrs.Concept savedConcept = referenceDataConceptService.saveConcept(concept); + return new ResponseEntity<>(conceptMapper.map(savedConcept), HttpStatus.CREATED); + } catch (Throwable error) { + return new ResponseEntity<>(new Concept(), HttpStatus.BAD_REQUEST); + } + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptSetController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptSetController.java new file mode 100644 index 0000000000..265cd4227f --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptSetController.java @@ -0,0 +1,36 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.mapper.ConceptSetMapper; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class ConceptSetController extends BaseRestController { + @Autowired + private ReferenceDataConceptService referenceDataConceptService; + private final ConceptSetMapper conceptSetMapper; + + public ConceptSetController() { + conceptSetMapper = new ConceptSetMapper(); + } + + @RequestMapping(value = "/rest/v1/reference-data/conceptset", method = RequestMethod.POST) + @ResponseBody + public ResponseEntity create(@RequestBody ConceptSet concept) { + try { + org.openmrs.Concept savedConcept = referenceDataConceptService.saveConcept(concept); + return new ResponseEntity<>(conceptSetMapper.map(savedConcept), HttpStatus.CREATED); + } catch (Throwable error) { + return new ResponseEntity<>(new ConceptSet(), HttpStatus.BAD_REQUEST); + } + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptsController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptsController.java new file mode 100644 index 0000000000..704918a74d --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ConceptsController.java @@ -0,0 +1,76 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.contract.ConceptDetails; +import org.bahmni.module.referencedata.contract.ConceptName; +import org.bahmni.module.referencedata.helper.ConceptHelper; +import org.bahmni.module.referencedata.labconcepts.contract.Concepts; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.openmrs.Concept; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +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 java.util.Collections; +import java.util.List; +import java.util.Set; + +@Controller + +@RequestMapping(value = "/rest/v1/reference-data/") +public class ConceptsController extends BaseRestController { + @Autowired + private ReferenceDataConceptService referenceDataConceptService; + + @Autowired + ConceptHelper conceptHelper; + + @RequestMapping(value = "/concepts", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity create(@RequestParam(value = "conceptName", required = true) String conceptName) { + try { + Concepts concepts = referenceDataConceptService.getConcept(conceptName); + return new ResponseEntity<>(concepts, HttpStatus.OK); + } catch (Throwable error) { + return new ResponseEntity<>(new Concepts(), HttpStatus.NOT_FOUND); + } + } + + + @RequestMapping(value = "/leafConcepts", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity> getLeafConcepts(@RequestParam(value = "conceptName", required = true) String conceptName) { + List concepts = conceptHelper.getConceptsForNames(Collections.singletonList(conceptName)); + Set leafConceptDetails = conceptHelper.getLeafConceptDetails(concepts, true); + return new ResponseEntity<>(leafConceptDetails, HttpStatus.OK); + } + + @RequestMapping(value = "/leafConceptNames", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity> getLeafConcepts(@RequestParam(value = "conceptNames", required = true) List conceptNames) { + List concepts = conceptHelper.getConceptsForNames(conceptNames); + Set leafConceptDetails = conceptHelper.getLeafConceptNames(concepts); + return new ResponseEntity<>(leafConceptDetails, HttpStatus.OK); + } + + @RequestMapping(value = "/getChildConcepts", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity> getChildConcepts(@RequestParam(value = "conceptNames", required = true) List conceptNames) { + List conceptsForNames = conceptHelper.getConceptsForNames(conceptNames); + Set childConceptNames = conceptHelper.getChildConceptNames(conceptsForNames); + return new ResponseEntity<>(childConceptNames, HttpStatus.OK); + } + + @RequestMapping(value = "/getConceptId", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity> getConceptId(@RequestParam(value = "conceptNames", required = true) List conceptNames) { + List conceptsForNames = conceptHelper.getConceptsForNames(conceptNames); + Set conceptIds=conceptHelper.getConceptIds(conceptsForNames); + return new ResponseEntity<>(conceptIds, HttpStatus.OK); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/DepartmentController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/DepartmentController.java new file mode 100644 index 0000000000..eba73f3c6c --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/DepartmentController.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.Department; +import org.bahmni.module.referencedata.labconcepts.mapper.DepartmentMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/department") +public class DepartmentController extends BaseRestController { + private ConceptService conceptService; + private final DepartmentMapper departmentMapper; + + @Autowired + public DepartmentController(ConceptService conceptService) { + departmentMapper = new DepartmentMapper(); + this.conceptService = conceptService; + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public Department getDepartment(@PathVariable("uuid") String uuid) { + final Concept department = conceptService.getConceptByUuid(uuid); + if (department == null) { + throw new ConceptNotFoundException("No department concept found with uuid " + uuid); + } + return departmentMapper.map(department); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/DrugController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/DrugController.java new file mode 100644 index 0000000000..c9dd931a03 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/DrugController.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.mapper.DrugMapper; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/drug") +public class DrugController extends BaseRestController { + private final DrugMapper drugMapper; + private ConceptService conceptService; + + @Autowired + public DrugController(ConceptService conceptService) { + drugMapper = new DrugMapper(); + this.conceptService = conceptService; + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public Drug getDrug(@PathVariable("uuid") String uuid) { + final org.openmrs.Drug drug = conceptService.getDrugByUuid(uuid); + if (drug == null) { + throw new ConceptNotFoundException("No drug found with uuid " + uuid); + } + return drugMapper.map(drug); + } + +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/PanelController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/PanelController.java new file mode 100644 index 0000000000..c3268835d5 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/PanelController.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.Panel; +import org.bahmni.module.referencedata.labconcepts.mapper.PanelMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/panel") +public class PanelController extends BaseRestController { + private ConceptService conceptService; + private final PanelMapper panelMapper; + + @Autowired + public PanelController(ConceptService conceptService) { + panelMapper = new PanelMapper(); + this.conceptService = conceptService; + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public Panel getPanel(@PathVariable("uuid") String uuid) { + final Concept panel = conceptService.getConceptByUuid(uuid); + if (panel == null) { + throw new ConceptNotFoundException("No panel concept found with uuid " + uuid); + } + return panelMapper.map(panel); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/RadiologyTestController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/RadiologyTestController.java new file mode 100644 index 0000000000..04a5de3ccc --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/RadiologyTestController.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest; +import org.bahmni.module.referencedata.labconcepts.mapper.RadiologyTestMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/radiology") +public class RadiologyTestController extends BaseRestController { + private ConceptService conceptService; + private final RadiologyTestMapper radiologyTestMapper; + + @Autowired + public RadiologyTestController(ConceptService conceptService) { + radiologyTestMapper = new RadiologyTestMapper(); + this.conceptService = conceptService; + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public RadiologyTest getRadiologyTest(@PathVariable("uuid") String uuid) { + final Concept test = conceptService.getConceptByUuid(uuid); + if (test == null) { + throw new ConceptNotFoundException("No radiology test concept found with uuid " + uuid); + } + return radiologyTestMapper.map(test); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ResourcesController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ResourcesController.java new file mode 100644 index 0000000000..75a646877b --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/ResourcesController.java @@ -0,0 +1,38 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.mapper.AttributableResourceMapper; +import org.openmrs.Concept; +import org.bahmni.module.referencedata.labconcepts.contract.Resource; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/resources") +public class ResourcesController extends BaseRestController { + public static final String UNIDENTIFIED_RESOURCE = "No resource was found for specified uuid"; + private ConceptService conceptService; + private AttributableResourceMapper attributeResourceMapper; + + @Autowired + public ResourcesController(ConceptService conceptService) { + this.conceptService = conceptService; + this.attributeResourceMapper = new AttributableResourceMapper(); + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public Resource getResourceFromConcept(@PathVariable("uuid") String uuid) { + final Concept concept = conceptService.getConceptByUuid(uuid); + if (concept == null) { + throw new ConceptNotFoundException(UNIDENTIFIED_RESOURCE + uuid); + } + return attributeResourceMapper.map(concept); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/SampleController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/SampleController.java new file mode 100644 index 0000000000..eb0c51f5c5 --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/SampleController.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.bahmni.module.referencedata.labconcepts.mapper.SampleMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/sample") +public class SampleController extends BaseRestController { + private ConceptService conceptService; + private final SampleMapper sampleMapper; + + @Autowired + public SampleController(ConceptService conceptService) { + sampleMapper = new SampleMapper(); + this.conceptService = conceptService; + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public Sample getSample(@PathVariable("uuid") String uuid) { + final Concept sample = conceptService.getConceptByUuid(uuid); + if (sample == null) { + throw new ConceptNotFoundException("No sample concept found with uuid " + uuid); + } + return sampleMapper.map(sample); + } +} diff --git a/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/TestController.java b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/TestController.java new file mode 100644 index 0000000000..daaa4ac97f --- /dev/null +++ b/reference-data/omod/src/main/java/org/bahmni/module/referencedata/web/controller/TestController.java @@ -0,0 +1,37 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.mapper.LabTestMapper; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.module.emrapi.encounter.exception.ConceptNotFoundException; +import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/rest/v1/reference-data/test") +public class TestController extends BaseRestController{ + private ConceptService conceptService; + private final LabTestMapper testMapper; + + @Autowired + public TestController(ConceptService conceptService) { + testMapper = new LabTestMapper(); + this.conceptService = conceptService; + } + + @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) + @ResponseBody + public LabTest getTest(@PathVariable("uuid") String uuid) { + final Concept test = conceptService.getConceptByUuid(uuid); + if (test == null) { + throw new ConceptNotFoundException("No test concept found with uuid " + uuid); + } + return testMapper.map(test); + } +} diff --git a/reference-data/omod/src/main/resources/config.xml b/reference-data/omod/src/main/resources/config.xml new file mode 100644 index 0000000000..ebae1e8b64 --- /dev/null +++ b/reference-data/omod/src/main/resources/config.xml @@ -0,0 +1,34 @@ + + + + + ${project.parent.artifactId} + ${project.parent.name} + ${project.parent.version} + ${project.parent.groupId}.${project.parent.artifactId} + Thoughtworks + + ${project.parent.description} + + ${openMRSRuntimeVersion} + + + org.ict4h.openmrs.openmrs-atomfeed + org.openmrs.module.webservices.rest + org.openmrs.module.emrapi + org.openmrs.module.addresshierarchy + + feed.FeedActivator + + org.openmrs.api.ConceptService + org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptor + + + org.openmrs.module.addresshierarchy.service.AddressHierarchyService + org.bahmni.module.referencedata.addresshierarchy.AddressHierarchyEntryEventInterceptor + + + + + + diff --git a/reference-data/omod/src/main/resources/liquibase.xml b/reference-data/omod/src/main/resources/liquibase.xml new file mode 100644 index 0000000000..c6f8987d52 --- /dev/null +++ b/reference-data/omod/src/main/resources/liquibase.xml @@ -0,0 +1,31 @@ + + + + + + + + + + SELECT COUNT(*) FROM concept_attribute_type where name = 'saleable'; + + + adding concept attribute type saleable + + + + + + + + + + + + \ No newline at end of file diff --git a/reference-data/omod/src/main/resources/webModuleApplicationContext.xml b/reference-data/omod/src/main/resources/webModuleApplicationContext.xml new file mode 100644 index 0000000000..206abd11ae --- /dev/null +++ b/reference-data/omod/src/main/resources/webModuleApplicationContext.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/BaseIntegrationTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/BaseIntegrationTest.java new file mode 100644 index 0000000000..72183f5875 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/BaseIntegrationTest.java @@ -0,0 +1,7 @@ +package org.bahmni.module.referencedata; + +import org.bahmni.test.web.controller.BaseWebControllerTest; + +@org.springframework.test.context.ContextConfiguration(locations = {"classpath:TestingApplicationContext.xml"}, inheritLocations = true) +public class BaseIntegrationTest extends BaseWebControllerTest { +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/addresshierarchy/AddressHierarchyEntryEventInterceptorTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/addresshierarchy/AddressHierarchyEntryEventInterceptorTest.java new file mode 100644 index 0000000000..304d5e3eb2 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/addresshierarchy/AddressHierarchyEntryEventInterceptorTest.java @@ -0,0 +1,97 @@ +package org.bahmni.module.referencedata.addresshierarchy; + +import org.ict4h.atomfeed.transaction.AFTransactionWorkWithoutResult; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.openmrs.module.addresshierarchy.AddressHierarchyEntry; +import org.openmrs.module.addresshierarchy.service.AddressHierarchyService; +import org.openmrs.module.atomfeed.transaction.support.AtomFeedSpringTransactionManager; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest({Context.class, AddressHierarchyEntryEventInterceptor.class}) +@RunWith(PowerMockRunner.class) +public class AddressHierarchyEntryEventInterceptorTest { + @Mock + private AtomFeedSpringTransactionManager atomFeedSpringTransactionManager; + @Mock + private UserContext userContext; + + private AddressHierarchyEntryEventInterceptor publishedFeed; + private AddressHierarchyEntry addressHierarchyEntry; + + @Before + public void setUp() throws Exception { + addressHierarchyEntry = new AddressHierarchyEntry(); + addressHierarchyEntry.setUuid("uuid"); + addressHierarchyEntry.setUserGeneratedId("707070"); + PowerMockito.mockStatic(Context.class); + + ArrayList platformTransactionManagers = new ArrayList<>(); + platformTransactionManagers.add(new HibernateTransactionManager()); + when(Context.getRegisteredComponents(PlatformTransactionManager.class)).thenReturn(platformTransactionManagers); + whenNew(AtomFeedSpringTransactionManager.class).withAnyArguments().thenReturn(atomFeedSpringTransactionManager); + publishedFeed = new AddressHierarchyEntryEventInterceptor(); + + } + + @Test + public void shouldPublishToFeedAfterSavingAddressHierarchyEntry() throws Throwable { + Method method = AddressHierarchyService.class.getMethod("saveAddressHierarchyEntry", AddressHierarchyEntry.class); + Object[] objects = new Object[]{addressHierarchyEntry}; + + publishedFeed.afterReturning(null, method, objects, null); + verify(atomFeedSpringTransactionManager).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + @Test + public void shouldPublishToFeedAfterSavingAddressHierarchyEntries() throws Throwable { + Method method = AddressHierarchyService.class.getMethod("saveAddressHierarchyEntries", List.class); + ArrayList entries = new ArrayList<>(); + entries.add(addressHierarchyEntry); + entries.add(addressHierarchyEntry); + Object[] objects = new Object[]{entries}; + + publishedFeed.afterReturning(null, method, objects, null); + verify(atomFeedSpringTransactionManager, times(2)).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + @Test + public void shouldNotCreateEventIfParameterIsNull() throws Exception { + Method method = AddressHierarchyService.class.getMethod("saveAddressHierarchyEntries", List.class); + + publishedFeed.afterReturning(null, method, null, null); + + verify(atomFeedSpringTransactionManager, never()).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + @Test + public void shouldNotCreateEventIfEntryInParameterIsNull() throws Exception { + Method method = AddressHierarchyService.class.getMethod("saveAddressHierarchyEntries", List.class); + ArrayList entries = new ArrayList<>(); + entries.add(null); + + Object[] objects = new Object[]{entries}; + + publishedFeed.afterReturning(null, method, objects, null); + + verify(atomFeedSpringTransactionManager, never()).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/helper/ConceptHelperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/helper/ConceptHelperTest.java new file mode 100644 index 0000000000..1081b51743 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/helper/ConceptHelperTest.java @@ -0,0 +1,284 @@ +package org.bahmni.module.referencedata.helper; + + +import java.util.Locale; +import org.bahmni.module.referencedata.contract.ConceptDetails; +import org.bahmni.module.referencedata.contract.ConceptName; +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.ConceptNumericBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.User; +import org.openmrs.api.ConceptService; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.MockitoAnnotations.initMocks; +import org.openmrs.api.context.Context; +import org.openmrs.util.LocaleUtility; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@PrepareForTest({Context.class,LocaleUtility.class}) +@RunWith(PowerMockRunner.class) +public class ConceptHelperTest { + @Mock + private ConceptService conceptService; + + private ConceptHelper conceptHelper; + + private boolean withoutAttributes = false; + + + @Before + public void setUp() throws Exception { + initMocks(this); + User mockUser = new User(); + mockUser.setUserProperty("defaultLocale","en"); + + mockStatic(Context.class); + when(Context.getAuthenticatedUser()).thenReturn(mockUser); + when(Context.getLocale()).thenReturn(Locale.ENGLISH); + + mockStatic(LocaleUtility.class); + when(LocaleUtility.fromSpecification("en")).thenReturn(Locale.ENGLISH); + when(LocaleUtility.getDefaultLocale()).thenReturn(Locale.ENGLISH); + + conceptHelper = new ConceptHelper(conceptService); + } + + @Test + public void shouldGetLeafConcepts() { + Concept weightConcept = new ConceptBuilder().withName("Weight").withClass("N/A").build(); + Concept heightConcept = new ConceptBuilder().withName("Height").withClass("N/A").build(); + Concept vitalsConcept = new ConceptBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withClass("N/A").build(); + vitalsConcept.setSet(true); + + Set leafConceptNames = conceptHelper.getLeafConceptDetails(Arrays.asList(vitalsConcept), withoutAttributes); + + assertEquals(2, leafConceptNames.size()); + Iterator leafConceptIterator = leafConceptNames.iterator(); + assertEquals("Height", leafConceptIterator.next().getName()); + assertEquals("Weight", leafConceptIterator.next().getName()); + } + + @Test + public void shouldGetLeafConceptsWithUnits() { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").build(); + Concept vitalsConcept = new ConceptNumericBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withClass("N/A").build(); + vitalsConcept.setSet(true); + + Set leafConceptNames = conceptHelper.getLeafConceptDetails(Arrays.asList(vitalsConcept), withoutAttributes); + + assertEquals(2, leafConceptNames.size()); + Iterator leafConceptIterator = leafConceptNames.iterator(); + ConceptDetails heightConceptResult = leafConceptIterator.next(); + assertEquals("Height", heightConceptResult.getName()); + assertEquals("Cms", heightConceptResult.getUnits()); + assertEquals("Weight", leafConceptIterator.next().getName()); + } + + @Test + public void shouldGetLeafConceptsWithAttributesForConceptSetWithConceptDetailsClass() { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").build(); + Concept vitalsConcept = new ConceptNumericBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withClass("Concept Details").build(); + vitalsConcept.setSet(true); + + Set leafConceptNames = conceptHelper.getLeafConceptDetails(Arrays.asList(vitalsConcept), withoutAttributes); + + assertEquals(1, leafConceptNames.size()); + Iterator leafConceptIterator = leafConceptNames.iterator(); + ConceptDetails vitalsConceptResult = leafConceptIterator.next(); + assertEquals("Vitals", vitalsConceptResult.getName()); + } + + @Test + public void shouldGetLeafConceptsWithExtraAttributesForConceptDetailsClassWhenWithAttributesIsTrue() { + Concept temperatureConcept = new ConceptNumericBuilder().withName("Temperature").withClass("N/A").build(); + Concept temperatureUnknownConcept = new ConceptNumericBuilder().withName("Temperature Unknown").withClass("Unknown").build(); + Concept temperatureAbnormalConcept = new ConceptNumericBuilder().withName("Temperature Abnormal").withClass("Abnormal").build(); + Concept temperatureDataConcept = new ConceptNumericBuilder() + .withName("Temperature Data") + .withSetMember(temperatureConcept) + .withSetMember(temperatureUnknownConcept) + .withSetMember(temperatureAbnormalConcept) + .withClass("Concept Details").build(); + temperatureDataConcept.setSet(true); + + Set leafConceptNames = conceptHelper.getLeafConceptDetails(Arrays.asList(temperatureDataConcept), true); + + assertEquals(1, leafConceptNames.size()); + Iterator leafConceptIterator = leafConceptNames.iterator(); + ConceptDetails temperatureConceptResult = leafConceptIterator.next(); + assertEquals("Temperature", temperatureConceptResult.getName()); + assertFalse(temperatureConceptResult.getAttributes().isEmpty()); + assertEquals("Temperature Unknown", temperatureConceptResult.getAttribute("Unknown Concept")); + } + + @Test + public void shouldGetLeafConceptsWithExtraAttributesForConceptDetailsClassWhenWithAttributesIsFalse() { + Concept temperatureConcept = new ConceptNumericBuilder().withName("Temperature").withClass("N/A").build(); + Concept temperatureUnknownConcept = new ConceptNumericBuilder().withName("Temperature Unknown").withClass("Unknown").build(); + Concept temperatureAbnormalConcept = new ConceptNumericBuilder().withName("Temperature Abnormal").withClass("Abnormal").build(); + Concept temperatureDataConcept = new ConceptNumericBuilder() + .withName("Temperature Data") + .withSetMember(temperatureConcept) + .withSetMember(temperatureUnknownConcept) + .withSetMember(temperatureAbnormalConcept) + .withClass("Concept Details").build(); + temperatureDataConcept.setSet(true); + + Set leafConceptNames = conceptHelper.getLeafConceptDetails(Arrays.asList(temperatureDataConcept), false); + + assertEquals(1, leafConceptNames.size()); + Iterator leafConceptIterator = leafConceptNames.iterator(); + ConceptDetails temperatureConceptResult = leafConceptIterator.next(); + assertEquals("Temperature Data", temperatureConceptResult.getName()); + assertFalse(temperatureConceptResult.getAttributes().isEmpty()); + assertEquals("Temperature Unknown", temperatureConceptResult.getAttribute("Unknown Concept")); + } + + @Test + public void shouldGetLeafConceptsWithUnitsLowAbsoluteAndHighAbsolute() { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").withLowNormal(50.0).withHiNormal(100.0).build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").withLowNormal(140.0).withHiNormal(180.0).build(); + Concept vitalsConcept = new ConceptNumericBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withClass("N/A").build(); + vitalsConcept.setSet(true); + + Set leafConceptNames = conceptHelper.getLeafConceptDetails(Arrays.asList(vitalsConcept), withoutAttributes); + + assertEquals(2, leafConceptNames.size()); + Iterator leafConceptIterator = leafConceptNames.iterator(); + ConceptDetails heightConceptResult = leafConceptIterator.next(); + assertEquals("Height", heightConceptResult.getName()); + assertEquals(new Double(140.0), heightConceptResult.getLowNormal()); + assertEquals(new Double(180.0), heightConceptResult.getHiNormal()); + assertEquals("Cms", heightConceptResult.getUnits()); + ConceptDetails weightConceptResult = leafConceptIterator.next(); + assertEquals("Weight", weightConceptResult.getName()); + assertEquals(new Double(50.0), weightConceptResult.getLowNormal()); + assertEquals(new Double(100.0), weightConceptResult.getHiNormal()); + } + + + @Test + public void shouldGetConceptDetailsFromConceptList() { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").withLowNormal(10.3).withHiNormal(11.1).build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").build(); + + Set conceptDetailsList = conceptHelper.getConceptDetails(Arrays.asList(heightConcept, weightConcept)); + + + assertEquals(2, conceptDetailsList.size()); + Iterator iterator = conceptDetailsList.iterator(); + ConceptDetails heightConceptDetails = iterator.next(); + assertEquals("Height", heightConceptDetails.getName()); + assertEquals("Cms", heightConceptDetails.getUnits()); + ConceptDetails weightConceptDetails = iterator.next(); + assertEquals("Weight", weightConceptDetails.getName()); + assertEquals(new Double(10.3), weightConceptDetails.getLowNormal()); + assertEquals(new Double(11.1), weightConceptDetails.getHiNormal()); + } + + @Test + public void shouldGetAllChildConceptNames() throws Exception { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").withLowNormal(50.0).withHiNormal(100.0).build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").withLowNormal(140.0).withHiNormal(180.0).build(); + Concept systolicConcept = new ConceptNumericBuilder().withName("Systolic").withClass("N/A").build(); + Concept diastolicConcept = new ConceptNumericBuilder().withName("Diastolic").withClass("N/A").build(); + Concept bpConcept = new ConceptNumericBuilder().withName("BP").withSetMember(systolicConcept).withSetMember(diastolicConcept).withClass("N/A").build(); + Concept vitalsConcept = new ConceptNumericBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withSetMember(bpConcept).withClass("N/A").build(); + + ArrayList concepts = new ArrayList<>(); + concepts.add(vitalsConcept); + + Set childConceptNames = conceptHelper.getChildConceptNames(concepts); + assertNotNull("Child concept names should not be null", childConceptNames); + assertEquals(6, childConceptNames.size()); + assertTrue("Should contain vitals", childConceptNames.contains("Vitals")); + assertTrue("Should contain height", childConceptNames.contains("Height")); + assertTrue("Should contain weight", childConceptNames.contains("Weight")); + assertTrue("Should contain BP", childConceptNames.contains("BP")); + assertTrue("Should contain systolic", childConceptNames.contains("Systolic")); + assertTrue("Should contain diastolic", childConceptNames.contains("Diastolic")); + } + + @Test + public void shouldNotGetVoidedConceptNames() throws Exception { + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").withLowNormal(140.0).withHiNormal(180.0).withRetired(true).build(); + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").withLowNormal(50.0).withHiNormal(100.0).build(); + Concept systolicConcept = new ConceptNumericBuilder().withName("Systolic").withClass("N/A").build(); + Concept diastolicConcept = new ConceptNumericBuilder().withName("Diastolic").withClass("N/A").build(); + Concept bpConcept = new ConceptNumericBuilder().withName("BP").withSetMember(systolicConcept).withSetMember(diastolicConcept).withClass("N/A").build(); + Concept vitalsConcept = new ConceptNumericBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withSetMember(bpConcept).withClass("N/A").build(); + + ArrayList concepts = new ArrayList<>(); + concepts.add(vitalsConcept); + + Set childConceptNames = conceptHelper.getChildConceptNames(concepts); + assertNotNull("Child concept names should not be null", childConceptNames); + assertEquals(5, childConceptNames.size()); + assertTrue("Should contain vitals", childConceptNames.contains("Vitals")); + assertFalse("Should not contain height", childConceptNames.contains("Height")); + assertTrue("Should contain weight", childConceptNames.contains("Weight")); + assertTrue("Should contain BP", childConceptNames.contains("BP")); + assertTrue("Should contain systolic", childConceptNames.contains("Systolic")); + assertTrue("Should contain diastolic", childConceptNames.contains("Diastolic")); + } + + @Test + public void shouldGetLeafConceptNames() throws Exception { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withShortName("WeightShort").withClass("N/A").withLowNormal(50.0).withHiNormal(100.0).build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withShortName("HeightShort").withClass("N/A").withUnit("Cms").withLowNormal(140.0).withHiNormal(180.0).build(); + Concept systolicConcept = new ConceptNumericBuilder().withName("Systolic").withClass("N/A").build(); + Concept diastolicConcept = new ConceptNumericBuilder().withName("Diastolic").withClass("N/A").build(); + Concept bpConcept = new ConceptBuilder().withName("BP").withSetMember(systolicConcept).withSetMember(diastolicConcept).withSet(true).withClass("N/A").build(); + Concept vitalsConcept = new ConceptBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withSetMember(bpConcept).withSet(true).withClass("N/A").build(); + + ArrayList concepts = new ArrayList<>(); + concepts.add(vitalsConcept); + + Set leafConceptNames = conceptHelper.getLeafConceptNames(concepts); + assertNotNull("Leaf concept names should not be null", leafConceptNames); + assertEquals(4, leafConceptNames.size()); + assertTrue("Should contain height", leafConceptNames.contains(new ConceptName("Height", "HeightShort"))); + assertTrue("Should contain weight", leafConceptNames.contains(new ConceptName("Weight", "WeightShort"))); + assertTrue("Should contain systolic", leafConceptNames.contains(new ConceptName("Systolic", null))); + assertTrue("Should contain diastolic", leafConceptNames.contains(new ConceptName("Diastolic", null))); + } + + @Test + public void shouldNotGetVoidedLeafConceptNames() throws Exception { + Concept weightConcept = new ConceptNumericBuilder().withName("Weight").withClass("N/A").withLowNormal(50.0).withHiNormal(100.0).withRetired(true).build(); + Concept heightConcept = new ConceptNumericBuilder().withName("Height").withClass("N/A").withUnit("Cms").withLowNormal(140.0).withHiNormal(180.0).build(); + Concept systolicConcept = new ConceptNumericBuilder().withName("Systolic").withClass("N/A").build(); + Concept diastolicConcept = new ConceptNumericBuilder().withName("Diastolic").withClass("N/A").build(); + Concept bpConcept = new ConceptBuilder().withName("BP").withSetMember(systolicConcept).withSetMember(diastolicConcept).withSet(true).withClass("N/A").build(); + Concept vitalsConcept = new ConceptBuilder().withName("Vitals").withSetMember(heightConcept).withSetMember(weightConcept).withSetMember(bpConcept).withSet(true).withClass("N/A").build(); + + ArrayList concepts = new ArrayList<>(); + concepts.add(vitalsConcept); + + Set leafConceptNames = conceptHelper.getLeafConceptNames(concepts); + assertNotNull("Leaf concept names should not be null", leafConceptNames); + assertEquals(3, leafConceptNames.size()); + assertTrue("Should contain height", leafConceptNames.contains(new ConceptName("Height", null))); + assertFalse("Should not contain weight", leafConceptNames.contains(new ConceptName("Weight", null))); + assertTrue("Should contain systolic", leafConceptNames.contains(new ConceptName("Systolic", null))); + assertTrue("Should contain diastolic", leafConceptNames.contains(new ConceptName("Diastolic", null))); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java new file mode 100644 index 0000000000..346d7cb4e7 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/advice/ConceptServiceEventInterceptorTest.java @@ -0,0 +1,146 @@ +package org.bahmni.module.referencedata.labconcepts.advice; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.bahmni.module.referencedata.labconcepts.model.event.SampleEventTest; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.EventService; +import org.ict4h.atomfeed.transaction.AFTransactionWork; +import org.ict4h.atomfeed.transaction.AFTransactionWorkWithoutResult; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.module.atomfeed.transaction.support.AtomFeedSpringTransactionManager; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class ConceptServiceEventInterceptorTest { + @Mock + private AtomFeedSpringTransactionManager atomFeedSpringTransactionManager; + @Mock + private EventService eventService; + @Mock + private ConceptService conceptService; + + private ArgumentCaptor captor = ArgumentCaptor.forClass(AFTransactionWorkWithoutResult.class); + + private ConceptServiceEventInterceptor publishedFeed; + + private Concept concept; + + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + concept = new ConceptBuilder().withClass(Sample.SAMPLE_CONCEPT_CLASS).withUUID(SampleEventTest.SAMPLE_CONCEPT_UUID).build(); + + Concept parentConcept = new ConceptBuilder().withName(AllSamples.ALL_SAMPLES).withSetMember(concept).build(); + + List conceptSets = getConceptSets(parentConcept, concept); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + + publishedFeed = new ConceptServiceEventInterceptor(atomFeedSpringTransactionManager, eventService); + } + + public static List getConceptSets(Concept parentConcept, Concept conceptMember) { + List conceptSets = new ArrayList<>(); + ConceptSet conceptSet = createConceptSet(parentConcept, conceptMember); + conceptSets.add(conceptSet); + return conceptSets; + } + + public static List getConceptSets(ConceptSet conceptSet) { + List conceptSets = new ArrayList<>(); + conceptSets.add(conceptSet); + return conceptSets; + } + + public static ConceptSet createConceptSet(Concept parentConcept, Concept conceptMember) { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setConceptSet(parentConcept); + conceptSet.setConcept(conceptMember); + return conceptSet; + } + + @Test + public void shouldPublishUpdateEventToFeedAfterUpdateConceptOperation() throws Throwable { + Method method = ConceptService.class.getMethod("saveConcept", Concept.class); + Object[] objects = new Object[]{concept}; + + publishedFeed.afterReturning(null, method, objects, null); + verify(atomFeedSpringTransactionManager).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + @Test + public void shouldPublishUpdateEventToFeedAfterEveryUpdateConceptOperation() throws Throwable { + Method method = ConceptService.class.getMethod("saveConcept", Concept.class); + Object[] objects = new Object[]{concept}; + int updates = 2; + for (int i = 0; i < updates; i++) { + publishedFeed.afterReturning(null, method, objects, null); + } + verify(atomFeedSpringTransactionManager, times(updates)).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + + @Test + public void shouldPublishUpdateEventToFeedAfterSaveConceptOperation() throws Throwable { + Method method = ConceptService.class.getMethod("saveConcept", Concept.class); + Object[] objects = new Object[]{concept}; + + publishedFeed.afterReturning(null, method, objects, null); + verify(atomFeedSpringTransactionManager).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + @Test + public void shouldPublishUpdateEventToFeedAfterEverySaveConceptOperation() throws Throwable { + Method method = ConceptService.class.getMethod("saveConcept", Concept.class); + Object[] objects = new Object[]{concept}; + int updates = 2; + for (int i = 0; i < updates; i++) { + publishedFeed.afterReturning(null, method, objects, null); + } + verify(atomFeedSpringTransactionManager, times(updates)).executeWithTransaction(any(AFTransactionWorkWithoutResult.class)); + } + + @Test + public void shouldSaveEventInTheSameTransactionAsTheTrigger() throws Throwable { + Method method = ConceptService.class.getMethod("saveConcept", Concept.class); + Object[] objects = new Object[]{concept}; + + publishedFeed.afterReturning(null, method, objects, null); + verify(atomFeedSpringTransactionManager).executeWithTransaction(captor.capture()); + + assertEquals(AFTransactionWork.PropagationDefinition.PROPAGATION_REQUIRED, captor.getValue().getTxPropagationDefinition()); + } + +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptSetMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptSetMapperTest.java new file mode 100644 index 0000000000..b568ebf62e --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/ConceptSetMapperTest.java @@ -0,0 +1,111 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class ConceptSetMapperTest { + + private ConceptSetMapper conceptSetMapper; + + @Mock + private ConceptMetaData conceptMetaData; + + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + conceptSetMapper = new ConceptSetMapper(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + } + + @Test + public void mapConceptSetNameToOpenmrsConceptname() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setUniqueName("Some"); + org.openmrs.Concept mappedConcept = conceptSetMapper.map(conceptSet, new ArrayList() , conceptMetaData); + assertEquals("Some", mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + } + + @Test + public void mapShortName() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setDisplayName("ShortName"); + org.openmrs.Concept mappedConcept = conceptSetMapper.map(conceptSet, new ArrayList(), conceptMetaData); + assertEquals("ShortName", mappedConcept.getShortestName(Context.getLocale(), false).getName()); + } + + @Test + public void mapDescription() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setDescription("Description"); + org.openmrs.Concept mappedConcept = conceptSetMapper.map(conceptSet, new ArrayList(), conceptMetaData); + assertEquals("Description", mappedConcept.getDescription(Context.getLocale()).getDescription()); + } + + @Test + public void mapConceptClass() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setClassName("ClassName"); + ConceptClass conceptClass = new ConceptClass(); + conceptClass.setName("ClassName"); + + when(conceptMetaData.getConceptClass()).thenReturn(conceptClass); + org.openmrs.Concept mappedConcept = conceptSetMapper.map(conceptSet, new ArrayList(),conceptMetaData); + assertEquals("ClassName", mappedConcept.getConceptClass().getName()); + } + + @Test + public void mapSetMembers() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + List children = new ArrayList<>(); + children.add("1"); + children.add("2"); + conceptSet.setChildren(children); + Concept child1 = new ConceptBuilder().withName("1").build(); + Concept child2 = new ConceptBuilder().withName("2").build(); + ArrayList childConcepts = new ArrayList<>(); + childConcepts.add(child1); + childConcepts.add(child2); + org.openmrs.Concept mappedConcept = conceptSetMapper.map(conceptSet, childConcepts, conceptMetaData); + List setMembers = mappedConcept.getSetMembers(); + assertEquals(2, setMembers.size()); + assertEquals("1", setMembers.get(0).getName(Context.getLocale()).getName()); + assertEquals("2", setMembers.get(1).getName(Context.getLocale()).getName()); + } + + @Test + public void dontMapShortNameIfDoesNotExist() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setDisplayName(null); + conceptSet.setUniqueName("uniqueName"); + conceptSet.setClassName("conceptClass"); + org.openmrs.Concept mappedConcept = conceptSetMapper.map(conceptSet, new ArrayList(), conceptMetaData); + assertEquals(0, mappedConcept.getShortNames().size()); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMapperTest.java new file mode 100644 index 0000000000..8b8f9eb7f6 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMapperTest.java @@ -0,0 +1,205 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.DrugBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class DrugMapperTest { + + private ConceptClass drugConceptClass; + private DrugMapper drugMapper; + + @Mock private UserContext userContext; + + @Before + public void setUp() throws Exception { + Locale locale = new Locale("en", "GB"); + mockStatic(Context.class); + when(Context.getLocale()).thenReturn(locale); + + drugMapper = new DrugMapper(); + drugConceptClass = new ConceptClass(); + drugConceptClass.setUuid(ConceptClass.DRUG_UUID); + drugConceptClass.setName("Drug"); + } + + @Test + public void createNewDrugWithNameAndGenericNameAndDosageForm() throws Exception { + Concept tablet = new ConceptBuilder().withName("Tablet").build(); + Concept existingConcept = new ConceptBuilder().withClassUUID(ConceptClass.DRUG_UUID).withName("Existing Concept").build(); + + + Drug drug = new Drug(); + drug.setName("Drug Name"); + drug.setGenericName("Existing Concept"); + drug.setDosageForm("Tablet"); + DrugMetaData drugMetaData = new DrugMetaData(); + drugMetaData.setDrugConceptClass(drugConceptClass); + drugMetaData.setDosageForm(tablet); + drugMetaData.setDrugConcept(existingConcept); + + org.openmrs.Drug mappedDrug = drugMapper.map(drug, drugMetaData); + assertEquals("Drug Name", mappedDrug.getName()); + assertEquals("Existing Concept", mappedDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Tablet", mappedDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertFalse(mappedDrug.getCombination()); + assertNull(mappedDrug.getMaximumDailyDose()); + assertNull(mappedDrug.getMinimumDailyDose()); + } + + @Test + public void createNewDrugWithAllFields() throws Exception { + Concept existingConcept = new ConceptBuilder().withClassUUID(ConceptClass.DRUG_UUID).withName("Existing Concept").build(); + + Drug drug = new Drug(); + drug.setName("Drug Name"); + drug.setGenericName("Existing Concept"); + drug.setDosageForm("Tablet"); + drug.setCombination(true); + drug.setMaximumDose("99.0"); + drug.setMinimumDose("12.0"); + drug.setStrength("Ok"); + DrugMetaData drugMetaData = new DrugMetaData(); + drugMetaData.setDrugConceptClass(drugConceptClass); + drugMetaData.setDosageForm(new Concept()); + drugMetaData.setDrugConcept(existingConcept); + org.openmrs.Drug mappedDrug = drugMapper.map(drug, drugMetaData); + assertEquals("Drug Name", mappedDrug.getName()); + assertEquals("Existing Concept", mappedDrug.getConcept().getName(Context.getLocale()).getName()); + assertTrue(mappedDrug.getCombination()); + assertEquals("Ok", mappedDrug.getStrength()); + assertTrue(mappedDrug.getMaximumDailyDose().equals(99.0)); + assertTrue(mappedDrug.getMinimumDailyDose().equals(12.0)); + } + + @Test + public void existingDrugOldConceptNewDosageForm() throws Exception { + Drug drug = new Drug(); + Concept existingConcept = new ConceptBuilder().withClassUUID(ConceptClass.DRUG_UUID).withName("Existing Concept").build(); + Concept capsule = new ConceptBuilder().withName("Capsule").build(); + org.openmrs.Drug existingDrug = new DrugBuilder().withName("Existing Drug").withConcept(existingConcept).withDosageForm("Tablet").withStrength("Very Strong").build(); + drug.setName("Existing Drug"); + drug.setGenericName("Existing Concept"); + drug.setDosageForm("Capsule"); + drug.setCombination(true); + drug.setMaximumDose("99.0"); + drug.setMinimumDose("12.0"); + drug.setStrength("Ok"); + DrugMetaData drugMetaData = new DrugMetaData(); + drugMetaData.setDrugConceptClass(drugConceptClass); + drugMetaData.setDrugConcept(existingConcept); + drugMetaData.setExistingDrug(existingDrug); + drugMetaData.setDosageForm(capsule); + assertEquals("Tablet", existingDrug.getDosageForm().getName(Context.getLocale()).getName()); + org.openmrs.Drug mappedDrug = drugMapper.map(drug, drugMetaData); + assertEquals("Existing Drug", mappedDrug.getName()); + assertEquals("Existing Concept", mappedDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Capsule", mappedDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertTrue(mappedDrug.getCombination()); + assertEquals("Ok", mappedDrug.getStrength()); + assertTrue(mappedDrug.getMaximumDailyDose().equals(99.0)); + assertTrue(mappedDrug.getMinimumDailyDose().equals(12.0)); + assertEquals(mappedDrug.getUuid(), existingDrug.getUuid()); + } + + @Test + public void existingDrugNewConceptNewDosageForm() throws Exception { + Drug drug = new Drug(); + Concept existingConcept = new ConceptBuilder().withClassUUID(ConceptClass.DRUG_UUID).withName("Existing Concept").build(); + Concept capsule = new ConceptBuilder().withName("Capsule").build(); + Concept newConcept = new ConceptBuilder().withName("New Drug Concept").withClassUUID(ConceptClass.DRUG_UUID).build(); + org.openmrs.Drug existingDrug = new DrugBuilder().withName("Existing Drug").withConcept(existingConcept).withDosageForm("Tablet").withStrength("Very Strong").build(); + drug.setName("Existing Drug"); + drug.setGenericName("New Drug Concept"); + drug.setDosageForm("Capsule"); + drug.setCombination(true); + drug.setMaximumDose("99.0"); + drug.setMinimumDose("12.0"); + drug.setStrength("Ok"); + DrugMetaData drugMetaData = new DrugMetaData(); + drugMetaData.setDrugConceptClass(drugConceptClass); + drugMetaData.setExistingDrug(existingDrug); + drugMetaData.setDosageForm(capsule); + drugMetaData.setDrugConcept(newConcept); + assertEquals("Tablet", existingDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertEquals("Existing Concept", existingDrug.getConcept().getName(Context.getLocale()).getName()); + org.openmrs.Drug mappedDrug = drugMapper.map(drug, drugMetaData); + assertEquals("Existing Drug", mappedDrug.getName()); + assertEquals("New Drug Concept", mappedDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Capsule", mappedDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertTrue(mappedDrug.getCombination()); + assertEquals("Ok", mappedDrug.getStrength()); + assertTrue(mappedDrug.getMaximumDailyDose().equals(99.0)); + assertTrue(mappedDrug.getMinimumDailyDose().equals(12.0)); + assertEquals(mappedDrug.getUuid(), existingDrug.getUuid()); + } + + @Test + public void existingDrugNewDrugName() throws Exception { + Drug drug = new Drug(); + Concept existingConcept = new ConceptBuilder().withClassUUID(ConceptClass.DRUG_UUID).withName("Existing Concept").build(); + Concept capsule = new ConceptBuilder().withName("Capsule").build(); + Concept newConcept = new ConceptBuilder().withName("New Drug Concept").withClassUUID(ConceptClass.DRUG_UUID).build(); + org.openmrs.Drug existingDrug = new DrugBuilder().withName("Existing Drug").withConcept(existingConcept).withDosageForm("Tablet").withStrength("Very Strong").build(); + drug.setName("New Drug Name"); + drug.setGenericName("New Drug Concept"); + drug.setDosageForm("Capsule"); + drug.setCombination(true); + drug.setMaximumDose("99.0"); + drug.setMinimumDose("12.0"); + drug.setStrength("Ok"); + DrugMetaData drugMetaData = new DrugMetaData(); + drugMetaData.setDrugConceptClass(drugConceptClass); + drugMetaData.setExistingDrug(existingDrug); + drugMetaData.setDosageForm(capsule); + drugMetaData.setDrugConcept(newConcept); + assertEquals("Tablet", existingDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertEquals("Existing Concept", existingDrug.getConcept().getName(Context.getLocale()).getName()); + org.openmrs.Drug mappedDrug = drugMapper.map(drug, drugMetaData); + assertEquals("New Drug Name", mappedDrug.getName()); + assertEquals(mappedDrug.getUuid(), existingDrug.getUuid()); + assertEquals("New Drug Concept", mappedDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Capsule", mappedDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertTrue(mappedDrug.getCombination()); + assertEquals("Ok", mappedDrug.getStrength()); + assertTrue(mappedDrug.getMaximumDailyDose().equals(99.0)); + assertTrue(mappedDrug.getMinimumDailyDose().equals(12.0)); + } + + @Test + public void testOpenmrsDrugToBahmniDrug(){ + Concept existingConcept = new ConceptBuilder().withClassUUID(ConceptClass.DRUG_UUID).withName("Existing Concept").withShortName("short").build(); + org.openmrs.Drug existingDrug = new DrugBuilder().withName("Existing Drug").withConcept(existingConcept).withDosageForm("Tablet").withStrength("Very Strong").build(); + + Drug bahmniDrug = drugMapper.map(existingDrug); + assertEquals("Existing Drug", bahmniDrug.getName()); + assertEquals("Existing Concept", bahmniDrug.getGenericName()); + assertEquals("Tablet", bahmniDrug.getDosageForm()); + assertEquals("short", bahmniDrug.getShortName()); + assertEquals("Very Strong", bahmniDrug.getStrength()); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMetaDataMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMetaDataMapperTest.java new file mode 100644 index 0000000000..44e687bee0 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/mapper/DrugMetaDataMapperTest.java @@ -0,0 +1,103 @@ +package org.bahmni.module.referencedata.labconcepts.mapper; + +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.bahmni.test.builder.ConceptBuilder; +import org.bahmni.test.builder.DrugBuilder; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.Drug; +import org.openmrs.api.context.Context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +public class DrugMetaDataMapperTest { + + private DrugMetaDataMapper drugMetaDataMapper; + private ConceptClass drugConceptClass; + + @Before + public void setUp() throws Exception { + drugMetaDataMapper = new DrugMetaDataMapper(); + drugConceptClass = new ConceptClass(); + drugConceptClass.setUuid(ConceptClass.DRUG_UUID); + ConceptDatatype naDatatype = new ConceptDatatype(); + naDatatype.setUuid(ConceptDatatype.N_A_UUID); + } + + @Test + public void createNewDrugIfExistingDrugIsNull() throws Exception { + DrugMetaData drugMetaData = new DrugMetaData(null, new Concept(), new Concept(), drugConceptClass); + Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + assertNotNull(conceptDrug); + assertNotNull(conceptDrug.getConcept()); + assertNotNull(conceptDrug.getDosageForm()); + } + + @Test + public void createNewDrugWithExistingConcept() throws Exception { + Concept drugConcept = new ConceptBuilder().withName("Drug Concept").withClassUUID(ConceptClass.DRUG_UUID).build(); + DrugMetaData drugMetaData = new DrugMetaData(null, drugConcept, null, drugConceptClass); + Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + assertNotNull(conceptDrug); + assertNotNull(conceptDrug.getConcept()); + assertEquals(drugConcept, conceptDrug.getConcept()); + assertEquals(ConceptClass.DRUG_UUID, conceptDrug.getConcept().getConceptClass().getUuid()); + assertNull(conceptDrug.getDosageForm()); + } + + @Test + public void createNewDrugWithDosageFormConcept() throws Exception { + Concept tablet = new ConceptBuilder().withName("Tablet").build(); + DrugMetaData drugMetaData = new DrugMetaData(null, new Concept(), tablet, drugConceptClass); + Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + assertNotNull(conceptDrug); + assertNotNull(conceptDrug.getConcept()); + assertNotNull(conceptDrug.getDosageForm()); + assertEquals("Tablet", conceptDrug.getDosageForm().getName(Context.getLocale()).getName()); + } + + @Test + public void createNewDrugWithDosageFormAndExistingConcept() throws Exception { + Concept tablet = new ConceptBuilder().withName("Tablet").build(); + Concept drugConcept = new ConceptBuilder().withName("Drug Concept").withClassUUID(ConceptClass.DRUG_UUID).build(); + DrugMetaData drugMetaData = new DrugMetaData(null, drugConcept, tablet, drugConceptClass); + Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + assertNotNull(conceptDrug); + assertNotNull(conceptDrug.getConcept()); + assertEquals("Drug Concept", conceptDrug.getConcept().getName(Context.getLocale()).getName()); + assertNotNull(conceptDrug.getDosageForm()); + assertEquals("Tablet", conceptDrug.getDosageForm().getName(Context.getLocale()).getName()); + } + + @Test + public void updateDrugConceptOnExistingDrug() throws Exception { + Drug existingDrug = new DrugBuilder().withConcept("Drug Concept").withDosageForm("Tablet").build(); + Concept drugConcept = new ConceptBuilder().withName("New Concept").withClassUUID(ConceptClass.DRUG_UUID).build(); + DrugMetaData drugMetaData = new DrugMetaData(existingDrug, drugConcept, null, drugConceptClass); + assertEquals("Drug Concept", existingDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Tablet", existingDrug.getDosageForm().getName(Context.getLocale()).getName()); + Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + assertEquals("New Concept", conceptDrug.getConcept().getName(Context.getLocale()).getName()); + assertNull(conceptDrug.getDosageForm()); + assertEquals(ConceptClass.DRUG_UUID, conceptDrug.getConcept().getConceptClass().getUuid()); + } + + @Test + public void updateAllFieldsOnExistingDrug() throws Exception { + Drug existingDrug = new DrugBuilder().withConcept("Drug Concept").withDosageForm("Tablet").build(); + Concept capsule = new ConceptBuilder().withName("Capsule").build(); + Concept drugConcept = new ConceptBuilder().withName("New Concept").withClassUUID(ConceptClass.DRUG_UUID).build(); + DrugMetaData drugMetaData = new DrugMetaData(existingDrug, drugConcept, capsule, drugConceptClass); + assertEquals("Drug Concept", existingDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Tablet", existingDrug.getDosageForm().getName(Context.getLocale()).getName()); + Drug conceptDrug = drugMetaDataMapper.map(drugMetaData); + assertEquals("New Concept", conceptDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals("Capsule", conceptDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertEquals(ConceptClass.DRUG_UUID, conceptDrug.getConcept().getConceptClass().getUuid()); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllLabSamplesEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllLabSamplesEventTest.java new file mode 100644 index 0000000000..ce1c1e5635 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllLabSamplesEventTest.java @@ -0,0 +1,63 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.List; +import java.util.Locale; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class AllLabSamplesEventTest { + + private Concept parentConcept; + @Mock + private ConceptService conceptService; + @Mock + private UserContext userContext; + + @Before + public void setup() { + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + when(Context.getConceptService()).thenReturn(conceptService); + Concept concept = new ConceptBuilder().withClassUUID(ConceptClass.LABSET_UUID).build(); + Concept anotherConcept = new ConceptBuilder().withClassUUID(ConceptClass.LABSET_UUID).build(); + parentConcept = new ConceptBuilder().withName(AllSamples.ALL_SAMPLES).withClass("ConvSet").withSetMember(concept).withSetMember(anotherConcept).build(); + + } + + @Test + public void shouldCreateOneEventForAllLabSamplesAndSetMembers() throws Exception { + + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{parentConcept}); + assertEquals(events.size(), 1); + Event event = events.get(0); + assertThat(event.getUri().toString(), containsString(parentConcept.getUuid())); + assertEquals(event.getTitle(), ConceptServiceEventFactory.LAB_SAMPLE); + assertEquals(event.getCategory(), "lab"); + + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java new file mode 100644 index 0000000000..6ab6cfea55 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/AllTestsPanelsConceptSetEventTest.java @@ -0,0 +1,63 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.List; +import java.util.Locale; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class AllTestsPanelsConceptSetEventTest { + private Concept parentConcept; + protected Concept testConcept; + protected Concept panelConcept; + @Mock + private ConceptService conceptService; + @Mock + private UserContext userContext; + + @Before + public void setUp() { + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + when(Context.getConceptService()).thenReturn(conceptService); + testConcept = new ConceptBuilder().withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).build(); + panelConcept = new ConceptBuilder().withClassUUID(ConceptClass.LABSET_UUID).build(); + parentConcept = new ConceptBuilder().withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withClass("ConvSet").withSetMember(testConcept).withSetMember(panelConcept).build(); + } + + @Test + public void shouldCreateOneEventForAllTestsAndPanelsAndSetMembers() throws Exception { + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{parentConcept}); + assertEquals(events.size(), 1); + Event event = events.get(0); + assertThat(event.getUri().toString(), containsString(parentConcept.getUuid())); + assertEquals(ConceptServiceEventFactory.TESTS_AND_PANEL, event.getTitle()); + assertEquals("lab", event.getCategory()); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptOperationEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptOperationEventTest.java new file mode 100644 index 0000000000..7fb19f5c9e --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/ConceptOperationEventTest.java @@ -0,0 +1,79 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptOperationEvent.isChildOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class ConceptOperationEventTest { + public static final String URL = "url"; + public static final String CATEGORY = "category"; + public static final String TITLE = "title"; + private ConceptOperationEvent conceptOperationEvent; + private Object[] arguments; + private Concept childConcept; + + @Mock + private ConceptService conceptService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + conceptOperationEvent = new SampleEvent(URL, CATEGORY, TITLE); + Concept concept = new ConceptBuilder().withUUID("UUID").build(); + arguments = new Object[]{concept}; + childConcept = new ConceptBuilder().withName("Child").build(); + Concept parentConcept = new ConceptBuilder().withName("Parent").withSetMember(childConcept).build(); + List conceptSets = getConceptSets(parentConcept, childConcept); + PowerMockito.mockStatic(Context.class); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + } + + + + @Test + public void triggerAtomfeedEvent() throws Exception { + Event event = conceptOperationEvent.asAtomFeedEvent(arguments); + assertEquals(CATEGORY, event.getCategory()); + assertEquals(TITLE, event.getTitle()); + assertEquals(URL, event.getUri().toString()); + } + + @Test + public void isConceptChildOfParentConcept() throws Exception { + assertTrue(isChildOf(childConcept, "Parent")); + } + + @Test + public void isConceptNotAChildOfParentConcept() throws Exception { + assertFalse(isChildOf(childConcept, "Not Parent")); + } + +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/DepartmentEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/DepartmentEventTest.java new file mode 100644 index 0000000000..3ce7df848d --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/DepartmentEventTest.java @@ -0,0 +1,110 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.Department; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class DepartmentEventTest { + public static final String DEPARTMENT_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + + private Concept concept; + + @Mock + private ConceptService conceptService; + private Concept parentConcept; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + concept = new ConceptBuilder().withClass("Department").withUUID(DEPARTMENT_CONCEPT_UUID).build(); + + parentConcept = new ConceptBuilder().withName(Department.DEPARTMENT_PARENT_CONCEPT_NAME).withSetMember(concept).build(); + + List conceptSets = getConceptSets(parentConcept, concept); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + } + + + @Test + public void createEventForDepartmentEvent() throws Exception { + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), ConceptServiceEventFactory.DEPARTMENT); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void shouldNotCreateEventForDepartmentEventIfThereIsDifferentConceptClass() throws Exception { + concept = new ConceptBuilder().withClassUUID("some").withClass("some").withUUID(DEPARTMENT_CONCEPT_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + assertTrue(events.isEmpty()); + } + + @Test + public void shouldCreateEventForDepartmentEventIfParentConceptIsMissing() throws Exception { + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(new ArrayList()); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.DEPARTMENT); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + + @Test + public void shouldCreateEventForDepartmentEventIfParentConceptIsWrong() throws Exception { + parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(concept).build(); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, concept)); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.DEPARTMENT); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void createEventForDepartmentWithParentConceptMissing() throws Exception { + Concept departmentConcept = new ConceptBuilder().withClass("Department").withUUID("departmentUUID").build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{departmentConcept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.DEPARTMENT); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/DrugEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/DrugEventTest.java new file mode 100644 index 0000000000..21d3c6bc9c --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/DrugEventTest.java @@ -0,0 +1,80 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.Drug; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class DrugEventTest { + + private static final Object[] WRONG_ARGUMENTS = new Object[]{}; + private Object[] drugs; + private Drug drug; + private Object[] notDrugs; + private DrugEvent drugEvent; + + + @Before + public void setUp() throws Exception { + Concept drugConcept = new ConceptBuilder().withClass("drug").withUUID("drugConceptUuid").withClassUUID(ConceptClass.DRUG_UUID).build(); + drug = new Drug(); + drug.setConcept(drugConcept); + drug.setUuid("drugUUID"); + drugs = new Object[]{drug}; + Concept notDrug = new Concept(); + notDrugs = new Object[]{notDrug}; + drugEvent = new DrugEvent(ConceptServiceEventFactory.CONCEPT_URL, ConceptServiceEventFactory.DRUG, ConceptServiceEventFactory.DRUG); + } + + + @Test + public void notApplicableForWrongOperation() throws Exception { + Boolean applicable = drugEvent.isApplicable("don'tSaveDrug", WRONG_ARGUMENTS); + assertFalse(applicable); + } + + @Test + public void notApplicableForNullOperation() throws Exception { + Boolean applicable = drugEvent.isApplicable(null, WRONG_ARGUMENTS); + assertFalse(applicable); + } + + @Test + public void notApplicableForNullArguments() throws Exception { + Boolean applicable = drugEvent.isApplicable("saveDrug", null); + assertFalse(applicable); + } + + @Test + public void notApplicableForWrongArguments() throws Exception { + Boolean applicable = drugEvent.isApplicable("saveDrug", WRONG_ARGUMENTS); + assertFalse(applicable); + } + + @Test + public void notApplicableForWrongArgumentType() throws Exception { + Boolean applicable = drugEvent.isApplicable("saveDrug", notDrugs); + assertFalse(applicable); + } + + @Test + public void applicableForRightOperationsAndArguments() throws Exception { + Boolean applicable = drugEvent.isApplicable("saveDrug", drugs); + assertTrue(applicable); + } + + @Test + public void publishEventForDrugs() throws Exception { + Event event = drugEvent.asAtomFeedEvent(drugs); + assertEquals(ConceptServiceEventFactory.DRUG, event.getCategory()); + assertEquals(ConceptServiceEventFactory.DRUG, event.getTitle()); + assertEquals(String.format(ConceptServiceEventFactory.CONCEPT_URL, event.getCategory(), drug.getUuid()), event.getUri().toString()); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java new file mode 100644 index 0000000000..bd489ac4be --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/LabTestEventTest.java @@ -0,0 +1,134 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class LabTestEventTest { + public static final String TEST_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + public static final String LAB_TEST_CONCEPT_UUID = "9b11d2d1-c7ea-40f7-8616-be9bec4c6bb7"; + + private Concept conceptWithLabTestClass; + private Concept conceptWithTestClass; + + @Mock + private ConceptService conceptService; + private Concept parentConcept; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + conceptWithLabTestClass = new ConceptBuilder().withClass("LabTest").withUUID(LAB_TEST_CONCEPT_UUID).build(); + conceptWithTestClass = new ConceptBuilder().withClass("Test").withUUID(TEST_CONCEPT_UUID).build(); + + parentConcept = new ConceptBuilder().withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(conceptWithLabTestClass).build(); + parentConcept.addSetMember(conceptWithTestClass); + + List conceptSets = getConceptSets(parentConcept, conceptWithLabTestClass); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + } + + + @Test + public void createEventForTestEventIfConceptClassIsLabTestOrTest() throws Exception { + Event eventForLabTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}).get(0); + Event anotherEventForLabTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}).get(0); + Event eventForTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithTestClass}).get(0); + Event anotherEventForTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithTestClass}).get(0); + assertNotNull(eventForLabTestConceptClass); + assertNotNull(eventForTestConceptClass); + assertFalse(eventForLabTestConceptClass.getUuid().equals(anotherEventForLabTestConceptClass.getUuid())); + assertEquals(eventForLabTestConceptClass.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(eventForLabTestConceptClass.getCategory(), ConceptServiceEventFactory.LAB); + assertFalse(eventForTestConceptClass.getUuid().equals(anotherEventForTestConceptClass.getUuid())); + assertEquals(eventForTestConceptClass.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(eventForTestConceptClass.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void shouldCreateEventForCaseInsensitiveConceptClassMatches() throws Exception { + Concept conceptWithClassLabTest = new ConceptBuilder().withClass("LabTest").withUUID(LAB_TEST_CONCEPT_UUID).build(); + Concept conceptWithClasslabtest = new ConceptBuilder().withClass("labtest").withUUID("9b11d2d1-c7ea-40f7-8616-be9bec4c6b98").build(); + Event eventForLabTestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithClassLabTest}).get(0); + Event eventForlabtestConceptClass = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithClasslabtest}).get(0); + assertNotNull(eventForLabTestConceptClass); + assertNotNull(eventForlabtestConceptClass); + + } + + @Test + public void shouldNotCreateEventForTestEventIfThereIsDifferentConceptClass() throws Exception { + conceptWithLabTestClass = new ConceptBuilder().withClassUUID("some").withClass("some").withUUID(TEST_CONCEPT_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}); + assertTrue(events.isEmpty()); + } + + @Test + public void shouldCreateEventForTestEventIfParentConceptIsMissing() throws Exception { + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(new ArrayList()); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + + @Test + public void shouldCreateEventForTestEventIfParentConceptIsWrong() throws Exception { + parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(conceptWithLabTestClass).build(); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, conceptWithLabTestClass)); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{conceptWithLabTestClass}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + + @Test + public void createEventForTestWithParentConceptMissing() throws Exception { + Concept testConcept = new ConceptBuilder().withUUID("testUUID").withClass("LabTest").build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{testConcept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.TEST); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/PanelEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/PanelEventTest.java new file mode 100644 index 0000000000..0dd7f97a6a --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/PanelEventTest.java @@ -0,0 +1,113 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class PanelEventTest { + public static final String PANEL_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + + private Concept parentConcept; + private Concept concept; + + @Mock + private ConceptService conceptService; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + concept = new ConceptBuilder().withName("abc").withClass("LabSet").withClassUUID(ConceptClass.LABSET_UUID).withUUID(PANEL_CONCEPT_UUID).build(); + + parentConcept = new ConceptBuilder().withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(concept).build(); + + List conceptSets = getConceptSets(parentConcept, concept); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + } + + + @Test + public void createEventForPanelEvent() throws Exception { + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), ConceptServiceEventFactory.PANEL); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void shouldNotCreateEventForPanelEventIfThereIsDifferentConceptClass() throws Exception { + concept = new ConceptBuilder().withClass("LabSet").withClassUUID("some").withUUID(PANEL_CONCEPT_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + assertTrue(events.isEmpty()); + } + + @Test + public void shouldCreateEventForPanelEventIfParentConceptIsMissing() throws Exception { + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(new ArrayList()); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.PANEL); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + + @Test + public void shouldCreateEventForPanelEventIfParentConceptIsWrong() throws Exception { + parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(concept).build(); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, concept)); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.PANEL); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + + @Test + public void createEventForPanelWithParentConceptMissing() throws Exception { + Concept panelConcept = new ConceptBuilder().withClass("LabSet").withUUID("panelUUID").withClassUUID(ConceptClass.LABSET_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{panelConcept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.PANEL); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java new file mode 100644 index 0000000000..5292c26af8 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/RadiologyTestEventTest.java @@ -0,0 +1,123 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class RadiologyTestEventTest { + public static final String RADIOLOGY_TEST_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + + private Concept concept; + + @Mock + private ConceptService conceptService; + private Concept parentConcept; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + concept = new ConceptBuilder().withClass("Radiology").withUUID(RADIOLOGY_TEST_CONCEPT_UUID).build(); + + parentConcept = new ConceptBuilder().withName(RadiologyTest.RADIOLOGY_TEST_PARENT_CONCEPT_NAME).withSetMember(concept).build(); + + List conceptSets = getConceptSets(parentConcept, concept); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + } + + + @Test + public void createEventForSampleEvent() throws Exception { + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), ConceptServiceEventFactory.RADIOLOGY); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + + } + + @Test + public void shouldCreateEventWhenClassIsRadiologyImagingProcedure() throws Exception{ + concept = new ConceptBuilder().withClass("Radiology/Imaging Procedure").withUUID(RADIOLOGY_TEST_CONCEPT_UUID).build(); + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), ConceptServiceEventFactory.RADIOLOGY); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void shouldNotCreateEventForRadiologyEventIfThereIsDifferentConceptClass() throws Exception { + concept = new ConceptBuilder().withClass("random").withClassUUID("some").withUUID(RADIOLOGY_TEST_CONCEPT_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + assertTrue(events.isEmpty()); + } + + @Test + public void shouldCreateEventForRadiologyTestIfParentConceptIsMissing() throws Exception { + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(new ArrayList()); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.RADIOLOGY); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + + @Test + public void shouldCreateEventForRadiologyTestIfParentConceptIsWrong() throws Exception { + parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(concept).build(); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, concept)); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.RADIOLOGY); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + + @Test + public void createEventForRadiologyTestWithParentConceptMissing() throws Exception { + Concept sampleConcept = new ConceptBuilder().withClass("Radiology").withUUID("RadiologyTestUUID").build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{sampleConcept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.RADIOLOGY); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEventTest.java new file mode 100644 index 0000000000..8c029daa90 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SaleableTypeEventTest.java @@ -0,0 +1,87 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Assert; +import org.openmrs.Concept; +import org.junit.Test; +import org.openmrs.ConceptAttribute; +import org.openmrs.ConceptAttributeType; + +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.CONCEPT_URL; +import static org.bahmni.module.referencedata.labconcepts.model.event.ConceptServiceEventFactory.SALEABLE; + +public class SaleableTypeEventTest { + + @Test + public void shouldRaiseEventForConceptWithSaleableAttribute() throws Exception { + ConceptAttributeType cat = new ConceptAttributeType(); + cat.setDatatypeClassname("org.openmrs.customdatatype.datatype.BooleanDatatype"); + cat.setName(SaleableTypeEvent.SALEABLE_ATTR_NAME); + + Concept procedureConcept = new org.bahmni.test.builder.ConceptBuilder() + .withClass("Procedure") + .withUUID("9d583329-5fb1-4e50-9420-dcbbf6991fbc") + .withName("Dressing Procedure") + .build(); + + ConceptAttribute ca = new ConceptAttribute(); + ca.setAttributeType(cat); + ca.setVoided(false); + ca.setValue(true); + procedureConcept.addAttribute(ca); + + SaleableTypeEvent saleableTypeEvent = new SaleableTypeEvent(CONCEPT_URL, SALEABLE); + Assert.assertEquals(true, saleableTypeEvent.isApplicable("saveConcept", new Object[]{procedureConcept})); + + Event event = saleableTypeEvent.asAtomFeedEvent(new Object[]{procedureConcept}); + Assert.assertNotNull(event); + Assert.assertEquals(SALEABLE, event.getCategory()); + Assert.assertEquals("/openmrs/ws/rest/v1/reference-data/resources/9d583329-5fb1-4e50-9420-dcbbf6991fbc", event.getContents()); + } + + @Test + public void shouldNotRaiseEventForConceptWithSaleableAttributeIfOfRadiologyClass() throws Exception { + ConceptAttributeType cat = new ConceptAttributeType(); + cat.setDatatypeClassname("org.openmrs.customdatatype.datatype.BooleanDatatype"); + cat.setName(SaleableTypeEvent.SALEABLE_ATTR_NAME); + + Concept procedureConcept = new org.bahmni.test.builder.ConceptBuilder() + .withClass("Radiology") + .withUUID("9d583329-5fb1-4e50-9420-dcbbf6991fbc") + .withName("Dressing Procedure") + .build(); + + ConceptAttribute ca = new ConceptAttribute(); + ca.setAttributeType(cat); + ca.setVoided(false); + ca.setValue(true); + procedureConcept.addAttribute(ca); + + SaleableTypeEvent saleableTypeEvent = new SaleableTypeEvent(CONCEPT_URL, SALEABLE); + Assert.assertEquals(false, saleableTypeEvent.isApplicable("saveConcept", new Object[]{procedureConcept})); + + } + + @Test + public void shouldNotRaiseEventForReservedConceptsWithSaleableAttribute() throws Exception { + ConceptAttributeType cat = new ConceptAttributeType(); + cat.setDatatypeClassname("org.openmrs.customdatatype.datatype.BooleanDatatype"); + cat.setName(SaleableTypeEvent.SALEABLE_ATTR_NAME); + + Concept procedureConcept = new org.bahmni.test.builder.ConceptBuilder() + .withClass("ConvSet") + .withUUID("9d583329-5fb1-4e50-9420-dcbbf6991fbc") + .withName("Lab Samples") + .build(); + + ConceptAttribute ca = new ConceptAttribute(); + ca.setAttributeType(cat); + ca.setVoided(false); + ca.setValue(true); + procedureConcept.addAttribute(ca); + + SaleableTypeEvent saleableTypeEvent = new SaleableTypeEvent(CONCEPT_URL, SALEABLE); + Assert.assertEquals(false, saleableTypeEvent.isApplicable("saveConcept", new Object[]{procedureConcept})); + + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java new file mode 100644 index 0000000000..43e60125ad --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/model/event/SampleEventTest.java @@ -0,0 +1,109 @@ +package org.bahmni.module.referencedata.labconcepts.model.event; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.model.Operation; +import org.bahmni.test.builder.ConceptBuilder; +import org.ict4h.atomfeed.server.service.Event; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class SampleEventTest { + public static final String SAMPLE_CONCEPT_UUID = "aebc57b7-0683-464e-ac48-48b8838abdfc"; + + private Concept concept; + + @Mock + private ConceptService conceptService; + private Concept parentConcept; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + concept = new ConceptBuilder().withClass("Sample").withUUID(SAMPLE_CONCEPT_UUID).build(); + + parentConcept = new ConceptBuilder().withName(AllSamples.ALL_SAMPLES).withSetMember(concept).build(); + + List conceptSets = getConceptSets(parentConcept, concept); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getConceptService()).thenReturn(conceptService); + PowerMockito.when(Context.getLocale()).thenReturn(defaultLocale); + } + + + @Test + public void createEventForSampleEvent() throws Exception { + Event event = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + Event anotherEvent = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}).get(0); + assertNotNull(event); + assertFalse(event.getUuid().equals(anotherEvent.getUuid())); + assertEquals(event.getTitle(), "sample"); + assertEquals(event.getCategory(), "lab"); + } + + @Test + public void shouldNotCreateEventForSampleEventIfThereIsDifferentConceptClass() throws Exception { + concept = new ConceptBuilder().withClass("procedure").withClassUUID("some").withUUID(SAMPLE_CONCEPT_UUID).build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + assertTrue(events.isEmpty()); + } + + @Test + public void shouldCreateEventForSampleEventIfParentConceptIsMissing() throws Exception { + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(new ArrayList()); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + assertNotNull(events.get(0)); + assertEquals(events.get(0).getTitle(), "sample"); + assertEquals(events.get(0).getCategory(), "lab"); + } + + + @Test + public void shouldCreateEventForSampleEventIfParentConceptIsWrong() throws Exception { + parentConcept = new ConceptBuilder().withName("Some wrong name").withSetMember(concept).build(); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(getConceptSets(parentConcept, concept)); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{concept}); + assertNotNull(events.get(0)); + assertEquals(events.get(0).getTitle(), "sample"); + assertEquals(events.get(0).getCategory(), "lab"); + } + + @Test + public void createEventForSampleWithParentConceptMissing() throws Exception { + Concept sampleConcept = new ConceptBuilder().withClass("Sample").withUUID("SampleUUID").build(); + List events = new Operation(ConceptService.class.getMethod("saveConcept", Concept.class)).apply(new Object[]{sampleConcept}); + Event event = events.get(0); + assertNotNull(event); + assertEquals(event.getTitle(), ConceptServiceEventFactory.SAMPLE); + assertEquals(event.getCategory(), ConceptServiceEventFactory.LAB); + } + +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImplIT.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImplIT.java new file mode 100644 index 0000000000..ab5cc81478 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImplIT.java @@ -0,0 +1,30 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.BaseIntegrationTest; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptReferenceTermService; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.ConceptReferenceTerm; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class ReferenceDataConceptReferenceTermServiceImplIT extends BaseIntegrationTest { + + @Autowired + private ReferenceDataConceptReferenceTermService referenceDataConceptReferenceTermService; + + @Before + public void setUp() throws Exception { + executeDataSet("referenceTermSetup.xml"); + } + + @Test + public void shouldGetConceptMapping() throws Exception { + ConceptReferenceTerm referenceTerm = referenceDataConceptReferenceTermService.getConceptReferenceTerm("New Code", "org.openmrs.module.emrapi"); + assertNotNull(referenceTerm); + assertEquals("New Code", referenceTerm.getCode()); + assertEquals("org.openmrs.module.emrapi", referenceTerm.getConceptSource().getName()); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImplTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImplTest.java new file mode 100644 index 0000000000..5044483f9a --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptReferenceTermServiceImplTest.java @@ -0,0 +1,74 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.ConceptReferenceTerm; +import org.openmrs.ConceptSource; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; + +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.when; + +public class ReferenceDataConceptReferenceTermServiceImplTest { + + @InjectMocks + private ReferenceDataConceptReferenceTermServiceImpl referenceDataConceptReferenceTermService = new ReferenceDataConceptReferenceTermServiceImpl(); + + @Mock + private ConceptService conceptService; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void shouldThrowExceptionIfConceptReferenceSourceNotFound() throws Exception { + when(conceptService.getConceptSourceByName(anyString())).thenReturn(null); + ConceptReferenceTerm conceptReferenceTerm = new ConceptReferenceTerm(); + conceptReferenceTerm.setConceptSource(new ConceptSource()); + when(conceptService.getConceptReferenceTermByCode(anyString(), any(ConceptSource.class))).thenReturn(conceptReferenceTerm); + exception.expect(APIException.class); + exception.expectMessage("Concept reference source not found"); + referenceDataConceptReferenceTermService.getConceptReferenceTerm("some", "some"); + fail("Should throw API exception as there is no concept reference source"); + } + + @Test + public void shouldThrowExceptionIfConceptReferenceTermNotFound() throws Exception { + when(conceptService.getConceptSourceByName(anyString())).thenReturn(new ConceptSource()); + when(conceptService.getConceptReferenceTermByCode(anyString(), any(ConceptSource.class))).thenReturn(null); + exception.expect(APIException.class); + exception.expectMessage("Concept reference term code not found"); + referenceDataConceptReferenceTermService.getConceptReferenceTerm("some", "some"); + fail("Should throw API exception as there is no concept reference term"); + } + + @Test + public void shouldThrowExceptionIfConceptReferenceTermNotMappedToSource() throws Exception { + ConceptSource source = new ConceptSource(1); + ConceptSource termSource = new ConceptSource(2); + source.setUuid("source"); + when(conceptService.getConceptSourceByName(anyString())).thenReturn(source); + termSource.setUuid("termSource"); + ConceptReferenceTerm conceptReferenceTerm = new ConceptReferenceTerm(); + conceptReferenceTerm.setConceptSource(termSource); + when(conceptService.getConceptReferenceTermByCode(anyString(), any(ConceptSource.class))).thenReturn(conceptReferenceTerm); + exception.expect(APIException.class); + exception.expectMessage("Concept reference term not mapped to the given source"); + referenceDataConceptReferenceTermService.getConceptReferenceTerm("some", "some"); + fail("Should throw API exception because concept reference term not mapped to concept reference source"); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptServiceImplIT.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptServiceImplIT.java new file mode 100644 index 0000000000..449a88d745 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataConceptServiceImplIT.java @@ -0,0 +1,423 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.BaseIntegrationTest; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptReferenceTerm; +import org.bahmni.module.referencedata.labconcepts.contract.ConceptSet; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataConceptService; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptMap; +import org.openmrs.ConceptNumeric; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptInUseException; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +public class ReferenceDataConceptServiceImplIT extends BaseIntegrationTest { + + @Autowired + private ReferenceDataConceptService referenceDataConceptService; + + @Autowired + private ConceptService conceptService; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + executeDataSet("labDataSetup.xml"); + } + + @Test + public void shouldSaveNewConceptSet() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + String uniqueName = "uniqueName"; + conceptSet.setUniqueName(uniqueName); + String displayName = "displayName"; + conceptSet.setDisplayName(displayName); + conceptSet.setClassName("Finding"); + String description = "Description"; + conceptSet.setDescription(description); + ConceptReferenceTerm conceptReferenceTerm = new ConceptReferenceTerm(); + conceptReferenceTerm.setReferenceTermCode("New Code"); + conceptReferenceTerm.setReferenceTermRelationship("SAME-AS"); + conceptReferenceTerm.setReferenceTermSource("org.openmrs.module.emrapi"); +// List conceptReferenceTerms = new ArrayList<>(); +// conceptReferenceTerms.add(conceptReferenceTerm); + conceptSet.getConceptReferenceTermsList().add(conceptReferenceTerm); + + Concept concept = referenceDataConceptService.saveConcept(conceptSet); + + assertTrue(concept.getSet()); + assertEquals(uniqueName, concept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortNames().iterator().next().getName()); + assertEquals("Finding", concept.getConceptClass().getName()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + Collection conceptMappings = concept.getConceptMappings(); + ConceptMap conceptMap = conceptMappings.iterator().next(); + assertEquals("New Code", conceptMap.getConceptReferenceTerm().getCode()); + assertEquals("org.openmrs.module.emrapi",conceptMap.getConceptReferenceTerm().getConceptSource().getName()); + assertEquals("same-as",conceptMap.getConceptMapType().toString()); + assertEquals(ConceptDatatype.N_A_UUID, concept.getDatatype().getUuid()); + } + + @Test + public void failIfConceptClassNotFound() throws Throwable { + ConceptSet conceptSet = new ConceptSet(); + String uniqueName = "uniqueName"; + conceptSet.setUniqueName(uniqueName); + String displayName = "displayName"; + conceptSet.setDisplayName(displayName); + conceptSet.setClassName("Illegal"); + + exception.expect(APIException.class); + exception.expectMessage("Concept Class Illegal not found"); + + referenceDataConceptService.saveConcept(conceptSet); + } + + @Test + public void shouldSaveConceptSetWithChildMembers() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + String uniqueName = "uniqueName"; + conceptSet.setUniqueName(uniqueName); + String displayName = "displayName"; + conceptSet.setDisplayName(displayName); + conceptSet.setClassName("Finding"); + conceptSet.setDescription("concept set"); + List children = new ArrayList<>(); + children.add("Child1"); + children.add("Child2"); + conceptSet.setChildren(children); + Concept concept = referenceDataConceptService.saveConcept(conceptSet); + List setMembers = concept.getSetMembers(); + assertEquals(2, setMembers.size()); + assertEquals("Child1", setMembers.get(0).getName(Context.getLocale()).getName()); + assertEquals("Child2", setMembers.get(1).getName(Context.getLocale()).getName()); + assertEquals(ConceptDatatype.N_A_UUID, concept.getDatatype().getUuid()); + } + + @Test + public void throwExceptionifChildConceptDoesntExist() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + String uniqueName = "uniqueName"; + conceptSet.setUniqueName(uniqueName); + String displayName = "displayName"; + conceptSet.setDisplayName(displayName); + conceptSet.setClassName("Finding"); + List children = new ArrayList<>(); + children.add("Child1"); + children.add("Child3"); + children.add("Child4"); + conceptSet.setChildren(children); + + exception.expect(APIException.class); + exception.expectMessage("Child3 Concept/ConceptAnswer not found\nChild4 Concept/ConceptAnswer not found"); + + referenceDataConceptService.saveConcept(conceptSet); + } + + + @Test + public void updateExistingConceptSet() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + String uniqueName = "Existing Concept"; + conceptSet.setUniqueName(uniqueName); + String displayName = "NewSName"; + conceptSet.setDisplayName(displayName); + conceptSet.setClassName("Finding"); + List children = new ArrayList<>(); + String description = "Description"; + conceptSet.setDescription(description); + + children.add("Child1"); + children.add("Child2"); + conceptSet.setChildren(children); + Concept concept = referenceDataConceptService.saveConcept(conceptSet); + + assertTrue(concept.getSet()); + assertEquals(uniqueName, concept.getName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals("Finding", concept.getConceptClass().getName()); + assertEquals(2, concept.getSetMembers().size()); + assertEquals("5d2d4cb7-mm3b-0037-70f7-0dmimmm22222", concept.getUuid()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + assertEquals(ConceptDatatype.N_A_UUID, concept.getDatatype().getUuid()); + } + + @Test + public void updateExistingConceptSetWithUUID() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + conceptSet.setUuid("5d2d4cb7-mm3b-0037-70f7-0dmimmm22222"); + String uniqueName = "Existing Concept New"; + conceptSet.setUniqueName(uniqueName); + String displayName = "NewSName"; + conceptSet.setDisplayName(displayName); + conceptSet.setClassName("Finding"); + List children = new ArrayList<>(); + String description = "Description"; + conceptSet.setDescription(description); + + children.add("Child1"); + children.add("Child2"); + conceptSet.setChildren(children); + Concept concept = referenceDataConceptService.saveConcept(conceptSet); + + assertTrue(concept.getSet()); + assertEquals(uniqueName, concept.getName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals("Finding", concept.getConceptClass().getName()); + assertEquals(2, concept.getSetMembers().size()); + assertEquals("5d2d4cb7-mm3b-0037-70f7-0dmimmm22222", concept.getUuid()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + assertEquals(ConceptDatatype.N_A_UUID, concept.getDatatype().getUuid()); + } + + @Test + public void createConceptWithUnits() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + concept.setUuid("5d2d4cb7-mm3b-0037-70k7-0dmimtm22222"); + String uniqueName = "Some Numeric Concept"; + concept.setUniqueName(uniqueName); + String displayName = "NumericConcept"; + concept.setDisplayName(displayName); + concept.setClassName("Finding"); + String description = "Description"; + concept.setDataType("Numeric"); + concept.setDescription(description); + concept.setUnits("unit"); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals(uniqueName, savedConcept.getName(Context.getLocale()).getName()); + assertEquals(displayName, savedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals("Finding", savedConcept.getConceptClass().getName()); + assertEquals(0, savedConcept.getSetMembers().size()); + assertEquals(description, savedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(ConceptDatatype.NUMERIC_UUID, savedConcept.getDatatype().getUuid()); + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(savedConcept.getConceptId()); + assertTrue(savedConcept.isNumeric()); + assertEquals("unit", conceptNumeric.getUnits()); + } + + @Test + public void createConceptWithHighNormalAndLowNormal() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + concept.setUuid("5d2d4cb7-mm3b-0037-70k7-0dmimtm22222"); + String uniqueName = "Some Numeric Concept"; + concept.setUniqueName(uniqueName); + String displayName = "NumericConcept"; + concept.setDisplayName(displayName); + concept.setClassName("Finding"); + String description = "Description"; + concept.setDataType("Numeric"); + concept.setDescription(description); + concept.setUnits("unit"); + concept.setHiNormal("99"); + concept.setLowNormal("10"); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals(uniqueName, savedConcept.getName(Context.getLocale()).getName()); + assertEquals(displayName, savedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals("Finding", savedConcept.getConceptClass().getName()); + assertEquals(0, savedConcept.getSetMembers().size()); + assertEquals(description, savedConcept.getDescription(Context.getLocale()).getDescription()); + assertEquals(ConceptDatatype.NUMERIC_UUID, savedConcept.getDatatype().getUuid()); + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(savedConcept.getConceptId()); + assertTrue(savedConcept.isNumeric()); + assertEquals("unit", conceptNumeric.getUnits()); + assertTrue(conceptNumeric.getHiNormal().equals(99.0)); + assertTrue(conceptNumeric.getLowNormal().equals(10.0)); + } + + @Test + public void updateExistingConceptShortname() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + concept.setUuid("5d2d4cb7-feet-0037-70f7-0dmimmm22222"); + String uniqueName = "Existing Numeric Concept"; + concept.setUniqueName(uniqueName); + String displayName = "NumericConcept"; + concept.setDisplayName(displayName); + concept.setClassName("Finding"); + concept.setDataType("Numeric"); + concept.setUnits("unit"); + concept.setDescription("description"); + + assertEquals(2, conceptService.getConceptByUuid("5d2d4cb7-mm3b-0037-70f7-0dmimmm22222").getNames().size()); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals(4, savedConcept.getNames().size()); + assertEquals(uniqueName, savedConcept.getName(Context.getLocale()).getName()); + assertEquals(displayName, savedConcept.getShortNames().iterator().next().getName()); + assertEquals("Finding", savedConcept.getConceptClass().getName()); + assertEquals(0, savedConcept.getSetMembers().size()); + assertEquals(ConceptDatatype.NUMERIC_UUID, savedConcept.getDatatype().getUuid()); + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(savedConcept.getConceptId()); + assertTrue(savedConcept.isNumeric()); + assertEquals("unit", conceptNumeric.getUnits()); + } + + @Test + public void updateExistingConceptNumericWithHighNormalAndLowNormal() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + concept.setUuid("5d2d4cb7-feet-0037-70f7-0dmimmm22222"); + String uniqueName = "Existing Numeric Concept"; + concept.setUniqueName(uniqueName); + String displayName = "NumericConcept"; + concept.setDisplayName(displayName); + concept.setClassName("Finding"); + concept.setDataType("Numeric"); + concept.setUnits("unit"); + concept.setHiNormal("99"); + concept.setLowNormal("10"); + concept.setDescription("existing numeric concept"); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals(uniqueName, savedConcept.getName(Context.getLocale()).getName()); + assertEquals(displayName, savedConcept.getShortestName(Context.getLocale(), false).getName()); + assertEquals("Finding", savedConcept.getConceptClass().getName()); + assertEquals(0, savedConcept.getSetMembers().size()); + assertEquals(ConceptDatatype.NUMERIC_UUID, savedConcept.getDatatype().getUuid()); + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(savedConcept.getConceptId()); + assertTrue(savedConcept.isNumeric()); + assertEquals("unit", conceptNumeric.getUnits()); + assertTrue(conceptNumeric.getHiNormal().equals(99.0)); + assertTrue(conceptNumeric.getLowNormal().equals(10.0)); + } + + @Test + public void throwExceptionifConceptHasObs() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + concept.setUuid("5d2d4cb7-t3tb-0037-70f7-0dmimmm22222"); + String uniqueName = "New Numeric Concept"; + concept.setUniqueName(uniqueName); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + concept.setUnits("unit"); + concept.setHiNormal("99"); + concept.setLowNormal("10"); + concept.setDescription("description"); + Concept existingConcept = conceptService.getConceptByUuid(concept.getUuid()); + assertNotEquals(ConceptDatatype.N_A_UUID, existingConcept.getDatatype().getUuid()); + + exception.expect(ConceptInUseException.class); + exception.expectMessage("The concepts datatype cannot be changed if it is already used/associated to an observation"); + referenceDataConceptService.saveConcept(concept); + } + + @Test + public void updateExistingConceptWithShortName() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + String uniqueName = "Existing Concept with obs"; + concept.setUniqueName(uniqueName); + String displayName = "NewShortName"; + concept.setDisplayName(displayName); + concept.setClassName("Finding"); + concept.setDescription("description"); + concept.setDataType("Coded"); + Concept existingConcept = conceptService.getConceptByName("Existing Concept with obs"); + assertEquals(1, existingConcept.getNames().size()); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals(uniqueName, savedConcept.getName(Context.getLocale()).getName()); + assertEquals(displayName, savedConcept.getShortNameInLocale(Context.getLocale()).getName()); + assertEquals("Finding", savedConcept.getConceptClass().getName()); + assertEquals(3, savedConcept.getNames().size()); + } + + @Test + public void updateExistingConceptSetWithChildMembers() throws Exception { + ConceptSet conceptSet = new ConceptSet(); + String uniqueName = "Existing Concept With Children"; + conceptSet.setUniqueName(uniqueName); + String displayName = "NewSName"; + conceptSet.setDisplayName(displayName); + conceptSet.setDescription("description"); + conceptSet.setClassName("Finding"); + List children = new ArrayList<>(); + + children.add("Child1"); + children.add("Child2"); + conceptSet.setChildren(children); + Concept existingConceptSet = conceptService.getConceptByName("Existing Concept With Children"); + assertEquals(1, existingConceptSet.getSetMembers().size()); + Concept concept = referenceDataConceptService.saveConcept(conceptSet); + + assertTrue(concept.getSet()); + assertEquals(uniqueName, concept.getName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals("Finding", concept.getConceptClass().getName()); + assertEquals(2, concept.getSetMembers().size()); + assertEquals("kf2d4cb7-t3tb-0037-70f7-0dmimmm22222", concept.getUuid()); + assertEquals(ConceptDatatype.N_A_UUID, concept.getDatatype().getUuid()); + } + + + @Test + public void updateExistingConceptWithAnswers() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + String uniqueName = "Existing Concept With Answer"; + concept.setUniqueName(uniqueName); + String displayName = "NewSName"; + concept.setDisplayName(displayName); + concept.setClassName("Finding"); + concept.setDataType("Coded"); + concept.setDescription("description"); + + List answers = new ArrayList<>(); + + answers.add("Answer1"); + answers.add("Answer2"); + concept.setAnswers(answers); + Concept existingConcept = conceptService.getConceptByName("Existing Concept With Answer"); + assertEquals(1, existingConcept.getAnswers().size()); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals(2, savedConcept.getAnswers().size()); + ArrayList conceptAnswers = new ArrayList<>(savedConcept.getAnswers()); + ConceptAnswer answer1 = conceptAnswers.get(0); + ConceptAnswer answer2 = conceptAnswers.get(1); + assertEquals("Answer1", answer1.getAnswerConcept().getName(Context.getLocale()).getName()); + assertEquals("Answer2", answer2.getAnswerConcept().getName(Context.getLocale()).getName()); + } + + @Test + public void migrateConceptDatatypeToNumeric() throws Exception { + org.bahmni.module.referencedata.labconcepts.contract.Concept concept = new org.bahmni.module.referencedata.labconcepts.contract.Concept(); + concept.setUuid("kf2d4cb7-t3tb-oo37-70f7-0dmimmm22222"); + concept.setClassName("Finding"); + concept.setDescription("some description"); + concept.setDataType("Numeric"); + concept.setUnits("unit"); + concept.setHiNormal("99"); + concept.setLowNormal("10"); + + Concept existingConcept = conceptService.getConceptByUuid("kf2d4cb7-t3tb-oo37-70f7-0dmimmm22222"); + assertNotEquals(ConceptDatatype.NUMERIC_UUID, existingConcept.getDatatype().getUuid()); + Concept savedConcept = referenceDataConceptService.saveConcept(concept); + + assertEquals("First Child", savedConcept.getName(Context.getLocale()).getName()); + assertEquals("Finding", savedConcept.getConceptClass().getName()); + assertEquals(0, savedConcept.getSetMembers().size()); + assertEquals(ConceptDatatype.NUMERIC_UUID, savedConcept.getDatatype().getUuid()); + ConceptNumeric conceptNumeric = conceptService.getConceptNumeric(savedConcept.getConceptId()); + assertTrue(savedConcept.isNumeric()); + assertEquals("unit", conceptNumeric.getUnits()); + assertTrue(conceptNumeric.getHiNormal().equals(99.0)); + assertTrue(conceptNumeric.getLowNormal().equals(10.0)); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImplIT.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImplIT.java new file mode 100644 index 0000000000..e330b0c5f6 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImplIT.java @@ -0,0 +1,123 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.BaseIntegrationTest; +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.service.ReferenceDataDrugService; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openmrs.ConceptClass; +import org.openmrs.api.APIException; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +public class ReferenceDataDrugServiceImplIT extends BaseIntegrationTest { + + @Autowired + private ReferenceDataDrugService referenceDataDrugService; + + @Before + public void setUp() throws Exception { + executeDataSet("drugSetup.xml"); + } + + @Test(expected = APIException.class) + public void createNewDrugWithNewConceptNewDosageFormShouldFail() throws Exception { + Drug drug = new Drug(); + drug.setName("New Drug"); + drug.setGenericName("Drug Concept name"); + drug.setMinimumDose("12"); + drug.setMaximumDose("15"); + drug.setCombination(false); + drug.setStrength("Very Strong"); + drug.setDosageForm("Unknown123"); + referenceDataDrugService.saveDrug(drug); + } + + @Test(expected=APIException.class) + public void existingDrugExistingConceptNewDosageFormShouldFail() throws Exception { + Drug drug = new Drug(); + drug.setName("Existing Drug"); + drug.setGenericName("Old Drug Concept"); + drug.setMinimumDose("12"); + drug.setMaximumDose("15"); + drug.setCombination(false); + drug.setStrength("Very Strong"); + drug.setDosageForm("Unknown123"); + referenceDataDrugService.saveDrug(drug); + } + + @Test + public void existingDrugExistingConceptExistingDosageForm() throws Exception { + Drug drug = new Drug(); + drug.setName("Existing Drug"); + drug.setGenericName("Old Drug Concept"); + drug.setMinimumDose("12"); + drug.setMaximumDose("15"); + drug.setCombination(false); + drug.setStrength("Very Strong"); + drug.setDosageForm("Capsule"); + org.openmrs.Drug savedDrug = referenceDataDrugService.saveDrug(drug); + assertFalse(savedDrug.getCombination()); + assertEquals("Existing Drug", savedDrug.getName()); + assertEquals("Old Drug Concept", savedDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals(ConceptClass.DRUG_UUID, savedDrug.getConcept().getConceptClass().getUuid()); + assertEquals("Capsule", savedDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertEquals("Very Strong", savedDrug.getStrength()); + assertTrue(savedDrug.getMaximumDailyDose().equals(drug.doubleMaximumDose())); + assertTrue(savedDrug.getMinimumDailyDose().equals(drug.doubleMinimumDose())); + } + + + @Test + public void newDrugExistingConceptExistingDosageForm() throws Exception { + Drug drug = new Drug(); + drug.setName("New Drug"); + drug.setGenericName("Old Drug Concept"); + drug.setMinimumDose("12"); + drug.setMaximumDose("15"); + drug.setCombination(false); + drug.setStrength("Very Strong"); + drug.setDosageForm("Capsule"); + org.openmrs.Drug savedDrug = referenceDataDrugService.saveDrug(drug); + assertFalse(savedDrug.getCombination()); + assertEquals("New Drug", savedDrug.getName()); + assertEquals("Old Drug Concept", savedDrug.getConcept().getName(Context.getLocale()).getName()); + assertEquals(ConceptClass.DRUG_UUID, savedDrug.getConcept().getConceptClass().getUuid()); + assertEquals("Capsule", savedDrug.getDosageForm().getName(Context.getLocale()).getName()); + assertEquals("Very Strong", savedDrug.getStrength()); + assertTrue(savedDrug.getMaximumDailyDose().equals(drug.doubleMaximumDose())); + assertTrue(savedDrug.getMinimumDailyDose().equals(drug.doubleMinimumDose())); + } + + @Test + @Ignore + public void sameDrugMultipleTimes() throws Exception { + Drug drug = new Drug(); + drug.setName("NEW DRUG"); + drug.setGenericName("Old Drug Concept"); + drug.setMinimumDose("12"); + drug.setMaximumDose("15"); + drug.setCombination(false); + drug.setStrength("Very Strong"); + drug.setDosageForm("Capsule"); + org.openmrs.Drug savedDrug1 = referenceDataDrugService.saveDrug(drug); + org.openmrs.Drug savedDrug2 = referenceDataDrugService.saveDrug(drug); + assertEquals(savedDrug1.getUuid(), savedDrug2.getUuid()); + + drug.setDosageForm("Tablet"); + savedDrug2 = referenceDataDrugService.saveDrug(drug); + assertNotEquals(savedDrug1.getUuid(), savedDrug2.getUuid()); + + drug.setDosageForm("Capsule"); + drug.setGenericName("Random Drug Concept"); + savedDrug2 = referenceDataDrugService.saveDrug(drug); + assertEquals(savedDrug1.getUuid(), savedDrug2.getUuid()); + assertEquals("Random Drug Concept",savedDrug2.getConcept().getName().getName()); //Updated one + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImplTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImplTest.java new file mode 100644 index 0000000000..51b75ec5f8 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/labconcepts/service/impl/ReferenceDataDrugServiceImplTest.java @@ -0,0 +1,72 @@ +package org.bahmni.module.referencedata.labconcepts.service.impl; + +import org.bahmni.module.referencedata.labconcepts.contract.Drug; +import org.bahmni.module.referencedata.labconcepts.model.DrugMetaData; +import org.bahmni.module.referencedata.labconcepts.service.DrugMetaDataService; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.api.APIException; +import org.openmrs.api.ConceptService; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class ReferenceDataDrugServiceImplTest { + + private ReferenceDataDrugServiceImpl referenceDataDrugService; + + @Mock + private ConceptService conceptService; + + @Mock + private DrugMetaDataService drugMetaDataService; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(drugMetaDataService.getDrugMetaData((Drug)anyObject())).thenReturn(new DrugMetaData(new org.openmrs.Drug(), new Concept(), new Concept(), new ConceptClass())); + referenceDataDrugService = new ReferenceDataDrugServiceImpl(conceptService, drugMetaDataService); + } + + @Test + public void throwErrorIfDrugNameNotDefined() throws Exception { + Drug drugData = new Drug(); + exception.expect(APIException.class); + exception.expectMessage("Drug name is mandatory"); + referenceDataDrugService.saveDrug(drugData); + } + + @Test + public void throwErrorIfDrugGenericNameNotDefined() throws Exception { + Drug drug = new Drug(); + drug.setName("Drug Name"); + exception.expect(APIException.class); + exception.expectMessage("Drug generic name is mandatory"); + referenceDataDrugService.saveDrug(drug); + } + + @Test + public void saveNewDrug() throws Exception { + Drug drugData = new Drug(); + drugData.setName("Drug Name"); + drugData.setGenericName("Concept name"); + Concept drugConcept = new ConceptBuilder().withName("Concept Name").withClassUUID(ConceptClass.DRUG_UUID).build(); + org.openmrs.Drug drugSave = new org.openmrs.Drug(); + drugSave.setConcept(drugConcept); + drugSave.setName("Drug Name"); + referenceDataDrugService.saveDrug(drugData); + verify(conceptService).saveDrug(any(org.openmrs.Drug.class)); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java new file mode 100644 index 0000000000..93b070b8bb --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllSamplesMapperTest.java @@ -0,0 +1,87 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.bahmni.module.referencedata.labconcepts.mapper.AllSamplesMapper; +import org.bahmni.module.referencedata.labconcepts.mapper.SampleMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class AllSamplesMapperTest { + + private AllSamplesMapper allSamplesMapper; + private SampleMapper sampleMapper; + private Concept sampleConcept; + private Date dateCreated; + private Date dateChanged; + private Concept labSampleConceptSet; + + + @Mock + private ConceptService conceptService; + + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + allSamplesMapper = new AllSamplesMapper(); + sampleMapper = new SampleMapper(); + dateCreated = new Date(); + dateChanged = new Date(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") + .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).build(); + + sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). + withDateChanged(dateChanged).withSetMember(testConcept).withShortName("ShortName").withName("SampleName").build(); + + labSampleConceptSet = new ConceptBuilder().withUUID("Lab Samples UUID").withDateCreated(dateCreated).withDateChanged(dateChanged) + .withName(AllSamples.ALL_SAMPLES).withClassUUID(ConceptClass.LABSET_UUID).withShortName("Lab samples short name").withDescription("Lab samples Description") + .withSetMember(sampleConcept).build(); + + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapAllSampleFieldsFromConcept() throws Exception { + + AllSamples labSamplesData = allSamplesMapper.map(labSampleConceptSet); + Sample sampleData = sampleMapper.map(sampleConcept); + assertEquals("Lab Samples UUID", labSamplesData.getId()); + assertEquals("Lab Samples", labSamplesData.getName()); + assertEquals(dateCreated, labSamplesData.getDateCreated()); + assertEquals(dateChanged, labSamplesData.getLastUpdated()); + assertEquals("Lab samples Description", labSamplesData.getDescription()); + List samples = labSamplesData.getSamples(); + assertEquals(1, samples.size()); + assertEquals(sampleData.getId(), samples.get(0).getId()); + } + +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java new file mode 100644 index 0000000000..3335cfa7ce --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AllTestsAndPanelsMapperTest.java @@ -0,0 +1,118 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Panel; +import org.bahmni.module.referencedata.labconcepts.contract.TestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.mapper.AllTestsAndPanelsMapper; +import org.bahmni.module.referencedata.labconcepts.mapper.LabTestMapper; +import org.bahmni.module.referencedata.labconcepts.mapper.PanelMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.Locale; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class AllTestsAndPanelsMapperTest { + private AllTestsAndPanelsMapper allTestsAndPanelsMapper; + private LabTestMapper testMapper; + private Date dateChanged; + private Date dateCreated; + private Concept testConcept; + private Concept panelConcept; + private Concept testAndPanelsConcept; + @Mock + private ConceptService conceptService; + private PanelMapper panelMapper; + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + allTestsAndPanelsMapper = new AllTestsAndPanelsMapper(); + testMapper = new LabTestMapper(); + panelMapper = new PanelMapper(); + dateCreated = new Date(); + dateChanged = new Date(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + + testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") + .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).build(); + + panelConcept = new ConceptBuilder().withUUID("Panel UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID).withDescription("SomeDescription") + .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name").withDataType(ConceptDatatype.NUMERIC).build(); + testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID).withDescription("Test and Panel Description") + .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(testConcept).withSetMember(panelConcept).build(); + + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapAllTestsAndPanelsFieldsFromConcept() throws Exception { + + AllTestsAndPanels allTestsAndPanels = allTestsAndPanelsMapper.map(testAndPanelsConcept); + LabTest testData = testMapper.map(testConcept); + Panel panelData = panelMapper.map(panelConcept); + + assertEquals("Test and Panels UUID", allTestsAndPanels.getId()); + assertEquals("All_Tests_and_Panels", allTestsAndPanels.getName()); + assertEquals(dateCreated, allTestsAndPanels.getDateCreated()); + assertEquals(dateChanged, allTestsAndPanels.getLastUpdated()); + assertEquals("Test and Panel Description", allTestsAndPanels.getDescription()); + + TestsAndPanels testsAndPanels = allTestsAndPanels.getTestsAndPanels(); + Set tests = testsAndPanels.getTests(); + assertEquals(1, tests.size()); + assertEquals(testData.getId(), tests.iterator().next().getId()); + + Set panels = testsAndPanels.getPanels(); + assertEquals(1, panels.size()); + assertEquals(panelData.getId(), panels.iterator().next().getId()); + } + + @Test + public void shouldNotMapTheTestOrPanelWhichIsRetired() throws Exception { + Concept testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") + .withDateChanged(dateChanged).withShortName("ShortName").withName("Test concept").withDataType(ConceptDatatype.NUMERIC).withRetired(true).build(); + Concept panelConcept = new ConceptBuilder().withUUID("Panel UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID).withDescription("SomeDescription") + .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name").withDataType(ConceptDatatype.NUMERIC).withRetired(true).build(); + Concept testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID).withDescription("Test and Panel Description") + .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(testConcept).withSetMember(panelConcept).build(); + AllTestsAndPanels allTestsAndPanels = allTestsAndPanelsMapper.map(testAndPanelsConcept); + + assertEquals("Test and Panels UUID", allTestsAndPanels.getId()); + assertEquals("All_Tests_and_Panels", allTestsAndPanels.getName()); + assertEquals(dateCreated, allTestsAndPanels.getDateCreated()); + assertEquals(dateChanged, allTestsAndPanels.getLastUpdated()); + assertEquals("Test and Panel Description", allTestsAndPanels.getDescription()); + + TestsAndPanels testsAndPanels = allTestsAndPanels.getTestsAndPanels(); + Set tests = testsAndPanels.getTests(); + assertEquals(0, tests.size()); + + Set panels = testsAndPanels.getPanels(); + assertEquals(0, panels.size()); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AttributableResourceMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AttributableResourceMapperTest.java new file mode 100644 index 0000000000..d4d1cb51ba --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/AttributableResourceMapperTest.java @@ -0,0 +1,62 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Resource; +import org.bahmni.module.referencedata.labconcepts.mapper.AttributableResourceMapper; +import org.bahmni.module.referencedata.labconcepts.model.event.SaleableTypeEvent; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptAttribute; +import org.openmrs.ConceptAttributeType; + +public class AttributableResourceMapperTest { + + private AttributableResourceMapper resourceMapper; + + + + @Before + public void setUp() throws Exception { + resourceMapper = new AttributableResourceMapper(); + } + + @Test + public void shouldMapConceptAttributesAsResourceProperties() throws Exception { + Concept procedureConcept = new ConceptBuilder() + .withClass("Procedure") + .withUUID("9d583329-5fb1-4e50-9420-dcbbf6991fbc") + .withName("Sample Procedure") + .withDescription("Sample Procedure") + .withDataType("N/A").build(); + + ConceptAttributeType saleableAttributeType = new ConceptAttributeType(); + saleableAttributeType.setDatatypeClassname("org.openmrs.customdatatype.datatype.BooleanDatatype"); + saleableAttributeType.setName(SaleableTypeEvent.SALEABLE_ATTR_NAME); + + ConceptAttribute saleableAttribute = new ConceptAttribute(); + saleableAttribute.setAttributeType(saleableAttributeType); + saleableAttribute.setVoided(false); + saleableAttribute.setValueReferenceInternal("true"); + procedureConcept.addAttribute(saleableAttribute); + + + ConceptAttributeType attributeUnderTest = new ConceptAttributeType(); + attributeUnderTest.setDatatypeClassname("java.lang.String"); + attributeUnderTest.setName("product_category"); + + ConceptAttribute testAttribute = new ConceptAttribute(); + testAttribute.setAttributeType(attributeUnderTest); + testAttribute.setVoided(false); + testAttribute.setValueReferenceInternal("Dental"); + procedureConcept.addAttribute(testAttribute); + + + Resource resource = resourceMapper.map(procedureConcept); + Assert.assertEquals("true", resource.getProperties().get(SaleableTypeEvent.SALEABLE_ATTR_NAME)); + Assert.assertEquals("Dental", resource.getProperties().get("product_category")); + + } + +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/ConceptMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/ConceptMapperTest.java new file mode 100644 index 0000000000..4b73a62baf --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/ConceptMapperTest.java @@ -0,0 +1,318 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Concept; +import org.bahmni.module.referencedata.labconcepts.mapper.ConceptMapper; +import org.bahmni.module.referencedata.labconcepts.model.ConceptMetaData; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openmrs.ConceptAnswer; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptDescription; +import org.openmrs.ConceptName; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@RunWith(PowerMockRunner.class) +@PrepareForTest(Context.class) +public class ConceptMapperTest { + private ConceptMapper conceptMapper; + + @Mock + ConceptMetaData conceptMetaData; + + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + conceptMapper = new ConceptMapper(); + } + + @Test + public void shouldMapRequestConceptToOpenMRSConcept() { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setDisplayName("displayName"); + concept.setDescription("description"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + ArrayList synonyms = new ArrayList<>(); + synonyms.add("1"); + synonyms.add("2"); + concept.setSynonyms(synonyms); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + ConceptMetaData conceptMetaData = new ConceptMetaData(null, conceptDatatype, conceptClassName, null); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(concept.getDisplayName(), mappedConcept.getShortNames().iterator().next().getName()); + assertEquals(concept.getDescription(), mappedConcept.getDescription().getDescription()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals(2, mappedConcept.getSynonyms().size()); + for (ConceptName conceptName : mappedConcept.getSynonyms()) { + assertTrue(conceptName.getName().equals("1") || conceptName.getName().equals("2")); + } + } + + @Test + public void shouldMapRequestConceptToOpenMRSConceptWhenLocaleIsSet() { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setDisplayName("displayName"); + concept.setDescription("description"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + ArrayList synonyms = new ArrayList<>(); + synonyms.add("1"); + synonyms.add("2"); + concept.setSynonyms(synonyms); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + + Locale frenchLocale = new Locale("fr", "FR"); + ConceptMetaData conceptMetaData = new ConceptMetaData(null, conceptDatatype, conceptClassName, frenchLocale); + + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(frenchLocale).getName()); + assertEquals(concept.getDisplayName(), mappedConcept.getShortNames().iterator().next().getName()); + assertEquals(concept.getDescription(), mappedConcept.getDescription(frenchLocale).getDescription()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals(2, mappedConcept.getSynonyms().size()); + for (ConceptName conceptName : mappedConcept.getSynonyms()) { + assertTrue(conceptName.getName().equals("1") || conceptName.getName().equals("2")); + } + } + + @Test + public void shouldMapConceptIfDescriptionIsNull() { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setDisplayName("displayName"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + + ConceptMetaData conceptMetaData = new ConceptMetaData(null, conceptDatatype, conceptClassName, null); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(concept.getDisplayName(), mappedConcept.getShortNames().iterator().next().getName()); + assertNull(mappedConcept.getDescription()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + } + + @Test + public void shouldMapConceptIfDisplayNameAndDescriptionIsNull() { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + + ConceptMetaData conceptMetaData = new ConceptMetaData(null, conceptDatatype, conceptClassName, null); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(0, mappedConcept.getShortNames().size()); + assertNull(mappedConcept.getDescription()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + } + + @Test + public void shouldMapCodedConceptWithAnswer() { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setClassName("Finding"); + concept.setDataType("Coded"); + concept.setAnswers(new ArrayList<>(Arrays.asList("answer-concept-name"))); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("Coded"); + List answers = new ArrayList<>(); + org.openmrs.Concept answerConcept = new org.openmrs.Concept(); + answerConcept.setFullySpecifiedName(new ConceptName("answer-concept-name", Context.getLocale())); + answers.add(new ConceptAnswer(answerConcept)); + + ConceptMetaData conceptMetaData = new ConceptMetaData(null, conceptDatatype, conceptClassName, null); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, answers); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(0, mappedConcept.getShortNames().size()); + assertNull(mappedConcept.getDescription()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals(concept.getAnswers().iterator().next(), mappedConcept.getAnswers().iterator().next().getAnswerConcept().getName(Context.getLocale()).getName()); + } + + @Test + public void shouldAllowToMapExistingConcepts() throws Exception { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setDisplayName("displayName"); + concept.setDescription("description"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + ArrayList synonyms = new ArrayList<>(); + synonyms.add("1"); + synonyms.add("2"); + concept.setSynonyms(synonyms); + org.openmrs.Concept existingConcept = new ConceptBuilder().withName("uniqueName").withShortName("displayName").build(); + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + + ConceptMetaData conceptMetaData = new ConceptMetaData(existingConcept, conceptDatatype, conceptClassName, null); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(concept.getDisplayName(), mappedConcept.getShortNames().iterator().next().getName()); + assertEquals(concept.getDescription(), mappedConcept.getDescription().getDescription()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals(2, mappedConcept.getSynonyms().size()); + for (ConceptName conceptName : mappedConcept.getSynonyms()) { + assertTrue(conceptName.getName().equals("1") || conceptName.getName().equals("2")); + } + } + + @Test + public void shouldAllowToMapExistingConceptsWithANewLocale() throws Exception { + Concept concept = new Concept(); + concept.setUniqueName("uniqueNameInFrench"); + concept.setDisplayName("displayNameInFrench"); + concept.setClassName("Finding"); + concept.setDescription("descriptionInFrench"); + concept.setDataType("N/A"); + ArrayList synonyms = new ArrayList<>(); + synonyms.add("1"); + synonyms.add("2"); + concept.setSynonyms(synonyms); + org.openmrs.Concept existingConcept = new ConceptBuilder().withName("uniqueName").withShortName("displayName").withDescription("description").build(); + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + + Locale frenchLocale = new Locale("fr", "FR"); + ConceptMetaData conceptMetaData = new ConceptMetaData(existingConcept, conceptDatatype, conceptClassName, frenchLocale); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals("uniqueNameInFrench", mappedConcept.getFullySpecifiedName(frenchLocale).getName()); + assertEquals("displayNameInFrench", mappedConcept.getShortNameInLocale(frenchLocale).getName()); + assertEquals("descriptionInFrench", mappedConcept.getDescription(frenchLocale).getDescription()); + + assertEquals("uniqueName", mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals("displayName", mappedConcept.getShortNameInLocale(Context.getLocale()).getName()); + assertEquals("description", mappedConcept.getDescription().getDescription()); + + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals(2, mappedConcept.getSynonyms().size()); + for (ConceptName conceptName : mappedConcept.getSynonyms()) { + assertTrue(conceptName.getName().equals("1") || conceptName.getName().equals("2")); + } + } + + @Test + public void shouldReplaceExistingDescriptions() throws Exception { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + concept.setDescription("New Description"); + org.openmrs.Concept existingConcept = new ConceptBuilder().withDescription("Some Description").withClass("Finding").withDataType("N/A").build(); + ConceptMetaData conceptMetaData = new ConceptMetaData(existingConcept, conceptDatatype, conceptClassName, null); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(0, mappedConcept.getShortNames().size()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals("New Description", mappedConcept.getDescription(Context.getLocale()).getDescription()); + } + + @Test + public void shouldReplaceExistingDescriptionSpecificToLocale() throws Exception { + Concept concept = new Concept(); + concept.setUniqueName("uniqueName"); + concept.setClassName("Finding"); + concept.setDataType("N/A"); + concept.setDescription("New description in French"); + + ConceptClass conceptClassName = new ConceptClass(); + conceptClassName.setName("Finding"); + ConceptDatatype conceptDatatype = new ConceptDatatype(); + conceptDatatype.setName("N/A"); + + Locale frenchLocale = new Locale("fr", "FR"); + + org.openmrs.Concept existingConcept = new ConceptBuilder().withClass("Finding").withDataType("N/A").build(); + Collection conceptDescriptions = new ArrayList<>(); + ConceptDescription conceptDescriptionInFrench = new ConceptDescription("Old description in French", frenchLocale); + ConceptDescription description = new ConceptDescription("description in default locale", Context.getLocale()); + conceptDescriptions.add(description); + conceptDescriptions.add(conceptDescriptionInFrench); + existingConcept.setDescriptions(conceptDescriptions); + + ConceptMetaData conceptMetaData = new ConceptMetaData(existingConcept, conceptDatatype, conceptClassName, frenchLocale); + org.openmrs.Concept mappedConcept = conceptMapper.map(concept, conceptMetaData, new ArrayList()); + + assertEquals(concept.getUniqueName(), mappedConcept.getFullySpecifiedName(frenchLocale).getName()); + assertEquals(0, mappedConcept.getShortNames().size()); + assertEquals(concept.getClassName(), mappedConcept.getConceptClass().getName()); + assertEquals(concept.getDataType(), mappedConcept.getDatatype().getName()); + assertEquals("description in default locale", mappedConcept.getDescription().getDescription()); + assertEquals(concept.getDescription(), mappedConcept.getDescription(frenchLocale).getDescription()); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/DepartmentMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/DepartmentMapperTest.java new file mode 100644 index 0000000000..518988de41 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/DepartmentMapperTest.java @@ -0,0 +1,111 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.Department; +import org.bahmni.module.referencedata.labconcepts.contract.ResourceReference; +import org.bahmni.module.referencedata.labconcepts.mapper.DepartmentMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.createConceptSet; +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class DepartmentMapperTest { + + private DepartmentMapper departmentMapper; + private Concept departmentConcept; + private Date dateCreated; + private Date dateChanged; + + @Mock + private ConceptService conceptService; + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + departmentMapper = new DepartmentMapper(); + dateCreated = new Date(); + dateChanged = new Date(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + departmentConcept = new ConceptBuilder().forDepartment().build(); + Concept allDepartmentsConcept = new ConceptBuilder().withUUID("Laboratory UUID") + .withName(Department.DEPARTMENT_PARENT_CONCEPT_NAME).withClass(Department.DEPARTMENT_CONCEPT_CLASS) + .withSetMember(departmentConcept).build(); + ConceptSet conceptSet = createConceptSet(allDepartmentsConcept, departmentConcept); + List conceptSets = getConceptSets(conceptSet); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapAllSampleFieldsFromConcept() throws Exception { + Department departmentData = departmentMapper.map(departmentConcept); + assertEquals("Department UUID", departmentData.getId()); + assertEquals(departmentData.getDateCreated(), departmentData.getDateCreated()); + assertEquals(departmentData.getLastUpdated(), departmentData.getLastUpdated()); + assertEquals("Some Description", departmentData.getDescription()); + } + + @Test + public void mapIfNoParentConcept() throws Exception { + Concept departmentConcept = new ConceptBuilder().withUUID("Department UUID").withDateCreated(dateCreated). + withDateChanged(dateChanged).withName("DepartmentName").build(); + Department departmentData = departmentMapper.map(departmentConcept); + assertEquals("Department UUID", departmentData.getId()); + } + + @Test + public void isActiveTrueByDefault() throws Exception { + Department departmentData = departmentMapper.map(departmentConcept); + assertTrue(departmentData.getIsActive()); + } + + @Test + public void shouldSetNameIfDescriptionIsNull() throws Exception { + + Concept departmentConceptWithOutDescription = new ConceptBuilder().withUUID("Department UUID").withDateCreated(dateCreated). + withDateChanged(dateChanged).withName("DepartmentName").build(); + Department departmentData = departmentMapper.map(departmentConceptWithOutDescription); + assertEquals("DepartmentName", departmentData.getDescription()); + } + + @Test + public void shouldMapTests() throws Exception { + Concept testConcept = new ConceptBuilder().forTest().build(); + departmentConcept.addSetMember(testConcept); + + Department departmentData = departmentMapper.map(departmentConcept); + List tests = departmentData.getTests(); + + assertEquals(1, tests.size()); + assertEquals("TestName", tests.get(0).getName()); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java new file mode 100644 index 0000000000..135e1b1805 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/LabTestMapperTest.java @@ -0,0 +1,142 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.Department; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.bahmni.module.referencedata.labconcepts.mapper.LabTestMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptNumeric; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.createConceptSet; +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class LabTestMapperTest { + private LabTestMapper testMapper; + private Date dateCreated; + private Date dateChanged; + @Mock + private ConceptService conceptService; + private Concept testConcept; + private List sampleConceptSets; + private List departmentConceptSets; + private List testConceptSets; + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + testMapper = new LabTestMapper(); + dateCreated = new Date(); + dateChanged = new Date(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") + .withDateChanged(dateChanged).withShortName("ShortName").withName("Test Name Here").withDataType(ConceptDatatype.NUMERIC).build(); + Concept testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID) + .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(testConcept).build(); + Concept sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). + withDateChanged(dateChanged).withSetMember(testConcept).withShortName("ShortName").withName("SampleName").build(); + Concept laboratoryConcept = new ConceptBuilder().withUUID("Laboratory UUID") + .withName(AllSamples.ALL_SAMPLES).withClassUUID(ConceptClass.LABSET_UUID) + .withSetMember(sampleConcept).build(); + Concept departmentConcept = new ConceptBuilder().withUUID("Department UUID").withDateCreated(dateCreated). + withDateChanged(dateChanged).withClass(Department.DEPARTMENT_CONCEPT_CLASS).withSetMember(testConcept).withDescription("Some Description").withName("Department Name").build(); + Concept labDepartmentConcept = new ConceptBuilder().withUUID("Laboratory Department UUID") + .withName(Department.DEPARTMENT_PARENT_CONCEPT_NAME).withClassUUID(ConceptClass.CONVSET_UUID) + .withSetMember(departmentConcept).build(); + ConceptSet sampleConceptSet = createConceptSet(laboratoryConcept, sampleConcept); + ConceptSet departmentConceptSet = createConceptSet(labDepartmentConcept, departmentConcept); + ConceptSet testConceptSet = createConceptSet(testAndPanelsConcept, testConcept); + ConceptSet testSampleConceptSet = createConceptSet(sampleConcept, testConcept); + ConceptSet testDepartmentConceptSet = createConceptSet(departmentConcept, testConcept); + departmentConceptSets = getConceptSets(departmentConceptSet); + sampleConceptSets = getConceptSets(sampleConceptSet); + testConceptSets = getConceptSets(testConceptSet); + testConceptSets.add(testSampleConceptSet); + testConceptSets.add(testDepartmentConceptSet); + ConceptNumeric conceptNumeric = new ConceptNumeric(testConcept); + conceptNumeric.setUnits("unit"); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenAnswer(new Answer>() { + @Override + public List answer(InvocationOnMock invocation) throws Throwable { + Object[] arguments = invocation.getArguments(); + Concept concept = (Concept) arguments[0]; + if (concept.getUuid().equals("Test UUID")) + return testConceptSets; + else if (concept.getUuid().equals("Sample UUID")) + return sampleConceptSets; + else if (concept.getUuid().equals("Department UUID")) + return departmentConceptSets; + + return null; + } + }); + when(conceptService.getConceptNumeric(eq(null))).thenReturn(conceptNumeric); + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapAllTestFieldsFromConcept() throws Exception { + LabTest testData = testMapper.map(testConcept); + assertEquals("Test UUID", testData.getId()); + assertEquals("Test Name Here", testData.getName()); + assertEquals(ConceptDatatype.NUMERIC, testData.getResultType()); + assertEquals(dateCreated, testData.getDateCreated()); + assertEquals(dateChanged, testData.getLastUpdated()); + assertEquals("unit", testData.getTestUnitOfMeasure()); + } + + @Test + public void testUnitOfMeasureIsNullIfNotSpecified() throws Exception { + when(conceptService.getConceptNumeric(eq(null))).thenReturn(null); + LabTest testData = testMapper.map(testConcept); + assertNull(testData.getTestUnitOfMeasure()); + } + + @Test + public void shouldSetNameIfDescriptionIsNull() throws Exception { + Concept testConceptWithOutDescription = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.TEST_UUID) + .withDateChanged(dateChanged).withShortName("ShortName").withName("Test Name Here").withDataType(ConceptDatatype.NUMERIC).build(); + + LabTest testData = testMapper.map(testConceptWithOutDescription); + assertEquals("Test Name Here", testData.getDescription()); + + } + +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java new file mode 100644 index 0000000000..37a9fc3aca --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/PanelMapperTest.java @@ -0,0 +1,132 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllTestsAndPanels; +import org.bahmni.module.referencedata.labconcepts.contract.LabTest; +import org.bahmni.module.referencedata.labconcepts.contract.Panel; +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.bahmni.module.referencedata.labconcepts.mapper.PanelMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.openmrs.Concept; +import org.openmrs.ConceptClass; +import org.openmrs.ConceptDatatype; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.createConceptSet; +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +//TODO: Mihir : write a test for empty tests list +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class PanelMapperTest { + private PanelMapper panelMapper; + private Date dateCreated; + private Date dateChanged; + @Mock + private ConceptService conceptService; + private Concept panelConcept; + private List testConceptSets; + private Concept testConcept; + private List panelConceptSets; + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + panelMapper = new PanelMapper(); + dateCreated = new Date(); + dateChanged = new Date(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + testConcept = new ConceptBuilder().withUUID("Test UUID").withDateCreated(dateCreated).withClass(LabTest.LAB_TEST_CONCEPT_CLASSES.get(0)).withDescription("SomeDescription") + .withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name Here").withDataType(ConceptDatatype.NUMERIC).build(); + panelConcept = new ConceptBuilder().withUUID("Panel UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID).withDescription("SomeDescription") + .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name Here").withDataType(ConceptDatatype.NUMERIC).build(); + Concept testAndPanelsConcept = new ConceptBuilder().withUUID("Test and Panels UUID").withDateCreated(dateCreated).withClassUUID(ConceptClass.CONVSET_UUID) + .withDateChanged(dateChanged).withShortName("ShortName").withName(AllTestsAndPanels.ALL_TESTS_AND_PANELS).withSetMember(panelConcept).build(); + Concept sampleConcept = new ConceptBuilder().withUUID("Sample UUID").withDateCreated(dateCreated).withClass(Sample.SAMPLE_CONCEPT_CLASS). + withDateChanged(dateChanged).withSetMember(panelConcept).withShortName("ShortName").withName("SampleName").build(); + Concept departmentConcept = new ConceptBuilder().withUUID("Department UUID").withDateCreated(dateCreated). + withDateChanged(dateChanged).withClass("Department").withClassUUID(ConceptClass.CONVSET_UUID).withSetMember(panelConcept).withDescription("Some Description").withName("Department Name").build(); + ConceptSet panelConceptSet = createConceptSet(testAndPanelsConcept, panelConcept); + ConceptSet testConceptSet = createConceptSet(testAndPanelsConcept, testConcept); + ConceptSet testPanelConceptSet = createConceptSet(testConcept, panelConcept); + ConceptSet panelSampleConceptSet = createConceptSet(sampleConcept, panelConcept); + ConceptSet testSampleConceptSet = createConceptSet(sampleConcept, testConcept); + ConceptSet testDepartmentConceptSet = createConceptSet(departmentConcept, testConcept); + + testConceptSets = getConceptSets(testConceptSet); + testConceptSets.add(testSampleConceptSet); + testConceptSets.add(testDepartmentConceptSet); + + panelConceptSets = getConceptSets(panelConceptSet); + panelConceptSets.add(panelSampleConceptSet); + panelConceptSets.add(testPanelConceptSet); + + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenAnswer(new Answer>() { + @Override + public List answer(InvocationOnMock invocation) throws Throwable { + Object[] arguments = invocation.getArguments(); + Concept concept = (Concept) arguments[0]; + if (concept.getUuid().equals("Test UUID")) + return testConceptSets; + else if (concept.getUuid().equals("Panel UUID")) + return panelConceptSets; + return null; + } + }); + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapAllPanelFieldsFromConcept() throws Exception { + Panel panelData = panelMapper.map(panelConcept); + assertEquals("Panel UUID", panelData.getId()); + assertEquals("Panel Name Here", panelData.getName()); + assertEquals(dateCreated, panelData.getDateCreated()); + assertEquals(dateChanged, panelData.getLastUpdated()); + assertEquals(1, panelData.getTests().size()); + assertEquals("Test UUID", panelData.getTests().get(0).getUuid()); + assertTrue(panelData.getSortOrder().equals(999.0)); + } + + @Test + public void isActiveTrueByDefault() throws Exception { + Panel panelData = panelMapper.map(panelConcept); + assertTrue(panelData.getIsActive()); + } + + @Test + public void shouldSetNameIfDescriptionIsNull() throws Exception { + Concept panelConceptWithoutDescription = new ConceptBuilder().withDateCreated(dateCreated).withClassUUID(ConceptClass.LABSET_UUID) + .withSetMember(testConcept).withDateChanged(dateChanged).withShortName("ShortName").withName("Panel Name Here").withDataType(ConceptDatatype.NUMERIC).build(); + + Panel panelData = panelMapper.map(panelConceptWithoutDescription); + assertEquals("Panel Name Here", panelData.getDescription()); + } +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java new file mode 100644 index 0000000000..404fe03d0a --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/RadiologyTestMapperTest.java @@ -0,0 +1,65 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.RadiologyTest; +import org.bahmni.module.referencedata.labconcepts.mapper.RadiologyTestMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class RadiologyTestMapperTest { + private RadiologyTestMapper testMapper; + private Concept radiologyConcept; + private Date dateCreated; + private Date dateChanged; + @Mock + private ConceptService conceptService; + @Mock + private UserContext userContext; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + testMapper = new RadiologyTestMapper(); + dateCreated = new Date(); + dateChanged = new Date(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + + radiologyConcept = new ConceptBuilder().withUUID("RadiologyUUID").withDateCreated(dateCreated).withClass(RadiologyTest.RADIOLOGY_TEST_CONCEPT_CLASSES.get(0)). + withDateChanged(dateChanged).withShortName("clavicle - right, 2 views (x-ray)").withName("Clavicle - Right, 2 views (X-ray)").build(); + + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapNameOfRadiologyTestFromConcept() throws Exception { + RadiologyTest testData = testMapper.map(radiologyConcept); + assertEquals("RadiologyUUID", testData.getId()); + assertEquals(dateCreated, testData.getDateCreated()); + assertEquals(dateChanged, testData.getLastUpdated()); + assertEquals("Clavicle - Right, 2 views (X-ray)", testData.getName()); + } + + +} diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java new file mode 100644 index 0000000000..429c5bbd7e --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/contract/mapper/SampleMapperTest.java @@ -0,0 +1,123 @@ +package org.bahmni.module.referencedata.web.contract.mapper; + +import org.bahmni.module.referencedata.labconcepts.contract.AllSamples; +import org.bahmni.module.referencedata.labconcepts.contract.Sample; +import org.bahmni.module.referencedata.labconcepts.mapper.ResourceMapper; +import org.bahmni.module.referencedata.labconcepts.mapper.SampleMapper; +import org.bahmni.test.builder.ConceptBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openmrs.Concept; +import org.openmrs.ConceptSet; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.openmrs.api.context.UserContext; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.List; +import java.util.Locale; + +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.createConceptSet; +import static org.bahmni.module.referencedata.labconcepts.advice.ConceptServiceEventInterceptorTest.getConceptSets; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@PowerMockIgnore("javax.management.*") +@PrepareForTest(Context.class) +@RunWith(PowerMockRunner.class) +public class SampleMapperTest { + + private SampleMapper sampleMapper; + private Concept sampleConcept; + private Concept allSamplesConcept; + @Mock + private ConceptService conceptService; + private Double sortOrder; + @Mock + private UserContext userContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + sampleMapper = new SampleMapper(); + Locale defaultLocale = new Locale("en", "GB"); + PowerMockito.mockStatic(Context.class); + when(Context.getLocale()).thenReturn(defaultLocale); + sampleConcept = new ConceptBuilder().forSample().withShortName("ShortName").build(); + allSamplesConcept = new ConceptBuilder().withUUID("Laboratory UUID") + .withName(AllSamples.ALL_SAMPLES).withClass(Sample.SAMPLE_CONCEPT_CLASS) + .withSetMember(sampleConcept).build(); + ConceptSet conceptSet = createConceptSet(allSamplesConcept, sampleConcept); + sortOrder = Double.valueOf(22); + conceptSet.setSortWeight(sortOrder); + List conceptSets = getConceptSets(conceptSet); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + when(Context.getConceptService()).thenReturn(conceptService); + } + + @Test + public void mapAllSampleFieldsFromConcept() { + Sample sampleData = sampleMapper.map(sampleConcept); + assertEquals("Sample UUID", sampleData.getId()); + assertEquals(sortOrder, sampleData.getSortOrder()); + assertEquals(sampleConcept.getDateCreated(), sampleData.getDateCreated()); + assertEquals(sampleConcept.getDateChanged(), sampleData.getLastUpdated()); + assertEquals("ShortName", sampleData.getShortName()); + } + + @Test + public void sendDefaultForNoShortName() { + sampleConcept = new ConceptBuilder().forSample().build(); + assertEquals(0, sampleConcept.getShortNames().size()); + + Sample sampleData = sampleMapper.map(sampleConcept); + assertEquals("Sample UUID", sampleData.getId()); + assertEquals("SampleName", sampleData.getShortName()); + } + + @Test + public void isActiveTrueByDefault() { + Sample sampleData = sampleMapper.map(sampleConcept); + assertTrue(sampleData.getIsActive()); + } + + @Test + public void doubleMaxAsSortOrderWhenSortOrderNotSpecified() { + ConceptSet conceptSet = createConceptSet(allSamplesConcept, sampleConcept); + List conceptSets = getConceptSets(conceptSet); + when(conceptService.getSetsContainingConcept(any(Concept.class))).thenReturn(conceptSets); + when(Context.getConceptService()).thenReturn(conceptService); + Sample sampleData = sampleMapper.map(sampleConcept); + assertTrue(sampleData.getSortOrder().equals(ResourceMapper.DEFAULT_SORT_ORDER)); + } + + @Test + public void mapTestsFromConceptSetMembers(){ + Concept testConcept = new ConceptBuilder().forTest().withDataType("N/A").build(); + Concept sampleConcept = new ConceptBuilder().forSample().withSetMember(testConcept).build(); + Sample sample = sampleMapper.map(sampleConcept); + assertNotNull(sample.getTests()); + assertEquals(1, sample.getTests().size()); + assertEquals("TestName", sample.getTests().get(0).getName()); + } + + @Test + public void mapPanelsFromConceptSetMembers(){ + Concept panelConcept = new ConceptBuilder().forPanel().build(); + Concept sampleConcept = new ConceptBuilder().forSample().withSetMember(panelConcept).build(); + Sample sample = sampleMapper.map(sampleConcept); + assertNotNull(sample.getPanels()); + assertEquals(1, sample.getPanels().size()); + assertEquals("PanelName", sample.getPanels().get(0).getName()); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/controller/ConceptControllerIT.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/controller/ConceptControllerIT.java new file mode 100644 index 0000000000..decadfd488 --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/controller/ConceptControllerIT.java @@ -0,0 +1,314 @@ +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.BaseIntegrationTest; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.ConceptAnswer; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import java.util.Collection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class ConceptControllerIT extends BaseIntegrationTest { + + @Autowired + private ConceptService conceptService; + + @Test + public void shouldCreateConcept() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "uniqueName"; + String className = "Finding"; + String description = "Sample basic concept being created"; + String dataType = "N/A"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(HttpStatus.CREATED.value(), response.getStatus()); + org.bahmni.module.referencedata.labconcepts.contract.Concept createdConcept = deserialize(response, org.bahmni.module.referencedata.labconcepts.contract.Concept.class); + + assertNotNull(createdConcept); + + Concept concept = conceptService.getConceptByUuid(createdConcept.getUuid()); + + assertEquals(uniqueName, concept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(className, concept.getConceptClass().getName()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + assertEquals(dataType, concept.getDatatype().getName()); + } + + @Test + public void shouldCreateCodedConceptWithAnswers() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "shortName"; + String className = "Finding"; + String description = "Sample basic concept being created"; + String dataType = "Coded"; + String answerConceptName = "HIV PROGRAM"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"," + + "\"answers\":" + "[\"" + answerConceptName + "\"]" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(HttpStatus.CREATED.value(), response.getStatus()); + org.bahmni.module.referencedata.labconcepts.contract.Concept createdConcept = deserialize(response, org.bahmni.module.referencedata.labconcepts.contract.Concept.class); + + assertNotNull(createdConcept); + + Concept concept = conceptService.getConceptByUuid(createdConcept.getUuid()); + + assertEquals(uniqueName, concept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(className, concept.getConceptClass().getName()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + assertEquals(dataType, concept.getDatatype().getName()); + assertEquals(answerConceptName, concept.getAnswers().iterator().next().getAnswerConcept().getName(Context.getLocale()).getName()); + } + + @Test + public void shouldCreateCodedConceptWithoutAnswers() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "shortName"; + String className = "Finding"; + String description = "Sample basic concept being created"; + String dataType = "Coded"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(HttpStatus.CREATED.value(), response.getStatus()); + org.bahmni.module.referencedata.labconcepts.contract.Concept createdConcept = deserialize(response, org.bahmni.module.referencedata.labconcepts.contract.Concept.class); + + assertNotNull(createdConcept); + + Concept concept = conceptService.getConceptByUuid(createdConcept.getUuid()); + + assertEquals(uniqueName, concept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(className, concept.getConceptClass().getName()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + assertEquals(dataType, concept.getDatatype().getName()); + assertEquals(0, concept.getAnswers().size()); + } + + @Test + public void shouldMaintainTheSortOrderOfAnswers() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "shortName"; + String className = "Finding"; + String description = "Sample basic concept being created"; + String dataType = "Coded"; + String answerConceptName1 = "HIV PROGRAM"; + String answerConceptName2 = "ASPIRIN"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"," + + "\"answers\":" + "[\"" + answerConceptName1 + "\", \"" + answerConceptName2 + "\"]" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(HttpStatus.CREATED.value(), response.getStatus()); + org.bahmni.module.referencedata.labconcepts.contract.Concept createdConcept = deserialize(response, org.bahmni.module.referencedata.labconcepts.contract.Concept.class); + + assertNotNull(createdConcept); + + Concept concept = conceptService.getConceptByUuid(createdConcept.getUuid()); + + assertEquals(uniqueName, concept.getFullySpecifiedName(Context.getLocale()).getName()); + assertEquals(displayName, concept.getShortestName(Context.getLocale(), false).getName()); + assertEquals(className, concept.getConceptClass().getName()); + assertEquals(description, concept.getDescription(Context.getLocale()).getDescription()); + assertEquals(dataType, concept.getDatatype().getName()); + Collection answers = concept.getAnswers(); + for (ConceptAnswer answer : answers) { + if (answer.getAnswerConcept().getName(Context.getLocale()).getName().equals("HIV PROGRAM")) { + assertTrue(answer.getSortWeight().equals(1.0)); + } + if (answer.getAnswerConcept().getName(Context.getLocale()).getName().equals("ASPIRIN")) { + assertTrue(answer.getSortWeight().equals(2.0)); + } + } + } + + @Test + public void shouldNotCreateConceptIfTheConceptDataTypeIsNotCodedAndAnswerIsSpecified() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "shortName"; + String className = "Finding"; + String description = "Sample basic concept being created"; + String dataType = "N/A"; + String answerConceptName = "HIV PROGRAM"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"," + + "\"answers\":" + "[\"" + answerConceptName + "\"]" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); + } + + @Test + public void shouldCreateConceptWithoutShortName() throws Exception { + String uniqueName = "uniqueName"; + String description = "Sample basic concept being created"; + String className = "Misc"; + String dataType = "N/A"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(response.getStatus(), HttpStatus.CREATED.value()); + } + + @Test + public void shouldNotCreateConceptForWrongDatatype() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "uniqueName"; + String className = "Finding"; + String description = "Sample basic concept being created"; + String dataType = "NA"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST.value()); + } + + @Test + public void shouldNotCreateConceptForWrongConceptClass() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "uniqueName"; + String className = "Ramesh"; + String description = "Sample basic concept being created"; + String dataType = "N/A"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST.value()); + } + + @Test + public void shouldNotCreateConceptForEmptyConceptUniqueName() throws Exception { + String uniqueName = ""; + String displayName = "uniqueName"; + String className = "Ramesh"; + String description = "Sample basic concept being created"; + String dataType = "N/A"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"," + + "\"dataType\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST.value()); + } + + + @Test + public void shouldNotCreateConceptForEmptyConceptDataType() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "uniqueName"; + String className = "Ramesh"; + String description = "Sample basic concept being created"; + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + className + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST.value()); + } + + @Test + public void shouldNotCreateConceptForEmptyConceptClass() throws Exception { + String uniqueName = "uniqueName"; + String displayName = "uniqueName"; + String description = "Sample basic concept being created"; + String dataType = "N/A"; + + + String conceptDataJson = "{" + + "\"uniqueName\":\"" + uniqueName + "\"," + + "\"displayName\":\"" + displayName + "\"," + + "\"description\":\"" + description + "\"," + + "\"className\":\"" + dataType + "\"" + + "}"; + + MockHttpServletRequest request = newPostRequest("/rest/v1/reference-data/concept", conceptDataJson); + MockHttpServletResponse response = handle(request); + assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST.value()); + } + +} \ No newline at end of file diff --git a/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/controller/ConceptOperationControllersIT.java b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/controller/ConceptOperationControllersIT.java new file mode 100644 index 0000000000..3e20be88ff --- /dev/null +++ b/reference-data/omod/src/test/java/org/bahmni/module/referencedata/web/controller/ConceptOperationControllersIT.java @@ -0,0 +1,92 @@ +//TODO : MIHIR : Add more ITs for tests and panels only happy path will be fine, and resolve all the TODOS in the Bahmni-Core +//TODO : MIHIR : Figure out a way to test the event interceptor. +package org.bahmni.module.referencedata.web.controller; + +import org.bahmni.module.referencedata.BaseIntegrationTest; +import org.bahmni.module.referencedata.labconcepts.contract.*; +import org.bahmni.module.referencedata.labconcepts.model.event.SaleableTypeEvent; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Concept; +import org.openmrs.api.ConceptService; +import org.openmrs.api.context.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class ConceptOperationControllersIT extends BaseIntegrationTest { + + @Autowired + private ConceptService conceptService; + private Concept sampleConcept; + private Concept departmentConcept; + private Concept testConcept; + private Concept radiologyTestConcept; + + @Before + public void setUp() throws Exception { + executeDataSet("labDataSetup.xml"); + sampleConcept = conceptService.getConcept(102); + departmentConcept = conceptService.getConcept(202); + testConcept = conceptService.getConcept(302); + radiologyTestConcept = conceptService.getConcept(401); + } + + @Test + public void shouldPublishSample() throws Exception { + MockHttpServletRequest sampleRequest = newGetRequest("/rest/v1/reference-data/sample/" + sampleConcept.getUuid()); + MockHttpServletResponse sampleResponse = handle(sampleRequest); + Sample sampleData = deserialize(sampleResponse, Sample.class); + assertEquals(sampleConcept.getUuid(), sampleData.getId()); + assertEquals(sampleConcept.getName(Context.getLocale()).getName(), sampleData.getShortName()); + assertEquals(sampleConcept.getName(Context.getLocale()).getName(), sampleData.getName()); + assertNotEquals(sampleConcept.getRetired(), sampleData.getIsActive()); + } + + + @Test + public void shouldPublishDepartment() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/reference-data/department/" + departmentConcept.getUuid()); + MockHttpServletResponse response = handle(request); + Department departmentResponse = deserialize(response, Department.class); + assertEquals(departmentConcept.getUuid(), departmentResponse.getId()); + assertEquals(departmentConcept.getName(Context.getLocale()).getName(), departmentResponse.getDescription()); + assertEquals(departmentConcept.getName(Context.getLocale()).getName(), departmentResponse.getName()); + assertNotEquals(departmentConcept.getRetired(), departmentResponse.getIsActive()); + } + + @Test + public void shouldPublishTest() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/reference-data/test/" + testConcept.getUuid()); + MockHttpServletResponse response = handle(request); + LabTest testResponse = deserialize(response, LabTest.class); + assertEquals(testConcept.getUuid(), testResponse.getId()); + assertEquals(testConcept.getName(Context.getLocale()).getName(), testResponse.getDescription()); + assertEquals(testConcept.getName(Context.getLocale()).getName(), testResponse.getName()); + assertNotEquals(testConcept.getRetired(), testResponse.getIsActive()); + assertEquals("Numeric", testResponse.getResultType()); + } + + @Test + public void shouldPublishRadiologyTest() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/reference-data/radiology/" + radiologyTestConcept.getUuid()); + MockHttpServletResponse response = handle(request); + RadiologyTest testResponse = deserialize(response, RadiologyTest.class); + assertEquals(radiologyTestConcept.getUuid(), testResponse.getId()); + assertEquals(radiologyTestConcept.getName(Context.getLocale()).getName(), testResponse.getName()); + assertNotEquals(radiologyTestConcept.getRetired(), testResponse.getIsActive()); + } + + @Test + public void shouldReturnGenericConceptResource() throws Exception { + MockHttpServletRequest request = newGetRequest("/rest/v1/reference-data/resources/fe334cb7-t3tb-0037-70f7-kjditree2222"); + MockHttpServletResponse response = handle(request); + Resource resource = deserialize(response, Resource.class); + assertEquals("fe334cb7-t3tb-0037-70f7-kjditree2222", resource.getId()); + assertEquals("Dressing Procedure", resource.getName()); + assertEquals("true", resource.getProperties().get(SaleableTypeEvent.SALEABLE_ATTR_NAME)); + } +} \ No newline at end of file diff --git a/reference-data/omod/src/test/resources/drugSetup.xml b/reference-data/omod/src/test/resources/drugSetup.xml new file mode 100644 index 0000000000..db3ddffef0 --- /dev/null +++ b/reference-data/omod/src/test/resources/drugSetup.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference-data/omod/src/test/resources/labDataSetup.xml b/reference-data/omod/src/test/resources/labDataSetup.xml new file mode 100644 index 0000000000..17ee53a796 --- /dev/null +++ b/reference-data/omod/src/test/resources/labDataSetup.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference-data/omod/src/test/resources/referenceTermSetup.xml b/reference-data/omod/src/test/resources/referenceTermSetup.xml new file mode 100644 index 0000000000..a580568946 --- /dev/null +++ b/reference-data/omod/src/test/resources/referenceTermSetup.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/reference-data/pom.xml b/reference-data/pom.xml new file mode 100644 index 0000000000..c7e84fd69c --- /dev/null +++ b/reference-data/pom.xml @@ -0,0 +1,99 @@ + + + 4.0.0 + + omod + api + + + org.bahmni.module + bahmni + 1.2.0-SNAPSHOT + + reference-data + pom + Reference Data + + Reference data for data setup for Bahmni + + + + Thoughtworks + + + + + OpenMRS + http://openmrs.org + + + + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + jar + provided + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + jar + provided + + + org.openmrs.api + openmrs-api + ${openMRSVersion} + test-jar + test + + + org.openmrs.web + openmrs-web + ${openMRSVersion} + test-jar + test + + + org.openmrs.test + openmrs-test + ${openMRSVersion} + pom + test + + + org.openmrs.module + webservices.rest-omod + ${openMRSWebServicesVersion} + provided + + + org.openmrs.module + metadatamapping-api + ${metadatamapping.version} + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + + + diff --git a/scripts/docker-link.sh b/scripts/docker-link.sh new file mode 100755 index 0000000000..97aa7cf93e --- /dev/null +++ b/scripts/docker-link.sh @@ -0,0 +1,17 @@ +#!/bin/sh -x + +USER=bahmni + +rm -f /opt/openmrs/modules/* +ln -s /bahmni-code/openmrs-distro-bahmni/distro/target/distro/*.omod /opt/openmrs/modules + +rm /opt/openmrs/modules/bahmnicore* +ln -s /bahmni-code/bahmni-core/bahmnicore-omod/target/*.omod /opt/openmrs/modules + +rm /opt/openmrs/modules/openelis-atomfeed-client* +ln -s /bahmni-code/bahmni-core/openmrs-elis-atomfeed-client-omod/target/*.omod /opt/openmrs/modules + +rm /opt/openmrs/modules/reference-data*.omod +ln -s /bahmni-code/bahmni-core/reference-data/omod/target/*.omod /opt/openmrs/modules + +chown -h ${USER}:${USER} /opt/openmrs/modules/* \ No newline at end of file diff --git a/scripts/vagrant-database.sh b/scripts/vagrant-database.sh new file mode 100755 index 0000000000..ba82208f68 --- /dev/null +++ b/scripts/vagrant-database.sh @@ -0,0 +1,12 @@ +#!/bin/sh -x +PATH_OF_CURRENT_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source $PATH_OF_CURRENT_SCRIPT/../vagrant-deploy/scripts/vagrant/vagrant_functions.sh + +set -e +$PATH_OF_CURRENT_SCRIPT/vagrant-deploy.sh + +#invoke migration of openmrs core +run_in_vagrant -c "sudo su - bahmni -c 'cd /bahmni_temp/ && ./run-liquibase-openmrs.sh'" +#invoke migrations of bahmni core omods +run_in_vagrant -c "sudo su - bahmni -c 'cd /bahmni_temp/ && ./run-core-bahmni-modules-liquibase.sh'" +run_in_vagrant -c "sudo su - bahmni -c 'cd /bahmni_temp/ && ./run-openelis-atomfeed-client-liquibase.sh'" diff --git a/scripts/vagrant-deploy.sh b/scripts/vagrant-deploy.sh new file mode 100755 index 0000000000..15171a6a7b --- /dev/null +++ b/scripts/vagrant-deploy.sh @@ -0,0 +1,7 @@ +#!/bin/sh -x + +PATH_OF_CURRENT_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +cd $PATH_OF_CURRENT_SCRIPT/../ + +mvn clean install -nsu -DskipTests -Pvagrant-deploy diff --git a/vagrant-deploy/pom.xml b/vagrant-deploy/pom.xml new file mode 100644 index 0000000000..5b8d62805b --- /dev/null +++ b/vagrant-deploy/pom.xml @@ -0,0 +1,94 @@ + + + + bahmni + org.bahmni.module + 1.2.0-SNAPSHOT + + + 4.0.0 + + vagrant-deploy + pom + Deploy scripts + + + openerpatomfeedclient + ${project.name} + ${project.version} + ${project.groupId}.${MODULE_ID} + + + + + org.bahmni.module + openelis-atomfeed-client-omod + + + org.bahmni.module + bahmnicore-omod + + + org.bahmni.module + reference-data-omod + ${project.parent.version} + + + + + + Windows + + + Windows + + + + .bat + + + + unix + + + unix + + + + .sh + + + + vagrant-deploy + + false + + + + + exec-maven-plugin + org.codehaus.mojo + + + Deploy + install + + exec + + + ${basedir}/scripts/vagrant/vagrant-deploy${script.extension} + + ${basedir} + ${project.version} + + + + + + + + + + diff --git a/vagrant-deploy/scripts/vagrant/deploy_omods.sh b/vagrant-deploy/scripts/vagrant/deploy_omods.sh new file mode 100644 index 0000000000..53bc0cd61a --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/deploy_omods.sh @@ -0,0 +1,12 @@ +#!/bin/sh -x + +TEMP_LOCATION=/tmp/deploy_bahmni_core +USER=bahmni_support +#USER=jss +OMOD_LOCATION=/opt/openmrs/modules + +sudo rm -f $OMOD_LOCATION/bahmnicore*.omod +sudo rm -f $OMOD_LOCATION/openelis-atomfeed-client*.omod +sudo rm -f $OMOD_LOCATION/reference-data*.omod + +sudo su - $USER -c "sudo cp -f $TEMP_LOCATION/* $OMOD_LOCATION" diff --git a/vagrant-deploy/scripts/vagrant/openmrs_start.sh b/vagrant-deploy/scripts/vagrant/openmrs_start.sh new file mode 100755 index 0000000000..7d328a2819 --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/openmrs_start.sh @@ -0,0 +1,2 @@ +#!/bin/sh -x +sudo service openmrs debug diff --git a/vagrant-deploy/scripts/vagrant/openmrs_stop.sh b/vagrant-deploy/scripts/vagrant/openmrs_stop.sh new file mode 100755 index 0000000000..03700e5d19 --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/openmrs_stop.sh @@ -0,0 +1,4 @@ +#!/bin/sh -x +set +e +sudo service openmrs stop +set -e diff --git a/vagrant-deploy/scripts/vagrant/setup_environment.sh b/vagrant-deploy/scripts/vagrant/setup_environment.sh new file mode 100755 index 0000000000..e05bcf84c3 --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/setup_environment.sh @@ -0,0 +1,9 @@ +#!/bin/sh -x + +TEMP_LOCATION=/tmp/deploy_bahmni_core + +if [[ ! -d $TEMP_LOCATION ]]; then + mkdir $TEMP_LOCATION +fi + +rm -rf $TEMP_LOCATION/* \ No newline at end of file diff --git a/vagrant-deploy/scripts/vagrant/vagrant-deploy.bat b/vagrant-deploy/scripts/vagrant/vagrant-deploy.bat new file mode 100755 index 0000000000..41354a4546 --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/vagrant-deploy.bat @@ -0,0 +1,34 @@ +@echo off + +REM !!!!IMPORTANT!!!! +REM Before using this script to deploy do the following +REM Add putty to your path +REM Use puttygen to generate win_insecure_private_key.ppk from your %USERPROFILE%\.vagrant.d\insecure_private_key that comes along with vagrant. +REM !!!End of IMPORTANT!!! + +REM All config is here + +set MACHINE_IP=192.168.33.10 +set MODULE_DEPLOYMENT_FOLDER=/tmp/deploy_bahmni_core +set VERSION=%2 +set CWD=%1 +set SCRIPTS_DIR=%CWD%/scripts/vagrant +set KEY_FILE=%USERPROFILE%\.vagrant.d\win_insecure_private_key.ppk + +if exist %KEY_FILE% ( + REM setup + putty -ssh vagrant@%MACHINE_IP% -i %KEY_FILE% -m %SCRIPTS_DIR%/setup_environment.sh + REM Kill tomcat + putty -ssh vagrant@%MACHINE_IP% -i %KEY_FILE% -m %SCRIPTS_DIR%/tomcat_stop.sh + REM Deploy Bhamni core + pscp -i %KEY_FILE% %CWD%/../../bahmnicore-omod/target/bahmnicore-omod-%VERSION%.omod vagrant@%MACHINE_IP%:%MODULE_DEPLOYMENT_FOLDER%/bahmnicore-%VERSION%.omod + REM Deploy Open elis + pscp -i %KEY_FILE% %CWD%/../../openmrs-elis-atomfeed-client-omod/target/openelis-atomfeed-client-omod-%VERSION%.omod vagrant@%MACHINE_IP%:%MODULE_DEPLOYMENT_FOLDER%/openelis-atomfeed-client-%VERSION%.omod + REM Copy omods into module directories + putty -ssh vagrant@%MACHINE_IP% -i %KEY_FILE% -m %SCRIPTS_DIR%/deploy_omods.sh + REM Start tomcat + putty -ssh vagrant@%MACHINE_IP% -i %KEY_FILE% -m %SCRIPTS_DIR%/tomcat_start.sh +) else ( + echo Use puttygen to generate win_insecure_private_key.ppk from your %USERPROFILE%\.vagrant.d\insecure_private_key that comes along with vagrant. +) + diff --git a/vagrant-deploy/scripts/vagrant/vagrant-deploy.sh b/vagrant-deploy/scripts/vagrant/vagrant-deploy.sh new file mode 100755 index 0000000000..01d26d5719 --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/vagrant-deploy.sh @@ -0,0 +1,30 @@ +#!/bin/bash -x -e + +PATH_OF_CURRENT_SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source $PATH_OF_CURRENT_SCRIPT/vagrant_functions.sh + +#All config is here +MODULE_DEPLOYMENT_FOLDER=/tmp/deploy_bahmni_core +CWD=$1 +VERSION=$2 +SCRIPTS_DIR=$CWD/scripts/vagrant +PROJECT_BASE=$PATH_OF_CURRENT_SCRIPT/../../.. + +# Setup environment +run_in_vagrant -f "$SCRIPTS_DIR/setup_environment.sh" + +# Kill tomcat +run_in_vagrant -f "$SCRIPTS_DIR/openmrs_stop.sh" + +# Deploy Bhamni core +scp_to_vagrant $PROJECT_BASE/bahmnicore-omod/target/bahmnicore*-$VERSION.omod $MODULE_DEPLOYMENT_FOLDER/bahmnicore-$VERSION.omod + +# Copy omod files to the vagrant box - in /tmp +scp_to_vagrant $PROJECT_BASE/openmrs-elis-atomfeed-client-omod/target/openelis-atomfeed-client*-$VERSION.omod $MODULE_DEPLOYMENT_FOLDER/openelis-atomfeed-client-$VERSION.omod +scp_to_vagrant $PROJECT_BASE/reference-data/omod/target/reference-data*-$VERSION.omod $MODULE_DEPLOYMENT_FOLDER/reference-data-$VERSION.omod + +#Deploy them from Vagrant /tmp to appropriate location +run_in_vagrant -f "$SCRIPTS_DIR/deploy_omods.sh" + +# Restart tomcat +run_in_vagrant -f "$SCRIPTS_DIR/openmrs_start.sh" diff --git a/vagrant-deploy/scripts/vagrant/vagrant_functions.sh b/vagrant-deploy/scripts/vagrant/vagrant_functions.sh new file mode 100755 index 0000000000..3f20ba6768 --- /dev/null +++ b/vagrant-deploy/scripts/vagrant/vagrant_functions.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +##################################################################################################### +# This script can be used to call functions which will execute a command in your vagrant box. +# -c option will be used to pass a command +# -f option will be used to pass a full qualified file that contains commands +# +# It can also be used to SCP into the vagrant box +##################################################################################################### + +MACHINE_IP=192.168.33.10 +KEY_FILE=~/.vagrant.d/insecure_private_key +TIMEOUT="-o ConnectTimeout=5" + +function run_in_vagrant { + + if [ "$1" == "-c" ]; then + ssh vagrant@$MACHINE_IP -i $KEY_FILE $TIMEOUT "$2" + elif [ "$1" == "-f" ]; then + ssh vagrant@$MACHINE_IP -i $KEY_FILE $TIMEOUT < "$2" + fi + +} + +# $1: Source $2: Dest +function scp_to_vagrant { + scp -i $KEY_FILE $TIMEOUT $1 vagrant@$MACHINE_IP:$2 +} \ No newline at end of file