diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml new file mode 100644 index 00000000000..37a5171543e --- /dev/null +++ b/.github/workflows/codacy.yml @@ -0,0 +1,61 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow checks out code, performs a Codacy security scan +# and integrates the results with the +# GitHub Advanced Security code scanning feature. For more information on +# the Codacy security scan action usage and parameters, see +# https://github.com/codacy/codacy-analysis-cli-action. +# For more information on Codacy Analysis CLI in general, see +# https://github.com/codacy/codacy-analysis-cli. + +name: Codacy Security Scan + +on: + push: + branches: [ "master", "master|hlm-[0-9]+.*", "dev" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master", "dev" ] + schedule: + - cron: '30 13 * * 1' + +permissions: + contents: read + +jobs: + codacy-security-scan: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + name: Codacy Security Scan + runs-on: ubuntu-latest + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout code + uses: actions/checkout@v3 + + # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis + - name: Run Codacy Analysis CLI + uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b + with: + # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository + # You can also omit the token and run the tools that support default configurations + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + verbose: true + output: results.sarif + format: sarif + # Adjust severity of non-security issues + gh-code-scanning-compat: true + # Force 0 exit code to allow SARIF file generation + # This will handover control about PR rejection to the GitHub side + max-allowed-issues: 2147483647 + + # Upload the SARIF file generated in the previous step + - name: Upload SARIF results file + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: results.sarif diff --git a/build/build-config.yml b/build/build-config.yml index 4ab442bf983..981c3dd7dff 100644 --- a/build/build-config.yml +++ b/build/build-config.yml @@ -36,6 +36,13 @@ config: dockerfile: "build/maven/Dockerfile" - work-dir: "health-services/project/src/main/resources/db" image-name: "project-db" + - name: "builds/health-campaign-services/health-services/referralmanagement" + build: + - work-dir: "health-services/referralmanagement" + image-name: "referralmanagement" + dockerfile: "build/maven/Dockerfile" + - work-dir: "health-services/referralmanagement/src/main/resources/db" + image-name: "referralmanagement-db" - name: "builds/health-campaign-services/health-services/household" build: - work-dir: "health-services/household" @@ -57,6 +64,11 @@ config: dockerfile: "build/maven/Dockerfile" - work-dir: "health-services/household/src/main/resources/db" image-name: "household-db" + - name: "builds/health-campaign-services/core-services/error-handler" + build: + - work-dir: "core-services/error-handler" + image-name: "error-handler" + dockerfile: "build/maven/Dockerfile" - name: "builds/health-campaign-services/core-services/dashboard-analytics" build: - work-dir: "core-services/dashboard-analytics" diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/AdvanceTableChartResponseHandler.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/AdvanceTableChartResponseHandler.java index dd41cca5179..8b81053c58b 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/AdvanceTableChartResponseHandler.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/AdvanceTableChartResponseHandler.java @@ -12,6 +12,7 @@ import com.tarento.analytics.dto.Plot; import com.tarento.analytics.helper.ComputedFieldFactory; import com.tarento.analytics.helper.IComputedField; +import com.tarento.analytics.helper.SortingHelper; import com.tarento.analytics.model.ComputedFields; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,6 +34,8 @@ public class AdvanceTableChartResponseHandler implements IResponseHandler { @Autowired private ObjectMapper mapper; + @Autowired + private SortingHelper sortingHelper; @Autowired private ComputedFieldFactory computedFieldFactory; @@ -116,6 +119,7 @@ public AggregateDto translate(AggregateRequestDto requestDto, ObjectNode aggrega }); }); + List finalDataList = dataList; mappings.entrySet().stream().forEach(plotMap -> { List plotList = plotMap.getValue().values().stream().collect(Collectors.toList()); //filter out data object with all zero data. @@ -146,7 +150,7 @@ public AggregateDto translate(AggregateRequestDto requestDto, ObjectNode aggrega logger.error("execution of computed field :"+e.getMessage()); } } - dataList.add(data); + finalDataList.add(data); } }); @@ -168,7 +172,11 @@ public AggregateDto translate(AggregateRequestDto requestDto, ObjectNode aggrega }); } } - + + if (chartNode.has("sort")) { + dataList = sortingHelper.tableSort(dataList, chartNode.get("sort").asText()); + } + return getAggregatedDto(chartNode, dataList, requestDto.getVisualizationCode()); } diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/LineChartResponseHandler.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/LineChartResponseHandler.java index 51a956346ad..5863585e956 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/LineChartResponseHandler.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/LineChartResponseHandler.java @@ -85,8 +85,8 @@ public AggregateDto translate(AggregateRequestDto requestDto, ObjectNode aggrega if(isPredictionEnabled ){ List aggrNodes = aggregationNode.findValues(CHART_SPECIFIC); - startDate = aggrNodes.get(0).findValues(START_DATE).get(0).findValues("key").get(0).asLong(); - endDate = aggrNodes.get(0).findValues(END_DATE).get(0).findValues("key").get(0).asLong(); + startDate = (aggrNodes.get(0).findValues(START_DATE).get(0).findValues("key").get(0).asLong()/86400000)*86400000; + endDate = (aggrNodes.get(0).findValues(END_DATE).get(0).findValues("key").get(0).asLong()/86400000)*86400000; interval=Constants.Interval.day.toString(); addTargetDates(startDate, endDate,targetEpochKeys); } @@ -117,7 +117,8 @@ public AggregateDto translate(AggregateRequestDto requestDto, ObjectNode aggrega Set finalBucketKeys = new LinkedHashSet<>(); // For multi aggr, find all plot keys first - enrichBucketKeys(aggrNodes, finalBucketKeys, interval); +// enrichBucketKeys(aggrNodes, finalBucketKeys, interval); + enrichBucketKeys(aggrNodes, finalBucketKeys, interval, startDate, isPredictionEnabled); initializeMultiAggrPlotMap(multiAggrPlotMap, finalBucketKeys); for(JsonNode aggrNode : aggrNodes) { @@ -125,6 +126,9 @@ public AggregateDto translate(AggregateRequestDto requestDto, ObjectNode aggrega ArrayNode buckets = (ArrayNode) aggrNode.findValues(IResponseHandler.BUCKETS).get(0); for(JsonNode bucket : buckets){ JsonNode bkey = bucket.findValue(IResponseHandler.KEY); + if (isPredictionEnabled && Long.parseLong(bkey.asText()) < startDate) { + continue; + } String key = getIntervalKey(bkey.asText(), Constants.Interval.valueOf(interval)); plotKeys.add(key); if(isPredictionEnabled && !headerPath.equals(predictionPath)){ @@ -354,13 +358,16 @@ private void initializeMultiAggrPlotMap(Map multiAggrPlotMap, Se }); } - private void enrichBucketKeys(List aggrNodes, Set finalBucketKeys, String interval) { + private void enrichBucketKeys(List aggrNodes, Set finalBucketKeys, String interval, Long startDate, Boolean isPredictionEnabled) { List bkeyList = new ArrayList<>(); for(JsonNode aggrNode : aggrNodes) { if (aggrNode.findValues(IResponseHandler.BUCKETS).size() > 0) { ArrayNode buckets = (ArrayNode) aggrNode.findValues(IResponseHandler.BUCKETS).get(0); for(JsonNode bucket : buckets){ String bkey = bucket.findValue(IResponseHandler.KEY).asText(); + if (isPredictionEnabled && Long.parseLong(bkey) < (startDate)) { + continue; + } bkeyList.add(bkey); } } diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/MetricChartResponseHandler.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/MetricChartResponseHandler.java index be03e77a56d..c7c7b67a486 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/MetricChartResponseHandler.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/handler/MetricChartResponseHandler.java @@ -59,7 +59,7 @@ public class MetricChartResponseHandler implements IResponseHandler{ @Override public AggregateDto translate(AggregateRequestDto request, ObjectNode aggregations) throws IOException { List dataList = new ArrayList<>(); - String requestId = request.getRequestId(); + String requestId = request.getRequestId(); String visualizationCode = request.getVisualizationCode(); JsonNode aggregationNode = aggregations.get(AGGREGATIONS); @@ -203,9 +203,20 @@ public AggregateDto translate(AggregateRequestDto request, ObjectNode aggregatio data.setPlots( Arrays.asList(latestDateplot,lastUpdatedTime)); request.getResponseRecorder().put(visualizationCode, request.getModuleLevel(), data); dataList.add(data); - if(chartNode.get(POST_AGGREGATION_THEORY) != null) { + if(chartNode.get(POST_AGGREGATION_THEORY) != null) { ComputeHelper computeHelper = computeHelperFactory.getInstance(chartNode.get(POST_AGGREGATION_THEORY).asText()); - computeHelper.compute(request, dataList); +// computeHelper.compute(request, dataList); + List capDataList = new ArrayList<>(); + + if (chartNode.has(IS_CAPPED_BY_CAMPAIGN_PERIOD)) { + List valueNode = aggregationNode.findValues(chartNode.get(IS_CAPPED_BY_CAMPAIGN_PERIOD).get(0).asText()); + if(valueNode.size() > 0) { + Long val = valueNode.get(0).get(IResponseHandler.VALUE).asLong(); + Data dataNode = new Data(aggrsPaths.get(0).asText(), val.doubleValue(), chartNode.get(IResponseHandler.VALUE_TYPE).asText()); + capDataList.add(dataNode); + } + } + computeHelper.compute(request, dataList, capDataList); } }catch (Exception e){ logger.info("data chart name = "+chartName +" ex occurred "+e.getMessage()); diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/AdditiveComputedField.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/AdditiveComputedField.java index 92ba43883b9..bb858e3dd1d 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/AdditiveComputedField.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/AdditiveComputedField.java @@ -1,6 +1,8 @@ package com.tarento.analytics.helper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.tarento.analytics.dto.AggregateRequestDto; import com.tarento.analytics.dto.Data; import com.tarento.analytics.dto.Plot; @@ -9,12 +11,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import static com.tarento.analytics.handler.IResponseHandler.HIDE_HEADER_DENOMINATION; +import static com.tarento.analytics.handler.IResponseHandler.IS_CAPPED_BY_CAMPAIGN_PERIOD; @Component public class AdditiveComputedField implements IComputedField { @@ -40,16 +44,31 @@ public void add(Data data, List fields, String newField,JsonNode chartNo Map plotMap = data.getPlots().stream().collect(Collectors.toMap(Plot::getName, Function.identity())); double total = 0.0; + double capTotal = 0.0; for (String field: fields){ if(plotMap.containsKey(field)){ dataType = plotMap.get(field).getSymbol(); + if(chartNode.has(IS_CAPPED_BY_CAMPAIGN_PERIOD) && doesTextExistInArrayNode((ArrayNode) chartNode.get(IS_CAPPED_BY_CAMPAIGN_PERIOD), field)) continue; total = total+ plotMap.get(field).getValue(); } } if(postAggrTheoryName != null && !postAggrTheoryName.isEmpty()) { ComputeHelper computeHelper = computeHelperFactory.getInstance(postAggrTheoryName); + if (chartNode.has(IS_CAPPED_BY_CAMPAIGN_PERIOD)) { + List commonStrings = new ArrayList<>(); + chartNode.get(IS_CAPPED_BY_CAMPAIGN_PERIOD).forEach( + item -> { + if (fields.contains(item.asText())) { + commonStrings.add(item.asText()); + } + } + ); + if(commonStrings.size()>0) { + capTotal = commonStrings.stream().mapToDouble(commonString -> plotMap.get(commonString).getValue()).sum(); + } + } - total = computeHelper.compute(aggregateRequestDto,total ); + total = computeHelper.compute(aggregateRequestDto,total,capTotal ); } @@ -62,5 +81,16 @@ public void add(Data data, List fields, String newField,JsonNode chartNo } } + private static boolean doesTextExistInArrayNode(ArrayNode arrayNode, String searchText) { + for (JsonNode element : arrayNode) { + if (element.isTextual()) { + String text = element.asText(); + if (text.equals(searchText)) { + return true; + } + } + } + return false; + } } diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/ComputeHelper.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/ComputeHelper.java index 3c50469fe94..f6a853dfd35 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/ComputeHelper.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/ComputeHelper.java @@ -12,8 +12,9 @@ * */ public interface ComputeHelper { - public List compute(AggregateRequestDto request, List data); + public List compute(AggregateRequestDto request, List data, List capValues); public Double compute(AggregateRequestDto request, double value); + public Double compute(AggregateRequestDto request, double value, double capTotal); } diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/NoOpsComputedField.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/NoOpsComputedField.java index b9715b43a50..9f6c83b0aca 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/NoOpsComputedField.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/NoOpsComputedField.java @@ -15,6 +15,7 @@ import java.util.List; import static com.tarento.analytics.constant.Constants.PostAggregationTheories.RESPONSE_DIFF_DATES; +import static com.tarento.analytics.handler.IResponseHandler.IS_CAPPED_BY_CAMPAIGN_PERIOD; @Component public class NoOpsComputedField implements IComputedField{ @@ -37,6 +38,7 @@ public void set(AggregateRequestDto requestDto, String postAggrTheoryName){ public void add(ObjectNode data, List fields, String newField, JsonNode chartNode ) { ObjectNode noOpsNode = JsonNodeFactory.instance.objectNode(); List dataList = new ArrayList<>(); + List capDataList = new ArrayList<>(); try { List values = data.findValues(fields.get(0)); if (postAggrTheoryName.equalsIgnoreCase(RESPONSE_DIFF_DATES)) { @@ -45,8 +47,14 @@ public void add(ObjectNode data, List fields, String newField, JsonNode Data dataNode = new Data(fields.get(0), val.doubleValue(), chartNode.get(IResponseHandler.VALUE_TYPE).asText()); dataList.add(dataNode); } + + if (chartNode.has(IS_CAPPED_BY_CAMPAIGN_PERIOD) && data.has((chartNode.get(IS_CAPPED_BY_CAMPAIGN_PERIOD).get(0).asText()))) { + Long capValue = data.findValues(chartNode.get(IS_CAPPED_BY_CAMPAIGN_PERIOD).get(0).asText()).get(0).get(IResponseHandler.VALUE).asLong(); + Data dataNode = new Data(fields.get(0), capValue.doubleValue(), chartNode.get(IResponseHandler.VALUE_TYPE).asText()); + capDataList.add(dataNode); + } ComputeHelper computeHelper = computeHelperFactory.getInstance(RESPONSE_DIFF_DATES); - List computedData = computeHelper.compute(aggregateRequestDto, dataList); + List computedData = computeHelper.compute(aggregateRequestDto, dataList, capDataList); noOpsNode.put(IResponseHandler.VALUE, ((Double) computedData.get(0).getHeaderValue()).longValue()); data.set(newField, noOpsNode); } diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/SortingHelper.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/SortingHelper.java index fcd11c1f943..5101bfa72df 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/SortingHelper.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/SortingHelper.java @@ -2,7 +2,6 @@ import org.springframework.stereotype.Component; import com.tarento.analytics.dto.Data; import com.tarento.analytics.dto.Plot; -import java.util.*; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -21,6 +20,11 @@ public List sort(String sortingKey, List dataList) { } return dataList; } + public List tableSort(List dataList, String sortingKey) { + Comparator tableSortComparator = tableSortComparator(sortingKey); + dataList.sort(tableSortComparator); + return dataList; + } private static Comparator plotSortComparator(String sortingKey, Boolean isValueSortingApplicable) { return new Comparator() { @@ -48,4 +52,18 @@ public int compare(Plot p1, Plot p2) { }; } + private static Comparator tableSortComparator(String sortingKey) { + return (p1, p2) -> { + String plotName1 = p1.getHeaderName().toUpperCase(); + String plotName2 = p2.getHeaderName().toUpperCase(); + + if (sortingKey.equals(SORT_KEY_ASC)) { + return plotName1.compareTo(plotName2); + } else if (sortingKey.equals(SORT_KEY_DESC)) { + return plotName2.compareTo(plotName1); + } + return 0; + }; + } + } \ No newline at end of file diff --git a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/TargetPerDateComputeHelper.java b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/TargetPerDateComputeHelper.java index ce05e5c26d4..8c99870ac86 100644 --- a/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/TargetPerDateComputeHelper.java +++ b/core-services/dashboard-analytics/src/main/java/com/tarento/analytics/helper/TargetPerDateComputeHelper.java @@ -46,14 +46,6 @@ public List compute(AggregateRequestDto request, List data) { Long dateDifference = TimeUnit.DAYS.convert((eDate - sDate), TimeUnit.MILLISECONDS); if(dateDifference == 0l) dateDifference = dateDifference + 1l ; - if(request.getChartNode().get(IS_CAPPED_BY_CAMPAIGN_PERIOD) != null && request.getChartNode().get(IS_CAPPED_BY_CAMPAIGN_PERIOD).asBoolean()){ - if(request.getFilters()!=null && request.getFilters().containsKey(CAMPAIGN_START_DATE) && request.getFilters().containsKey(CAMPAIGN_END_DATE)) { - Long campaignStartDate = Long.parseLong(String.valueOf(request.getFilters().get(CAMPAIGN_START_DATE))); - Long campaignEndDate = Long.parseLong(String.valueOf(request.getFilters().get(CAMPAIGN_END_DATE))); - Long campaignDateDifference = TimeUnit.DAYS.convert((campaignEndDate - campaignStartDate), TimeUnit.MILLISECONDS); - dateDifference = Math.min(dateDifference, campaignDateDifference); - } - } for(Data eachData : data) { Double value = (Double) eachData.getHeaderValue(); logger.info("Value is : " + value + " :: Date Difference is : " + dateDifference); @@ -67,6 +59,49 @@ public List compute(AggregateRequestDto request, List data) { return data; } + + @Override + public List compute(AggregateRequestDto request, List data, List capValues) { + if(request.getRequestDate()!= null && request.getRequestDate().getStartDate() != null && request.getRequestDate().getEndDate() != null) { + try { + Long sDate = Long.parseLong(request.getRequestDate().getStartDate()); + logger.info("Start Date : " + String.valueOf(sDate)); + Long eDate = Long.parseLong(request.getRequestDate().getEndDate()); + logger.info("End Date : " + String.valueOf(eDate)); + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date(eDate)); + if(cal.get(Calendar.HOUR_OF_DAY) == LAST_HOUR && cal.get(Calendar.MINUTE) == LAST_MINUTE) { + eDate = eDate + ROUND_OFF; + } + logger.info("End Date after Round Off: " + String.valueOf(eDate)); + Long dateDifference = TimeUnit.DAYS.convert((eDate - sDate), TimeUnit.MILLISECONDS); + if(dateDifference == 0l) dateDifference = dateDifference + 1l ; + + for(Data eachData : data) { + Double value = (Double) eachData.getHeaderValue(); + logger.info("Value is : " + value + " :: Date Difference is : " + dateDifference); + if(request.getChartNode().get(IS_CAPPED_BY_CAMPAIGN_PERIOD) != null && capValues.size()>0){ + if(request.getFilters()!=null && request.getFilters().containsKey(CAMPAIGN_START_DATE) && request.getFilters().containsKey(CAMPAIGN_END_DATE)) { + Long campaignStartDate = Long.parseLong(String.valueOf(request.getFilters().get(CAMPAIGN_START_DATE))); + Long campaignEndDate = Long.parseLong(String.valueOf(request.getFilters().get(CAMPAIGN_END_DATE))); + Long campaignDateDifference = TimeUnit.DAYS.convert((campaignEndDate - campaignStartDate), TimeUnit.MILLISECONDS); + if (dateDifference >= campaignDateDifference) { + Double capValue = (Double) capValues.get(0).getHeaderValue(); + eachData.setHeaderValue(capValue); + continue; + } + } + } + value = (value / NUMBER_OF_DAYS) * dateDifference; + eachData.setHeaderValue(value); + } + } catch (Exception ex) { + logger.error("Encountered an error while computing the logic in Target Date Computer : " + ex.getMessage()); + } + } + return data; + } + @Override public Double compute(AggregateRequestDto request, double value){ @@ -97,6 +132,49 @@ public Double compute(AggregateRequestDto request, double value){ + } + + @Override + public Double compute(AggregateRequestDto request, double value, double capTotal){ + + if(request.getRequestDate()!= null && request.getRequestDate().getStartDate() != null && request.getRequestDate().getEndDate() !=null) { + try { + Long sDate = Long.parseLong(request.getRequestDate().getStartDate()); + logger.info("Start Date : " + String.valueOf(sDate)); + Long eDate = Long.parseLong(request.getRequestDate().getEndDate()); + logger.info("End Date : " + String.valueOf(eDate)); + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date(eDate)); + if(cal.get(Calendar.HOUR_OF_DAY) == LAST_HOUR && cal.get(Calendar.MINUTE) == LAST_MINUTE) { + eDate = eDate + ROUND_OFF; + } + logger.info("End Date after Round Off: " + String.valueOf(eDate)); + Long dateDifference = TimeUnit.DAYS.convert((eDate - sDate), TimeUnit.MILLISECONDS); + if(dateDifference == 0l) dateDifference = dateDifference + 1l ; + + value = (value / NUMBER_OF_DAYS) * dateDifference; + + if(request.getChartNode().get(IS_CAPPED_BY_CAMPAIGN_PERIOD) != null ){ + if(request.getFilters()!=null && request.getFilters().containsKey(CAMPAIGN_START_DATE) && request.getFilters().containsKey(CAMPAIGN_END_DATE)) { + Long campaignStartDate = Long.parseLong(String.valueOf(request.getFilters().get(CAMPAIGN_START_DATE))); + Long campaignEndDate = Long.parseLong(String.valueOf(request.getFilters().get(CAMPAIGN_END_DATE))); + Long campaignDateDifference = TimeUnit.DAYS.convert((campaignEndDate - campaignStartDate), TimeUnit.MILLISECONDS); + if (dateDifference >= campaignDateDifference) { + value = capTotal; + } + } + } + logger.info("Value is : " + value + " :: Date Difference is : " + dateDifference); + + } catch (Exception ex) { + logger.error("Encountered an error while computing the logic in Target Date Computer : " + ex.getMessage()); + } + } + + return value; + + + } } diff --git a/docs/health-api-specs/contracts/project.yml b/docs/health-api-specs/contracts/project.yml index 69c19b24a0a..5989673ca43 100644 --- a/docs/health-api-specs/contracts/project.yml +++ b/docs/health-api-specs/contracts/project.yml @@ -174,7 +174,7 @@ paths: schema: $ref: >- https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes - + /project/beneficiary/v1/bulk/_update: post: diff --git a/docs/health-api-specs/contracts/referral-management.yml b/docs/health-api-specs/contracts/referral-management.yml new file mode 100644 index 00000000000..d93dbdd05d5 --- /dev/null +++ b/docs/health-api-specs/contracts/referral-management.yml @@ -0,0 +1,786 @@ +swagger: '2.0' +info: + version: 1.0.0 + title: Referral Management System + contact: + name: egovernments foundation + email: info@egovernments.org +schemes: + - https +x-common-path: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-0-0.yml +paths: + /referralmanagement/side-effect/v1/_create: + post: + summary: >- + Create side effect for the project + description: >- + Create side effect for the project + parameters: + - name: SideEffect + in: body + description: Capture details of Side Effect + required: true + schema: + $ref: '#/definitions/SideEffectRequest' + tags: + - Side Effect + responses: + '202': + description: Create side effect request has been accepted for creation. + schema: + $ref: '#/definitions/SideEffectResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/side-effect/v1/bulk/_create: + post: + summary: >- + Create side effects for the project in bulk + description: >- + Create side effects for the project in bulk + parameters: + - name: SideEffect + in: body + description: Capture details of Task + required: true + schema: + $ref: '#/definitions/SideEffectBulkRequest' + tags: + - Side Effect + responses: + '202': + description: Create side effect request has been accepted for creation. + schema: + $ref: '#/definitions/BulkAcceptedResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/side-effect/v1/_update: + post: + summary: >- + Side Effect Request + description: >- + Side Effect Request + parameters: + - name: SideEffect + in: body + description: Capture details of Existing side effect + required: true + schema: + $ref: '#/definitions/SideEffectRequest' + tags: + - Side Effect + responses: + '202': + description: update side effect request has been accepted for update. + schema: + $ref: '#/definitions/SideEffectResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/side-effect/v1/bulk/_update: + post: + summary: >- + Side Effect Request in bulk for a project + description: >- + Side Effect Request in bulk for a project + parameters: + - name: SideEffect + in: body + description: Capture details of Existing Side Effects + required: true + schema: + $ref: '#/definitions/SideEffectBulkRequest' + tags: + - Side Effect + responses: + '202': + description: update Side Effects bulk request has been accepted for update. + schema: + $ref: '#/definitions/BulkAcceptedResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/side-effect/v1/_delete: + post: + summary: >- + Soft delete Side Effect for a project + description: >- + Soft delete Side Effect for a project + parameters: + - name: SideEffect + in: body + description: Capture details of Existing Side Effect + required: true + schema: + $ref: '#/definitions/SideEffectRequest' + tags: + - Side Effect + responses: + '202': + description: delete Side Effect request has been accepted for deletion. + schema: + $ref: '#/definitions/SideEffectResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/side-effect/v1/bulk/_delete: + post: + summary: >- + Soft delete Side Effects for a project + description: >- + Soft delete Side Effects for a project + parameters: + - name: SideEffect + in: body + description: Capture details of Existing Side Effect + required: true + schema: + $ref: '#/definitions/SideEffectRequest' + tags: + - Side Effect + responses: + '202': + description: delete bulk Side Effect request has been accepted for deletion. + schema: + $ref: '#/definitions/BulkAcceptedResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/side-effect/v1/_search: + post: + summary: >- + Search Side Effect for Project + description: >- + Search Side Effect for Project + parameters: + - name: SideEffect + in: body + description: Side Effect Search. + required: true + schema: + $ref: '#/definitions/SideEffectSearchRequest' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/tenantId' + - $ref: '#/parameters/lastChangedSince' + - $ref: '#/parameters/includeDeleted' + tags: + - Side Effect + responses: + '200': + description: Side Effects. + schema: + $ref: '#/definitions/SideEffectBulkResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/_create: + post: + summary: >- + Create referral for the project beneficiary + description: >- + Create referral for the project benefiaciary + parameters: + - name: Referral + in: body + description: Capture details of Referral + required: true + schema: + $ref: '#/definitions/ReferralRequest' + tags: + - Referral + responses: + '202': + description: Create referral request has been accepted for creation. + schema: + $ref: '#/definitions/ReferralResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/bulk/_create: + post: + summary: >- + Create referrals for the project beneficiary in bulk + description: >- + Create referrals for the project beneficiary in bulk + parameters: + - name: Referral + in: body + description: Capture details of Task + required: true + schema: + $ref: '#/definitions/ReferralBulkRequest' + tags: + - Referral + responses: + '202': + description: Create referral request has been accepted for creation. + schema: + $ref: '#/definitions/BulkAcceptedResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/_update: + post: + summary: >- + Referral Request + description: >- + Referral Request + parameters: + - name: Referral + in: body + description: Capture details of Existing referral + required: true + schema: + $ref: '#/definitions/ReferralRequest' + tags: + - Referral + responses: + '202': + description: update referral request has been accepted for update. + schema: + $ref: '#/definitions/ReferralResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/bulk/_update: + post: + summary: >- + Referral Request in bulk for a project beneficiary + description: >- + Referral Request in bulk for a project beneficiary + parameters: + - name: Referral + in: body + description: Capture details of Existing Referrals + required: true + schema: + $ref: '#/definitions/ReferralBulkRequest' + tags: + - Referral + responses: + '202': + description: update Referrals bulk request has been accepted for update. + schema: + $ref: '#/definitions/BulkAcceptedResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/_delete: + post: + summary: >- + Soft delete Referral for a project beneficiary + description: >- + Soft delete Referral for a project beneficiary + parameters: + - name: Referral + in: body + description: Capture details of Existing Referral + required: true + schema: + $ref: '#/definitions/ReferralRequest' + tags: + - Referral + responses: + '202': + description: delete Referral request has been accepted for deletion. + schema: + $ref: '#/definitions/ReferralResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/bulk/_delete: + post: + summary: >- + Soft delete Referrals for a project beneficiary + description: >- + Soft delete Referrals for a project beneficiary + parameters: + - name: Referral + in: body + description: Capture details of Existing Referral + required: true + schema: + $ref: '#/definitions/ReferralRequest' + tags: + - Referral + responses: + '202': + description: delete bulk Referral request has been accepted for deletion. + schema: + $ref: '#/definitions/BulkAcceptedResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + + /referralmanagement/v1/_search: + post: + summary: >- + Search Referral for Project + description: >- + Search Referral for Project + parameters: + - name: Referral + in: body + description: Referral Search. + required: true + schema: + $ref: '#/definitions/ReferralSearchRequest' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/tenantId' + - $ref: '#/parameters/lastChangedSince' + - $ref: '#/parameters/includeDeleted' + tags: + - Referral + responses: + '200': + description: Referrals. + schema: + $ref: '#/definitions/ReferralBulkResponse' + '400': + description: Invalid Input body. + schema: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ErrorRes + +parameters: + #TODO is tenantId required as a query param if it can be determine from requestInfo->userInfo + tenantId: + name: tenantId + in: query + description: Unique id for a tenant. + required: true + type: string + format: varchar + + lastChangedSince: + name: lastChangedSince + description: | + epoch of the time since when the changes on the object should be picked up. Search results from this parameter should include both newly created objects since this time as well as any modified objects since this time. This criterion is included to help polling clients to get the changes in system since a last time they synchronized with the platform. + in: query + required: false + type: integer + format: int64 + + echoResource: + name: echoResource + in: query + type: boolean + required: false + default: true + description: Client can specify if the resource in request body needs to be sent back in the response. This is being used to limit amount of data that needs to flow back from the server to the client in low bandwidth scenarios. Server will always send the server generated id for validated requests. + + serverHandlesErrors: + name: serverHandlesErrors + in: query + type: boolean + required: false + default: false + description: Client can specify that it is incapable of handling any errors with the requests and server should route these for manual intervention if required. + + limit: + name: limit + description: Pagination - limit records in response + in: query + type: integer + minimum: 0 + maximum: 1000 #TODO review + required: true + + offset: + name: offset + description: Pagination - offset from which records should be returned in response + in: query + type: integer + minimum: 0 + required: true + + includeDeleted: + name: includeDeleted + description: Used in search APIs to specify if (soft) deleted records should be included in search results. + in: query + type: boolean + default: false + required: false + + includeEnded: + name: includeEnded + description: Used in project search API to specify if records past end date should be included in search results. + in: query + type: boolean + default: false + required: false + + includeAncestors: + name: includeAncestors + description: Used in project search API to specify if response should include project elements that are in the preceding hierarchy of matched projects. + in: query + type: boolean + default: false + required: false + + includeDescendants: + name: includeDescendants + description: Used in project search API to specify if response should include project elements that are in the following hierarchy of matched projects. + in: query + type: boolean + default: false + required: false + + createdFrom: + name: createdFrom + description: | + Used in project search API to limit the search results to only those projects whose creation date is after the specified 'createdFrom' date. + in: query + required: false + type: integer + format: int64 + + createdTo: + name: createdTo + description: | + Used in project search API to limit the search results to only those projects whose creation date is before the specified 'createdTo' date. + in: query + required: false + type: integer + format: int64 + +definitions: + boundaryCode: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/boundaryCode' + id: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/id' + idForSearch: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/idForSearch' + clientReferenceIdForSearch: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/clientReferenceIdForSearch' + clientReferenceId: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/clientReferenceId' + tenantId: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/tenantId' + eventTimestamp: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/eventTimestamp' + isDeleted: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/isDeleted' + rowVersion: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/rowVersion' + apiOperation: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/apiOperation' + additionalFields: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/additionalFields' + Address: + $ref: 'https://raw.githubusercontent.com/digit-egov/health-api-specs/main/contracts/common.yaml#/definitions/Address' + + SideEffect: + type: object + required: + - tenantId + - taskId + - symptoms + properties: + id: + $ref: '#/definitions/id' + clientReferenceId: + $ref: '#/definitions/clientReferenceId' + tenantId: + $ref: '#/definitions/tenantId' + taskId: + type: string + minLength: 2 + maxLength: 64 + description: Unique TaskId + taskClientReferenceId: + type: string + example: "R-ID-1" + description: Unique Task Client Reference Id + projectBeneficiaryId: + type: string + minLength: 2 + maxLength: 64 + description: Project Beneficiary Id + projectBeneficiaryClientReferenceId: + type: string + minLength: 2 + maxLength: 64 + description: Project Beneficiary Client Reference Id + symptoms: + type: array + items: + type: string + isDeleted: + $ref: '#/definitions/isDeleted' + rowVersion: + $ref: '#/definitions/rowVersion' + auditDetails: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/AuditDetails + clientAuditDetails: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/AuditDetails + + SideEffectRequest: + type: object + properties: + RequestInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/RequestInfo + SideEffect: + type: object + $ref: '#/definitions/SideEffect' + required: + - RequestInfo + - SideEffect + + SideEffectBulkRequest: + type: object + properties: + RequestInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/RequestInfo + SideEffects: + type: array + minItems: 1 + items: + $ref: '#/definitions/SideEffect' + required: + - RequestInfo + - SideEffects + + SideEffectSearch: + type: object + properties: + id: + $ref: '#/definitions/idForSearch' + clientReferenceId: + $ref: '#/definitions/clientReferenceIdForSearch' + taskId: + type: string + minLength: 2 + maxLength: 64 + description: Unique TaskId + taskClientReferenceId: + type: string + example: "R-ID-1" + + SideEffectSearchRequest: + type: object + properties: + RequestInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/RequestInfo + SideEffect: + $ref: '#/definitions/SideEffectSearch' + required: + - RequestInfo + - SideEffect + + SideEffectResponse: + type: object + properties: + ResponseInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ResponseInfo + SideEffect: + type: object + $ref: '#/definitions/SideEffect' + required: + - ResponseInfo + - SideEffect + + SideEffectBulkResponse: + type: object + properties: + ResponseInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ResponseInfo + SideEffects: + type: array + items: + $ref: '#/definitions/SideEffect' + required: + - ResponseInfo + - SideEffects + + Referral: + type: object + required: + - tenantId + properties: + id: + $ref: '#/definitions/id' + clientReferenceId: + $ref: '#/definitions/clientReferenceId' + tenantId: + $ref: '#/definitions/tenantId' + projectBeneficiaryId: + type: string + minLength: 2 + maxLength: 64 + description: Project Beneficiary Id + projectBeneficiaryClientReferenceId: + type: string + minLength: 2 + maxLength: 64 + description: Project Beneficiary Client Reference Id + referringById: + type: string + minLength: 2 + maxLength: 64 + description: Worker Id that is referring the Beneficiary + referredToId: + type: string + minLength: 2 + maxLength: 64 + description: Individual or Facility Id whom the Beneficiary is referred to. + referredToType: + type: string + description: Individual or Facility + reasons: + type: array + items: + type: string + sideEffect: + $ref: '#/definition/SideEffect' + isDeleted: + $ref: '#/definitions/isDeleted' + rowVersion: + $ref: '#/definitions/rowVersion' + auditDetails: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/AuditDetails + clientAuditDetails: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/AuditDetails + + ReferralRequest: + type: object + properties: + RequestInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/RequestInfo + Referral: + type: object + $ref: '#/definitions/Referral' + required: + - RequestInfo + - Referral + + ReferralBulkRequest: + type: object + properties: + RequestInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/RequestInfo + Referrals: + type: array + minItems: 1 + items: + $ref: '#/definitions/Referral' + required: + - RequestInfo + - Referrals + + ReferralSearch: + type: object + properties: + id: + $ref: '#/definitions/idForSearch' + clientReferenceId: + $ref: '#/definitions/clientReferenceIdForSearch' + projectBeneficiaryId: + type: array + items: + type: string + projectBeneficiaryClientReferenceId: + type: array + items: + type: string + + ReferralSearchRequest: + type: object + properties: + RequestInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/RequestInfo + Referral: + $ref: '#/definitions/ReferralSearch' + required: + - RequestInfo + - Referral + + ReferralResponse: + type: object + properties: + ResponseInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ResponseInfo + Referral: + type: object + $ref: '#/definitions/Referral' + required: + - ResponseInfo + - Referral + + ReferralBulkResponse: + type: object + properties: + ResponseInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ResponseInfo + Referrals: + type: array + items: + $ref: '#/definitions/Referral' + required: + - ResponseInfo + - Referrals + + BulkAcceptedResponse: + type: object + properties: + ResponseInfo: + $ref: >- + https://raw.githubusercontent.com/egovernments/egov-services/master/docs/common/contracts/v1-1-1.yml#/definitions/ResponseInfo + required: + - ResponseInfo diff --git a/health-services/individual/src/main/java/org/egov/individual/Constants.java b/health-services/individual/src/main/java/org/egov/individual/Constants.java index 8df6088b70b..9db46cf85e9 100644 --- a/health-services/individual/src/main/java/org/egov/individual/Constants.java +++ b/health-services/individual/src/main/java/org/egov/individual/Constants.java @@ -17,4 +17,5 @@ public interface Constants { String INDIVIDUAL_MODULE_CODE = "rainmaker-masters"; String INDIVIDUAL_LOCALIZATION_CODES_JSONPATH = "$.messages.*.code"; String INDIVIDUAL_LOCALIZATION_MSGS_JSONPATH = "$.messages.*.message"; + String ORG_ADMIN_ROLE_CODE = "ORG_ADMIN"; } diff --git a/health-services/individual/src/main/java/org/egov/individual/config/IndividualProperties.java b/health-services/individual/src/main/java/org/egov/individual/config/IndividualProperties.java index d481b47d5c8..44f9ed5be70 100644 --- a/health-services/individual/src/main/java/org/egov/individual/config/IndividualProperties.java +++ b/health-services/individual/src/main/java/org/egov/individual/config/IndividualProperties.java @@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.util.List; + @Data @AllArgsConstructor @NoArgsConstructor @@ -63,6 +65,9 @@ public class IndividualProperties { @Value("${kafka.topics.notification.sms}") private String smsNotifTopic; + @Value("${notification.sms.disabled.roles}") + private List smsDisabledRoles; + //Localization @Value("${egov.localization.host}") private String localizationHost; diff --git a/health-services/individual/src/main/java/org/egov/individual/service/IndividualService.java b/health-services/individual/src/main/java/org/egov/individual/service/IndividualService.java index 198c8714f0b..65559c99b76 100644 --- a/health-services/individual/src/main/java/org/egov/individual/service/IndividualService.java +++ b/health-services/individual/src/main/java/org/egov/individual/service/IndividualService.java @@ -6,6 +6,7 @@ import org.egov.common.ds.Tuple; import org.egov.common.models.Error; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.Role; import org.egov.common.models.individual.Identifier; import org.egov.common.models.individual.Individual; import org.egov.common.models.individual.IndividualBulkRequest; @@ -31,16 +32,10 @@ import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -55,8 +50,7 @@ import static org.egov.common.utils.CommonUtils.lastChangedSince; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; -import static org.egov.individual.Constants.SET_INDIVIDUALS; -import static org.egov.individual.Constants.VALIDATION_ERROR; +import static org.egov.individual.Constants.*; @Service @Slf4j @@ -119,7 +113,9 @@ public List create(IndividualRequest request) { IndividualBulkRequest bulkRequest = IndividualBulkRequest.builder().requestInfo(request.getRequestInfo()) .individuals(Collections.singletonList(request.getIndividual())).build(); List individuals = create(bulkRequest, false); - if(properties.getIsSMSEnabled()) + + // check if sms feature is enable for the environment role + if(properties.getIsSMSEnabled() && isSmsEnabledForRole(request)) notificationService.sendNotification(request, true); return individuals; } @@ -180,7 +176,9 @@ public List update(IndividualRequest request) { IndividualBulkRequest bulkRequest = IndividualBulkRequest.builder().requestInfo(request.getRequestInfo()) .individuals(Collections.singletonList(request.getIndividual())).build(); List individuals = update(bulkRequest, false); - if(properties.getIsSMSEnabled()) + + // check if sms feature is enable for the environment role + if(properties.getIsSMSEnabled() && isSmsEnabledForRole(request)) notificationService.sendNotification(request, false); return individuals; } @@ -415,4 +413,20 @@ private void integrateWithUserService(IndividualBulkRequest request, } } } + Boolean isSmsEnabledForRole(IndividualRequest request) { + if (CollectionUtils.isEmpty(properties.getSmsDisabledRoles())) + return true; + List smsDisabledRoles = properties.getSmsDisabledRoles(); + List roleCodes = new ArrayList<>(); + if(request != null && request.getIndividual() != null && request.getIndividual().getUserDetails() != null + && request.getIndividual().getUserDetails().getRoles() != null) { + // get the role codes from the list of roles + roleCodes = request.getIndividual().getUserDetails().getRoles().stream().map(Role::getCode).collect(Collectors.toList()); + } + for (String smsDisabledRole : smsDisabledRoles) { + if (roleCodes.contains(smsDisabledRole)) + return false; + } + return true; + } } diff --git a/health-services/individual/src/main/resources/application.properties b/health-services/individual/src/main/resources/application.properties index 14813237ab4..78db07bc7d0 100644 --- a/health-services/individual/src/main/resources/application.properties +++ b/health-services/individual/src/main/resources/application.properties @@ -91,6 +91,7 @@ user.service.account.locked=false #Notification notification.sms.enabled=true kafka.topics.notification.sms=egov.core.notification.sms +notification.sms.disabled.roles=ORG_ADMIN #Localization config egov.localization.host=https://works-dev.digit.org/ diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index 202e7ac2a58..619fbb2bf28 100644 --- a/health-services/libraries/health-services-models/pom.xml +++ b/health-services/libraries/health-services-models/pom.xml @@ -3,10 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.egov.common health-services-models - 1.0.7-SNAPSHOT + 1.0.9-SNAPSHOT 8 diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java index f7c0f205af7..18d20c408a4 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java @@ -1,19 +1,21 @@ package org.egov.common.models.project; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.springframework.validation.annotation.Validated; + import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; + import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; /** * This object defines the mapping of a system staff user to a project for a certain period. diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java index fbbc67ffb33..01002770204 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java @@ -54,9 +54,8 @@ public class Task { private String projectBeneficiaryClientReferenceId = null; @JsonProperty("resources") - @NotNull @Valid - @Size(min = 1) + @Builder.Default private List resources = new ArrayList<>(); @JsonProperty("plannedStartDate") diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java new file mode 100644 index 00000000000..50612ab91dc --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java @@ -0,0 +1,81 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import digit.models.coremodels.AuditDetails; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class Referral { + + @JsonProperty("id") + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("clientReferenceId") + @Size(min = 2, max = 64) + private String clientReferenceId = null; + + @JsonProperty("projectBeneficiaryId") + @Size(min = 2, max = 64) + private String projectBeneficiaryId = null; + + @JsonProperty("projectBeneficiaryClientReferenceId") + @Size(min = 2, max = 64) + private String projectBeneficiaryClientReferenceId = null; + + @JsonProperty("referredById") + @Size(min = 2, max = 64) + private String referredById = null; + + @JsonProperty("referredToType") + private String referredToType = null; + + @JsonProperty("referredToId") + @Size(min = 2, max = 64) + private String referredToId = null; + + @JsonProperty("reasons") + @NotNull + @Size(min=1) + private List reasons = null; + + @JsonProperty("sideEffect") + private SideEffect sideEffect = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min=2, max = 1000) + private String tenantId = null; + + @JsonProperty("isDeleted") + private Boolean isDeleted = Boolean.FALSE; + + @JsonProperty("rowVersion") + private Integer rowVersion = null; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails = null; + + @JsonProperty("clientAuditDetails") + @Valid + private AuditDetails clientAuditDetails = null; + + @JsonIgnore + private Boolean hasErrors = Boolean.FALSE; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralBulkRequest.java new file mode 100644 index 00000000000..fd5621197ed --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralBulkRequest.java @@ -0,0 +1,38 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class ReferralBulkRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Referrals") + @NotNull + @Valid + @Size(min = 1) + private List referrals = new ArrayList<>(); + + public ReferralBulkRequest addReferralItem(Referral referralItem) { + this.referrals.add(referralItem); + return this; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralBulkResponse.java new file mode 100644 index 00000000000..3dfbd9dff25 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralBulkResponse.java @@ -0,0 +1,36 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class ReferralBulkResponse { + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Referrals") + @NotNull + @Valid + private List referrals = new ArrayList<>(); + + public ReferralBulkResponse addReferralItem(Referral referralItem) { + this.referrals.add(referralItem); + return this; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralRequest.java new file mode 100644 index 00000000000..8ad1990acc9 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralRequest.java @@ -0,0 +1,29 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class ReferralRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Referral") + @NotNull + @Valid + private Referral referral = null; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralResponse.java new file mode 100644 index 00000000000..b367fb35a98 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralResponse.java @@ -0,0 +1,29 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class ReferralResponse { + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Referral") + @NotNull + @Valid + private Referral referral = null; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralSearch.java new file mode 100644 index 00000000000..31c9a223704 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralSearch.java @@ -0,0 +1,29 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class ReferralSearch { + @JsonProperty("id") + private List id = null; + + @JsonProperty("clientReferenceId") + private List clientReferenceId = null; + + @JsonProperty("projectBeneficiaryId") + private List projectBeneficiaryId = null; + + @JsonProperty("projectBeneficiaryClientReferenceId") + private List projectBeneficiaryClientReferenceId = null; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralSearchRequest.java new file mode 100644 index 00000000000..d6ae41f8f01 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/ReferralSearchRequest.java @@ -0,0 +1,28 @@ +package org.egov.common.models.referralmanagement; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class ReferralSearchRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Referral") + @Valid + private ReferralSearch referral = null; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java new file mode 100644 index 00000000000..badde74f599 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java @@ -0,0 +1,75 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import digit.models.coremodels.AuditDetails; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffect { + + @JsonProperty("id") + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("clientReferenceId") + @Size(min = 2, max = 64) + private String clientReferenceId = null; + + @JsonProperty("taskId") + @Size(min = 2, max = 64) + private String taskId = null; + + @JsonProperty("taskClientReferenceId") + @NotNull + @Size(min = 2, max = 64) + private String taskClientReferenceId = null; + + @JsonProperty("projectBeneficiaryId") + @Size(min = 2, max = 64) + private String projectBeneficiaryId = null; + + @JsonProperty("projectBeneficiaryClientReferenceId") + @Size(min = 2, max = 64) + private String projectBeneficiaryClientReferenceId = null; + + @JsonProperty("symptoms") + @NotNull + @Size(min=1) + private List symptoms = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min=2, max = 1000) + private String tenantId = null; + + @JsonProperty("isDeleted") + private Boolean isDeleted = Boolean.FALSE; + + @JsonProperty("rowVersion") + private Integer rowVersion = null; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails = null; + + @JsonProperty("clientAuditDetails") + @Valid + private AuditDetails clientAuditDetails = null; + + @JsonIgnore + private Boolean hasErrors = Boolean.FALSE; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectBulkRequest.java new file mode 100644 index 00000000000..51319d73b51 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectBulkRequest.java @@ -0,0 +1,39 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffectBulkRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("SideEffects") + @NotNull + @Valid + @Size(min=1) + private List sideEffects = new ArrayList<>(); + + public SideEffectBulkRequest addSideEffectItem(SideEffect sideEffectItem) { + this.sideEffects.add(sideEffectItem); + return this; + } + +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectBulkResponse.java new file mode 100644 index 00000000000..bfcfda3dae4 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectBulkResponse.java @@ -0,0 +1,37 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffectBulkResponse { + + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("SideEffects") + @NotNull + @Valid + private List sideEffects = new ArrayList<>(); + + public SideEffectBulkResponse addSideEffectItem(SideEffect sideEffectItem) { + this.sideEffects.add(sideEffectItem); + return this; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectRequest.java new file mode 100644 index 00000000000..9de2e92b66e --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectRequest.java @@ -0,0 +1,29 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffectRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("SideEffect") + @NotNull + @Valid + private SideEffect sideEffect = null; +} \ No newline at end of file diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectResponse.java new file mode 100644 index 00000000000..9e96194482c --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectResponse.java @@ -0,0 +1,31 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffectResponse { + + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("SideEffect") + @NotNull + @Valid + private SideEffect sideEffect = null; + +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectSearch.java new file mode 100644 index 00000000000..3183a2533d6 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectSearch.java @@ -0,0 +1,30 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffectSearch { + @JsonProperty("id") + private List id = null; + + @JsonProperty("clientReferenceId") + private List clientReferenceId = null; + + @JsonProperty("taskId") + private String taskId = null; + + @JsonProperty("taskClientReferenceId") + private String taskClientReferenceId = null; + +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectSearchRequest.java new file mode 100644 index 00000000000..69cc688f884 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffectSearchRequest.java @@ -0,0 +1,28 @@ +package org.egov.common.models.referralmanagement.sideeffect; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class SideEffectSearchRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("SideEffect") + @Valid + private SideEffectSearch sideEffect = null; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java index 102474fae63..a08748daf49 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java @@ -1,18 +1,21 @@ package org.egov.common.models.stock; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.springframework.validation.annotation.Validated; + import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; + import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Builder.Default; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; /** * Stock @@ -26,85 +29,96 @@ @Builder @JsonIgnoreProperties(ignoreUnknown = true) public class Stock { + @JsonProperty("id") @Size(min=2, max=64) - private String id = null; + private String id; @JsonProperty("clientReferenceId") @Size(min=2, max=64) - private String clientReferenceId = null; + private String clientReferenceId; @JsonProperty("tenantId") @NotNull @Size(min=2, max=1000) - private String tenantId = null; - - @JsonProperty("facilityId") - @NotNull - @Size(min=2, max=64) - private String facilityId = null; + private String tenantId; + /* product fields */ @JsonProperty("productVariantId") @NotNull @Size(min=2, max=64) - private String productVariantId = null; + private String productVariantId; @JsonProperty("quantity") @NotNull - private Integer quantity = null; + private Integer quantity; + /* project id in-case of health */ @JsonProperty("referenceId") - private String referenceId = null; + private String referenceId; @JsonProperty("referenceIdType") @Size(min=2, max=64) - private String referenceIdType = null; + private String referenceIdType; + // transaction fields @JsonProperty("transactionType") @NotNull @Valid - private TransactionType transactionType = null; + private TransactionType transactionType; @JsonProperty("transactionReason") @Valid - private TransactionReason transactionReason = null; + private TransactionReason transactionReason; - @JsonProperty("transactingPartyId") + @JsonProperty("senderId") + @NotNull + @Size(min=2, max=64) + private String senderId; + + @JsonProperty("senderType") + @NotNull + @Size(min=2, max=64) + private String senderType; + + @JsonProperty("receiverId") @NotNull @Size(min=2, max=64) - private String transactingPartyId = null; + private String receiverId; - @JsonProperty("transactingPartyType") + @JsonProperty("receiverType") @NotNull @Size(min=2, max=64) - private String transactingPartyType = null; + private String receiverType; @JsonProperty("wayBillNumber") @Size(min = 2, max = 200) - private String wayBillNumber = null; + private String wayBillNumber; @JsonProperty("additionalFields") @Valid - private AdditionalFields additionalFields = null; + private AdditionalFields additionalFields; @JsonProperty("isDeleted") + @Default private Boolean isDeleted = Boolean.FALSE; @JsonProperty("rowVersion") - private Integer rowVersion = null; + private Integer rowVersion; @JsonIgnore + @Default private Boolean hasErrors = Boolean.FALSE; @JsonProperty("auditDetails") @Valid - private AuditDetails auditDetails = null; + private AuditDetails auditDetails; @JsonProperty("dateOfEntry") - private Long dateOfEntry = null; + private Long dateOfEntry; @JsonProperty("clientAuditDetails") @Valid - private AuditDetails clientAuditDetails = null; + private AuditDetails clientAuditDetails; } diff --git a/health-services/project/README.md b/health-services/project/README.md index 518e8b8653a..89424d22e48 100644 --- a/health-services/project/README.md +++ b/health-services/project/README.md @@ -130,7 +130,6 @@ Project service APIs - contains create, update, delete and search end point - update-project-resource-bulk-topic - delete-project-resource-bulk-topic - ### Kafka Producers - save-project-staff-topic @@ -153,7 +152,6 @@ Project service APIs - contains create, update, delete and search end point - update-project-resource-topic - delete-project-resource-topic - ## Pre commit script [commit-msg](https://gist.github.com/jayantp-egov/14f55deb344f1648503c6be7e580fa12) diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index 564e18f6d1d..36d3c0885ea 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -49,7 +49,7 @@ org.egov.common health-services-models - 1.0.7-SNAPSHOT + 1.0.9-SNAPSHOT compile diff --git a/health-services/project/src/main/java/org/egov/project/Constants.java b/health-services/project/src/main/java/org/egov/project/Constants.java index fdf557ad07b..42b730bbd11 100644 --- a/health-services/project/src/main/java/org/egov/project/Constants.java +++ b/health-services/project/src/main/java/org/egov/project/Constants.java @@ -53,4 +53,5 @@ public interface Constants { String PIPE = "||"; String PROJECT_ID = "projectId"; + } diff --git a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java index e90e34ef1d7..fe9291ab137 100644 --- a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java +++ b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java @@ -182,4 +182,5 @@ public class ProjectConfiguration { @Value("${egov.user.id.validator}") private String egovUserIdValidator; + } diff --git a/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java b/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java index fd1d029bb4e..ec885f723b1 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java +++ b/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java @@ -112,7 +112,7 @@ private List getProjectsBasedOnSearchCriteria(List projectsReq } /* Fetch Projects based on Project ids */ - private List getProjectsBasedOnProjectIds(List projectIds, List preparedStmtList) { + public List getProjectsBasedOnProjectIds(List projectIds, List preparedStmtList) { String query = queryBuilder.getProjectSearchQueryBasedOnIds(projectIds, preparedStmtList); List projects = jdbcTemplate.query(query, addressRowMapper, preparedStmtList.toArray()); log.info("Fetched project list based on given Project Ids"); diff --git a/health-services/project/src/main/java/org/egov/project/repository/ProjectTaskRepository.java b/health-services/project/src/main/java/org/egov/project/repository/ProjectTaskRepository.java index ca8e598b50e..76a4f8e87cc 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/ProjectTaskRepository.java +++ b/health-services/project/src/main/java/org/egov/project/repository/ProjectTaskRepository.java @@ -124,4 +124,5 @@ public List findById(List ids, String columnName, Boolean includeD putInCache(objFound); return objFound; } + } diff --git a/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java b/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java index 90be2dcf45c..0f76c26f507 100644 --- a/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java +++ b/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java @@ -24,6 +24,7 @@ import org.egov.project.validator.task.PtProductVariantIdValidator; import org.egov.project.validator.task.PtProjectBeneficiaryIdValidator; import org.egov.project.validator.task.PtProjectIdValidator; +import org.egov.project.validator.task.PtIsResouceEmptyValidator; import org.egov.project.validator.task.PtRowVersionValidator; import org.egov.project.validator.task.PtUniqueEntityValidator; import org.egov.project.validator.task.PtUniqueSubEntityValidator; @@ -69,11 +70,13 @@ public class ProjectTaskService { private final Predicate> isApplicableForCreate = validator -> validator.getClass().equals(PtProjectIdValidator.class) + || validator.getClass().equals(PtIsResouceEmptyValidator.class) || validator.getClass().equals(PtProjectBeneficiaryIdValidator.class) || validator.getClass().equals(PtProductVariantIdValidator.class); private final Predicate> isApplicableForUpdate = validator -> validator.getClass().equals(PtProjectIdValidator.class) + || validator.getClass().equals(PtIsResouceEmptyValidator.class) || validator.getClass().equals(PtProjectBeneficiaryIdValidator.class) || validator.getClass().equals(PtProductVariantIdValidator.class) || validator.getClass().equals(PtNullIdValidator.class) diff --git a/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java b/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java index c3b7564e49f..9706c877ff2 100644 --- a/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java +++ b/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java @@ -9,6 +9,7 @@ import org.egov.common.service.IdGenService; import org.egov.project.config.ProjectConfiguration; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Map; @@ -143,6 +144,8 @@ private static void enrichResourcesForCreate(TaskBulkRequest request, for (Task task : validTasks) { log.info("enriching resources"); List resources = task.getResources(); + if(CollectionUtils.isEmpty(resources)) + continue; enrichResourcesForCreate(request, resources, task.getId()); } } diff --git a/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java b/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java index 5d0240ba7e7..5a431833f41 100644 --- a/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java +++ b/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java @@ -1,5 +1,8 @@ package org.egov.project.util; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + public class ProjectConstants { public static final String MASTER_TENANTS = "tenants"; public static final String MDMS_TENANT_MODULE_NAME = "tenant"; @@ -13,4 +16,32 @@ public class ProjectConstants { public static final String SEMICOLON = ":"; public static final String DOT = "."; public static final String PROJECT_PARENT_HIERARCHY_SEPERATOR = "."; -} + public static final String TASK_NOT_ALLOWED = "TASK_NOT_ALLOWED"; + public static final String TASK_NOT_ALLOWED_BENEFICIARY_REFUSED_RESOURCE_EMPTY_ERROR_MESSAGE = "Task not allowed as resources can not be provided when " + TaskStatus.BENEFICIARY_REFUSED; + public static final String TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE = "Task not allowed as resources can not be empty when "; + public enum TaskStatus { + BENEFICIARY_REFUSED("BENEFICIARY_REFUSED"); + private String value; + + TaskStatus(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TaskStatus fromValue(String text) { + for (TaskStatus status : TaskStatus.values()) { + if (String.valueOf(status.value).equals(text)) { + return status; + } + } + return null; + } + } + +} \ No newline at end of file diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java new file mode 100644 index 00000000000..f5d5cd42a77 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java @@ -0,0 +1,64 @@ +package org.egov.project.validator.task; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.project.Task; +import org.egov.common.models.project.TaskBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.project.util.ProjectConstants; +import org.egov.tracer.model.CustomException; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.project.util.ProjectConstants.TASK_NOT_ALLOWED; + +/** + * To Validate when task resource is empty or null + */ +@Component +@Order(value = 1) +@Slf4j +public class PtIsResouceEmptyValidator implements Validator { + + /** + * Returns all the invalid objects in the request based on the task resources. + * @param request of TaskBulkRequest class + * @return errorDetailsMap + */ + public Map> validate(TaskBulkRequest request) { + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getTasks(); + if(!entities.isEmpty()) { + entities.forEach(task -> { + if(CollectionUtils.isEmpty(task.getResources()) && !ProjectConstants.TaskStatus.BENEFICIARY_REFUSED.toString().equals(task.getStatus())) { + /** + * If the task resource is empty or null and task status is not BENEFICIARY_REFUSED it is invalid + */ + Error error = Error.builder() + .errorMessage(ProjectConstants.TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE + ProjectConstants.TaskStatus.BENEFICIARY_REFUSED) + .errorCode(TASK_NOT_ALLOWED) + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException(TASK_NOT_ALLOWED, ProjectConstants.TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE + ProjectConstants.TaskStatus.BENEFICIARY_REFUSED)).build(); + populateErrorDetails(task, error, errorDetailsMap); + } else if (!CollectionUtils.isEmpty(task.getResources()) && ProjectConstants.TaskStatus.BENEFICIARY_REFUSED.toString().equals(task.getStatus())) { + /** + * If the task resource is not empty and task status is BENEFICIARY_REFUSED + */ + Error error = Error.builder() + .errorMessage(ProjectConstants.TASK_NOT_ALLOWED_BENEFICIARY_REFUSED_RESOURCE_EMPTY_ERROR_MESSAGE) + .errorCode(TASK_NOT_ALLOWED) + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException(TASK_NOT_ALLOWED, ProjectConstants.TASK_NOT_ALLOWED_BENEFICIARY_REFUSED_RESOURCE_EMPTY_ERROR_MESSAGE)).build(); + populateErrorDetails(task, error, errorDetailsMap); + } + }); + } + return errorDetailsMap; + } +} \ No newline at end of file diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtProductVariantIdValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtProductVariantIdValidator.java index bef18b723b5..c59928aa153 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtProductVariantIdValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtProductVariantIdValidator.java @@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.HashMap; @@ -62,6 +63,8 @@ public Map> validate(TaskBulkRequest request) { .filter(notHavingErrors()).collect(Collectors.toList()); if (!entities.isEmpty()) { for (Task task : entities) { + if(CollectionUtils.isEmpty(task.getResources())) + continue; Set productVariantIds = new HashSet<>(getIdList(task.getResources(), getIdMethod(task.getResources(), "productVariantId"))); try { diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index dc9d0bf08f8..81fc4cd7f12 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -163,6 +163,3 @@ project.resource.consumer.bulk.delete.topic=delete-project-resource-bulk-topic project.mdms.module=HCM-PROJECT-TYPES egov.location.hierarchy.type=ADMIN - - - diff --git a/health-services/project/src/main/resources/project-task-persister.yml b/health-services/project/src/main/resources/project-task-persister.yml index e8e2a62dcd5..76b7b467397 100644 --- a/health-services/project/src/main/resources/project-task-persister.yml +++ b/health-services/project/src/main/resources/project-task-persister.yml @@ -155,4 +155,4 @@ serviceMaps: - jsonPath: $.*.auditDetails.lastModifiedBy - jsonPath: $.*.auditDetails.lastModifiedTime - jsonPath: $.*.isDeleted - - jsonPath: $.*.id \ No newline at end of file + - jsonPath: $.*.id diff --git a/health-services/referralmanagement/pom.xml b/health-services/referralmanagement/pom.xml new file mode 100644 index 00000000000..3b5fded205c --- /dev/null +++ b/health-services/referralmanagement/pom.xml @@ -0,0 +1,136 @@ + + + + 4.0.0 + + org.egov + referralmanagement + jar + referralmanagement + 1.0.0 + + 1.8 + ${java.version} + ${java.version} + + + org.springframework.boot + spring-boot-starter-parent + 2.2.6.RELEASE + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.egov.common + health-services-common + 1.0.8-SNAPSHOT + + + org.egov.common + health-services-models + 1.0.9-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-starter-data-redis + + + io.lettuce + lettuce-core + + + + + redis.clients + jedis + + + org.flywaydb + flyway-core + + + org.postgresql + postgresql + 42.2.2.jre7 + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.swagger + swagger-core + 1.5.18 + + + + org.egov.services + digit-models + 1.0.0-SNAPSHOT + + + org.projectlombok + lombok + true + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + javax.validation + validation-api + + + + + + repo.egovernments.org + eGov ERP Releases Repository + https://nexus-repo.egovernments.org/nexus/content/repositories/releases/ + + + repo.egovernments.org.snapshots + eGov ERP Releases Repository + https://nexus-repo.egovernments.org/nexus/content/repositories/snapshots/ + + + repo.egovernments.org.public + eGov Public Repository Group + https://nexus-repo.egovernments.org/nexus/content/groups/public/ + + + repo.digit.org + eGov DIGIT Releases Repository + https://nexus-repo.digit.org/nexus/content/repositories/snapshots/ + + + \ No newline at end of file diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java new file mode 100644 index 00000000000..8aa7a484a82 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java @@ -0,0 +1,15 @@ +package org.egov.referralmanagement; + +public interface Constants { + String SET_SIDE_EFFECTS = "setSideEffects"; + String GET_SIDE_EFFECTS = "getSideEffects"; + String SET_REFERRALS = "setReferrals"; + String GET_REFERRALS = "getReferrals"; + String VALIDATION_ERROR = "VALIDATION_ERROR"; + String PROJECT_TYPES = "projectTypes"; + String MDMS_RESPONSE = "MdmsRes"; + String INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR"; + String GET_ID = "getId"; + String PROJECT_STAFF = "project_staff"; + String FACILITY = "facility"; +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/ReferralManagementApplication.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/ReferralManagementApplication.java new file mode 100644 index 00000000000..03494a4c86b --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/ReferralManagementApplication.java @@ -0,0 +1,18 @@ +package org.egov.referralmanagement; + + +import org.egov.tracer.config.TracerConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@EnableCaching +@Import({ TracerConfiguration.class }) +public class ReferralManagementApplication +{ + public static void main(String[] args) throws Exception { + SpringApplication.run(ReferralManagementApplication.class, args); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/MainConfiguration.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/MainConfiguration.java new file mode 100644 index 00000000000..86310611791 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/MainConfiguration.java @@ -0,0 +1,93 @@ +package org.egov.referralmanagement.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.egov.tracer.config.TracerConfiguration; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import javax.annotation.PostConstruct; +import java.util.TimeZone; + +@Import({TracerConfiguration.class}) +@Configuration +@ComponentScan(basePackages = {"org.egov"}) +public class MainConfiguration { + + @Value("${app.timezone}") + private String timeZone; + + @Value("${spring.redis.host}") + private String redisHost; + + @PostConstruct + public void initialize() { + TimeZone.setDefault(TimeZone.getTimeZone(timeZone)); + } + + @Bean + @Qualifier("objectMapper") + public ObjectMapper objectMapper(){ + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).setTimeZone(TimeZone.getTimeZone(timeZone)); + objectMapper.registerModule(new JavaTimeModule()); + return objectMapper; + } + + @Bean + @Qualifier("redisObjectMapper") + public ObjectMapper redisObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, + ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); + objectMapper.registerModule(new JavaTimeModule()); + return objectMapper; + } + + @Bean + public MappingJackson2HttpMessageConverter jacksonConverter(ObjectMapper objectMapper) { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setObjectMapper(objectMapper); + return converter; + } + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); + redisStandaloneConfiguration.setHostName(redisHost); + return new JedisConnectionFactory(redisStandaloneConfiguration); + } + + + @Bean + public RedisTemplate redisTemplate(@Qualifier("redisObjectMapper") ObjectMapper redisObjectMapper, + RedisConnectionFactory redisConnectionFactory) { + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + serializer.setObjectMapper(redisObjectMapper); + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(serializer); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(serializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} \ No newline at end of file diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java new file mode 100644 index 00000000000..be30c29e5d4 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java @@ -0,0 +1,71 @@ +package org.egov.referralmanagement.config; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Component +public class ReferralManagementConfiguration { + @Value("${referralmanagement.sideeffect.kafka.create.topic}") + private String createSideEffectTopic; + + @Value("${referralmanagement.sideeffect.kafka.update.topic}") + private String updateSideEffectTopic; + + @Value("${referralmanagement.sideeffect.kafka.delete.topic}") + private String deleteSideEffectTopic; + + @Value("${referralmanagement.sideeffect.consumer.bulk.create.topic}") + private String createSideEffectBulkTopic; + + @Value("${referralmanagement.sideeffect.consumer.bulk.update.topic}") + private String updateSideEffectBulkTopic; + + @Value("${referralmanagement.sideeffect.consumer.bulk.delete.topic}") + private String deleteSideEffectBulkTopic; + + @Value("${egov.project.host}") + private String projectHost; + + @Value("${egov.search.project.task.url}") + private String projectTaskSearchUrl; + + @Value("${egov.search.project.beneficiary.url}") + private String projectBeneficiarySearchUrl; + + @Value("${referralmanagement.referral.kafka.create.topic}") + private String createReferralTopic; + + @Value("${referralmanagement.referral.kafka.update.topic}") + private String updateReferralTopic; + + @Value("${referralmanagement.referral.kafka.delete.topic}") + private String deleteReferralTopic; + + @Value("${referralmanagement.referral.consumer.bulk.create.topic}") + private String createReferralBulkTopic; + + @Value("${referralmanagement.referral.consumer.bulk.update.topic}") + private String updateReferralBulkTopic; + + @Value("${referralmanagement.referral.consumer.bulk.delete.topic}") + private String deleteReferralBulkTopic; + + @Value("${egov.search.project.staff.url}") + private String projectStaffSearchUrl; + + @Value("${egov.facility.host}") + private String facilityHost; + + @Value("${egov.search.facility.url}") + private String facilitySearchUrl; +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/ReferralManagementConsumer.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/ReferralManagementConsumer.java new file mode 100644 index 00000000000..d4902d7ea33 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/ReferralManagementConsumer.java @@ -0,0 +1,71 @@ +package org.egov.referralmanagement.consumer; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.egov.referralmanagement.service.ReferralManagementService; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@Slf4j +public class ReferralManagementConsumer { + + private final ReferralManagementService referralManagementService; + + private final ObjectMapper objectMapper; + + @Autowired + public ReferralManagementConsumer(ReferralManagementService referralManagementService, + @Qualifier("objectMapper") ObjectMapper objectMapper) { + this.referralManagementService = referralManagementService; + this.objectMapper = objectMapper; + } + + @KafkaListener(topics = "${referralmanagement.referral.consumer.bulk.create.topic}") + public void bulkCreate(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + ReferralBulkRequest request = objectMapper.convertValue(consumerRecord, ReferralBulkRequest.class); + referralManagementService.create(request, true); + } catch (Exception exception) { + log.error("Error in Referral consumer bulk create", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + throw new CustomException("HCM_ADRM_REFERRAL_MANAGEMENT_CREATE", exception.getMessage()); + } + } + + @KafkaListener(topics = "${referralmanagement.referral.consumer.bulk.update.topic}") + public void bulkUpdate(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + ReferralBulkRequest request = objectMapper.convertValue(consumerRecord, ReferralBulkRequest.class); + referralManagementService.update(request, true); + } catch (Exception exception) { + log.error("Error in Referral consumer bulk update", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + throw new CustomException("HCM_ADRM_REFERRAL_MANAGEMENT_CREATE", exception.getMessage()); + } + } + + @KafkaListener(topics = "${referralmanagement.referral.consumer.bulk.delete.topic}") + public void bulkDelete(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + ReferralBulkRequest request = objectMapper.convertValue(consumerRecord, ReferralBulkRequest.class); + referralManagementService.delete(request, true); + } catch (Exception exception) { + log.error("Error in Referral consumer bulk delete", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + throw new CustomException("HCM_ADRM_REFERRAL_MANAGEMENT_CREATE", exception.getMessage()); + } + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/SideEffectConsumer.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/SideEffectConsumer.java new file mode 100644 index 00000000000..e1d8204cb06 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/SideEffectConsumer.java @@ -0,0 +1,71 @@ +package org.egov.referralmanagement.consumer; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.referralmanagement.service.SideEffectService; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@Slf4j +public class SideEffectConsumer { + + private final SideEffectService sideEffectService; + + private final ObjectMapper objectMapper; + + @Autowired + public SideEffectConsumer(SideEffectService sideEffectService, + @Qualifier("objectMapper") ObjectMapper objectMapper) { + this.sideEffectService = sideEffectService; + this.objectMapper = objectMapper; + } + + @KafkaListener(topics = "${referralmanagement.sideeffect.consumer.bulk.create.topic}") + public void bulkCreate(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + SideEffectBulkRequest request = objectMapper.convertValue(consumerRecord, SideEffectBulkRequest.class); + sideEffectService.create(request, true); + } catch (Exception exception) { + log.error("Error in Side Effect consumer bulk create", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + throw new CustomException("HCM_PROJECT_SIDE_EFFECT_CREATE", exception.getMessage()); + } + } + + @KafkaListener(topics = "${referralmanagement.sideeffect.consumer.bulk.update.topic}") + public void bulkUpdate(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + SideEffectBulkRequest request = objectMapper.convertValue(consumerRecord, SideEffectBulkRequest.class); + sideEffectService.update(request, true); + } catch (Exception exception) { + log.error("Error in Side Effect consumer bulk update", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + throw new CustomException("HCM_PROJECT_SIDE_EFFECT_CREATE", exception.getMessage()); + } + } + + @KafkaListener(topics = "${referralmanagement.sideeffect.consumer.bulk.delete.topic}") + public void bulkDelete(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + SideEffectBulkRequest request = objectMapper.convertValue(consumerRecord, SideEffectBulkRequest.class); + sideEffectService.delete(request, true); + } catch (Exception exception) { + log.error("Error in Side Effect consumer bulk delete", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + throw new CustomException("HCM_PROJECT_SIDE_EFFECT_CREATE", exception.getMessage()); + } + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/ReferralRepository.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/ReferralRepository.java new file mode 100644 index 00000000000..ca6e891bf97 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/ReferralRepository.java @@ -0,0 +1,95 @@ +package org.egov.referralmanagement.repository; + +import lombok.extern.slf4j.Slf4j; +import org.egov.referralmanagement.repository.rowmapper.ReferralRowMapper; +import org.egov.common.data.query.builder.GenericQueryBuilder; +import org.egov.common.data.query.builder.QueryFieldChecker; +import org.egov.common.data.query.builder.SelectQueryBuilder; +import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.data.repository.GenericRepository; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralSearch; +import org.egov.common.producer.Producer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.getIdMethod; + +@Repository +@Slf4j +public class ReferralRepository extends GenericRepository { + @Autowired + private ReferralRowMapper rowMapper; + + @Autowired + protected ReferralRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, + RedisTemplate redisTemplate, SelectQueryBuilder selectQueryBuilder, + ReferralRowMapper rowMapper) { + super(producer, namedParameterJdbcTemplate, redisTemplate, selectQueryBuilder, rowMapper, Optional.of("referral")); + } + + public List find(ReferralSearch searchObject, Integer limit, Integer offset, String tenantId, + Long lastChangedSince, Boolean includeDeleted) throws QueryBuilderException { + String query = "SELECT r.*, se.id, se.clientreferenceid, se.tenantid, se.taskid, se.taskclientreferenceid, se.symptoms, se.reattempts, se.createdby, se.createdtime, se.lastmodifiedby, se.lastmodifiedtime, se.clientcreatedtime, se.clientlastmodifiedtime, se.rowversion, se.isdeleted FROM referral r left join side_effect se on r.sideEffectClientReferenceid = se.clientreferenceid"; + Map paramsMap = new HashMap<>(); + List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, + QueryFieldChecker.isNotNull, paramsMap); + query = GenericQueryBuilder.generateQuery(query, whereFields).toString(); + query = query.replace("id IN (:id)", "r.id IN (:id)"); + query = query.replace("clientReferenceId IN (:clientReferenceId)", "r.clientReferenceId IN (:clientReferenceId)"); + + query = query + " and r.tenantId=:tenantId "; + if (Boolean.FALSE.equals(includeDeleted)) { + query = query + "and r.isDeleted=:isDeleted "; + } + + if (lastChangedSince != null) { + query = query + "and r.lastModifiedTime>=:lastModifiedTime "; + } + query = query + "ORDER BY r.id ASC LIMIT :limit OFFSET :offset"; + paramsMap.put("tenantId", tenantId); + paramsMap.put("isDeleted", includeDeleted); + paramsMap.put("lastModifiedTime", lastChangedSince); + paramsMap.put("limit", limit); + paramsMap.put("offset", offset); + List referralList = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + return referralList; + } + + public List findById(List ids, String columnName, Boolean includeDeleted) { + List objFound = findInCache(ids).stream() + .filter(entity -> entity.getIsDeleted().equals(includeDeleted)) + .collect(Collectors.toList()); + if (!objFound.isEmpty()) { + Method idMethod = getIdMethod(objFound, columnName); + ids.removeAll(objFound.stream() + .map(obj -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) + .collect(Collectors.toList())); + if (ids.isEmpty()) { + return objFound; + } + } + + String query = String.format("SELECT r.*, se.id, se.clientreferenceid, se.tenantid, se.taskid, se.taskclientreferenceid, se.symptoms, se.reattempts, se.createdby, se.createdtime, se.lastmodifiedby, se.lastmodifiedtime, se.clientcreatedtime, se.clientlastmodifiedtime, se.rowversion, se.isdeleted FROM referral r left join side_effect se on r.sideEffectClientReferenceid = se.clientreferenceid WHERE r.%s IN (:ids) ", columnName); + if (includeDeleted == null || !includeDeleted) { + query += " AND r.isDeleted = false "; + } + Map paramMap = new HashMap<>(); + paramMap.put("ids", ids); + List referralList = this.namedParameterJdbcTemplate.query(query, paramMap, this.rowMapper); + + objFound.addAll(referralList); + putInCache(objFound); + return objFound; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/SideEffectRepository.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/SideEffectRepository.java new file mode 100644 index 00000000000..c3ce7ea000b --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/SideEffectRepository.java @@ -0,0 +1,119 @@ +package org.egov.referralmanagement.repository; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.data.query.builder.GenericQueryBuilder; +import org.egov.common.data.query.builder.QueryFieldChecker; +import org.egov.common.data.query.builder.SelectQueryBuilder; +import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.data.repository.GenericRepository; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearch; +import org.egov.common.models.project.Task; +import org.egov.common.producer.Producer; +import org.egov.referralmanagement.repository.rowmapper.SideEffectRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Method; +import java.util.*; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.getIdList; +import static org.egov.common.utils.CommonUtils.getIdMethod; + +@Repository +@Slf4j +public class SideEffectRepository extends GenericRepository { + @Autowired + private SideEffectRowMapper rowMapper; + + @Autowired + protected SideEffectRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, + RedisTemplate redisTemplate, SelectQueryBuilder selectQueryBuilder, + SideEffectRowMapper rowMapper) { + super(producer, namedParameterJdbcTemplate, redisTemplate, selectQueryBuilder, rowMapper, Optional.of("side_effect")); + } + + public Map> fetchSideEffects(List taskList) { + if (taskList.isEmpty()) { + return Collections.emptyMap(); + } + List taskIds = getIdList(taskList); + Map resourceParamsMap = new HashMap<>(); + String resourceQuery = "SELECT * FROM side_effect ae where ae.taskId IN (:taskIds)"; + resourceParamsMap.put("taskIds", taskIds); + List sideEffectList = this.namedParameterJdbcTemplate.query(resourceQuery, resourceParamsMap, + this.rowMapper); + Map> idToObjMap = new HashMap<>(); + + sideEffectList.forEach(sideEffect -> { + String taskId = sideEffect.getTaskId(); + if (idToObjMap.containsKey(taskId)) { + idToObjMap.get(taskId).add(sideEffect); + } else { + List sideEffects = new ArrayList<>(); + sideEffects.add(sideEffect); + idToObjMap.put(taskId, sideEffects); + } + }); + return idToObjMap; + } + + public List find(SideEffectSearch searchObject, Integer limit, Integer offset, String tenantId, + Long lastChangedSince, Boolean includeDeleted) throws QueryBuilderException { + String query = "SELECT * FROM side_effect ae LEFT JOIN project_task pt ON ae.taskId = pt.id "; + Map paramsMap = new HashMap<>(); + List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, + QueryFieldChecker.isNotNull, paramsMap); + query = GenericQueryBuilder.generateQuery(query, whereFields).toString(); + query = query.replace("id IN (:id)", "ae.id IN (:id)"); + query = query.replace("clientReferenceId IN (:clientReferenceId)", "ae.clientReferenceId IN (:clientReferenceId)"); + + query = query + " and ae.tenantId=:tenantId "; + if (Boolean.FALSE.equals(includeDeleted)) { + query = query + "and ae.isDeleted=:isDeleted "; + } + + if (lastChangedSince != null) { + query = query + "and as.lastModifiedTime>=:lastModifiedTime "; + } + query = query + "ORDER BY ae.id ASC LIMIT :limit OFFSET :offset"; + paramsMap.put("tenantId", tenantId); + paramsMap.put("isDeleted", includeDeleted); + paramsMap.put("lastModifiedTime", lastChangedSince); + paramsMap.put("limit", limit); + paramsMap.put("offset", offset); + List sideEffectList = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + return sideEffectList; + } + + public List findById(List ids, String columnName, Boolean includeDeleted) { + List objFound = findInCache(ids).stream() + .filter(entity -> entity.getIsDeleted().equals(includeDeleted)) + .collect(Collectors.toList()); + if (!objFound.isEmpty()) { + Method idMethod = getIdMethod(objFound, columnName); + ids.removeAll(objFound.stream() + .map(obj -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) + .collect(Collectors.toList())); + if (ids.isEmpty()) { + return objFound; + } + } + + String query = String.format("SELECT * FROM side_effect ae LEFT JOIN project_task pt ON ae.taskid = pt.id WHERE ae.%s IN (:ids) ", columnName); + if (includeDeleted == null || !includeDeleted) { + query += " AND ae.isDeleted = false "; + } + Map paramMap = new HashMap<>(); + paramMap.put("ids", ids); + List sideEffectList = this.namedParameterJdbcTemplate.query(query, paramMap, this.rowMapper); + + objFound.addAll(sideEffectList); + putInCache(objFound); + return objFound; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java new file mode 100644 index 00000000000..a7a3692d3ed --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java @@ -0,0 +1,83 @@ +package org.egov.referralmanagement.repository.rowmapper; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.models.coremodels.AuditDetails; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + +@Component +public class ReferralRowMapper implements RowMapper { + + @Autowired + ObjectMapper objectMapper; + + @Override + public Referral mapRow(ResultSet resultSet, int i) throws SQLException { + try { + SideEffect sideEffect = null; + String sideEffectClientReferenceId = resultSet.getString("sideEffectClientReferenceId"); + if(sideEffectClientReferenceId != null) { + AuditDetails sideEffectAuditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("se.createdBy")) + .createdTime(resultSet.getLong("se.createdTime")) + .lastModifiedBy(resultSet.getString("se.lastModifiedBy")) + .lastModifiedTime(resultSet.getLong("se.lastModifiedTime")) + .build(); + AuditDetails sideEffectClientAuditDetails = AuditDetails.builder() + .createdTime(resultSet.getLong("se.clientCreatedTime")) + .lastModifiedTime(resultSet.getLong("se.clientLastModifiedTime")) + .build(); + sideEffect = SideEffect.builder() + .id(resultSet.getString("se.id")) + .clientReferenceId(resultSet.getString("se.clientreferenceid")) + .taskId(resultSet.getString("se.taskId")) + .taskClientReferenceId(resultSet.getString("se.taskClientreferenceid")) + .tenantId(resultSet.getString("se.tenantid")) + .symptoms(resultSet.getString("se.symptoms") == null ? null : objectMapper.readValue(resultSet.getString("se.symptoms"), ArrayList.class)) + .rowVersion(resultSet.getInt("se.rowversion")) + .isDeleted(resultSet.getBoolean("se.isdeleted")) + .auditDetails(sideEffectAuditDetails) + .clientAuditDetails(sideEffectClientAuditDetails) + .build(); + } + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("createdBy")) + .createdTime(resultSet.getLong("createdTime")) + .lastModifiedBy(resultSet.getString("lastModifiedBy")) + .lastModifiedTime(resultSet.getLong("lastModifiedTime")) + .build(); + AuditDetails clientAuditDetails= AuditDetails.builder() + .createdBy(resultSet.getString("clientCreatedBy")) + .createdTime(resultSet.getLong("clientCreatedTime")) + .lastModifiedBy(resultSet.getString("clientLastModifiedBy")) + .lastModifiedTime(resultSet.getLong("clientLastModifiedTime")) + .build(); + return Referral.builder() + .id(resultSet.getString("id")) + .clientReferenceId(resultSet.getString("clientreferenceid")) + .projectBeneficiaryId(resultSet.getString("projectBeneficiaryId")) + .projectBeneficiaryClientReferenceId(resultSet.getString("projectbeneficiaryclientreferenceid")) + .referredById(resultSet.getString("referredById")) + .referredToId(resultSet.getString("referredToId")) + .referredToType(resultSet.getString("referredToType")) + .sideEffect(sideEffect) + .tenantId(resultSet.getString("tenantid")) + .reasons(resultSet.getString("reasons") == null ? null : objectMapper.readValue(resultSet.getString("reasons"), ArrayList.class)) + .rowVersion(resultSet.getInt("rowversion")) + .isDeleted(resultSet.getBoolean("isdeleted")) + .auditDetails(auditDetails) + .clientAuditDetails(clientAuditDetails) + .build(); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java new file mode 100644 index 00000000000..7a49ceef93e --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java @@ -0,0 +1,54 @@ +package org.egov.referralmanagement.repository.rowmapper; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.models.coremodels.AuditDetails; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + +@Component +public class SideEffectRowMapper implements RowMapper { + + @Autowired + ObjectMapper objectMapper; + + @Override + public SideEffect mapRow(ResultSet resultSet, int i) throws SQLException { + try { + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("createdBy")) + .createdTime(resultSet.getLong("createdTime")) + .lastModifiedBy(resultSet.getString("lastModifiedBy")) + .lastModifiedTime(resultSet.getLong("lastModifiedTime")) + .build(); + AuditDetails clientAuditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("clientCreatedBy")) + .createdTime(resultSet.getLong("clientCreatedTime")) + .lastModifiedBy(resultSet.getString("clientLastModifiedBy")) + .lastModifiedTime(resultSet.getLong("clientLastModifiedTime")) + .build(); + return SideEffect.builder() + .id(resultSet.getString("id")) + .clientReferenceId(resultSet.getString("clientreferenceid")) + .taskId(resultSet.getString("taskId")) + .taskClientReferenceId(resultSet.getString("taskClientreferenceid")) + .projectBeneficiaryId(resultSet.getString("projectBeneficiaryId")) + .projectBeneficiaryClientReferenceId(resultSet.getString("projectBeneficiaryClientReferenceId")) + .tenantId(resultSet.getString("tenantid")) + .symptoms(resultSet.getString("symptoms") == null ? null : objectMapper.readValue(resultSet.getString("symptoms"), ArrayList.class)) + .rowVersion(resultSet.getInt("rowversion")) + .isDeleted(resultSet.getBoolean("isdeleted")) + .auditDetails(auditDetails) + .clientAuditDetails(clientAuditDetails) + .build(); + } catch (JsonProcessingException e) { + throw new SQLException(e); + } + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java new file mode 100644 index 00000000000..ea7f107e0ea --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java @@ -0,0 +1,232 @@ +package org.egov.referralmanagement.service; + +import lombok.extern.slf4j.Slf4j; +import org.egov.referralmanagement.Constants; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.referralmanagement.repository.ReferralRepository; +import org.egov.referralmanagement.service.enrichment.ReferralManagementEnrichmentService; +import org.egov.referralmanagement.validator.RmFacilityEntitiesIdValidator; +import org.egov.referralmanagement.validator.RmIsDeletedValidator; +import org.egov.referralmanagement.validator.RmNonExistentEntityValidator; +import org.egov.referralmanagement.validator.RmNullIdValidator; +import org.egov.referralmanagement.validator.RmProjectEntitiesIdValidator; +import org.egov.referralmanagement.validator.RmUniqueEntityValidator; +import org.egov.common.ds.Tuple; +import org.egov.common.models.ErrorDetails; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.models.referralmanagement.ReferralRequest; +import org.egov.common.models.referralmanagement.ReferralSearchRequest; +import org.egov.common.service.IdGenService; +import org.egov.common.utils.CommonUtils; +import org.egov.common.validator.Validator; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Service; +import org.springframework.util.ReflectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdMethod; +import static org.egov.common.utils.CommonUtils.handleErrors; +import static org.egov.common.utils.CommonUtils.havingTenantId; +import static org.egov.common.utils.CommonUtils.includeDeleted; +import static org.egov.common.utils.CommonUtils.isSearchByIdOnly; +import static org.egov.common.utils.CommonUtils.lastChangedSince; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; + +@Service +@Slf4j +public class ReferralManagementService { + private final IdGenService idGenService; + + private final ReferralRepository referralRepository; + + private final ReferralManagementConfiguration referralManagementConfiguration; + + private final ReferralManagementEnrichmentService referralManagementEnrichmentService; + + private final List> validators; + + private final Predicate> isApplicableForCreate = validator -> + validator.getClass().equals(RmProjectEntitiesIdValidator.class) + || validator.getClass().equals(RmFacilityEntitiesIdValidator.class); + + private final Predicate> isApplicableForUpdate = validator -> + validator.getClass().equals(RmProjectEntitiesIdValidator.class) + || validator.getClass().equals(RmFacilityEntitiesIdValidator.class) + || validator.getClass().equals(RmNullIdValidator.class) + || validator.getClass().equals(RmIsDeletedValidator.class) + || validator.getClass().equals(RmUniqueEntityValidator.class) + || validator.getClass().equals(RmNonExistentEntityValidator.class); + + private final Predicate> isApplicableForDelete = validator -> + validator.getClass().equals(RmNullIdValidator.class) + || validator.getClass().equals(RmNonExistentEntityValidator.class); + + + public ReferralManagementService(IdGenService idGenService, ReferralRepository referralRepository, ReferralManagementConfiguration referralManagementConfiguration, ReferralManagementEnrichmentService referralManagementEnrichmentService, List> validators) { + this.idGenService = idGenService; + this.referralRepository = referralRepository; + this.referralManagementConfiguration = referralManagementConfiguration; + this.referralManagementEnrichmentService = referralManagementEnrichmentService; + this.validators = validators; + } + + public Referral create(ReferralRequest request) { + log.info("received request to create referrals"); + ReferralBulkRequest bulkRequest = ReferralBulkRequest.builder().requestInfo(request.getRequestInfo()) + .referrals(Collections.singletonList(request.getReferral())).build(); + log.info("creating bulk request"); + return create(bulkRequest, false).get(0); + } + + public List create(ReferralBulkRequest referralRequest, boolean isBulk) { + log.info("received request to create bulk referrals"); + Tuple, Map> tuple = validate(validators, + isApplicableForCreate, referralRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validReferrals = tuple.getX(); + + try { + if (!validReferrals.isEmpty()) { + log.info("processing {} valid entities", validReferrals.size()); + referralManagementEnrichmentService.create(validReferrals, referralRequest); + referralRepository.save(validReferrals, + referralManagementConfiguration.getCreateReferralTopic()); + log.info("successfully created referrals"); + } + } catch (Exception exception) { + log.error("error occurred while creating referrals: {}", exception.getMessage()); + populateErrorDetails(referralRequest, errorDetailsMap, validReferrals, + exception, Constants.SET_SIDE_EFFECTS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validReferrals; + } + + public Referral update(ReferralRequest request) { + log.info("received request to update referral"); + ReferralBulkRequest bulkRequest = ReferralBulkRequest.builder().requestInfo(request.getRequestInfo()) + .referrals(Collections.singletonList(request.getReferral())).build(); + log.info("creating bulk request"); + return update(bulkRequest, false).get(0); + } + + public List update(ReferralBulkRequest referralRequest, boolean isBulk) { + log.info("received request to update bulk referral"); + Tuple, Map> tuple = validate(validators, + isApplicableForUpdate, referralRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validReferrals = tuple.getX(); + + try { + if (!validReferrals.isEmpty()) { + log.info("processing {} valid entities", validReferrals.size()); + referralManagementEnrichmentService.update(validReferrals, referralRequest); + referralRepository.save(validReferrals, + referralManagementConfiguration.getUpdateReferralTopic()); + log.info("successfully updated bulk referrals"); + } + } catch (Exception exception) { + log.error("error occurred while updating referrals", exception); + populateErrorDetails(referralRequest, errorDetailsMap, validReferrals, + exception, Constants.SET_SIDE_EFFECTS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validReferrals; + } + + public List search(ReferralSearchRequest referralSearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { + log.info("received request to search referrals"); + String idFieldName = getIdFieldName(referralSearchRequest.getReferral()); + if (isSearchByIdOnly(referralSearchRequest.getReferral(), idFieldName)) { + log.info("searching referrals by id"); + List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections + .singletonList(referralSearchRequest.getReferral())), + referralSearchRequest.getReferral()); + log.info("fetching referrals with ids: {}", ids); + return referralRepository.findById(ids, includeDeleted, idFieldName).stream() + .filter(lastChangedSince(lastChangedSince)) + .filter(havingTenantId(tenantId)) + .filter(includeDeleted(includeDeleted)) + .collect(Collectors.toList()); + } + log.info("searching referrals using criteria"); + return referralRepository.find(referralSearchRequest.getReferral(), + limit, offset, tenantId, lastChangedSince, includeDeleted); + } + + public Referral delete(ReferralRequest referralRequest) { + log.info("received request to delete a referral"); + ReferralBulkRequest bulkRequest = ReferralBulkRequest.builder().requestInfo(referralRequest.getRequestInfo()) + .referrals(Collections.singletonList(referralRequest.getReferral())).build(); + log.info("creating bulk request"); + return delete(bulkRequest, false).get(0); + } + + public List delete(ReferralBulkRequest referralRequest, boolean isBulk) { + Tuple, Map> tuple = validate(validators, + isApplicableForDelete, referralRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validReferrals = tuple.getX(); + + try { + if (!validReferrals.isEmpty()) { + log.info("processing {} valid entities", validReferrals.size()); + List referralIds = validReferrals.stream().map(entity -> entity.getId()).collect(Collectors.toSet()).stream().collect(Collectors.toList()); + List existingReferrals = referralRepository + .findById(referralIds, false); + referralManagementEnrichmentService.delete(existingReferrals, referralRequest); + referralRepository.save(existingReferrals, + referralManagementConfiguration.getDeleteReferralTopic()); + log.info("successfully deleted entities"); + } + } catch (Exception exception) { + log.error("error occurred while deleting entities: {}", exception); + populateErrorDetails(referralRequest, errorDetailsMap, validReferrals, + exception, Constants.SET_SIDE_EFFECTS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validReferrals; + } + + public void putInCache(List referrals) { + log.info("putting {} referrals in cache", referrals.size()); + referralRepository.putInCache(referrals); + log.info("successfully put referrals in cache"); + } + + private Tuple, Map> validate( + List> validators, + Predicate> isApplicable, + ReferralBulkRequest request, + boolean isBulk + ) { + log.info("validating request"); + Map errorDetailsMap = CommonUtils.validate(validators, + isApplicable, request, + Constants.SET_SIDE_EFFECTS); + if (!errorDetailsMap.isEmpty() && !isBulk) { + log.error("validation error occurred. error details: {}", errorDetailsMap.values().toString()); + throw new CustomException(Constants.VALIDATION_ERROR, errorDetailsMap.values().toString()); + } + List validReferrals = request.getReferrals().stream() + .filter(notHavingErrors()).collect(Collectors.toList()); + log.info("validation successful, found valid referrals"); + return new Tuple<>(validReferrals, errorDetailsMap); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/SideEffectService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/SideEffectService.java new file mode 100644 index 00000000000..fcb56d335b6 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/SideEffectService.java @@ -0,0 +1,293 @@ +package org.egov.referralmanagement.service; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.ds.Tuple; +import org.egov.common.models.ErrorDetails; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectRequest; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearchRequest; +import org.egov.common.utils.CommonUtils; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.Constants; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.referralmanagement.repository.SideEffectRepository; +import org.egov.referralmanagement.service.enrichment.SideEffectEnrichmentService; +import org.egov.referralmanagement.validator.sideeffect.SeIsDeletedValidator; +import org.egov.referralmanagement.validator.sideeffect.SeNonExistentEntityValidator; +import org.egov.referralmanagement.validator.sideeffect.SeNullIdValidator; +import org.egov.referralmanagement.validator.sideeffect.SeProjectBeneficiaryIdValidator; +import org.egov.referralmanagement.validator.sideeffect.SeProjectTaskIdValidator; +import org.egov.referralmanagement.validator.sideeffect.SeUniqueEntityValidator; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.ReflectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdMethod; +import static org.egov.common.utils.CommonUtils.handleErrors; +import static org.egov.common.utils.CommonUtils.havingTenantId; +import static org.egov.common.utils.CommonUtils.includeDeleted; +import static org.egov.common.utils.CommonUtils.isSearchByIdOnly; +import static org.egov.common.utils.CommonUtils.lastChangedSince; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; + +/** + * @author kanishq-egov + * Service created to enrich, validate request and perform crud operations + */ +@Service +@Slf4j +public class SideEffectService { + private final SideEffectRepository sideEffectRepository; + + private final ReferralManagementConfiguration referralManagementConfiguration; + + private final SideEffectEnrichmentService sideEffectEnrichmentService; + + private final List> validators; + + private final Predicate> isApplicableForCreate = validator -> + validator.getClass().equals(SeProjectTaskIdValidator.class) + || validator.getClass().equals(SeProjectBeneficiaryIdValidator.class); + + private final Predicate> isApplicableForUpdate = validator -> + validator.getClass().equals(SeProjectTaskIdValidator.class) + || validator.getClass().equals(SeNullIdValidator.class) + || validator.getClass().equals(SeIsDeletedValidator.class) + || validator.getClass().equals(SeUniqueEntityValidator.class) + || validator.getClass().equals(SeNonExistentEntityValidator.class); + + private final Predicate> isApplicableForDelete = validator -> + validator.getClass().equals(SeNullIdValidator.class) + || validator.getClass().equals(SeNonExistentEntityValidator.class); + + @Autowired + public SideEffectService( + SideEffectRepository sideEffectRepository, + ReferralManagementConfiguration referralManagementConfiguration, + SideEffectEnrichmentService sideEffectEnrichmentService, + List> validators + ) { + this.sideEffectRepository = sideEffectRepository; + this.referralManagementConfiguration = referralManagementConfiguration; + this.sideEffectEnrichmentService = sideEffectEnrichmentService; + this.validators = validators; + } + + /** + * converting SideEffectRequest to SideEffectBulkRequest + * @param request + * @return + */ + public SideEffect create(SideEffectRequest request) { + log.info("received request to create side effects"); + SideEffectBulkRequest bulkRequest = SideEffectBulkRequest.builder().requestInfo(request.getRequestInfo()) + .sideEffects(Collections.singletonList(request.getSideEffect())).build(); + log.info("creating bulk request"); + return create(bulkRequest, false).get(0); + } + + /** + * validate the request, for valid objects after enriching them, sending it to kafka, and + * throwing error for the invalid objects. + * @param sideEffectRequest + * @param isBulk + * @return + */ + public List create(SideEffectBulkRequest sideEffectRequest, boolean isBulk) { + log.info("received request to create bulk side effects"); + Tuple, Map> tuple = validate(validators, + isApplicableForCreate, sideEffectRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validSideEffects = tuple.getX(); + + try { + if (!validSideEffects.isEmpty()) { + log.info("processing {} valid entities", validSideEffects.size()); + sideEffectEnrichmentService.create(validSideEffects, sideEffectRequest); + sideEffectRepository.save(validSideEffects, + referralManagementConfiguration.getCreateSideEffectTopic()); + log.info("successfully created side effects"); + } + } catch (Exception exception) { + log.error("error occurred while creating side effects: {}", exception.getMessage()); + populateErrorDetails(sideEffectRequest, errorDetailsMap, validSideEffects, + exception, Constants.SET_SIDE_EFFECTS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validSideEffects; + } + + /** + * converting SideEffectRequest to SideEffectBulkRequest + * @param request + * @return + */ + public SideEffect update(SideEffectRequest request) { + log.info("received request to update side effect"); + SideEffectBulkRequest bulkRequest = SideEffectBulkRequest.builder().requestInfo(request.getRequestInfo()) + .sideEffects(Collections.singletonList(request.getSideEffect())).build(); + log.info("creating bulk request"); + return update(bulkRequest, false).get(0); + } + + /** + * validate the request, for valid objects after enriching them, sending it to kafka, and + * throwing error for the invalid objects. + * @param sideEffectRequest + * @param isBulk + * @return + */ + public List update(SideEffectBulkRequest sideEffectRequest, boolean isBulk) { + log.info("received request to update bulk side effect"); + Tuple, Map> tuple = validate(validators, + isApplicableForUpdate, sideEffectRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validSideEffects = tuple.getX(); + + try { + if (!validSideEffects.isEmpty()) { + log.info("processing {} valid entities", validSideEffects.size()); + sideEffectEnrichmentService.update(validSideEffects, sideEffectRequest); + sideEffectRepository.save(validSideEffects, + referralManagementConfiguration.getUpdateSideEffectTopic()); + log.info("successfully updated bulk side effects"); + } + } catch (Exception exception) { + log.error("error occurred while updating side effects", exception); + populateErrorDetails(sideEffectRequest, errorDetailsMap, validSideEffects, + exception, Constants.SET_SIDE_EFFECTS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validSideEffects; + } + + /** + * searching based on parameters + * @param sideEffectSearchRequest + * @param limit + * @param offset + * @param tenantId + * @param lastChangedSince + * @param includeDeleted + * @return + * @throws Exception + */ + public List search(SideEffectSearchRequest sideEffectSearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { + log.info("received request to search side effects"); + String idFieldName = getIdFieldName(sideEffectSearchRequest.getSideEffect()); + if (isSearchByIdOnly(sideEffectSearchRequest.getSideEffect(), idFieldName)) { + log.info("searching side effects by id"); + List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections + .singletonList(sideEffectSearchRequest.getSideEffect())), + sideEffectSearchRequest.getSideEffect()); + log.info("fetching side effects with ids: {}", ids); + return sideEffectRepository.findById(ids, includeDeleted, idFieldName).stream() + .filter(lastChangedSince(lastChangedSince)) + .filter(havingTenantId(tenantId)) + .filter(includeDeleted(includeDeleted)) + .collect(Collectors.toList()); + } + log.info("searching side effects using criteria"); + return sideEffectRepository.find(sideEffectSearchRequest.getSideEffect(), + limit, offset, tenantId, lastChangedSince, includeDeleted); + } + + /** + * converting SideEffectRequest to SideEffectBulkRequest + * @param sideEffectRequest + * @return + */ + public SideEffect delete(SideEffectRequest sideEffectRequest) { + log.info("received request to delete a side effect"); + SideEffectBulkRequest bulkRequest = SideEffectBulkRequest.builder().requestInfo(sideEffectRequest.getRequestInfo()) + .sideEffects(Collections.singletonList(sideEffectRequest.getSideEffect())).build(); + log.info("creating bulk request"); + return delete(bulkRequest, false).get(0); + } + + /** + * validating the request, enriching the valid objects and sending them to kafka + * throwing error on invalid objects + * @param sideEffectRequest + * @param isBulk + * @return + */ + public List delete(SideEffectBulkRequest sideEffectRequest, boolean isBulk) { + Tuple, Map> tuple = validate(validators, + isApplicableForDelete, sideEffectRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validSideEffects = tuple.getX(); + + try { + if (!validSideEffects.isEmpty()) { + log.info("processing {} valid entities", validSideEffects.size()); + List sideEffectIds = validSideEffects.stream().map(entity -> entity.getId()).collect(Collectors.toSet()).stream().collect(Collectors.toList()); + List existingSideEffects = sideEffectRepository + .findById(sideEffectIds, false); + sideEffectEnrichmentService.delete(existingSideEffects, sideEffectRequest); + sideEffectRepository.save(existingSideEffects, + referralManagementConfiguration.getDeleteSideEffectTopic()); + log.info("successfully deleted entities"); + } + } catch (Exception exception) { + log.error("error occurred while deleting entities: {}", exception); + populateErrorDetails(sideEffectRequest, errorDetailsMap, validSideEffects, + exception, Constants.SET_SIDE_EFFECTS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validSideEffects; + } + + public void putInCache(List sideEffects) { + log.info("putting {} side effects in cache", sideEffects.size()); + sideEffectRepository.putInCache(sideEffects); + log.info("successfully put side effects in cache"); + } + + /** + * method use to valid request using parameters objects + * @param validators + * @param isApplicable + * @param request + * @param isBulk + * @return + */ + private Tuple, Map> validate( + List> validators, + Predicate> isApplicable, + SideEffectBulkRequest request, + boolean isBulk + ) { + log.info("validating request"); + Map errorDetailsMap = CommonUtils.validate(validators, + isApplicable, request, + Constants.SET_SIDE_EFFECTS); + if (!errorDetailsMap.isEmpty() && !isBulk) { + log.error("validation error occurred. error details: {}", errorDetailsMap.values().toString()); + throw new CustomException(Constants.VALIDATION_ERROR, errorDetailsMap.values().toString()); + } + List validSideEffects = request.getSideEffects().stream() + .filter(notHavingErrors()).collect(Collectors.toList()); + log.info("validation successful, found valid side effects"); + return new Tuple<>(validSideEffects, errorDetailsMap); + } + +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/ReferralManagementEnrichmentService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/ReferralManagementEnrichmentService.java new file mode 100644 index 00000000000..659e54eb280 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/ReferralManagementEnrichmentService.java @@ -0,0 +1,56 @@ +package org.egov.referralmanagement.service.enrichment; + +import lombok.extern.slf4j.Slf4j; +import org.egov.referralmanagement.repository.ReferralRepository; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.service.IdGenService; +import org.egov.common.utils.CommonUtils; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static org.egov.common.utils.CommonUtils.enrichForCreate; +import static org.egov.common.utils.CommonUtils.enrichForDelete; +import static org.egov.common.utils.CommonUtils.enrichForUpdate; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; + +@Component +@Slf4j +public class ReferralManagementEnrichmentService { + private final IdGenService idGenService; + + private final ReferralManagementConfiguration referralManagementConfiguration; + + private final ReferralRepository referralRepository; + + public ReferralManagementEnrichmentService(IdGenService idGenService, ReferralManagementConfiguration referralManagementConfiguration, ReferralRepository referralRepository) { + this.idGenService = idGenService; + this.referralManagementConfiguration = referralManagementConfiguration; + this.referralRepository = referralRepository; + } + + public void create(List entities, ReferralBulkRequest request) throws Exception { + log.info("starting the enrichment for create referrals"); + log.info("generating IDs using UUID"); + List idList = CommonUtils.uuidSupplier().apply(entities.size()); + log.info("enriching referrals with generated IDs"); + enrichForCreate(entities, idList, request.getRequestInfo()); + log.info("enrichment done"); + } + + public void update(List entities, ReferralBulkRequest request) { + log.info("starting the enrichment for create referrals"); + Map referralMap = getIdToObjMap(entities); + enrichForUpdate(referralMap, entities, request); + log.info("enrichment done"); + } + + public void delete(List entities, ReferralBulkRequest request) { + log.info("starting the enrichment for delete referrals"); + enrichForDelete(entities, request.getRequestInfo(), true); + log.info("enrichment done"); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/SideEffectEnrichmentService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/SideEffectEnrichmentService.java new file mode 100644 index 00000000000..03eefb43298 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/SideEffectEnrichmentService.java @@ -0,0 +1,60 @@ +package org.egov.referralmanagement.service.enrichment; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.utils.CommonUtils; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static org.egov.common.utils.CommonUtils.enrichForCreate; +import static org.egov.common.utils.CommonUtils.enrichForDelete; +import static org.egov.common.utils.CommonUtils.enrichForUpdate; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; + +/** + * Class use to enrich SideEffectBulkRequest object + */ +@Component +@Slf4j +public class SideEffectEnrichmentService { + + /** + * + * @param entities + * @param request + */ + public void create(List entities, SideEffectBulkRequest request) { + log.info("starting the enrichment for create side effect"); + log.info("generating IDs using UUID"); + List idList = CommonUtils.uuidSupplier().apply(entities.size()); + log.info("enriching side effects with generated IDs"); + enrichForCreate(entities, idList, request.getRequestInfo()); + log.info("enrichment done"); + } + + /** + * + * @param entities + * @param request + */ + public void update(List entities, SideEffectBulkRequest request) { + log.info("starting the enrichment for create side effect"); + Map sideEffectMap = getIdToObjMap(entities); + enrichForUpdate(sideEffectMap, entities, request); + log.info("enrichment done"); + } + + /** + * + * @param entities + * @param request + */ + public void delete(List entities, SideEffectBulkRequest request) { + log.info("starting the enrichment for delete side effect"); + enrichForDelete(entities, request.getRequestInfo(), true); + log.info("enrichment done"); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmFacilityEntitiesIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmFacilityEntitiesIdValidator.java new file mode 100644 index 00000000000..83d4377ee0c --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmFacilityEntitiesIdValidator.java @@ -0,0 +1,100 @@ +package org.egov.referralmanagement.validator; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.http.client.ServiceRequestClient; +import org.egov.common.models.Error; +import org.egov.common.models.facility.Facility; +import org.egov.common.models.facility.FacilityBulkResponse; +import org.egov.common.models.facility.FacilitySearch; +import org.egov.common.models.facility.FacilitySearchRequest; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; +import static org.egov.referralmanagement.Constants.FACILITY; + + +@Component +@Order(value = 3) +@Slf4j +public class RmFacilityEntitiesIdValidator implements Validator { + private final ServiceRequestClient serviceRequestClient; + private final ReferralManagementConfiguration referralManagementConfiguration; + + @Autowired + public RmFacilityEntitiesIdValidator(ServiceRequestClient serviceRequestClient, ReferralManagementConfiguration referralManagementConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + + @Override + public Map> validate(ReferralBulkRequest request) { + log.info("validating facility id"); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getReferrals(); + Map> tenantIdReferralMap = entities.stream().collect(Collectors.groupingBy(Referral::getTenantId)); + List tenantIds = new ArrayList<>(tenantIdReferralMap.keySet()); + tenantIds.forEach(tenantId -> { + List referralList = tenantIdReferralMap.get(tenantId); + if (!referralList.isEmpty()) { + List existingFacilityList = null; + final List facilityIdList = new ArrayList<>(); + try { + referralList.forEach(referral -> { + if(referral.getReferredToType().equals(FACILITY)){ + addIgnoreNull(facilityIdList, referral.getReferredToId()); + } + }); + FacilitySearch facilitySearch = FacilitySearch.builder() + .id(facilityIdList.isEmpty() ? null : facilityIdList) + .build(); + FacilityBulkResponse facilityBulkResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getFacilityHost() + + referralManagementConfiguration.getFacilitySearchUrl() + +"?limit=" + entities.size() + + "&offset=0&tenantId=" + tenantId), + FacilitySearchRequest.builder().requestInfo(request.getRequestInfo()).facility(facilitySearch).build(), + FacilityBulkResponse.class + ); + existingFacilityList = facilityBulkResponse.getFacilities(); + } catch (QueryBuilderException e) { + existingFacilityList = Collections.emptyList(); + } catch (Exception e) { + throw new RuntimeException(e); + } + final List existingFacilityIds = new ArrayList<>(); + existingFacilityList.forEach(facility -> existingFacilityIds.add(facility.getId())); + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + (!entity.getReferredToType().equals(FACILITY) || !existingFacilityIds.contains(entity.getReferredToId())) + ).collect(Collectors.toList()); + invalidEntities.forEach(referral -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(referral, error, errorDetailsMap); + }); + + } + }); + return errorDetailsMap; + } + + private void addIgnoreNull(List list, String item) { + if(Objects.nonNull(item)) list.add(item); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmIsDeletedValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmIsDeletedValidator.java new file mode 100644 index 00000000000..ca58f6deb30 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmIsDeletedValidator.java @@ -0,0 +1,34 @@ +package org.egov.referralmanagement.validator; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForIsDelete; + +@Component +@Order(2) +@Slf4j +public class RmIsDeletedValidator implements Validator { + + @Override + public Map> validate(ReferralBulkRequest request) { + log.info("validating isDeleted field"); + HashMap> errorDetailsMap = new HashMap<>(); + List validEntities = request.getReferrals(); + validEntities.stream().filter(Referral::getIsDeleted).forEach(referral -> { + Error error = getErrorForIsDelete(); + populateErrorDetails(referral, error, errorDetailsMap); + }); + return errorDetailsMap; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmNonExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmNonExistentEntityValidator.java new file mode 100644 index 00000000000..295d88f5227 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmNonExistentEntityValidator.java @@ -0,0 +1,71 @@ +package org.egov.referralmanagement.validator; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.repository.ReferralRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.egov.referralmanagement.Constants.GET_ID; +import static org.egov.common.utils.CommonUtils.checkNonExistentEntities; +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.common.utils.CommonUtils.getMethod; +import static org.egov.common.utils.CommonUtils.getObjClass; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + +@Component +@Order(value = 4) +@Slf4j +public class RmNonExistentEntityValidator implements Validator { + + private final ReferralRepository referralRepository; + + private final ObjectMapper objectMapper; + + @Autowired + public RmNonExistentEntityValidator(ReferralRepository referralRepository, ObjectMapper objectMapper) { + this.referralRepository = referralRepository; + this.objectMapper = objectMapper; + } + + + @Override + public Map> validate(ReferralBulkRequest request) { + log.info("validating for existence of entity"); + Map> errorDetailsMap = new HashMap<>(); + List referrals = request.getReferrals(); + Class objClass = getObjClass(referrals); + Method idMethod = getMethod(GET_ID, objClass); + Map iMap = getIdToObjMap(referrals + .stream().filter(notHavingErrors()).collect(Collectors.toList()), idMethod); + if (!iMap.isEmpty()) { + List sideEffectIds = new ArrayList<>(iMap.keySet()); + List existingReferrals = referralRepository + .findById(sideEffectIds, false, getIdFieldName(idMethod)); + List nonExistentReferrals = checkNonExistentEntities(iMap, + existingReferrals, idMethod); + nonExistentReferrals.forEach(sideEffect -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(sideEffect, error, errorDetailsMap); + }); + } + + return errorDetailsMap; + } +} + diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmNullIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmNullIdValidator.java new file mode 100644 index 00000000000..07df0399a64 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmNullIdValidator.java @@ -0,0 +1,27 @@ +package org.egov.referralmanagement.validator; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static org.egov.referralmanagement.Constants.GET_REFERRALS; +import static org.egov.common.utils.CommonUtils.validateForNullId; + + +@Component +@Order(value = 1) +@Slf4j +public class RmNullIdValidator implements Validator { + @Override + public Map> validate(ReferralBulkRequest request) { + log.info("validating for null id"); + return validateForNullId(request, GET_REFERRALS); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmProjectEntitiesIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmProjectEntitiesIdValidator.java new file mode 100644 index 00000000000..61c87b9f4ab --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmProjectEntitiesIdValidator.java @@ -0,0 +1,134 @@ +package org.egov.referralmanagement.validator; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.http.client.ServiceRequestClient; +import org.egov.common.models.Error; +import org.egov.common.models.project.BeneficiaryBulkResponse; +import org.egov.common.models.project.BeneficiarySearchRequest; +import org.egov.common.models.project.ProjectBeneficiary; +import org.egov.common.models.project.ProjectBeneficiarySearch; +import org.egov.common.models.project.ProjectStaff; +import org.egov.common.models.project.ProjectStaffBulkResponse; +import org.egov.common.models.project.ProjectStaffSearch; +import org.egov.common.models.project.ProjectStaffSearchRequest; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.egov.referralmanagement.Constants.PROJECT_STAFF; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + + +@Component +@Order(value = 3) +@Slf4j +public class RmProjectEntitiesIdValidator implements Validator { + private final ServiceRequestClient serviceRequestClient; + private final ReferralManagementConfiguration referralManagementConfiguration; + + @Autowired + public RmProjectEntitiesIdValidator(ServiceRequestClient serviceRequestClient, ReferralManagementConfiguration referralManagementConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + + @Override + public Map> validate(ReferralBulkRequest request) { + log.info("validating project beneficiary id, project staff id"); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getReferrals(); + Map> tenantIdReferralMap = entities.stream().collect(Collectors.groupingBy(Referral::getTenantId)); + List tenantIds = new ArrayList<>(tenantIdReferralMap.keySet()); + tenantIds.forEach(tenantId -> { + List referralList = tenantIdReferralMap.get(tenantId); + if (!referralList.isEmpty()) { + List existingProjectBeneficiaries = null; + List existingProjectStaffList = null; + final List projectBeneficiaryIdList = new ArrayList<>(); + final List projectBeneficiaryClientReferenceIdList = new ArrayList<>(); + final List projectStaffIdList = new ArrayList<>(); + try { + referralList.forEach(referral -> { + addIgnoreNull(projectBeneficiaryIdList, referral.getProjectBeneficiaryId()); + addIgnoreNull(projectBeneficiaryClientReferenceIdList, referral.getProjectBeneficiaryClientReferenceId()); + addIgnoreNull(projectStaffIdList, referral.getReferredById()); + if(referral.getReferredToType().equals(PROJECT_STAFF)){ + addIgnoreNull(projectStaffIdList, referral.getReferredToId()); + } + }); + ProjectBeneficiarySearch projectBeneficiarySearch = ProjectBeneficiarySearch.builder() + .id(projectBeneficiaryIdList.isEmpty() ? null : projectBeneficiaryIdList) + .clientReferenceId(projectBeneficiaryClientReferenceIdList.isEmpty() ? null : projectBeneficiaryClientReferenceIdList) + .build(); + BeneficiaryBulkResponse beneficiaryBulkResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getProjectHost() + + referralManagementConfiguration.getProjectBeneficiarySearchUrl() + +"?limit=" + entities.size() + + "&offset=0&tenantId=" + tenantId), + BeneficiarySearchRequest.builder().requestInfo(request.getRequestInfo()).projectBeneficiary(projectBeneficiarySearch).build(), + BeneficiaryBulkResponse.class + ); + existingProjectBeneficiaries = beneficiaryBulkResponse.getProjectBeneficiaries(); + ProjectStaffSearch projectStaffSearch = ProjectStaffSearch.builder() + .id(projectStaffIdList.isEmpty() ? null : projectStaffIdList) + .build(); + ProjectStaffBulkResponse projectStaffBulkResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getProjectHost() + + referralManagementConfiguration.getProjectStaffSearchUrl() + +"?limit=" + entities.size() + + "&offset=0&tenantId=" + tenantId), + ProjectStaffSearchRequest.builder().requestInfo(request.getRequestInfo()).projectStaff(projectStaffSearch).build(), + ProjectStaffBulkResponse.class + ); + existingProjectStaffList = projectStaffBulkResponse.getProjectStaff(); + + } catch (QueryBuilderException e) { + if(existingProjectBeneficiaries == null) existingProjectBeneficiaries = Collections.emptyList(); + existingProjectStaffList = Collections.emptyList(); + } catch (Exception e) { + throw new RuntimeException(e); + } + final List existingProjectBeneficiaryIds = new ArrayList<>(); + final List existingProjectBeneficiaryClientReferenceIds = new ArrayList<>(); + existingProjectBeneficiaries.forEach(projectBeneficiary -> { + existingProjectBeneficiaryIds.add(projectBeneficiary.getId()); + existingProjectBeneficiaryClientReferenceIds.add(projectBeneficiary.getClientReferenceId()); + }); + final List existingProjectStaffIds = new ArrayList<>(); + existingProjectStaffList.forEach(projectStaff -> existingProjectStaffIds.add(projectStaff.getId())); + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + !existingProjectStaffIds.contains(entity.getReferredById()) + && !existingProjectBeneficiaryIds.contains(entity.getProjectBeneficiaryId()) + && !existingProjectBeneficiaryClientReferenceIds.contains(entity.getProjectBeneficiaryClientReferenceId()) + && (!entity.getReferredToType().equals(PROJECT_STAFF) || !existingProjectStaffIds.contains(entity.getReferredToId())) + ).collect(Collectors.toList()); + invalidEntities.forEach(referral -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(referral, error, errorDetailsMap); + }); + + } + }); + return errorDetailsMap; + } + + private void addIgnoreNull(List list, String item) { + if(Objects.nonNull(item)) list.add(item); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmUniqueEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmUniqueEntityValidator.java new file mode 100644 index 00000000000..e35159b57f7 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmUniqueEntityValidator.java @@ -0,0 +1,47 @@ +package org.egov.referralmanagement.validator; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; + +@Component +@Order(value = 2) +@Slf4j +public class RmUniqueEntityValidator implements Validator { + + @Override + public Map> validate(ReferralBulkRequest request) { + log.info("validating unique entity"); + Map> errorDetailsMap = new HashMap<>(); + List validEntities = request.getReferrals() + .stream().filter(notHavingErrors()).collect(Collectors.toList()); + if (!validEntities.isEmpty()) { + Map eMap = getIdToObjMap(validEntities); + if (eMap.keySet().size() != validEntities.size()) { + List duplicates = eMap.keySet().stream().filter(id -> + validEntities.stream() + .filter(entity -> entity.getId().equals(id)).count() > 1 + ).collect(Collectors.toList()); + for (String key : duplicates) { + Error error = getErrorForUniqueEntity(); + populateErrorDetails(eMap.get(key), error, errorDetailsMap); + } + } + } + return errorDetailsMap; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeIsDeletedValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeIsDeletedValidator.java new file mode 100644 index 00000000000..b6e4d3f94f3 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeIsDeletedValidator.java @@ -0,0 +1,34 @@ +package org.egov.referralmanagement.validator.sideeffect; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForIsDelete; + +@Component +@Order(2) +@Slf4j +public class SeIsDeletedValidator implements Validator { + + @Override + public Map> validate(SideEffectBulkRequest request) { + log.info("validating isDeleted field"); + HashMap> errorDetailsMap = new HashMap<>(); + List validIndividuals = request.getSideEffects(); + validIndividuals.stream().filter(SideEffect::getIsDeleted).forEach(individual -> { + Error error = getErrorForIsDelete(); + populateErrorDetails(individual, error, errorDetailsMap); + }); + return errorDetailsMap; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeNonExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeNonExistentEntityValidator.java new file mode 100644 index 00000000000..5f70cd0fef5 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeNonExistentEntityValidator.java @@ -0,0 +1,71 @@ +package org.egov.referralmanagement.validator.sideeffect; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.egov.referralmanagement.repository.SideEffectRepository; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.egov.referralmanagement.Constants.GET_ID; +import static org.egov.common.utils.CommonUtils.checkNonExistentEntities; +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.common.utils.CommonUtils.getMethod; +import static org.egov.common.utils.CommonUtils.getObjClass; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + +@Component +@Order(value = 4) +@Slf4j +public class SeNonExistentEntityValidator implements Validator { + + private final SideEffectRepository sideEffectRepository; + + private final ObjectMapper objectMapper; + + @Autowired + public SeNonExistentEntityValidator(SideEffectRepository sideEffectRepository, ObjectMapper objectMapper) { + this.sideEffectRepository = sideEffectRepository; + this.objectMapper = objectMapper; + } + + + @Override + public Map> validate(SideEffectBulkRequest request) { + log.info("validating for existence of entity"); + Map> errorDetailsMap = new HashMap<>(); + List sideEffects = request.getSideEffects(); + Class objClass = getObjClass(sideEffects); + Method idMethod = getMethod(GET_ID, objClass); + Map iMap = getIdToObjMap(sideEffects + .stream().filter(notHavingErrors()).collect(Collectors.toList()), idMethod); + if (!iMap.isEmpty()) { + List sideEffectIds = new ArrayList<>(iMap.keySet()); + List existingSideEffects = sideEffectRepository + .findById(sideEffectIds, false, getIdFieldName(idMethod)); + List nonExistentIndividuals = checkNonExistentEntities(iMap, + existingSideEffects, idMethod); + nonExistentIndividuals.forEach(sideEffect -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(sideEffect, error, errorDetailsMap); + }); + } + + return errorDetailsMap; + } +} + diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeNullIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeNullIdValidator.java new file mode 100644 index 00000000000..f27f88830c4 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeNullIdValidator.java @@ -0,0 +1,27 @@ +package org.egov.referralmanagement.validator.sideeffect; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static org.egov.referralmanagement.Constants.GET_SIDE_EFFECTS; +import static org.egov.common.utils.CommonUtils.validateForNullId; + + +@Component +@Order(value = 1) +@Slf4j +public class SeNullIdValidator implements Validator { + @Override + public Map> validate(SideEffectBulkRequest request) { + log.info("validating for null id"); + return validateForNullId(request, GET_SIDE_EFFECTS); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeProjectBeneficiaryIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeProjectBeneficiaryIdValidator.java new file mode 100644 index 00000000000..3350fb90f4a --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeProjectBeneficiaryIdValidator.java @@ -0,0 +1,109 @@ +package org.egov.referralmanagement.validator.sideeffect; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.http.client.ServiceRequestClient; +import org.egov.common.models.Error; +import org.egov.common.models.project.BeneficiaryBulkResponse; +import org.egov.common.models.project.BeneficiarySearchRequest; +import org.egov.common.models.project.ProjectBeneficiary; +import org.egov.common.models.project.ProjectBeneficiarySearch; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + +/** + * Validate whether project beneficiary exist in db or not using project beneficiary id and project beneficiary client beneficiary id for SideEffect object + */ +@Component +@Order(value = 3) +@Slf4j +public class SeProjectBeneficiaryIdValidator implements Validator { + private final ServiceRequestClient serviceRequestClient; + private final ReferralManagementConfiguration referralManagementConfiguration; + + @Autowired + public SeProjectBeneficiaryIdValidator(ServiceRequestClient serviceRequestClient, ReferralManagementConfiguration referralManagementConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + /** + * + * @param request + * @return + */ + @Override + public Map> validate(SideEffectBulkRequest request) { + log.info("validating project task id"); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getSideEffects(); + Map> tenantIdSideEffectMap = entities.stream().collect(Collectors.groupingBy(SideEffect::getTenantId)); + tenantIdSideEffectMap.forEach((tenantId, sideEffects) -> { + List sideEffectList = tenantIdSideEffectMap.get(tenantId); + if (!sideEffectList.isEmpty()) { + List existingProjectBeneficiaries = null; + final List projectBeneficiaryIdList = new ArrayList<>(); + final List projectBeneficiaryClientReferenceIdList = new ArrayList<>(); + sideEffectList.forEach(sideEffect -> { + addIgnoreNull(projectBeneficiaryIdList, sideEffect.getProjectBeneficiaryId()); + addIgnoreNull(projectBeneficiaryClientReferenceIdList, sideEffect.getProjectBeneficiaryClientReferenceId()); + }); + ProjectBeneficiarySearch projectBeneficiarySearch = ProjectBeneficiarySearch.builder() + .id(projectBeneficiaryIdList.isEmpty() ? null : projectBeneficiaryIdList) + .clientReferenceId(projectBeneficiaryClientReferenceIdList.isEmpty() ? null : projectBeneficiaryClientReferenceIdList) + .build(); + try { + BeneficiaryBulkResponse beneficiaryBulkResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getProjectHost() + + referralManagementConfiguration.getProjectBeneficiarySearchUrl() + +"?limit=" + entities.size() + + "&offset=0&tenantId=" + tenantId), + BeneficiarySearchRequest.builder().requestInfo(request.getRequestInfo()).projectBeneficiary(projectBeneficiarySearch).build(), + BeneficiaryBulkResponse.class + ); + existingProjectBeneficiaries = beneficiaryBulkResponse.getProjectBeneficiaries(); + } catch (QueryBuilderException qbe) { + existingProjectBeneficiaries = Collections.emptyList(); + } catch (Exception e) { + throw new CustomException("Project Beneficiaries failed to fetch", "Exception : "+e.getMessage()); + } + final List existingProjectBeneficiaryIds = new ArrayList<>(); + final List existingProjectBeneficiaryClientReferenceIds = new ArrayList<>(); + existingProjectBeneficiaries.forEach(projectBeneficiary -> { + existingProjectBeneficiaryIds.add(projectBeneficiary.getId()); + existingProjectBeneficiaryClientReferenceIds.add(projectBeneficiary.getClientReferenceId()); + }); + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + !existingProjectBeneficiaryClientReferenceIds.contains(entity.getProjectBeneficiaryClientReferenceId()) + && !existingProjectBeneficiaryIds.contains(entity.getProjectBeneficiaryId()) + ).collect(Collectors.toList()); + invalidEntities.forEach(sideEffect -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(sideEffect, error, errorDetailsMap); + }); + } + }); + return errorDetailsMap; + } + private void addIgnoreNull(List list, String item) { + if(Objects.nonNull(item)) list.add(item); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeProjectTaskIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeProjectTaskIdValidator.java new file mode 100644 index 00000000000..1230987e3be --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeProjectTaskIdValidator.java @@ -0,0 +1,115 @@ +package org.egov.referralmanagement.validator.sideeffect; + +import lombok.extern.slf4j.Slf4j; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.http.client.ServiceRequestClient; +import org.egov.common.models.Error; +import org.egov.common.models.project.BeneficiaryBulkResponse; +import org.egov.common.models.project.BeneficiarySearchRequest; +import org.egov.common.models.project.ProjectBeneficiary; +import org.egov.common.models.project.ProjectBeneficiarySearch; +import org.egov.common.models.project.Task; +import org.egov.common.models.project.TaskBulkResponse; +import org.egov.common.models.project.TaskSearch; +import org.egov.common.models.project.TaskSearchRequest; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + +/** + * Validate whether project task exist in db or not using project task id and project task client beneficiary id for SideEffect object + */ +@Component +@Order(value = 3) +@Slf4j +public class SeProjectTaskIdValidator implements Validator { + private final ServiceRequestClient serviceRequestClient; + private final ReferralManagementConfiguration referralManagementConfiguration; + + @Autowired + public SeProjectTaskIdValidator(ServiceRequestClient serviceRequestClient, ReferralManagementConfiguration referralManagementConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + + /** + * validating whether the project task id and client reference id exist or not in db + * return the invalid Side effect objects as error map + * + * @param request of SideEffectBulkRequest + * @return + */ + @Override + public Map> validate(SideEffectBulkRequest request) { + log.info("validating project task id"); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getSideEffects(); + Map> tenantIdSideEffectMap = entities.stream().collect(Collectors.groupingBy(SideEffect::getTenantId)); + List tenantIds = new ArrayList<>(tenantIdSideEffectMap.keySet()); + tenantIds.forEach(tenantId -> { + List sideEffectList = tenantIdSideEffectMap.get(tenantId); + if (!sideEffectList.isEmpty()) { + List existingTasks = null; + final List taskIdList = new ArrayList<>(); + final List taskClientReferenceIdList = new ArrayList<>(); + sideEffectList.forEach(sideEffect -> { + addIgnoreNull(taskIdList, sideEffect.getTaskId()); + addIgnoreNull(taskClientReferenceIdList, sideEffect.getTaskClientReferenceId()); + }); + TaskSearch taskSearch = TaskSearch.builder() + .id(taskIdList.isEmpty() ? null : taskIdList) + .clientReferenceId(taskClientReferenceIdList.isEmpty() ? null : taskClientReferenceIdList).build(); + try { + TaskBulkResponse taskBulkResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getProjectHost() + + referralManagementConfiguration.getProjectTaskSearchUrl() + +"?limit=" + entities.size() + + "&offset=0&tenantId=" + tenantId), + TaskSearchRequest.builder().requestInfo(request.getRequestInfo()).task(taskSearch).build(), + TaskBulkResponse.class + ); + existingTasks = taskBulkResponse.getTasks(); + } catch (QueryBuilderException e) { + existingTasks = Collections.emptyList(); + } catch (Exception e) { + throw new CustomException("Project Task failed to fetch", "Exception : "+e.getMessage()); + } + final List existingProjectTaskIds = existingTasks.stream().map(Task::getId).collect(Collectors.toList()); + final List existingProjectReferenceTaskIds = existingTasks.stream().map(Task::getClientReferenceId).collect(Collectors.toList()); + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + !existingProjectReferenceTaskIds.contains(entity.getTaskClientReferenceId()) + && !existingProjectTaskIds.contains(entity.getTaskId()) + ).collect(Collectors.toList()); + invalidEntities.forEach(sideEffect -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(sideEffect, error, errorDetailsMap); + }); + + } + }); + + return errorDetailsMap; + } + + private void addIgnoreNull(List list, String item) { + if(Objects.nonNull(item)) list.add(item); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeUniqueEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeUniqueEntityValidator.java new file mode 100644 index 00000000000..43f99f7cef2 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeUniqueEntityValidator.java @@ -0,0 +1,45 @@ +package org.egov.referralmanagement.validator.sideeffect; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.egov.common.utils.CommonUtils.*; +import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; + +@Component +@Order(value = 2) +@Slf4j +public class SeUniqueEntityValidator implements Validator { + + @Override + public Map> validate(SideEffectBulkRequest request) { + log.info("validating unique entity"); + Map> errorDetailsMap = new HashMap<>(); + List validEntities = request.getSideEffects() + .stream().filter(notHavingErrors()).collect(Collectors.toList()); + if (!validEntities.isEmpty()) { + Map eMap = getIdToObjMap(validEntities); + if (eMap.keySet().size() != validEntities.size()) { + List duplicates = eMap.keySet().stream().filter(id -> + validEntities.stream() + .filter(entity -> entity.getId().equals(id)).count() > 1 + ).collect(Collectors.toList()); + for (String key : duplicates) { + Error error = getErrorForUniqueEntity(); + populateErrorDetails(eMap.get(key), error, errorDetailsMap); + } + } + } + return errorDetailsMap; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/ReferralManagementApiController.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/ReferralManagementApiController.java new file mode 100644 index 00000000000..949f84fbde8 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/ReferralManagementApiController.java @@ -0,0 +1,141 @@ +package org.egov.referralmanagement.web.controllers; + +import io.swagger.annotations.ApiParam; +import org.egov.referralmanagement.service.ReferralManagementService; +import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.referralmanagement.Referral; +import org.egov.common.models.referralmanagement.ReferralBulkRequest; +import org.egov.common.models.referralmanagement.ReferralBulkResponse; +import org.egov.common.models.referralmanagement.ReferralRequest; +import org.egov.common.models.referralmanagement.ReferralResponse; +import org.egov.common.models.referralmanagement.ReferralSearchRequest; +import org.egov.common.producer.Producer; +import org.egov.common.utils.ResponseInfoFactory; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +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 javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Controller +@RequestMapping("") +@Validated +public class ReferralManagementApiController { + private final HttpServletRequest httpServletRequest; + + private final ReferralManagementService referralManagementService; + + private final Producer producer; + + private final ReferralManagementConfiguration referralManagementConfiguration; + + public ReferralManagementApiController( + HttpServletRequest httpServletRequest, + ReferralManagementService referralManagementService, + Producer producer, + ReferralManagementConfiguration referralManagementConfiguration + ) { + this.httpServletRequest = httpServletRequest; + this.referralManagementService = referralManagementService; + this.producer = producer; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + @RequestMapping(value = "/v1/_create", method = RequestMethod.POST) + public ResponseEntity referralV1CreatePost(@ApiParam(value = "Capture details of Referral", required = true) @Valid @RequestBody ReferralRequest request) { + + Referral referral = referralManagementService.create(request); + ReferralResponse response = ReferralResponse.builder() + .referral(referral) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } + + + + @RequestMapping(value = "/v1/bulk/_create", method = RequestMethod.POST) + public ResponseEntity referralBulkV1CreatePost(@ApiParam(value = "Capture details of Referral", required = true) @Valid @RequestBody ReferralBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + referralManagementService.putInCache(request.getReferrals()); + producer.push(referralManagementConfiguration.getCreateReferralBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + + @RequestMapping(value = "/v1/_search", method = RequestMethod.POST) + public ResponseEntity referralV1SearchPost(@ApiParam(value = "Referral Search.", required = true) @Valid @RequestBody ReferralSearchRequest request, + @NotNull @Min(0) @Max(1000) @ApiParam(value = "Pagination - limit records in response", required = true) @Valid @RequestParam(value = "limit", required = true) Integer limit, + @NotNull @Min(0) @ApiParam(value = "Pagination - offset from which records should be returned in response", required = true) @Valid @RequestParam(value = "offset", required = true) Integer offset, + @NotNull @ApiParam(value = "Unique id for a tenant.", required = true) @Valid @RequestParam(value = "tenantId", required = true) String tenantId, + @ApiParam(value = "epoch of the time since when the changes on the object should be picked up. Search results from this parameter should include both newly created objects since this time as well as any modified objects since this time. This criterion is included to help polling clients to get the changes in system since a last time they synchronized with the platform. ") @Valid @RequestParam(value = "lastChangedSince", required = false) Long lastChangedSince, + @ApiParam(value = "Used in search APIs to specify if (soft) deleted records should be included in search results.", defaultValue = "false") @Valid @RequestParam(value = "includeDeleted", required = false, defaultValue = "false") Boolean includeDeleted) throws Exception { + + List referrals = referralManagementService.search(request, limit, offset, tenantId, lastChangedSince, includeDeleted); + ReferralBulkResponse response = ReferralBulkResponse.builder().responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)).referrals(referrals).build(); + + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + @RequestMapping(value = "/v1/_update", method = RequestMethod.POST) + public ResponseEntity referralV1UpdatePost(@ApiParam(value = "Capture details of Existing Referral", required = true) @Valid @RequestBody ReferralRequest request) { + Referral referral = referralManagementService.update(request); + + ReferralResponse response = ReferralResponse.builder() + .referral(referral) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + + } + + @RequestMapping(value = "/v1/bulk/_update", method = RequestMethod.POST) + public ResponseEntity referralV1BulkUpdatePost(@ApiParam(value = "Capture details of Existing Referral", required = true) @Valid @RequestBody ReferralBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + producer.push(referralManagementConfiguration.getUpdateReferralBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + + @RequestMapping(value = "/v1/_delete", method = RequestMethod.POST) + public ResponseEntity referralV1DeletePost(@ApiParam(value = "Capture details of Existing Referral", required = true) @Valid @RequestBody ReferralRequest request) { + Referral referral = referralManagementService.delete(request); + + ReferralResponse response = ReferralResponse.builder() + .referral(referral) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + + } + + @RequestMapping(value = "/v1/bulk/_delete", method = RequestMethod.POST) + public ResponseEntity referralV1BulkDeletePost(@ApiParam(value = "Capture details of Existing Referral", required = true) @Valid @RequestBody ReferralBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + producer.push(referralManagementConfiguration.getDeleteReferralBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/SideEffectApiController.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/SideEffectApiController.java new file mode 100644 index 00000000000..c43db332fa7 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/SideEffectApiController.java @@ -0,0 +1,141 @@ +package org.egov.referralmanagement.web.controllers; + +import io.swagger.annotations.ApiParam; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.referralmanagement.service.SideEffectService; +import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkResponse; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectRequest; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectResponse; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearchRequest; +import org.egov.common.producer.Producer; +import org.egov.common.utils.ResponseInfoFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +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 javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Controller +@RequestMapping("/side-effect") +@Validated +public class SideEffectApiController { + + private final HttpServletRequest httpServletRequest; + + private final SideEffectService sideEffectService; + + private final Producer producer; + + private final ReferralManagementConfiguration referralManagementConfiguration; + + public SideEffectApiController( + HttpServletRequest httpServletRequest, + SideEffectService sideEffectService, + Producer producer, + ReferralManagementConfiguration referralManagementConfiguration + ) { + this.httpServletRequest = httpServletRequest; + this.sideEffectService = sideEffectService; + this.producer = producer; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + @RequestMapping(value = "/v1/_create", method = RequestMethod.POST) + public ResponseEntity sideEffectV1CreatePost(@ApiParam(value = "Capture details of Side Effect", required = true) @Valid @RequestBody SideEffectRequest request) { + + SideEffect sideEffect = sideEffectService.create(request); + SideEffectResponse response = SideEffectResponse.builder() + .sideEffect(sideEffect) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } + + + + @RequestMapping(value = "/v1/bulk/_create", method = RequestMethod.POST) + public ResponseEntity sideEffectBulkV1CreatePost(@ApiParam(value = "Capture details of Side Effect", required = true) @Valid @RequestBody SideEffectBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + sideEffectService.putInCache(request.getSideEffects()); + producer.push(referralManagementConfiguration.getCreateSideEffectBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + + @RequestMapping(value = "/v1/_search", method = RequestMethod.POST) + public ResponseEntity sideEffectV1SearchPost(@ApiParam(value = "Side Effect Search.", required = true) @Valid @RequestBody SideEffectSearchRequest request, + @NotNull @Min(0) @Max(1000) @ApiParam(value = "Pagination - limit records in response", required = true) @Valid @RequestParam(value = "limit", required = true) Integer limit, + @NotNull @Min(0) @ApiParam(value = "Pagination - offset from which records should be returned in response", required = true) @Valid @RequestParam(value = "offset", required = true) Integer offset, + @NotNull @ApiParam(value = "Unique id for a tenant.", required = true) @Valid @RequestParam(value = "tenantId", required = true) String tenantId, + @ApiParam(value = "epoch of the time since when the changes on the object should be picked up. Search results from this parameter should include both newly created objects since this time as well as any modified objects since this time. This criterion is included to help polling clients to get the changes in system since a last time they synchronized with the platform. ") @Valid @RequestParam(value = "lastChangedSince", required = false) Long lastChangedSince, + @ApiParam(value = "Used in search APIs to specify if (soft) deleted records should be included in search results.", defaultValue = "false") @Valid @RequestParam(value = "includeDeleted", required = false, defaultValue = "false") Boolean includeDeleted) throws Exception { + + List sideEffects = sideEffectService.search(request, limit, offset, tenantId, lastChangedSince, includeDeleted); + SideEffectBulkResponse response = SideEffectBulkResponse.builder().responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)).sideEffects(sideEffects).build(); + + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + @RequestMapping(value = "/v1/_update", method = RequestMethod.POST) + public ResponseEntity sideEffectV1UpdatePost(@ApiParam(value = "Capture details of Existing side effect", required = true) @Valid @RequestBody SideEffectRequest request) { + SideEffect sideEffect = sideEffectService.update(request); + + SideEffectResponse response = SideEffectResponse.builder() + .sideEffect(sideEffect) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + + } + + @RequestMapping(value = "/v1/bulk/_update", method = RequestMethod.POST) + public ResponseEntity sideEffectV1BulkUpdatePost(@ApiParam(value = "Capture details of Existing side effect", required = true) @Valid @RequestBody SideEffectBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + producer.push(referralManagementConfiguration.getUpdateSideEffectBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + + @RequestMapping(value = "/v1/_delete", method = RequestMethod.POST) + public ResponseEntity sideEffectV1DeletePost(@ApiParam(value = "Capture details of Existing side effect", required = true) @Valid @RequestBody SideEffectRequest request) { + SideEffect sideEffect = sideEffectService.delete(request); + + SideEffectResponse response = SideEffectResponse.builder() + .sideEffect(sideEffect) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + + } + + @RequestMapping(value = "/v1/bulk/_delete", method = RequestMethod.POST) + public ResponseEntity sideEffectV1BulkDeletePost(@ApiParam(value = "Capture details of Existing side effect", required = true) @Valid @RequestBody SideEffectBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + producer.push(referralManagementConfiguration.getDeleteSideEffectBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } +} diff --git a/health-services/referralmanagement/src/main/resources/application.properties b/health-services/referralmanagement/src/main/resources/application.properties new file mode 100644 index 00000000000..1241002ce27 --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/application.properties @@ -0,0 +1,143 @@ +server.servlet.context-path=/referralmanagement +server.port=8080 +app.timezone=UTC + +# REDIS CONFIG +spring.redis.host=localhost +spring.redis.port=6379 +spring.cache.type=redis +# Seconds +spring.cache.redis.time-to-live=60 +spring.cache.autoexpiry=true + +# DATABASE CONFIG +spring.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password=postgres + +# FLYWAY CONFIG +spring.flyway.url=jdbc:postgresql://localhost:5432/postgres +spring.flyway.user=postgres +spring.flyway.password=postgres +spring.flyway.table=public +spring.flyway.baseline-on-migrate=true +spring.flyway.outOfOrder=true +spring.flyway.locations=classpath:/db/migration/main +spring.flyway.enabled=true + +# TRACER CONFIG +# KAFKA SERVER CONFIG +kafka.config.bootstrap_server_config=localhost:9092 +spring.kafka.consumer.value-deserializer=org.egov.tracer.kafka.deserializer.HashMapDeserializer +spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer +spring.kafka.consumer.group-id=project +spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer +spring.kafka.listener.missing-topics-fatal=false +spring.kafka.consumer.properties.spring.json.use.type.headers=false + +# KAFKA CONSUMER CONFIG +kafka.consumer.config.auto_commit=true +kafka.consumer.config.auto_commit_interval=100 +kafka.consumer.config.session_timeout=15000 +kafka.consumer.config.auto_offset_reset=earliest + +# KAFKA PRODUCER CONFIG +kafka.producer.config.retries_config=0 +kafka.producer.config.batch_size_config=16384 +kafka.producer.config.linger_ms_config=1 +kafka.producer.config.buffer_memory_config=33554432 + +# IDGEN CONFIG +# egov.idgen.host=https://dev.digit.org/ +#egov.idgen.host=https://health-dev.digit.org/ +egov.idgen.host=http://localhost:8081/ +egov.idgen.path=egov-idgen/id/_generate +egov.idgen.integration.enabled=true +referralmanagement.sideeffect.idgen.id.format=referralmanagement.sideeffect.id +referralmanagement.referral.idgen.id.format=referralmanagement.referral.id +idgen.project.beneficiary.id.format=project.beneficiary.id +project.staff.idgen.id.format=project.staff.id +project.facility.idgen.id.format=project.facility.id +egov.idgen.project.number.name=project.number +project.resource.idgen.id.format=project.resource.id + +# The value of the following field should be changed to service specific name +kafka.topics.consumer=project-consumer-topic + +# USER CONFIG +egov.user.host=https://unified-dev.digit.org +#egov.user.host=http://localhost:8286 +egov.search.user.url=/user/_search +egov.user.integration.enabled=true + +# MDMS CONFIG +egov.mdms.host=https://unified-dev.digit.org +egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +egov.mdms.master.name=project_master +egov.mdms.module.name=project +egov.mdms.integration.enabled=true + +# FACILITY SERVICE +egov.facility.host=http://localhost:8083 +egov.search.facility.url=/facility/v1/_search + +# HOUSEHOLD SERVICE +egov.household.host= +egov.search.household.url=/household/v1/_search + +# INDIVIDUAL SERVICE +egov.individual.host= +egov.search.individual.url= + +# use the value as "egov-user" to validate against egov-user service +# use the value as "individual" to validate against individual service +egov.user.id.validator=individual + +# PROJECT SERVICE +egov.project.host=https://unified-dev.digit.org +egov.search.project.task.url=/project/task/v1/_search +egov.search.project.beneficiary.url=/project/beneficiary/v1/_search +egov.search.project.staff.url=/project/staff/v1/_search + + +# ADRM KAFKA CONFIG +referralmanagement.sideeffect.kafka.create.topic=save-side-effect-topic +referralmanagement.sideeffect.kafka.update.topic=update-side-effect-topic +referralmanagement.sideeffect.kafka.delete.topic=delete-side-effect-topic + +referralmanagement.sideeffect.consumer.bulk.create.topic=save-side-effect-bulk-topic +referralmanagement.sideeffect.consumer.bulk.update.topic=update-side-effect-bulk-topic +referralmanagement.sideeffect.consumer.bulk.delete.topic=delete-side-effect-bulk-topic + +referralmanagement.referral.kafka.create.topic=save-referral-topic +referralmanagement.referral.kafka.update.topic=update-referral-topic +referralmanagement.referral.kafka.delete.topic=delete-referral-topic + +referralmanagement.referral.consumer.bulk.create.topic=save-referral-bulk-topic +referralmanagement.referral.consumer.bulk.update.topic=update-referral-bulk-topic +referralmanagement.referral.consumer.bulk.delete.topic=delete-referral-bulk-topic + +search.api.limit=1000 + +referralmanagement.default.offset=0 +referralmanagement.default.limit=100 +referralmanagement.search.max.limit=200 + + +#location config +egov.location.host=https://works-dev.digit.org +egov.location.context.path=/egov-location/location/v11/ +egov.location.endpoint=/boundarys/_search +egov.location.code.query.param=codes + +project.document.id.verification.required=false + + +project.mdms.module=HCM-PROJECT-TYPES +egov.location.hierarchy.type=ADMIN + + + + diff --git a/health-services/referralmanagement/src/main/resources/db/Dockerfile b/health-services/referralmanagement/src/main/resources/db/Dockerfile new file mode 100644 index 00000000000..60fc07ce69f --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/db/Dockerfile @@ -0,0 +1,9 @@ +FROM egovio/flyway:4.1.2 + +COPY ./migration/main /flyway/sql + +COPY migrate.sh /usr/bin/migrate.sh + +RUN chmod +x /usr/bin/migrate.sh + +CMD ["/usr/bin/migrate.sh"] \ No newline at end of file diff --git a/health-services/referralmanagement/src/main/resources/db/migrate.sh b/health-services/referralmanagement/src/main/resources/db/migrate.sh new file mode 100644 index 00000000000..43960b25cdb --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/db/migrate.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true -ignoreMissingMigrations=true migrate \ No newline at end of file diff --git a/health-services/referralmanagement/src/main/resources/db/migration/main/V20230928113400__referral_create_ddl.sql b/health-services/referralmanagement/src/main/resources/db/migration/main/V20230928113400__referral_create_ddl.sql new file mode 100644 index 00000000000..15ed8373d7f --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/db/migration/main/V20230928113400__referral_create_ddl.sql @@ -0,0 +1,26 @@ +CREATE TABLE REFERRAL +( + id character varying(64), + clientReferenceId character varying(64), + tenantId character varying(1000), + projectBeneficiaryId character varying(64), + projectBeneficiaryClientReferenceId character varying(64), + referredById character varying(100), + referredToId character varying(100), + referredToType character varying(100), + reasons jsonb, + sideEffectId character varying(100), + sideEffectClientReferenceId character varying(100), + createdBy character varying(64), + createdTime bigint, + lastModifiedBy character varying(64), + lastModifiedTime bigint, + clientCreatedBy character varying(64), + clientCreatedTime bigint, + clientLastModifiedBy character varying(64), + clientLastModifiedTime bigint, + rowVersion bigint, + isDeleted boolean, + CONSTRAINT uk_referral_id PRIMARY KEY (id), + CONSTRAINT uk_referral_clientReferenceId UNIQUE (clientReferenceId) +); diff --git a/health-services/referralmanagement/src/main/resources/db/migration/main/V20231010120100__side_effect_create_ddl.sql b/health-services/referralmanagement/src/main/resources/db/migration/main/V20231010120100__side_effect_create_ddl.sql new file mode 100644 index 00000000000..2cb20d2a998 --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/db/migration/main/V20231010120100__side_effect_create_ddl.sql @@ -0,0 +1,22 @@ +CREATE TABLE IF NOT EXISTS SIDE_EFFECT( + id character varying(64), + clientReferenceId character varying(64) NOT NULL, + tenantId character varying(1000), + taskId character varying(64), + taskClientReferenceId character varying(64) NOT NULL, + projectBeneficiaryId character varying(64), + projectBeneficiaryClientReferenceId character varying(64), + symptoms jsonb, + createdBy character varying(64), + createdTime bigint, + lastModifiedBy character varying(64), + lastModifiedTime bigint, + clientCreatedBy character varying(64), + clientCreatedTime bigint, + clientLastModifiedBy character varying(64), + clientLastModifiedTime bigint, + rowVersion bigint, + isDeleted bool, + CONSTRAINT uk_side_effect PRIMARY KEY (id), + CONSTRAINT uk_side_effect_clientReference_id unique (clientReferenceId) +); \ No newline at end of file diff --git a/health-services/referralmanagement/src/main/resources/referral-management-persister.yml b/health-services/referralmanagement/src/main/resources/referral-management-persister.yml new file mode 100644 index 00000000000..a3342191930 --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/referral-management-persister.yml @@ -0,0 +1,146 @@ +serviceMaps: + serviceName: referralmanagement + mappings: + - version: 1.0 + description: Saves a side effect + fromTopic: save-side-effect-topic + isTransaction: true + queryMaps: + - query: INSERT INTO SIDE_EFFECT(id, clientReferenceId, tenantId, taskId, taskClientReferenceId, projectBeneficiaryId, projectBeneficiaryClientReferenceId,symptoms, createdBy, createdTime, lastModifiedBy, lastModifiedTime, clientCreatedBy, clientCreatedTime, clientLastModifiedBy, clientLastModifiedTime, rowVersion, isDeleted) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?); + basePath: $.* + jsonMaps: + - jsonPath: $.*.id + - jsonPath: $.*.clientReferenceId + - jsonPath: $.*.tenantId + - jsonPath: $.*.taskId + - jsonPath: $.*.taskClientReferenceId + - jsonPath: $.*.projectBeneficiaryId + - jsonPath: $.*.projectBeneficiaryClientReferenceId + - jsonPath: $.*.symptoms + type: JSON + dbType: JSONB + - jsonPath: $.*.auditDetails.createdBy + - jsonPath: $.*.auditDetails.createdTime + - jsonPath: $.*.auditDetails.lastModifiedBy + - jsonPath: $.*.auditDetails.lastModifiedTime + - jsonPath: $.*.clientAuditDetails.createdBy + - jsonPath: $.*.clientAuditDetails.createdTime + - jsonPath: $.*.clientAuditDetails.lastModifiedBy + - jsonPath: $.*.clientAuditDetails.lastModifiedTime + - jsonPath: $.*.rowVersion + - jsonPath: $.*.isDeleted + + - version: 1.0 + description: Updates a side effect + fromTopic: update-side-effect-topic + isTransaction: true + queryMaps: + - query: UPDATE SIDE_EFFECT SET tenantId = ?, taskId = ?, taskClientReferenceId = ?, projectBeneficiaryId = ?, projectBeneficiaryClientReferenceId = ?, symptoms = ?, lastModifiedBy = ?, lastModifiedTime = ?, clientLastModifiedBy = ?, clientLastModifiedTime = ?, rowVersion = ?, isDeleted = ? WHERE ID = ?; + basePath: $.* + jsonMaps: + - jsonPath: $.*.tenantId + - jsonPath: $.*.taskId + - jsonPath: $.*.taskClientReferenceId + - jsonPath: $.*.projectBeneficiaryId + - jsonPath: $.*.projectBeneficiaryClientReferenceId + - jsonPath: $.*.symptoms + type: JSON + dbType: JSONB + - jsonPath: $.*.auditDetails.lastModifiedBy + - jsonPath: $.*.auditDetails.lastModifiedTime + - jsonPath: $.*.clientAuditDetails.lastModifiedBy + - jsonPath: $.*.clientAuditDetails.lastModifiedTime + - jsonPath: $.*.rowVersion + - jsonPath: $.*.isDeleted + - jsonPath: $.*.id + + - version: 1.0 + description: Deletes a side effect + fromTopic: delete-side-effect-topic + isTransaction: true + queryMaps: + - query: UPDATE SIDE_EFFECT SET lastModifiedBy = ?, lastModifiedTime = ?, clientLastModifiedBy = ?, clientLastModifiedTime = ?, rowVersion = ?, isDeleted = ? WHERE ID = ?; + basePath: $.* + jsonMaps: + - jsonPath: $.*.auditDetails.lastModifiedBy + - jsonPath: $.*.auditDetails.lastModifiedTime + - jsonPath: $.*.clientAuditDetails.lastModifiedBy + - jsonPath: $.*.clientAuditDetails.lastModifiedTime + - jsonPath: $.*.rowVersion + - jsonPath: $.*.isDeleted + - jsonPath: $.*.id + + - version: 1.0 + description: Saves a referral + fromTopic: save-referral-topic + isTransaction: true + queryMaps: + - query: INSERT INTO REFERRAL(id, clientReferenceId, tenantId, projectBeneficiaryId, projectBeneficiaryClientReferenceId, referredById, referredToId, referredToType, reasons, sideEffectId, createdBy, createdTime, lastModifiedBy, lastModifiedTime, clientCreatedBy, clientCreatedTime, clientLastModifiedBy, clientLastModifiedTime, rowVersion, isDeleted) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?); + basePath: $.* + jsonMaps: + - jsonPath: $.*.id + - jsonPath: $.*.clientReferenceId + - jsonPath: $.*.tenantId + - jsonPath: $.*.projectBeneficiaryId + - jsonPath: $.*.projectBeneficiaryClientReferenceId + - jsonPath: $.*.referredById + - jsonPath: $.*.referredToId + - jsonPath: $.*.referredToType + - jsonPath: $.*.reasons + type: JSON + dbType: JSONB + - jsonPath: $.*.sideEffect.id + - jsonPath: $.*.auditDetails.createdBy + - jsonPath: $.*.auditDetails.createdTime + - jsonPath: $.*.auditDetails.lastModifiedBy + - jsonPath: $.*.auditDetails.lastModifiedTime + - jsonPath: $.*.clientAuditDetails.createdBy + - jsonPath: $.*.clientAuditDetails.createdTime + - jsonPath: $.*.clientAuditDetails.lastModifiedBy + - jsonPath: $.*.clientAuditDetails.lastModifiedTime + - jsonPath: $.*.rowVersion + - jsonPath: $.*.isDeleted + + - version: 1.0 + description: Updates a referral + fromTopic: update-referral-topic + isTransaction: true + queryMaps: + - query: UPDATE REFERRAL SET tenantId = ?, projectBeneficiaryId = ?, projectBeneficiaryClientReferenceId = ?, referredById = ?, referredToId = ?, referredToType = ?, reasons = ?, sideEffectId = ?, createdBy = ?, createdTime = ?, lastModifiedBy = ?, lastModifiedTime = ?, clientCreatedBy = ?, clientCreatedTime = ?, clientLastModifiedBy = ?, clientLastModifiedTime = ?, rowVersion = ?, isDeleted WHERE ID = ?; + basePath: $.* + jsonMaps: + - jsonPath: $.*.tenantId + - jsonPath: $.*.projectBeneficiaryId + - jsonPath: $.*.projectBeneficiaryClientReferenceId + - jsonPath: $.*.referredById + - jsonPath: $.*.referredToId + - jsonPath: $.*.referredToType + - jsonPath: $.*.reasons + type: JSON + dbType: JSONB + - jsonPath: $.*.sideEffect.id + - jsonPath: $.*.auditDetails.lastModifiedBy + - jsonPath: $.*.auditDetails.lastModifiedTime + - jsonPath: $.*.clientAuditDetails.lastModifiedBy + - jsonPath: $.*.clientAuditDetails.lastModifiedTime + - jsonPath: $.*.rowVersion + - jsonPath: $.*.isDeleted + - jsonPath: $.*.id + + - version: 1.0 + description: Deletes a referral + fromTopic: delete-referral-topic + isTransaction: true + queryMaps: + - query: UPDATE REFERRAL SET lastModifiedBy = ?, lastModifiedTime = ?, clientLastModifiedBy = ?, clientLastModifiedTime = ?, rowVersion = ?, isDeleted = ? WHERE ID = ?; + basePath: $.* + jsonMaps: + - jsonPath: $.*.auditDetails.lastModifiedBy + - jsonPath: $.*.auditDetails.lastModifiedTime + - jsonPath: $.*.clientAuditDetails.lastModifiedBy + - jsonPath: $.*.clientAuditDetails.lastModifiedTime + - jsonPath: $.*.rowVersion + - jsonPath: $.*.isDeleted + - jsonPath: $.*.id + + diff --git a/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/AppTest.java b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/AppTest.java new file mode 100644 index 00000000000..48b5fb750f6 --- /dev/null +++ b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/AppTest.java @@ -0,0 +1,20 @@ +package org.egov.referralmanagement; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +} diff --git a/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/TestConfiguration.java b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/TestConfiguration.java new file mode 100644 index 00000000000..c27d6693d1c --- /dev/null +++ b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/TestConfiguration.java @@ -0,0 +1,16 @@ +package org.egov.referralmanagement; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.KafkaTemplate; + +import static org.mockito.Mockito.mock; + +@Configuration +public class TestConfiguration { + @Bean + @SuppressWarnings("unchecked") + public KafkaTemplate kafkaTemplate() { + return mock(KafkaTemplate.class); + } +} \ No newline at end of file diff --git a/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/helper/SideEffectRequestTestBuilder.java b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/helper/SideEffectRequestTestBuilder.java new file mode 100644 index 00000000000..d5bf7a9195c --- /dev/null +++ b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/helper/SideEffectRequestTestBuilder.java @@ -0,0 +1,60 @@ +package org.egov.referralmanagement.helper; + +import org.egov.common.helper.RequestInfoTestBuilder; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectRequest; + +import java.util.ArrayList; + +public class SideEffectRequestTestBuilder { + private SideEffectRequest.SideEffectRequestBuilder builder; + + private ArrayList sideEffect = new ArrayList(); + + public SideEffectRequestTestBuilder() { + this.builder = SideEffectRequest.builder(); + } + + public static SideEffectRequestTestBuilder builder() { + return new SideEffectRequestTestBuilder(); + } + + public SideEffectRequest build() { + return this.builder.build(); + } + + public SideEffectRequestTestBuilder withOneSideEffect() { + builder.requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()) + .sideEffect(SideEffectTestBuilder.builder().withId().withAuditDetails().build()); + return this; + } + + public SideEffectRequestTestBuilder withApiOperationNotNullAndNotCreate() { + builder.requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()) + .sideEffect(SideEffectTestBuilder.builder().withIdNull().build()); + return this; + } + + public SideEffectRequestTestBuilder withApiOperationNotUpdate() { + builder.requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()) + .sideEffect(SideEffectTestBuilder.builder().withIdNull().build()); + return this; + } + + public SideEffectRequestTestBuilder withOneSideEffectHavingId() { + builder.requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()) + .sideEffect(SideEffectTestBuilder.builder().withId().withAuditDetails().build()); + return this; + } + + public SideEffectRequestTestBuilder withBadTenantIdInOneSideEffect() { + + builder.requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()) + .sideEffect(SideEffectTestBuilder.builder().withIdNull().withBadTenantId().build()); + return this; + } + + public SideEffectRequestTestBuilder withRequestInfo(){ + this.builder.requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()); + return this; + } +} diff --git a/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/helper/SideEffectTestBuilder.java b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/helper/SideEffectTestBuilder.java new file mode 100644 index 00000000000..d4c3c04c686 --- /dev/null +++ b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/helper/SideEffectTestBuilder.java @@ -0,0 +1,76 @@ +package org.egov.referralmanagement.helper; + +import org.egov.common.helper.AuditDetailsTestBuilder; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; + +import java.util.ArrayList; +import java.util.Arrays; + +public class SideEffectTestBuilder { + + private SideEffect.SideEffectBuilder builder; + + public SideEffectTestBuilder() { + this.builder = SideEffect.builder(); + } + + public static SideEffectTestBuilder builder() { + return new SideEffectTestBuilder(); + } + + public SideEffect build() { + return this.builder.hasErrors(false).build(); + } + + public SideEffectTestBuilder withIdNull() { + this.builder.taskId("some-task-id") + .clientReferenceId("sideEffectClientReferenceId") + .id(null) + .taskClientReferenceId("null") + .symptoms(new ArrayList<>(Arrays.asList("fever"))) + .tenantId("some-tenant-id") + .rowVersion(1); + return this; + } + + public SideEffectTestBuilder withId() { + withIdNull().builder.id("some-id").taskId("some-task-id") + .clientReferenceId("sideEffectClientReferenceId") + .taskClientReferenceId("null") + .symptoms(new ArrayList<>(Arrays.asList("fever"))) + .tenantId("some-tenant-id"); + return this; + } + + public SideEffectTestBuilder withId(String id) { + this.builder.id(id); + return this; + } + + public SideEffectTestBuilder withBadTenantId() { + this.builder.tenantId(null); + return this; + } + + public SideEffectTestBuilder goodSideEffect() { + this.builder.id("some-id").taskId("some-task-id") + .clientReferenceId("sideEffectClientReferenceId") + .taskClientReferenceId("null") + .symptoms(new ArrayList<>(Arrays.asList("fever"))) + .tenantId("some-tenant-id") + .rowVersion(1) + .auditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build()) + .clientAuditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build()); + return this; + } + + public SideEffectTestBuilder withAuditDetails() { + this.builder.auditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build()); + return this; + } + + public SideEffectTestBuilder withDeleted() { + this.builder.isDeleted(true); + return this; + } +} diff --git a/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/web/controllers/SideEffectApiControllerTest.java b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/web/controllers/SideEffectApiControllerTest.java new file mode 100644 index 00000000000..d163458fd62 --- /dev/null +++ b/health-services/referralmanagement/src/test/java/org/egov/referralmanagement/web/controllers/SideEffectApiControllerTest.java @@ -0,0 +1,208 @@ +package org.egov.referralmanagement.web.controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.egov.common.helper.RequestInfoTestBuilder; +import org.egov.common.models.referralmanagement.sideeffect.SideEffect; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkResponse; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectRequest; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectResponse; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearch; +import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearchRequest; +import org.egov.common.producer.Producer; +import org.egov.referralmanagement.TestConfiguration; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.referralmanagement.helper.SideEffectRequestTestBuilder; +import org.egov.referralmanagement.helper.SideEffectTestBuilder; +import org.egov.referralmanagement.service.SideEffectService; +import org.egov.tracer.model.CustomException; +import org.egov.tracer.model.ErrorRes; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@WebMvcTest(SideEffectApiController.class) +@Import(TestConfiguration.class) +public class SideEffectApiControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + private SideEffectService sideEffectService; + + @MockBean + private Producer producer; + + @MockBean + ReferralManagementConfiguration referralManagementConfiguration; + + @Test + @DisplayName("should create side effect and return with 202 accepted") + void shouldCreateSideEffectAndReturnWith202Accepted() throws Exception { + SideEffectRequest request = SideEffectRequestTestBuilder.builder() + .withOneSideEffect() + .withApiOperationNotUpdate() + .build(); + List sideEffects = getSideEffects(); + Mockito.when(sideEffectService.create(ArgumentMatchers.any(SideEffectRequest.class))).thenReturn(sideEffects.get(0)); + + final MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/side-effect/v1/_create") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(MockMvcResultMatchers.status().isAccepted()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andReturn(); + String responseStr = result.getResponse().getContentAsString(); + SideEffectResponse response = objectMapper.readValue(responseStr, SideEffectResponse.class); + + Assertions.assertNotNull(response.getSideEffect()); + Assertions.assertNotNull(response.getSideEffect().getId()); + Assertions.assertEquals("successful", response.getResponseInfo().getStatus()); + } + + private List getSideEffects() { + SideEffect sideEffect = SideEffectTestBuilder.builder().withId().build(); + List sideEffects = new ArrayList<>(); + sideEffects.add(sideEffect); + return sideEffects; + } + + + @Test + @DisplayName("should send error response with error details with 400 bad request for create") + void shouldSendErrorResWithErrorDetailsWith400BadRequestForCreate() throws Exception { + final MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/side-effect/v1/_create") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(SideEffectRequestTestBuilder.builder() + .withOneSideEffect() + .withBadTenantIdInOneSideEffect() + .build()))) + .andExpect(MockMvcResultMatchers.status().isBadRequest()) + .andReturn(); + String responseStr = result.getResponse().getContentAsString(); + ErrorRes response = objectMapper.readValue(responseStr, ErrorRes.class); + + Assertions.assertEquals(1, response.getErrors().size()); + Assertions.assertTrue(response.getErrors().get(0).getCode().contains("tenantId")); + } + + @Test + @DisplayName("should update side effect and return with 202 accepted") + void shouldUpdateSideEffectAndReturnWith202Accepted() throws Exception { + SideEffectRequest request = SideEffectRequestTestBuilder.builder() + .withOneSideEffectHavingId() + .withApiOperationNotNullAndNotCreate() + .build(); + SideEffect sideEffect = SideEffectTestBuilder.builder().withId().build(); + Mockito.when(sideEffectService.update(ArgumentMatchers.any(SideEffectRequest.class))).thenReturn(sideEffect); + + final MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/side-effect/v1/_update") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(MockMvcResultMatchers.status().isAccepted()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andReturn(); + String responseStr = result.getResponse().getContentAsString(); + SideEffectResponse response = objectMapper.readValue(responseStr, SideEffectResponse.class); + + Assertions.assertNotNull(response.getSideEffect()); + Assertions.assertNotNull(response.getSideEffect().getId()); + Assertions.assertEquals("successful", response.getResponseInfo().getStatus()); + } + + @Test + @DisplayName("should send error response with error details with 400 bad request for update") + void shouldSendErrorResWithErrorDetailsWith400BadRequestForUpdate() throws Exception { + final MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/side-effect/v1/_update") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(SideEffectRequestTestBuilder.builder() + .withOneSideEffectHavingId() + .withBadTenantIdInOneSideEffect() + .build()))) + .andExpect(MockMvcResultMatchers.status().isBadRequest()) + .andReturn(); + String responseStr = result.getResponse().getContentAsString(); + ErrorRes response = objectMapper.readValue(responseStr, + ErrorRes.class); + + Assertions.assertEquals(1, response.getErrors().size()); + Assertions.assertTrue(response.getErrors().get(0).getCode().contains("tenantId")); + } + + @Test + @DisplayName("Should accept search request and return response as accepted") + void shouldAcceptSearchRequestAndReturnSideEffect() throws Exception { + + SideEffectSearchRequest sideEffectSearchRequest = SideEffectSearchRequest.builder().sideEffect( + SideEffectSearch.builder().taskId("some-task-id").build() + ).requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()).build(); + + Mockito.when(sideEffectService.search(ArgumentMatchers.any(SideEffectSearchRequest.class), + ArgumentMatchers.any(Integer.class), + ArgumentMatchers.any(Integer.class), + ArgumentMatchers.any(String.class), + ArgumentMatchers.any(Long.class), + ArgumentMatchers.any(Boolean.class))).thenReturn(Arrays.asList(SideEffectTestBuilder.builder().withId().withAuditDetails().build())); + + final MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post( + "/side-effect/v1/_search?limit=10&offset=100&tenantId=default&lastChangedSince=1234322&includeDeleted=false") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(sideEffectSearchRequest))) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andReturn(); + String responseStr = result.getResponse().getContentAsString(); + SideEffectBulkResponse response = objectMapper.readValue(responseStr, + SideEffectBulkResponse.class); + + Assertions.assertEquals(response.getSideEffects().size(), 1); + } + + @Test + @DisplayName("Should accept search request and return response as accepted") + void shouldThrowExceptionIfNoResultFound() throws Exception { + + SideEffectSearchRequest sideEffectSearchRequest = SideEffectSearchRequest.builder().sideEffect( + SideEffectSearch.builder().taskId("some-task-id").build() + ).requestInfo(RequestInfoTestBuilder.builder().withCompleteRequestInfo().build()).build(); + + Mockito.when(sideEffectService.search(ArgumentMatchers.any(SideEffectSearchRequest.class), + ArgumentMatchers.any(Integer.class), + ArgumentMatchers.any(Integer.class), + ArgumentMatchers.any(String.class), + ArgumentMatchers.any(Long.class), + ArgumentMatchers.any(Boolean.class))).thenThrow(new CustomException("NO_RESULT_FOUND", "No Side Effect found.")); + + + final MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/side-effect/v1/_search?limit=10&offset=100&tenantId=default&lastChangedSince=1234322&includeDeleted=false") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(sideEffectSearchRequest))) + .andExpect(MockMvcResultMatchers.status().isBadRequest()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andReturn(); + String responseStr = result.getResponse().getContentAsString(); + ErrorRes response = objectMapper.readValue(responseStr, + ErrorRes.class); + + Assertions.assertEquals(response.getErrors().size(), 1); + } + +} diff --git a/health-services/stock/pom.xml b/health-services/stock/pom.xml index edaaf44102e..81e99bf2071 100644 --- a/health-services/stock/pom.xml +++ b/health-services/stock/pom.xml @@ -49,7 +49,7 @@ org.egov.common health-services-models - 1.0.7-SNAPSHOT + 1.0.9-SNAPSHOT diff --git a/health-services/stock/src/main/java/org/egov/stock/Constants.java b/health-services/stock/src/main/java/org/egov/stock/Constants.java index 9895af2597d..cb7589dc33f 100644 --- a/health-services/stock/src/main/java/org/egov/stock/Constants.java +++ b/health-services/stock/src/main/java/org/egov/stock/Constants.java @@ -17,12 +17,16 @@ public class Constants { public static String VALIDATION_ERROR = "VALIDATION_ERROR"; public static String GET_FACILITY_ID = "getFacilityId"; + + public static String GET_SENDER_ID = "getSenderId"; public static String GET_REFERENCE_ID = "getReferenceId"; public static String GET_TRANSACTING_PARTY_ID = "getTransactingPartyId"; public static String WAREHOUSE = "WAREHOUSE"; + + public static String STAFF = "STAFF"; public static String PROJECT = "PROJECT"; diff --git a/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java b/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java index 94b430ae45b..89471581084 100644 --- a/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java +++ b/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java @@ -37,7 +37,6 @@ public Stock mapRow(ResultSet resultSet, int i) throws SQLException { .id(resultSet.getString("id")) .clientReferenceId(resultSet.getString("clientReferenceId")) .tenantId(resultSet.getString("tenantId")) - .facilityId(resultSet.getString("facilityId")) .productVariantId(resultSet.getString("productVariantId")) .quantity(resultSet.getInt("quantity")) .wayBillNumber(resultSet.getString("wayBillNumber")) @@ -45,8 +44,10 @@ public Stock mapRow(ResultSet resultSet, int i) throws SQLException { .referenceIdType(resultSet.getString("referenceIdType")) .transactionType(TransactionType.fromValue(resultSet.getString("transactionType"))) .transactionReason(TransactionReason.fromValue(resultSet.getString("transactionReason"))) - .transactingPartyId(resultSet.getString("transactingPartyId")) - .transactingPartyType(resultSet.getString("transactingPartyType")) + .senderId(resultSet.getString("senderId")) + .senderType(resultSet.getString("senderType")) + .receiverId(resultSet.getString("receiverId")) + .receiverType(resultSet.getString("receiverType")) .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper .readValue(resultSet.getString("additionalDetails"), AdditionalFields.class)) .auditDetails(auditDetails) diff --git a/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java b/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java index 3a54d0ec400..068a26a99fb 100644 --- a/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java +++ b/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java @@ -1,6 +1,20 @@ package org.egov.stock.service; -import lombok.extern.slf4j.Slf4j; +import static org.egov.common.utils.CommonUtils.getIdList; +import static org.egov.common.utils.CommonUtils.getMethod; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForEntityWithNetworkError; +import static org.egov.stock.Constants.GET_FACILITY_ID; +import static org.egov.stock.Constants.GET_REFERENCE_ID; +import static org.egov.stock.Constants.WAREHOUSE; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import org.egov.common.contract.request.RequestInfo; import org.egov.common.http.client.ServiceRequestClient; import org.egov.common.models.Error; @@ -11,21 +25,13 @@ import org.egov.common.models.project.ProjectFacilityBulkResponse; import org.egov.common.models.project.ProjectFacilitySearch; import org.egov.common.models.project.ProjectFacilitySearchRequest; +import org.egov.common.models.stock.Stock; +import org.egov.common.models.stock.StockReconciliation; import org.egov.stock.config.StockConfiguration; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static org.egov.common.utils.CommonUtils.getIdList; -import static org.egov.common.utils.CommonUtils.getMethod; -import static org.egov.common.utils.CommonUtils.populateErrorDetails; -import static org.egov.common.utils.ValidatorUtils.getErrorForEntityWithNetworkError; -import static org.egov.stock.Constants.GET_FACILITY_ID; -import static org.egov.stock.Constants.GET_REFERENCE_ID; -import static org.egov.stock.Constants.PIPE; +import lombok.extern.slf4j.Slf4j; @Service @Slf4j @@ -40,12 +46,15 @@ public FacilityService(StockConfiguration stockConfiguration, ServiceRequestClie this.serviceRequestClient = serviceRequestClient; } - public List validateFacilityIds(List entityIds, + public List validateFacilityIds(List entityIds, List entities, String tenantId, Map> errorDetailsMap, RequestInfo requestInfo) { + if (CollectionUtils.isEmpty(entityIds)) + return Collections.emptyList(); + FacilitySearchRequest facilitySearchRequest = FacilitySearchRequest.builder() .facility(FacilitySearch.builder().id(entityIds).build()) .requestInfo(requestInfo) @@ -62,20 +71,41 @@ public List validateFacilityIds(List entityIds, return response.getFacilities().stream().map(Facility::getId).collect(Collectors.toList()); } catch (Exception e) { log.error("error while fetching facility list", e); - entities.forEach(b -> { + entities.forEach( stockEntity -> { Error error = getErrorForEntityWithNetworkError(); - populateErrorDetails(b, error, errorDetailsMap); + populateErrorDetails(stockEntity, error, errorDetailsMap); }); return Collections.emptyList(); } } - public List validateProjectFacilityMappings(List entities, + public Map> validateProjectFacilityMappings(List entities, String tenantId, Map> errorDetailsMap, RequestInfo requestInfo) { + + List projectIds = getIdList(entities, getMethod(GET_REFERENCE_ID, entities.get(0).getClass())); - List facilityIds = getIdList(entities, getMethod(GET_FACILITY_ID, entities.get(0).getClass())); + List facilityIds = null; + + if (entities.get(0) instanceof StockReconciliation) { + facilityIds = getIdList(entities, getMethod(GET_FACILITY_ID, entities.get(0).getClass())); + } else if (entities.get(0) instanceof Stock) { + + facilityIds = new ArrayList<>(); + for (T entity : entities) { + + Stock stock = (Stock) entity; + + if (stock.getSenderType().equalsIgnoreCase(WAREHOUSE)) { + facilityIds.add(stock.getSenderId()); + } + if (stock.getReceiverType().equalsIgnoreCase(WAREHOUSE)) { + facilityIds.add(stock.getReceiverId()); + } + } + } + Integer searchLimit = projectIds.size() * facilityIds.size(); ProjectFacilitySearchRequest projectFacilitySearchRequest = ProjectFacilitySearchRequest.builder() @@ -91,16 +121,18 @@ public List validateProjectFacilityMappings(List entities, + "&offset=0&tenantId=" + tenantId), projectFacilitySearchRequest, ProjectFacilityBulkResponse.class); - return response.getProjectFacilities().stream() - .map(projectFacility -> projectFacility.getFacilityId() + PIPE + projectFacility.getProjectId()) - .collect(Collectors.toList()); + + return response.getProjectFacilities().stream() + .collect(Collectors.groupingBy(projectFacility -> projectFacility.getProjectId(), + Collectors.mapping(projectFacility -> projectFacility.getFacilityId(), Collectors.toList()))); + } catch (Exception e) { log.error("error while fetching project facility list", e); entities.forEach(b -> { Error error = getErrorForEntityWithNetworkError(); populateErrorDetails(b, error, errorDetailsMap); }); - return Collections.emptyList(); + return Collections.emptyMap(); } } } diff --git a/health-services/stock/src/main/java/org/egov/stock/service/StockService.java b/health-services/stock/src/main/java/org/egov/stock/service/StockService.java index 8b5c232c09c..8bbbd72c065 100644 --- a/health-services/stock/src/main/java/org/egov/stock/service/StockService.java +++ b/health-services/stock/src/main/java/org/egov/stock/service/StockService.java @@ -1,6 +1,24 @@ package org.egov.stock.service; -import lombok.extern.slf4j.Slf4j; +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdMethod; +import static org.egov.common.utils.CommonUtils.handleErrors; +import static org.egov.common.utils.CommonUtils.havingTenantId; +import static org.egov.common.utils.CommonUtils.includeDeleted; +import static org.egov.common.utils.CommonUtils.isSearchByIdOnly; +import static org.egov.common.utils.CommonUtils.lastChangedSince; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.CommonUtils.validate; +import static org.egov.stock.Constants.GET_STOCK; +import static org.egov.stock.Constants.SET_STOCK; +import static org.egov.stock.Constants.VALIDATION_ERROR; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; import org.egov.common.models.stock.Stock; @@ -10,37 +28,19 @@ import org.egov.stock.config.StockConfiguration; import org.egov.stock.repository.StockRepository; import org.egov.stock.service.enrichment.StockEnrichmentService; -import org.egov.stock.validator.stock.SFacilityIdValidator; import org.egov.stock.validator.stock.SIsDeletedValidator; import org.egov.stock.validator.stock.SNonExistentValidator; import org.egov.stock.validator.stock.SNullIdValidator; import org.egov.stock.validator.stock.SProductVariantIdValidator; import org.egov.stock.validator.stock.SReferenceIdValidator; import org.egov.stock.validator.stock.SRowVersionValidator; -import org.egov.stock.validator.stock.STransactingPartyIdValidator; import org.egov.stock.validator.stock.SUniqueEntityValidator; +import org.egov.stock.validator.stock.StocktransferPartiesValidator; import org.egov.stock.web.models.StockSearchRequest; import org.springframework.stereotype.Service; import org.springframework.util.ReflectionUtils; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import static org.egov.common.utils.CommonUtils.getIdFieldName; -import static org.egov.common.utils.CommonUtils.getIdMethod; -import static org.egov.common.utils.CommonUtils.handleErrors; -import static org.egov.common.utils.CommonUtils.havingTenantId; -import static org.egov.common.utils.CommonUtils.includeDeleted; -import static org.egov.common.utils.CommonUtils.isSearchByIdOnly; -import static org.egov.common.utils.CommonUtils.lastChangedSince; -import static org.egov.common.utils.CommonUtils.populateErrorDetails; -import static org.egov.common.utils.CommonUtils.validate; -import static org.egov.stock.Constants.GET_STOCK; -import static org.egov.stock.Constants.SET_STOCK; -import static org.egov.stock.Constants.VALIDATION_ERROR; +import lombok.extern.slf4j.Slf4j; @Service @@ -57,9 +57,8 @@ public class StockService { private final Predicate> isApplicableForCreate = validator -> validator.getClass().equals(SProductVariantIdValidator.class) - || validator.getClass().equals(SFacilityIdValidator.class) - || validator.getClass().equals(SReferenceIdValidator.class) - || validator.getClass().equals(STransactingPartyIdValidator.class); + || validator.getClass().equals(StocktransferPartiesValidator.class) + || validator.getClass().equals(SReferenceIdValidator.class); private final Predicate> isApplicableForUpdate = validator -> validator.getClass().equals(SProductVariantIdValidator.class) @@ -68,9 +67,8 @@ public class StockService { || validator.getClass().equals(SNullIdValidator.class) || validator.getClass().equals(SRowVersionValidator.class) || validator.getClass().equals(SUniqueEntityValidator.class) - || validator.getClass().equals(SFacilityIdValidator.class) || validator.getClass().equals(SReferenceIdValidator.class) - || validator.getClass().equals(STransactingPartyIdValidator.class); + || validator.getClass().equals(StocktransferPartiesValidator.class); private final Predicate> isApplicableForDelete = validator -> validator.getClass().equals(SNonExistentValidator.class) diff --git a/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java b/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java index 92c1297cf7c..b39ad93699d 100644 --- a/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java +++ b/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java @@ -1,17 +1,5 @@ package org.egov.stock.util; -import org.egov.common.contract.request.RequestInfo; -import org.egov.common.models.Error; -import org.egov.stock.service.FacilityService; -import org.egov.tracer.model.CustomException; -import org.springframework.util.ReflectionUtils; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import static org.egov.common.utils.CommonUtils.getIdToObjMap; import static org.egov.common.utils.CommonUtils.getMethod; import static org.egov.common.utils.CommonUtils.getObjClass; @@ -19,84 +7,327 @@ import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentRelatedEntity; -import static org.egov.stock.Constants.GET_FACILITY_ID; import static org.egov.stock.Constants.GET_REQUEST_INFO; import static org.egov.stock.Constants.NO_PROJECT_FACILITY_MAPPING_EXISTS; -import static org.egov.stock.Constants.PIPE; +import static org.egov.stock.Constants.STAFF; +import static org.egov.stock.Constants.WAREHOUSE; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.ds.Tuple; +import org.egov.common.models.Error; +import org.egov.common.models.stock.Stock; +import org.egov.common.models.stock.StockReconciliation; +import org.egov.common.service.UserService; +import org.egov.stock.service.FacilityService; +import org.egov.tracer.model.CustomException; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ReflectionUtils; + +import digit.models.coremodels.UserSearchRequest; public class ValidatorUtil { - public static Map> validateFacilityIds(R request, - Map> errorDetailsMap, - List validEntities, - String getId, - FacilityService facilityService) { - if (!validEntities.isEmpty()) { - String tenantId = getTenantId(validEntities); - Class objClass = getObjClass(validEntities); - Method idMethod = getMethod(getId, objClass); - Map eMap = getIdToObjMap(validEntities, idMethod); - RequestInfo requestInfo = (RequestInfo) ReflectionUtils.invokeMethod(getMethod(GET_REQUEST_INFO, - request.getClass()), request); - - if (!eMap.isEmpty()) { - List entityIds = new ArrayList<>(eMap.keySet()); - List existingFacilityIds = facilityService.validateFacilityIds(entityIds, - validEntities, - tenantId, errorDetailsMap, requestInfo); - List invalidEntities = validEntities.stream() - .filter(notHavingErrors()).filter(entity -> - !existingFacilityIds.contains((String) ReflectionUtils.invokeMethod(idMethod, entity))) - .collect(Collectors.toList()); - invalidEntities.forEach(entity -> { - Error error = getErrorForNonExistentRelatedEntity((String) ReflectionUtils.invokeMethod(idMethod, - entity)); - populateErrorDetails(entity, error, errorDetailsMap); - }); - } - } - - return errorDetailsMap; - } - - public static Map> validateProjectFacilityMappings(R request, - Map> errorDetailsMap, - List validEntities, - String getId, - FacilityService facilityService) { - if (!validEntities.isEmpty()) { - String tenantId = getTenantId(validEntities); - Class objClass = getObjClass(validEntities); - Method idMethod = getMethod(getId, objClass); - RequestInfo requestInfo = (RequestInfo) ReflectionUtils.invokeMethod(getMethod(GET_REQUEST_INFO, - request.getClass()), request); - - List existingProjectFacilityMappingIds = facilityService - .validateProjectFacilityMappings(validEntities, tenantId, - errorDetailsMap, requestInfo); - List invalidEntities = validEntities.stream() - .filter(notHavingErrors()).filter(entity -> - { - String comboId = (String) ReflectionUtils.invokeMethod(getMethod(GET_FACILITY_ID, objClass), - entity) - + PIPE + (String) ReflectionUtils.invokeMethod(idMethod, entity); - return !existingProjectFacilityMappingIds.contains(comboId); - }) - .collect(Collectors.toList()); - invalidEntities.forEach(entity -> { - String errorMessage = String.format("No mapping exists for project id: %s & facility id: %s", - (String) ReflectionUtils.invokeMethod(idMethod, entity), - (String) ReflectionUtils.invokeMethod(getMethod(GET_FACILITY_ID, objClass), - entity)); - Error error = Error.builder() - .errorMessage(errorMessage) - .errorCode(NO_PROJECT_FACILITY_MAPPING_EXISTS) - .type(Error.ErrorType.NON_RECOVERABLE) - .exception(new CustomException(NO_PROJECT_FACILITY_MAPPING_EXISTS, errorMessage)).build(); - populateErrorDetails(entity, error, errorDetailsMap); - }); - } - - return errorDetailsMap; - } + public static Map> validateFacilityIds(R request, Map> errorDetailsMap, + List validEntities, String getId, FacilityService facilityService) { + + if (!validEntities.isEmpty()) { + String tenantId = getTenantId(validEntities); + Class objClass = getObjClass(validEntities); + Method idMethod = getMethod(getId, objClass); + Map eMap = getIdToObjMap(validEntities, idMethod); + RequestInfo requestInfo = (RequestInfo) ReflectionUtils + .invokeMethod(getMethod(GET_REQUEST_INFO, request.getClass()), request); + + if (!eMap.isEmpty()) { + List entityIds = new ArrayList<>(eMap.keySet()); + List existingFacilityIds = facilityService.validateFacilityIds(entityIds, validEntities, + tenantId, errorDetailsMap, requestInfo); + List invalidEntities = validEntities.stream().filter(notHavingErrors()) + .filter(entity -> !existingFacilityIds + .contains((String) ReflectionUtils.invokeMethod(idMethod, entity))) + .collect(Collectors.toList()); + invalidEntities.forEach(entity -> { + Error error = getErrorForNonExistentRelatedEntity( + (String) ReflectionUtils.invokeMethod(idMethod, entity)); + populateErrorDetails(entity, error, errorDetailsMap); + }); + } + } + + return errorDetailsMap; + } + + /** + * + * Non generic method used for validating sender/receiver (parties) against + * facility or staff based on the type + * + * @param + * @param + * @param stockRequest + * @param errorDetailsMap + * @param validEntities + * @param getId + * @param facilityService + * @return + */ + public static Map> validateStockTransferParties(RequestInfo requestInfo, + Map> errorDetailsMap, List validStockEntities, FacilityService facilityService, + UserService userService) { + + if (!validStockEntities.isEmpty()) { + + Tuple, List> tupleOfInvalidStaffIdsAndFacilityIds = validateAndEnrichInvalidPartyIds( + requestInfo, errorDetailsMap, validStockEntities, facilityService, userService); + + enrichErrorMapFromInvalidPartyIds(errorDetailsMap, validStockEntities, + tupleOfInvalidStaffIdsAndFacilityIds.getX(), tupleOfInvalidStaffIdsAndFacilityIds.getY()); + + } + return errorDetailsMap; + } + + /** + * validates the list of party-ids (facility and staff) against the respective + * APIs and enriches the invalid ids list for both parties + * + * @param + * @param stockRequest + * @param errorDetailsMap + * @param validStockEntities + * @param facilityService + * @param facilityIds + * @param InvalidStaffId + * @param invalidFacilityIds + */ + @SuppressWarnings("unchecked") + private static Tuple, List> validateAndEnrichInvalidPartyIds(RequestInfo requestInfo, + Map> errorDetailsMap, List validStockEntities, FacilityService facilityService, + UserService userService) { + + List facilityIds = new ArrayList<>(); + List staffIds = new ArrayList<>(); + + enrichFaciltyAndStaffIdsFromStock(validStockEntities, facilityIds, staffIds); + + // copy all of party identifiers into invalid list + List invalidStaffIds = new ArrayList<>(staffIds); + List invalidFacilityIds = new ArrayList<>(facilityIds); + + String tenantId = getTenantId(validStockEntities); + + // validate and remove valid identifiers from invalidStaffIds + validateAndEnrichStaffIds(requestInfo, userService, staffIds, invalidStaffIds); + + // validate and remove valid identifiers from invalidfacilityIds + List validFacilityIds = facilityService.validateFacilityIds(facilityIds, (List) validStockEntities, + tenantId, errorDetailsMap, requestInfo); + invalidFacilityIds.removeAll(validFacilityIds); + + return new Tuple<>(invalidStaffIds, invalidFacilityIds); + } + + private static void validateAndEnrichStaffIds(RequestInfo requestInfo, UserService userService, + List staffIds, List invalidStaffIds) { + if (!CollectionUtils.isEmpty(staffIds)) { + + UserSearchRequest userSearchRequest = new UserSearchRequest(); + userSearchRequest.setRequestInfo(requestInfo); + userSearchRequest.setUuid(staffIds); + List validStaffIds = userService.search(userSearchRequest).stream().map(user -> user.getUuid()) + .collect(Collectors.toList()); + invalidStaffIds.removeAll(validStaffIds); + } + } + + /** + * Private method to enrich facility id and staff id + * + * @param validStockEntities + * @param facilityIds + * @param staffIds + */ + private static void enrichFaciltyAndStaffIdsFromStock(List validStockEntities, List facilityIds, + List staffIds) { + + for (Stock stock : validStockEntities) { + + if (stock.getSenderType().equalsIgnoreCase(WAREHOUSE)) { + facilityIds.add(stock.getSenderId()); + } + if (stock.getSenderType().equalsIgnoreCase(STAFF)) { + staffIds.add(stock.getSenderId()); + } + if (stock.getReceiverType().equalsIgnoreCase(WAREHOUSE)) { + facilityIds.add(stock.getReceiverId()); + } + if (stock.getReceiverType().equalsIgnoreCase(STAFF)) { + staffIds.add(stock.getReceiverId()); + } + } + } + + /** + * + * creates the error map from the stock objects with invalid party ids + * + * @param errorDetailsMap + * @param validStockEntities + * @param InvalidStaffId + * @param invalidFacilityIds + */ + @SuppressWarnings("unchecked") + private static void enrichErrorMapFromInvalidPartyIds(Map> errorDetailsMap, + List validStockEntities, List invalidStaffIds, List invalidFacilityIds) { + + Class objClass = getObjClass(validStockEntities); + Method senderIdMethod = getMethod("getSenderId", objClass); + Method recieverIdMethod = getMethod("getReceiverId", objClass); + + for (Stock stock : validStockEntities) { + + String senderId = stock.getSenderId(); + String recieverId = stock.getReceiverId(); + + if ((stock.getSenderType().equalsIgnoreCase(WAREHOUSE) && invalidFacilityIds.contains(senderId)) + + || (stock.getSenderType().equalsIgnoreCase(STAFF) && invalidStaffIds.contains(senderId))) { + + getIdForErrorFromMethod(errorDetailsMap, (T) stock, senderIdMethod); + } + + if ((stock.getReceiverType().equalsIgnoreCase(WAREHOUSE) && invalidFacilityIds.contains(recieverId)) + + || (stock.getReceiverType().equalsIgnoreCase(STAFF) && invalidStaffIds.contains(recieverId))) { + + getIdForErrorFromMethod(errorDetailsMap, (T) stock, recieverIdMethod); + } + } + } + + /** + * method to populate error details map + * + * @param + * @param errorDetailsMap + * @param entity + * @param idMethod + */ + private static void getIdForErrorFromMethod(Map> errorDetailsMap, T entity, Method idMethod) { + + Error error = getErrorForNonExistentRelatedEntity((String) ReflectionUtils.invokeMethod(idMethod, entity)); + populateErrorDetails(entity, error, errorDetailsMap); + } + + /** + * + * @param + * @param + * @param request + * @param errorDetailsMap + * @param validEntities + * @param getId + * @param facilityService + * @return + */ + @SuppressWarnings("unchecked") + public static Map> validateProjectFacilityMappings(R request, + Map> errorDetailsMap, List validEntities, String getReferenceId, + FacilityService facilityService) { + + if (!validEntities.isEmpty()) { + + String tenantId = getTenantId(validEntities); + Class objClass = getObjClass(validEntities); + Method idMethod = getMethod(getReferenceId, objClass); + RequestInfo requestInfo = (RequestInfo) ReflectionUtils + .invokeMethod(getMethod(GET_REQUEST_INFO, request.getClass()), request); + + Map> ProjectFacilityMappingOfIds = facilityService + .validateProjectFacilityMappings((List) validEntities, tenantId, errorDetailsMap, requestInfo); + + List invalidStocks = new ArrayList<>(); + + if (validEntities.get(0) instanceof Stock) + enrichErrorForStock((List) validEntities, ProjectFacilityMappingOfIds, invalidStocks, + errorDetailsMap); + else if (validEntities.get(0) instanceof StockReconciliation) + enrichErrorForStockReconciliation((List) validEntities, + ProjectFacilityMappingOfIds, invalidStocks, errorDetailsMap); + + } + + return errorDetailsMap; + } + + @SuppressWarnings("unchecked") + private static void enrichErrorForStock(List validEntities, + Map> ProjectFacilityMappingOfIds, List invalidStocks, + Map> errorDetailsMap) { + + for (Stock stock : validEntities) { + + String senderId = stock.getSenderId(); + String receiverId = stock.getReceiverId(); + + List facilityIds = ProjectFacilityMappingOfIds.get(stock.getReferenceId()); + if (!CollectionUtils.isEmpty(facilityIds)) { + + if (stock.getSenderType().equalsIgnoreCase("WAREHOUSE") && !facilityIds.contains(senderId)) { + populateErrorForStock(stock, senderId, errorDetailsMap); + } + + if (stock.getReceiverType().equalsIgnoreCase("WAREHOUSE") && !facilityIds.contains(receiverId)) + populateErrorForStock(stock, receiverId, errorDetailsMap); + } else { + populateErrorForStock(stock, senderId + " and " + receiverId, errorDetailsMap); + } + } + } + + @SuppressWarnings("unchecked") + private static void populateErrorForStock(Stock stock, String facilityId, Map> errorDetailsMap) { + + String errorMessage = String.format("No mapping exists for project id: %s & facility id: %s", + stock.getReferenceId(), facilityId); + + Error error = Error.builder().errorMessage(errorMessage).errorCode(NO_PROJECT_FACILITY_MAPPING_EXISTS) + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException(NO_PROJECT_FACILITY_MAPPING_EXISTS, errorMessage)).build(); + populateErrorDetails((T) stock, error, errorDetailsMap); + } + + @SuppressWarnings("unchecked") + private static void enrichErrorForStockReconciliation(List validEntities, + Map> ProjectFacilityMappingOfIds, List invalidStocks, + Map> errorDetailsMap) { + + for (StockReconciliation stockReconciliation : validEntities) { + + List facilityIds = ProjectFacilityMappingOfIds.get(stockReconciliation.getReferenceId()); + if (CollectionUtils.isEmpty(facilityIds)) { + populateErrorForStockReconciliation(stockReconciliation, errorDetailsMap); + } else if (!facilityIds.contains(stockReconciliation.getFacilityId())) + populateErrorForStockReconciliation(stockReconciliation, errorDetailsMap); + } + } + + @SuppressWarnings("unchecked") + private static void populateErrorForStockReconciliation(StockReconciliation stockReconciliation, + Map> errorDetailsMap) { + + String errorMessage = String.format("No mapping exists for project id: %s & facility id: %s", + stockReconciliation.getReferenceId(), stockReconciliation.getFacilityId()); + + Error error = Error.builder().errorMessage(errorMessage).errorCode(NO_PROJECT_FACILITY_MAPPING_EXISTS) + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException(NO_PROJECT_FACILITY_MAPPING_EXISTS, errorMessage)).build(); + populateErrorDetails((T) stockReconciliation, error, errorDetailsMap); + } } diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SFacilityIdValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SFacilityIdValidator.java deleted file mode 100644 index 21fa18af4a2..00000000000 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SFacilityIdValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.egov.stock.validator.stock; - -import lombok.extern.slf4j.Slf4j; -import org.egov.common.models.Error; -import org.egov.common.models.stock.Stock; -import org.egov.common.models.stock.StockBulkRequest; -import org.egov.common.validator.Validator; -import org.egov.stock.service.FacilityService; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static org.egov.common.utils.CommonUtils.notHavingErrors; -import static org.egov.stock.Constants.GET_FACILITY_ID; -import static org.egov.stock.util.ValidatorUtil.validateFacilityIds; - -@Component -@Order(value = 7) -@Slf4j -public class SFacilityIdValidator implements Validator { - - private final FacilityService facilityService; - - public SFacilityIdValidator(FacilityService facilityService) { - this.facilityService = facilityService; - } - - @Override - public Map> validate(StockBulkRequest request) { - log.info("validating for facility id"); - Map> errorDetailsMap = new HashMap<>(); - - List validEntities = request.getStock().stream() - .filter(notHavingErrors()) - .collect(Collectors.toList()); - return validateFacilityIds(request, errorDetailsMap, validEntities, GET_FACILITY_ID, facilityService); - } -} diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java index 7b791a29031..47a17106727 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java @@ -39,6 +39,13 @@ public Map> validate(StockBulkRequest request) { .filter(notHavingErrors()) .filter(entity -> PROJECT.equals(entity.getReferenceIdType())) .collect(Collectors.toList()); + + long countOfWareHouseInStock = request.getStock().stream().filter(stock -> + stock.getReceiverType().equalsIgnoreCase("WAREHOUSE") || stock.getSenderType().equalsIgnoreCase("WAREHOUSE") + ).count(); + if(countOfWareHouseInStock == 0) + return errorDetailsMap; + return validateProjectFacilityMappings(request, errorDetailsMap, validEntities, GET_REFERENCE_ID, facilityService); } diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/STransactingPartyIdValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/STransactingPartyIdValidator.java deleted file mode 100644 index 5e7604e635f..00000000000 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/STransactingPartyIdValidator.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.egov.stock.validator.stock; - -import lombok.extern.slf4j.Slf4j; -import org.egov.common.models.Error; -import org.egov.common.models.stock.Stock; -import org.egov.common.models.stock.StockBulkRequest; -import org.egov.common.validator.Validator; -import org.egov.stock.service.FacilityService; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static org.egov.common.utils.CommonUtils.notHavingErrors; -import static org.egov.stock.Constants.GET_TRANSACTING_PARTY_ID; -import static org.egov.stock.Constants.WAREHOUSE; -import static org.egov.stock.util.ValidatorUtil.validateFacilityIds; - -@Component -@Order(value = 9) -@Slf4j -public class STransactingPartyIdValidator implements Validator { - - private final FacilityService facilityService; - - public STransactingPartyIdValidator(FacilityService facilityService) { - this.facilityService = facilityService; - } - - @Override - public Map> validate(StockBulkRequest request) { - log.info("validating for reference id"); - Map> errorDetailsMap = new HashMap<>(); - - List validFacilityTransactingPartyIdEntities = request.getStock().stream() - .filter(notHavingErrors()) - .filter(entity -> WAREHOUSE.equals(entity.getTransactingPartyType())) - .collect(Collectors.toList()); - return validateFacilityIds(request, errorDetailsMap, validFacilityTransactingPartyIdEntities, - GET_TRANSACTING_PARTY_ID, facilityService); - } -} diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/StocktransferPartiesValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/StocktransferPartiesValidator.java new file mode 100644 index 00000000000..10ee33cf1f1 --- /dev/null +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/StocktransferPartiesValidator.java @@ -0,0 +1,48 @@ +package org.egov.stock.validator.stock; + +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.stock.util.ValidatorUtil.validateStockTransferParties; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.egov.common.models.Error; +import org.egov.common.models.stock.Stock; +import org.egov.common.models.stock.StockBulkRequest; +import org.egov.common.service.UserService; +import org.egov.common.validator.Validator; +import org.egov.stock.service.FacilityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Component +@Order(value = 7) +@Slf4j +public class StocktransferPartiesValidator implements Validator { + + private final FacilityService facilityService; + + private UserService userService; + + @Autowired + public StocktransferPartiesValidator(FacilityService facilityService, UserService userService) { + this.facilityService = facilityService; + this.userService = userService; + } + + @Override + public Map> validate(StockBulkRequest request) { + log.info("validating for facility id"); + Map> errorDetailsMap = new HashMap<>(); + + List validEntities = request.getStock().stream().filter(notHavingErrors()).collect(Collectors.toList()); + + return validateStockTransferParties(request.getRequestInfo(), errorDetailsMap, validEntities, facilityService, + userService); + } +} diff --git a/health-services/stock/src/main/resources/application.properties b/health-services/stock/src/main/resources/application.properties index 007aa1f216a..5f192d7bdf8 100644 --- a/health-services/stock/src/main/resources/application.properties +++ b/health-services/stock/src/main/resources/application.properties @@ -59,12 +59,14 @@ stock.reconciliation.idgen.id.format=stock.reconciliation.id # The value of the following field should be changed to service specific name kafka.topics.consumer=stock-consumer-topic + # USER CONFIG +egov.user.integration.enabled=true egov.user.host=https://dev.digit.org egov.user.context.path=/user/users -egov.user.create.path=/_createnovalidate -egov.user.search.path=/user/_search -egov.user.update.path=/_updatenovalidate +egov.create.user.path=/_createnovalidate +egov.search.user.url=/user/_search +egov.update.user.url=/_updatenovalidate # MDMS CONFIG egov.mdms.host=https://dev.digit.org diff --git a/health-services/stock/src/main/resources/db/migration/main/V20231005182626__alter_stock_add_transaction_parties.sql b/health-services/stock/src/main/resources/db/migration/main/V20231005182626__alter_stock_add_transaction_parties.sql new file mode 100644 index 00000000000..e8794b86346 --- /dev/null +++ b/health-services/stock/src/main/resources/db/migration/main/V20231005182626__alter_stock_add_transaction_parties.sql @@ -0,0 +1,4 @@ +ALTER TABLE STOCK ADD COLUMN IF NOT EXISTS senderType character varying(128); +ALTER TABLE STOCK ADD COLUMN IF NOT EXISTS receiverType character varying(128); +ALTER TABLE STOCK ADD COLUMN IF NOT EXISTS senderid character varying(128); +ALTER TABLE STOCK ADD COLUMN IF NOT EXISTS receiverid character varying(128); diff --git a/health-services/stock/src/test/java/org/egov/stock/helper/StockReconciliationTestBuilder.java b/health-services/stock/src/test/java/org/egov/stock/helper/StockReconciliationTestBuilder.java index 616b726e29a..d7cfc4c247d 100644 --- a/health-services/stock/src/test/java/org/egov/stock/helper/StockReconciliationTestBuilder.java +++ b/health-services/stock/src/test/java/org/egov/stock/helper/StockReconciliationTestBuilder.java @@ -21,7 +21,7 @@ public StockReconciliation build() { } public StockReconciliationTestBuilder withStock() { - this.builder.facilityId("facility-id").productVariantId("pv-id").physicalCount(10) + this.builder.facilityId("sender-id").productVariantId("pv-id").physicalCount(10) .calculatedCount(100).referenceId("reference-id") .referenceIdType("PROJECT").rowVersion(1).tenantId("default").hasErrors(false).isDeleted(Boolean.FALSE) .auditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build()); diff --git a/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java b/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java index d755e8fd06d..90960baf5a3 100644 --- a/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java +++ b/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java @@ -23,11 +23,19 @@ public Stock build() { } public StockTestBuilder withStock() { - this.builder.facilityId("facility-id").productVariantId("pv-id").quantity(0).referenceId("reference-id") - .referenceIdType("PROJECT").rowVersion(1).tenantId("default").transactingPartyId("transaction-party-id") - .transactionType(TransactionType.DISPATCHED).transactionReason(TransactionReason.RECEIVED) - .transactingPartyType("WAREHOUSE").hasErrors(false).isDeleted(Boolean.FALSE) - .auditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build()); + this.builder + .senderId("sender-id") + .receiverId("receiver-id") + .productVariantId("pv-id").quantity(0) + .referenceId("reference-id") + .referenceIdType("PROJECT").rowVersion(1).tenantId("default") + .transactionType(TransactionType.DISPATCHED) + .transactionReason(TransactionReason.RECEIVED) + .senderType("WAREHOUSE") + .receiverType("STAFF") + .hasErrors(false) + .isDeleted(Boolean.FALSE) + .auditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build()); return this; } diff --git a/health-services/stock/src/test/java/org/egov/stock/validator/FacilityIdValidatorTest.java b/health-services/stock/src/test/java/org/egov/stock/validator/FacilityIdValidatorTest.java deleted file mode 100644 index ad7e257a488..00000000000 --- a/health-services/stock/src/test/java/org/egov/stock/validator/FacilityIdValidatorTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.egov.stock.validator; - - -import org.egov.common.contract.request.RequestInfo; -import org.egov.common.models.Error; -import org.egov.common.models.stock.Stock; -import org.egov.common.models.stock.StockBulkRequest; -import org.egov.common.models.stock.StockReconciliation; -import org.egov.common.models.stock.StockReconciliationBulkRequest; -import org.egov.stock.helper.StockBulkRequestTestBuilder; -import org.egov.stock.helper.StockReconciliationBulkRequestTestBuilder; -import org.egov.stock.service.FacilityService; -import org.egov.stock.validator.stock.SFacilityIdValidator; -import org.egov.stock.validator.stockreconciliation.SrFacilityIdValidator; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class FacilityIdValidatorTest { - - @InjectMocks - private SFacilityIdValidator sFacilityIdValidator; - - @InjectMocks - private SrFacilityIdValidator srFacilityIdValidator; - - @Mock - private FacilityService facilityService; - - private void mockEmptyResponse() { - when(facilityService.validateFacilityIds(any(List.class), - any(List.class), - any(String.class), - any(Map.class), - any(RequestInfo.class))).thenReturn(Collections.emptyList()); - } - - private void mockSomeResponse() { - when(facilityService.validateFacilityIds(any(List.class), - any(List.class), - any(String.class), - any(Map.class), - any(RequestInfo.class))).thenReturn(Collections.singletonList("facility-id")); - } - - @Test - @DisplayName("should add stock to error details if facility id not found") - void shouldAddStockToErrorDetailsIfFacilityIdNotFound() { - StockBulkRequest request = StockBulkRequestTestBuilder.builder().withStock().withRequestInfo().build(); - - mockEmptyResponse(); - - Map> errorDetailsMap = sFacilityIdValidator.validate(request); - assertEquals(errorDetailsMap.size(), 1); - } - - @Test - @DisplayName("should not add stock to error details if facility id found") - void shouldAddStockToErrorDetailsIfFacilityIdFound() { - StockBulkRequest request = StockBulkRequestTestBuilder.builder().withStock().withRequestInfo().build(); - - mockSomeResponse(); - - Map> errorDetailsMap = sFacilityIdValidator.validate(request); - assertEquals(errorDetailsMap.size(), 0); - } - - @Test - @DisplayName("should add stock reconciliation to error details if facility id not found") - void shouldAddStockReconciliationToErrorDetailsFacilityIdNotFound() { - StockReconciliationBulkRequest request = StockReconciliationBulkRequestTestBuilder.builder() - .withStock().withRequestInfo().build(); - - mockEmptyResponse(); - - Map> errorDetailsMap = srFacilityIdValidator.validate(request); - assertEquals(errorDetailsMap.size(), 1); - } - - @Test - @DisplayName("should not add stock reconciliation to error details if facility id found") - void shouldAddStockReconciliationToErrorDetailsIfFacilityIdFound() { - StockReconciliationBulkRequest request = StockReconciliationBulkRequestTestBuilder.builder() - .withStock().withRequestInfo().build(); - - mockSomeResponse(); - - Map> errorDetailsMap = srFacilityIdValidator.validate(request); - assertEquals(errorDetailsMap.size(), 0); - } -} diff --git a/health-services/stock/src/test/java/org/egov/stock/validator/ReferenceIdValidatorTest.java b/health-services/stock/src/test/java/org/egov/stock/validator/ReferenceIdValidatorTest.java index 096a1ffd9e6..d1a19f6df06 100644 --- a/health-services/stock/src/test/java/org/egov/stock/validator/ReferenceIdValidatorTest.java +++ b/health-services/stock/src/test/java/org/egov/stock/validator/ReferenceIdValidatorTest.java @@ -1,6 +1,16 @@ package org.egov.stock.validator; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.assertj.core.util.Arrays; import org.egov.common.contract.request.RequestInfo; import org.egov.common.models.Error; import org.egov.common.models.stock.Stock; @@ -19,14 +29,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - @ExtendWith(MockitoExtension.class) class ReferenceIdValidatorTest { @@ -43,14 +45,18 @@ private void mockEmptyResponse() { when(facilityService.validateProjectFacilityMappings(any(List.class), any(String.class), any(Map.class), - any(RequestInfo.class))).thenReturn(Collections.emptyList()); + any(RequestInfo.class))).thenReturn(Collections.emptyMap()); } private void mockSomeResponse() { + + List facilityIds = new ArrayList<>(); + facilityIds.add("sender-id"); + when(facilityService.validateProjectFacilityMappings(any(List.class), any(String.class), any(Map.class), - any(RequestInfo.class))).thenReturn(Collections.singletonList("facility-id||reference-id")); + any(RequestInfo.class))).thenReturn(Collections.singletonMap("reference-id", facilityIds)); } @Test diff --git a/health-services/stock/src/test/java/org/egov/stock/validator/TransactingPartyIdValidatorTest.java b/health-services/stock/src/test/java/org/egov/stock/validator/TransactingPartyIdValidatorTest.java deleted file mode 100644 index 0eda35fe11a..00000000000 --- a/health-services/stock/src/test/java/org/egov/stock/validator/TransactingPartyIdValidatorTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.egov.stock.validator; - - -import org.egov.common.contract.request.RequestInfo; -import org.egov.common.models.Error; -import org.egov.common.models.stock.Stock; -import org.egov.common.models.stock.StockBulkRequest; -import org.egov.stock.helper.StockBulkRequestTestBuilder; -import org.egov.stock.service.FacilityService; -import org.egov.stock.validator.stock.STransactingPartyIdValidator; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class TransactingPartyIdValidatorTest { - - @InjectMocks - private STransactingPartyIdValidator sTransactingPartyIdValidator; - - @Mock - private FacilityService facilityService; - - private void mockEmptyResponse() { - when(facilityService.validateFacilityIds(any(List.class), - any(List.class), - any(String.class), - any(Map.class), - any(RequestInfo.class))).thenReturn(Collections.emptyList()); - } - - private void mockSomeResponse() { - when(facilityService.validateFacilityIds(any(List.class), - any(List.class), - any(String.class), - any(Map.class), - any(RequestInfo.class))).thenReturn(Collections.singletonList("transaction-party-id")); - } - - @Test - @DisplayName("should add stock to error details if transacting party id not found") - void shouldAddStockToErrorDetailsIfTransactingPartyIdNotFound() { - StockBulkRequest request = StockBulkRequestTestBuilder.builder().withStock().withRequestInfo().build(); - - mockEmptyResponse(); - - Map> errorDetailsMap = sTransactingPartyIdValidator.validate(request); - assertEquals(errorDetailsMap.size(), 1); - } - - @Test - @DisplayName("should not add stock to error details if transacting party id found") - void shouldAddStockToErrorDetailsIfTransactingPartyIdFound() { - StockBulkRequest request = StockBulkRequestTestBuilder.builder().withStock().withRequestInfo().build(); - - mockSomeResponse(); - - Map> errorDetailsMap = sTransactingPartyIdValidator.validate(request); - assertEquals(errorDetailsMap.size(), 0); - } -}