mastering bridging
This commit is contained in:
9
.env-example
Normal file
9
.env-example
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
AUTH_URL=
|
||||||
|
BASE_URL=
|
||||||
|
CONSENT_URL=
|
||||||
|
KFA_URL=
|
||||||
|
CLIENT_ID=
|
||||||
|
CLIENT_SECRET=
|
||||||
|
ORGANIZATION_ID=
|
||||||
|
|
||||||
|
HTTP_PORT=8080
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.env
|
||||||
|
.vscode
|
||||||
32
Dockerfile
Normal file
32
Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Build stage
|
||||||
|
FROM golang:1.21 AS build-env
|
||||||
|
ENV GO111MODULE=on
|
||||||
|
|
||||||
|
# Set /app as the working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy all files to /app
|
||||||
|
COPY . .
|
||||||
|
COPY .env .env
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN go mod download && go mod verify
|
||||||
|
RUN go mod tidy -v
|
||||||
|
|
||||||
|
# Build the Go application
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -v -installsuffix cgo -o app cmd/main.go
|
||||||
|
|
||||||
|
# final
|
||||||
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
|
RUN apt-get update -y
|
||||||
|
RUN apt-get -y install wget
|
||||||
|
|
||||||
|
|
||||||
|
COPY --from=build-env /app/app .
|
||||||
|
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Define the command to run the application
|
||||||
|
CMD ["./app"]
|
||||||
5
builder-api.sh
Normal file
5
builder-api.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
sudo docker build -t satusehat-bridge:1.0 .
|
||||||
|
|
||||||
|
sudo docker stop satusehat-bridge_satusehat-bridge_1
|
||||||
|
sudo docker-compose down --volumes --remove-orphans
|
||||||
|
sudo docker-compose --env-file .env up --build
|
||||||
6
builder-swag.sh
Normal file
6
builder-swag.sh
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
cd openapi/
|
||||||
|
sudo docker stop swagger-satusehat
|
||||||
|
sudo docker rm swagger-satusehat
|
||||||
|
|
||||||
|
sudo docker build -t openapi:1.0 .
|
||||||
|
sudo docker run --name swagger-satusehat -p 8081:8080 openapi:1.0
|
||||||
146
cmd/main.go
Normal file
146
cmd/main.go
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/config"
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
"satusehat-rssa/internal/routes"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// load environment
|
||||||
|
if err := godotenv.Load(); err != nil {
|
||||||
|
log.Println("No .env file found or error loading it")
|
||||||
|
}
|
||||||
|
|
||||||
|
// init gin engine
|
||||||
|
e := gin.Default()
|
||||||
|
|
||||||
|
err = e.SetTrustedProxies(nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cors middleware
|
||||||
|
e.Use(func(c *gin.Context) {
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization")
|
||||||
|
|
||||||
|
// log to ensure the middleware is being executed
|
||||||
|
c.Writer.Header().Set("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Content-Disposition")
|
||||||
|
if c.Request.Method == "OPTIONS" {
|
||||||
|
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
|
||||||
|
c.AbortWithStatus(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
})
|
||||||
|
|
||||||
|
// health check
|
||||||
|
e.GET("/health", func(c *gin.Context) {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"message": "ok",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// route for handling 404
|
||||||
|
e.NoRoute(func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"message": "Hello in API Satu Sehat Integration"})
|
||||||
|
})
|
||||||
|
|
||||||
|
//Load Akses
|
||||||
|
akses := config.LoadConfig()
|
||||||
|
authMiddleware := midleware.AuthMiddleware{}
|
||||||
|
|
||||||
|
oa := integration.NewOauthRequestRepo(akses)
|
||||||
|
at := integration.NewAllergancyToleranRepo(akses)
|
||||||
|
cp := integration.NewCarePlanRepo(akses)
|
||||||
|
qr := integration.NewQuestionnaireResponseRepo(akses)
|
||||||
|
ms := integration.NewMedicationStatementRepo(akses)
|
||||||
|
im := integration.NewImmunizationRepo(akses)
|
||||||
|
is := integration.NewImagingStudyRepo(akses)
|
||||||
|
mr := integration.NewMedicationRequestRepo(akses)
|
||||||
|
md := integration.NewMedicationDispenseRepo(akses)
|
||||||
|
gl := integration.NewGoalRepo(akses)
|
||||||
|
medic := integration.NewMedicineKfaRepo(akses)
|
||||||
|
patient := integration.NewPatientRepo(akses)
|
||||||
|
practioner := integration.NewPracticionerRepo(akses)
|
||||||
|
encounter := integration.NewEncounterRepo(akses)
|
||||||
|
clinicalImpression := integration.NewClinicalImpressionRepo(akses)
|
||||||
|
observation := integration.NewObservationRepo(akses)
|
||||||
|
organization := integration.NewOrganizationRepo(akses)
|
||||||
|
condition := integration.NewConditionRepo(akses)
|
||||||
|
dianosisReport := integration.NewDiagnosisReportRepo(akses)
|
||||||
|
serviceRequest := integration.NewServiceRequestRepository(akses)
|
||||||
|
specimen := integration.NewSpecimenRepository(akses)
|
||||||
|
episodeOfCare := integration.NewEpisodeOfCareRepo(akses)
|
||||||
|
procedure := integration.NewProcedureRepo(akses)
|
||||||
|
composition := integration.NewCompositionRepo(akses)
|
||||||
|
|
||||||
|
oahandler := handler.NewOuathHandler(oa)
|
||||||
|
athandler := handler.NewAllergancyToleranHandler(at)
|
||||||
|
cphandler := handler.NewCarePlanHandler(cp)
|
||||||
|
qrhandler := handler.NewQuestionnaireResponseHandler(qr)
|
||||||
|
mshandler := handler.NewMedicationStatementHandler(ms)
|
||||||
|
imhandler := handler.NewImmunizationHandler(im)
|
||||||
|
ishandler := handler.NewImagingStudyHandler(is)
|
||||||
|
mrhandler := handler.NewMedicationRequestHandler(mr)
|
||||||
|
mdhandler := handler.NewMedicationDispenseHandler(md)
|
||||||
|
glhandler := handler.NewGoalHandler(gl)
|
||||||
|
medicineHandler := handler.NewMedicineHandler(medic)
|
||||||
|
patientHandler := handler.NewPatientHandler(patient)
|
||||||
|
practicionerHandler := handler.NewPracticionerHandler(practioner)
|
||||||
|
encounterHandler := handler.NewEncounterHandler(encounter)
|
||||||
|
clinicalImpressionHandler := handler.NewClinicalImpressionHandler(clinicalImpression)
|
||||||
|
observationHandler := handler.NewObservationHandler(observation)
|
||||||
|
organizationHandler := handler.NewOrganizationHandler(organization)
|
||||||
|
conditionHandler := handler.NewConditionHandler(condition)
|
||||||
|
diagnosisReportHandler := handler.NewDiagnosisReportHandler(dianosisReport)
|
||||||
|
serviceRequestHandler := handler.NewServiceRequestHandler(serviceRequest)
|
||||||
|
specimenHandler := handler.NewSpecimenHandler(specimen)
|
||||||
|
episodeOfCareHandler := handler.NewEpisodeOfCareHandler(episodeOfCare)
|
||||||
|
procedureHandler := handler.NewProcedureHandler(procedure)
|
||||||
|
compositionHandler := handler.NewCompositionHandler(composition)
|
||||||
|
|
||||||
|
routes.Oauth(e, oahandler, authMiddleware)
|
||||||
|
routes.AllergancyToleran(e, athandler, authMiddleware)
|
||||||
|
routes.CarePlan(e, cphandler, authMiddleware)
|
||||||
|
routes.QuestionnaireResponse(e, qrhandler, authMiddleware)
|
||||||
|
routes.MedicationStatement(e, mshandler, authMiddleware)
|
||||||
|
routes.Immunization(e, imhandler, authMiddleware)
|
||||||
|
routes.ImagingStudy(e, ishandler, authMiddleware)
|
||||||
|
routes.MedicationRequest(e, mrhandler, authMiddleware)
|
||||||
|
routes.MedicationDispense(e, mdhandler, authMiddleware)
|
||||||
|
routes.Goal(e, glhandler, authMiddleware)
|
||||||
|
routes.MedicineKfa(e, medicineHandler, authMiddleware)
|
||||||
|
routes.Patient(e, patientHandler, authMiddleware)
|
||||||
|
routes.Practicioner(e, practicionerHandler, authMiddleware)
|
||||||
|
routes.Encounter(e, encounterHandler, authMiddleware)
|
||||||
|
routes.ClinicalImpression(e, clinicalImpressionHandler, authMiddleware)
|
||||||
|
routes.Observation(e, observationHandler, authMiddleware)
|
||||||
|
routes.Organization(e, organizationHandler, authMiddleware)
|
||||||
|
routes.Condition(e, conditionHandler, authMiddleware)
|
||||||
|
routes.DiagnosisReport(e, diagnosisReportHandler, authMiddleware)
|
||||||
|
routes.ServiceRequest(e, serviceRequestHandler, authMiddleware)
|
||||||
|
routes.Specimen(e, specimenHandler, authMiddleware)
|
||||||
|
routes.EpisodeOfCare(e, episodeOfCareHandler, authMiddleware)
|
||||||
|
routes.Procedure(e, procedureHandler, authMiddleware)
|
||||||
|
routes.Composition(e, compositionHandler, authMiddleware)
|
||||||
|
|
||||||
|
port := fmt.Sprintf(":%s", os.Getenv("HTTP_PORT"))
|
||||||
|
if err = e.Run(port); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
10
docker-compose.yaml
Normal file
10
docker-compose.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
satusehat-bridge:
|
||||||
|
image: satusehat-bridge:1.0
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
37
go.mod
Normal file
37
go.mod
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
module satusehat-rssa
|
||||||
|
|
||||||
|
go 1.21.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gin-gonic/gin v1.10.1
|
||||||
|
github.com/go-playground/validator/v10 v10.26.0
|
||||||
|
github.com/joho/godotenv v1.5.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/bytedance/sonic v1.11.6 // indirect
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||||
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
|
golang.org/x/arch v0.8.0 // indirect
|
||||||
|
golang.org/x/crypto v0.33.0 // indirect
|
||||||
|
golang.org/x/net v0.34.0 // indirect
|
||||||
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
|
golang.org/x/text v0.22.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.34.1 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
93
go.sum
Normal file
93
go.sum
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||||
|
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||||
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||||
|
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||||
|
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||||
|
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||||
|
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||||
|
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||||
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
|
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||||
|
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
|
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||||
|
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||||
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||||
|
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
18
internal/config/akses_satusehat.go
Normal file
18
internal/config/akses_satusehat.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadConfig() *model.Akses {
|
||||||
|
|
||||||
|
return &model.Akses{
|
||||||
|
AuthUrl: os.Getenv("AUTH_URL"),
|
||||||
|
BaseUrl: os.Getenv("BASE_URL"),
|
||||||
|
ConsentUrl: os.Getenv("CONSENT_URL"),
|
||||||
|
KfaUrl: os.Getenv("KFA_URL"),
|
||||||
|
ClientId: os.Getenv("CLIENT_ID"),
|
||||||
|
ClientSecret: os.Getenv("CLIENT_SECRET"),
|
||||||
|
}
|
||||||
|
}
|
||||||
29
internal/constant/const.go
Normal file
29
internal/constant/const.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
const (
|
||||||
|
AllergyIntoleranceResourceType = "AllergyIntolerance"
|
||||||
|
ClinicalImpressionResourceType = "ClinicalImpression"
|
||||||
|
ServiceRequestResourceType = "ServiceRequest"
|
||||||
|
EpisodeOfCareResourceType = "EpisodeOfCare"
|
||||||
|
SpecimenResourceType = "Specimen"
|
||||||
|
DiagnosticReportResourceType = "DiagnosticReport"
|
||||||
|
ObservationResourceType = "Observation"
|
||||||
|
OrganizationResourceType = "Organization"
|
||||||
|
CarePlanResourceType = "CarePlan"
|
||||||
|
QuestionnaireResponseResourceType = "QuestionnaireResponse"
|
||||||
|
MedicationStatementResourceType = "MedicationStatement"
|
||||||
|
ImmunizationResourceType = "Immunization"
|
||||||
|
ImagingStudyResourceType = "ImagingStudy"
|
||||||
|
MedicationRequestResourceType = "MedicationRequest"
|
||||||
|
MedicationDispenseResourceType = "MedicationDispense"
|
||||||
|
ProcedureResourceType = "Procedure"
|
||||||
|
GoalResourceType = "Goal"
|
||||||
|
PatientResourceType = "Patient"
|
||||||
|
EncounterResourceType = "Encounter"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ContentTypeFHIRJSON = "application/fhir+json"
|
||||||
|
PatientProfile = "https://fhir.kemkes.go.id/r4/StructureDefinition/Patient"
|
||||||
|
FHIRMedicationProfile = "https://fhir.kemkes.go.id/r4/StructureDefinition/Medication"
|
||||||
|
)
|
||||||
5
internal/constant/error.go
Normal file
5
internal/constant/error.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrGenerateToken = "failed to generate access token"
|
||||||
|
)
|
||||||
58
internal/handler/allergancytoleran_handler.go
Normal file
58
internal/handler/allergancytoleran_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AllergancyToleranHandler struct {
|
||||||
|
AllergancyToleran integration.AllergancyToleranInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAllergancyToleranHandler(AllergancyToleran integration.AllergancyToleranInterface) *AllergancyToleranHandler {
|
||||||
|
return &AllergancyToleranHandler{AllergancyToleran: AllergancyToleran}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AllergancyToleranHandler) CreateAllergancyToleran(c *gin.Context) {
|
||||||
|
var bodyParam model.AllergancyToleranRequest
|
||||||
|
if err := c.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := a.AllergancyToleran.CreateAllergancyToleran(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AllergancyToleranHandler) UpdateAllergancyToleran(c *gin.Context) {
|
||||||
|
var bodyParam model.AllergancyToleranRequest
|
||||||
|
if err := c.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyParam.Id = c.Param("id")
|
||||||
|
res, err := a.AllergancyToleran.UpdateAllergancyToleran(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
58
internal/handler/careplan_handler.go
Normal file
58
internal/handler/careplan_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CarePlanHandler struct {
|
||||||
|
CarePlan integration.CarePlanInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCarePlanHandler(CarePlan integration.CarePlanInterface) *CarePlanHandler {
|
||||||
|
return &CarePlanHandler{CarePlan: CarePlan}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h CarePlanHandler) CreateCarePlan(c *gin.Context) {
|
||||||
|
var req model.CarePlanRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.CarePlan.CreateCarePlan(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h CarePlanHandler) UpdateCarePlan(c *gin.Context) {
|
||||||
|
var req model.CarePlanRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.CarePlan.CreateCarePlan(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
62
internal/handler/clinicalImpression_handler.go
Normal file
62
internal/handler/clinicalImpression_handler.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClinicalImpressionHandler struct {
|
||||||
|
// Define fields for ClinicalImpressionHandler
|
||||||
|
ClinicalImpression integration.ClinicalImppressionInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClinicalImpressionHandler(ClinicalImpression integration.ClinicalImppressionInterface) *ClinicalImpressionHandler {
|
||||||
|
return &ClinicalImpressionHandler{ClinicalImpression: ClinicalImpression}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClinicalImpressionHandler) CreateClinicalImpression(ctx *gin.Context) {
|
||||||
|
var bodyParam model.ClinicalImpressionRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyParam.Identifier = append(bodyParam.Identifier, common.GetIdentifier("clinicalImpression"))
|
||||||
|
|
||||||
|
res, err := c.ClinicalImpression.CreateClinicalImpression(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClinicalImpressionHandler) UpdateClinicalImpression(ctx *gin.Context) {
|
||||||
|
var bodyParam model.ClinicalImpressionRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyParam.Id = ctx.Param("id")
|
||||||
|
bodyParam.Identifier = append(bodyParam.Identifier, common.GetIdentifier("clinicalImpression"))
|
||||||
|
|
||||||
|
res, err := c.ClinicalImpression.UpdateClinicalImpression(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
62
internal/handler/composition_handler.go
Normal file
62
internal/handler/composition_handler.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CompositionHandler struct {
|
||||||
|
Composition integration.CompositionInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCompositionHandler(composition integration.CompositionInterface) *CompositionHandler {
|
||||||
|
return &CompositionHandler{
|
||||||
|
Composition: composition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ch *CompositionHandler) CreateComposition(c *gin.Context) {
|
||||||
|
var req model.CompositionRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Identifier = common.GetIdentifier("composition")
|
||||||
|
resp, err := ch.Composition.CreateComposition(req)
|
||||||
|
if err != nil {
|
||||||
|
if resp != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ch *CompositionHandler) UpdateComposition(c *gin.Context) {
|
||||||
|
var req model.CompositionRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Identifier = common.GetIdentifier("composition")
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
resp, err := ch.Composition.UpdateComposition(req)
|
||||||
|
if err != nil {
|
||||||
|
if resp != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, resp)
|
||||||
|
}
|
||||||
75
internal/handler/condition_handler.go
Normal file
75
internal/handler/condition_handler.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConditionHandler struct {
|
||||||
|
// Define fields for ConditionHandler
|
||||||
|
Condition integration.ConditionInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConditionHandler(condition integration.ConditionInterface) *ConditionHandler {
|
||||||
|
return &ConditionHandler{Condition: condition}
|
||||||
|
}
|
||||||
|
func (c *ConditionHandler) CreateCondition(ctx *gin.Context) {
|
||||||
|
var bodyParam model.ConditionRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := c.Condition.CreateCondition(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ConditionHandler) GetConditionByPatient(ctx *gin.Context) {
|
||||||
|
patientId := ctx.Query("subject")
|
||||||
|
if patientId == "" {
|
||||||
|
ctx.JSON(http.StatusBadRequest, "patientId is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.Condition.GetConditionByPatient(patientId)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ConditionHandler) UpdateCondition(ctx *gin.Context) {
|
||||||
|
var bodyParam model.ConditionRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
ctx.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyParam.Id = ctx.Param("id")
|
||||||
|
res, err := c.Condition.UpdateCondition(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
62
internal/handler/diagnosisreport_handler.go
Normal file
62
internal/handler/diagnosisreport_handler.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DiagnosisReportHandler struct {
|
||||||
|
DiagnosisReport integration.DiagnosisReportInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDiagnosisReportHandler(diagnosisReport integration.DiagnosisReportInterface) *DiagnosisReportHandler {
|
||||||
|
return &DiagnosisReportHandler{DiagnosisReport: diagnosisReport}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiagnosisReportHandler) CreateDiagnosisReport(c *gin.Context) {
|
||||||
|
var req model.DiagnosticReportRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
identifier := common.GetIdentifier("diagnostic")
|
||||||
|
identifier.System += "/lab"
|
||||||
|
req.Identifier = append(req.Identifier, identifier)
|
||||||
|
res, err := d.DiagnosisReport.CreateDiagnosisReport(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiagnosisReportHandler) UpdateDiagnosisReport(c *gin.Context) {
|
||||||
|
var req model.DiagnosticReportRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
identifier := common.GetIdentifier("diagnostic")
|
||||||
|
identifier.System += "/lab"
|
||||||
|
req.Identifier = append(req.Identifier, identifier)
|
||||||
|
res, err := d.DiagnosisReport.UpdateDiagnosisReport(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
81
internal/handler/encounter_handler.go
Normal file
81
internal/handler/encounter_handler.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EncounterHandler struct {
|
||||||
|
// Define any dependencies needed for the handler
|
||||||
|
Encounter integration.EncounterInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEncounterHandler(encounter integration.EncounterInterface) *EncounterHandler {
|
||||||
|
return &EncounterHandler{Encounter: encounter}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add methods for handling encounter-related requests here
|
||||||
|
func (e *EncounterHandler) CreateEncounter(c *gin.Context) {
|
||||||
|
var req model.EncounterRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := e.Encounter.CreateEncounter(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EncounterHandler) GetEncounterByPatient(c *gin.Context) {
|
||||||
|
id := c.Query("subject")
|
||||||
|
if id == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Subject is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
encounter, err := e.Encounter.GetEncounterByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounter == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"message": "Encounter not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, encounter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EncounterHandler) UpdateEncounter(c *gin.Context) {
|
||||||
|
var req model.EncounterUpdateRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// set id for param
|
||||||
|
id := c.Param("id")
|
||||||
|
req.ID = id
|
||||||
|
|
||||||
|
res, err := e.Encounter.UpdateEncounter(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
80
internal/handler/episodeofcare_handler.go
Normal file
80
internal/handler/episodeofcare_handler.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EpisodeOfCareHandler struct {
|
||||||
|
// Define any dependencies needed for the handler
|
||||||
|
EpisodeOfCare integration.EpisodeOfCareInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEpisodeOfCareHandler(episodeOfCare integration.EpisodeOfCareInterface) *EpisodeOfCareHandler {
|
||||||
|
return &EpisodeOfCareHandler{EpisodeOfCare: episodeOfCare}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add methods for handling episode of care-related requests here
|
||||||
|
func (e *EpisodeOfCareHandler) CreateEpisodeOfCare(c *gin.Context) {
|
||||||
|
var req model.EpisodeOfCareRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("episode-of-care"))
|
||||||
|
res, err := e.EpisodeOfCare.CreateEpisodeOfCare(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EpisodeOfCareHandler) GetEpisodeOfCareByPatient(c *gin.Context) {
|
||||||
|
id := c.Query("patient")
|
||||||
|
if id == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Patient is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
episodeOfCare, err := e.EpisodeOfCare.GetEpisodeOfCareByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if episodeOfCare == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"message": "Episode of care not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, episodeOfCare)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EpisodeOfCareHandler) UpdateEpisodeOfCare(c *gin.Context) {
|
||||||
|
var req model.EpisodeOfCareRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("episode-of-care"))
|
||||||
|
res, err := e.EpisodeOfCare.UpdateEpisodeOfCare(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
58
internal/handler/goal_handler.go
Normal file
58
internal/handler/goal_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoalHandler struct {
|
||||||
|
Goal integration.GoalInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoalHandler(Goal integration.GoalInterface) *GoalHandler {
|
||||||
|
return &GoalHandler{Goal: Goal}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GoalHandler) CreateGoal(c *gin.Context) {
|
||||||
|
var req model.GoalRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.Goal.CreateGoal(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h GoalHandler) UpdateGoal(c *gin.Context) {
|
||||||
|
var req model.GoalRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.Goal.CreateGoal(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
97
internal/handler/imagingstudy_handler.go
Normal file
97
internal/handler/imagingstudy_handler.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImagingStudyHandler struct {
|
||||||
|
ImagingStudy integration.ImagingStudyInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImagingStudyHandler(ImagingStudy integration.ImagingStudyInterface) *ImagingStudyHandler {
|
||||||
|
return &ImagingStudyHandler{ImagingStudy: ImagingStudy}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h ImagingStudyHandler) CreateImagingStudy(c *gin.Context) {
|
||||||
|
var req model.ImagingStudyRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Identifier) < 1 {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "identifier is required."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Identifier) > 0 {
|
||||||
|
for k, i := range req.Identifier {
|
||||||
|
if k == 0 && i.Value == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("identifier[%d].value (ACSN) required", k)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if k == 1 && i.Value == "" {
|
||||||
|
// c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("identifier[%d].value (urn:dicom:uid) required", k)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.ImagingStudy.CreateImagingStudy(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h ImagingStudyHandler) UpdateImagingStudy(c *gin.Context) {
|
||||||
|
var req model.ImagingStudyRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Identifier) < 1 {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "identifier is required."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Identifier) > 0 {
|
||||||
|
for k, i := range req.Identifier {
|
||||||
|
if k == 0 && i.Value == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("identifier[%d].value (ACSN) required", k)})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if k == 1 && i.Value == "" {
|
||||||
|
// c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("identifier[%d].value (urn:dicom:uid) required", k)})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.ImagingStudy.CreateImagingStudy(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
58
internal/handler/immunization_handler.go
Normal file
58
internal/handler/immunization_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImmunizationHandler struct {
|
||||||
|
Immunization integration.ImmunizationInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImmunizationHandler(Immunization integration.ImmunizationInterface) *ImmunizationHandler {
|
||||||
|
return &ImmunizationHandler{Immunization: Immunization}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h ImmunizationHandler) CreateImmunization(c *gin.Context) {
|
||||||
|
var req model.ImmunizationRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.Immunization.CreateImmunization(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h ImmunizationHandler) UpdateImmunization(c *gin.Context) {
|
||||||
|
var req model.ImmunizationRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.Immunization.CreateImmunization(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
58
internal/handler/medicationdispense_handler.go
Normal file
58
internal/handler/medicationdispense_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicationDispenseHandler struct {
|
||||||
|
MedicationDispense integration.MedicationDispenseInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicationDispenseHandler(MedicationDispense integration.MedicationDispenseInterface) *MedicationDispenseHandler {
|
||||||
|
return &MedicationDispenseHandler{MedicationDispense: MedicationDispense}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h MedicationDispenseHandler) CreateMedicationDispense(c *gin.Context) {
|
||||||
|
var req model.MedicationDispenseRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.MedicationDispense.CreateMedicationDispense(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h MedicationDispenseHandler) UpdateMedicationDispense(c *gin.Context) {
|
||||||
|
var req model.MedicationDispenseRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.MedicationDispense.CreateMedicationDispense(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
58
internal/handler/medicationrequest_handler.go
Normal file
58
internal/handler/medicationrequest_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicationRequestHandler struct {
|
||||||
|
MedicationRequest integration.MedicationRequestInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicationRequestHandler(MedicationRequest integration.MedicationRequestInterface) *MedicationRequestHandler {
|
||||||
|
return &MedicationRequestHandler{MedicationRequest: MedicationRequest}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h MedicationRequestHandler) CreateMedicationRequest(c *gin.Context) {
|
||||||
|
var req model.MedicationRequestRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.MedicationRequest.CreateMedicationRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h MedicationRequestHandler) UpdateMedicationRequest(c *gin.Context) {
|
||||||
|
var req model.MedicationRequestRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.MedicationRequest.CreateMedicationRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
60
internal/handler/medicationstatement_handler.go
Normal file
60
internal/handler/medicationstatement_handler.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicationStatementHandler struct {
|
||||||
|
MedicationStatement integration.MedicationStatementInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicationStatementHandler(MedicationStatement integration.MedicationStatementInterface) *MedicationStatementHandler {
|
||||||
|
return &MedicationStatementHandler{MedicationStatement: MedicationStatement}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h MedicationStatementHandler) CreateMedicationStatement(c *gin.Context) {
|
||||||
|
var req model.MedicationStatementRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.MedicationStatement.CreateMedicationStatement(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h MedicationStatementHandler) UpdateMedicationStatement(c *gin.Context) {
|
||||||
|
var req model.MedicationStatementRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.MedicationStatement.CreateMedicationStatement(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
40
internal/handler/medicine_handler.go
Normal file
40
internal/handler/medicine_handler.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicineHandler struct {
|
||||||
|
Medicine integration.MedicineIntegrationInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicineHandler(medicine integration.MedicineIntegrationInterface) *MedicineHandler {
|
||||||
|
return &MedicineHandler{Medicine: medicine}
|
||||||
|
}
|
||||||
|
func (m MedicineHandler) GetMedicineKfa(c *gin.Context) {
|
||||||
|
var req model.MedicineKfaRequest
|
||||||
|
if err := c.ShouldBindQuery(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := m.Medicine.GetMedicineKfa(req)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MedicineHandler) GetMedicineByKfaCode(c *gin.Context) {
|
||||||
|
kfaCode := c.Param("kfa_code")
|
||||||
|
res, err := m.Medicine.GetMedicineByKfaCode(kfaCode)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
33
internal/handler/oauth_handler.go
Normal file
33
internal/handler/oauth_handler.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OauthHandler struct {
|
||||||
|
Oauth integration.OauthInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOuathHandler(Oauth integration.OauthInterface) *OauthHandler {
|
||||||
|
return &OauthHandler{Oauth: Oauth}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (oh OauthHandler) GenerateToken(c *gin.Context) {
|
||||||
|
var bodyParam model.OauthRequest
|
||||||
|
if err := c.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := oh.Oauth.GenerateToken(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
78
internal/handler/observation_handler.go
Normal file
78
internal/handler/observation_handler.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ObservationHandler struct {
|
||||||
|
// Define any dependencies needed for the handler
|
||||||
|
Observation integration.ObservationInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObservationHandler(observation integration.ObservationInterface) *ObservationHandler {
|
||||||
|
return &ObservationHandler{Observation: observation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add methods for handling observation-related requests here
|
||||||
|
func (o *ObservationHandler) CreateObservation(c *gin.Context) {
|
||||||
|
var req model.ObservationRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := o.Observation.CreateObservation(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ObservationHandler) GetObservationByPatient(c *gin.Context) {
|
||||||
|
id := c.Query("subject")
|
||||||
|
if id == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Subject is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
observation, err := o.Observation.GetObservationByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if observation == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"message": "Observation not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, observation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ObservationHandler) UpdateObservation(c *gin.Context) {
|
||||||
|
var req model.ObservationRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := o.Observation.UpdateObservation(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
54
internal/handler/organization_handler.go
Normal file
54
internal/handler/organization_handler.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrganizationHandler struct {
|
||||||
|
Organization integration.OrganizationInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOrganizationHandler(organization integration.OrganizationInterface) *OrganizationHandler {
|
||||||
|
return &OrganizationHandler{Organization: organization}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OrganizationHandler) CreateOrganization(c *gin.Context) {
|
||||||
|
var bodyParam model.OrganizationRequest
|
||||||
|
if err := c.ShouldBindJSON(&bodyParam); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bodyParam.Identifier = append(bodyParam.Identifier, common.GetIdentifier("organization"))
|
||||||
|
res, err := o.Organization.CreateOrganization(bodyParam)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OrganizationHandler) GetOrganizationPatient(c *gin.Context) {
|
||||||
|
id := c.Query("subject")
|
||||||
|
if id == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, "Patient ID is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := o.Organization.GetOrganizationPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
47
internal/handler/patient_handler.go
Normal file
47
internal/handler/patient_handler.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PatientHandler struct {
|
||||||
|
// Define any dependencies or services needed for the PatientHandler
|
||||||
|
Patient integration.PatientInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPatientHandler(patient integration.PatientInterface) *PatientHandler {
|
||||||
|
return &PatientHandler{Patient: patient}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add methods for handling patient-related requests here
|
||||||
|
func (p *PatientHandler) GetPatientByNIK(c *gin.Context) {
|
||||||
|
param := c.Query("identifier")
|
||||||
|
res, err := p.Patient.GetPatientByNIK(param)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PatientHandler) CreatePatient(c *gin.Context) {
|
||||||
|
var req model.PatientRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := p.Patient.CreataPatient(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
37
internal/handler/practitioner_handler.go
Normal file
37
internal/handler/practitioner_handler.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PracticionerHandler struct {
|
||||||
|
Practicioner integration.PracticionerInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPracticionerHandler(practicioner integration.PracticionerInterface) *PracticionerHandler {
|
||||||
|
return &PracticionerHandler{Practicioner: practicioner}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PracticionerHandler) GetPracticionerByNik(c *gin.Context) {
|
||||||
|
nik := c.Query("identifier")
|
||||||
|
if nik == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "identifier is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
practicioner, err := p.Practicioner.GetPracticionerByNIK(nik)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if practicioner == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"message": "Practicioner not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, practicioner)
|
||||||
|
}
|
||||||
71
internal/handler/procedure_handler.go
Normal file
71
internal/handler/procedure_handler.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcedureHandler struct {
|
||||||
|
Procedure integration.ProcedureInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcedureHandler(procedure integration.ProcedureInterface) *ProcedureHandler {
|
||||||
|
return &ProcedureHandler{
|
||||||
|
Procedure: procedure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProcedureHandler) CreateProcedure(c *gin.Context) {
|
||||||
|
var req model.ProcedureRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := p.Procedure.CreateProcedure(req)
|
||||||
|
if err != nil {
|
||||||
|
if result != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProcedureHandler) GetProcedure(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
|
||||||
|
result, err := p.Procedure.GetProcedure(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProcedureHandler) UpdateProcedure(c *gin.Context) {
|
||||||
|
var req model.ProcedureRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := p.Procedure.UpdateProcedure(req)
|
||||||
|
if err != nil {
|
||||||
|
if result != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, result)
|
||||||
|
}
|
||||||
58
internal/handler/questionnaireresponse_handler.go
Normal file
58
internal/handler/questionnaireresponse_handler.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type QuestionnaireResponseHandler struct {
|
||||||
|
QuestionnaireResponse integration.QuestionnaireResponseInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuestionnaireResponseHandler(QuestionnaireResponse integration.QuestionnaireResponseInterface) *QuestionnaireResponseHandler {
|
||||||
|
return &QuestionnaireResponseHandler{QuestionnaireResponse: QuestionnaireResponse}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h QuestionnaireResponseHandler) CreateQuestionnaireResponse(c *gin.Context) {
|
||||||
|
var req model.QuestionnaireResponseRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := h.QuestionnaireResponse.CreateQuestionnaireResponse(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h QuestionnaireResponseHandler) UpdateQuestionnaireResponse(c *gin.Context) {
|
||||||
|
var req model.QuestionnaireResponseRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
res, err := h.QuestionnaireResponse.CreateQuestionnaireResponse(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
77
internal/handler/servicerequest_handler.go
Normal file
77
internal/handler/servicerequest_handler.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceRequestHandler struct {
|
||||||
|
repo integration.ServiceRequestInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceRequestHandler(repo integration.ServiceRequestInterface) *ServiceRequestHandler {
|
||||||
|
return &ServiceRequestHandler{repo: repo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ServiceRequestHandler) CreateServiceRequest(c *gin.Context) {
|
||||||
|
var req model.ServiceRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("servicerequest"))
|
||||||
|
data, err := h.repo.CreateServiceRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
if data != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ServiceRequestHandler) GetServiceRequestByPatient(c *gin.Context) {
|
||||||
|
id := c.Query("subject")
|
||||||
|
if id == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Patient ID is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := h.repo.GetServiceRequestByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ServiceRequestHandler) UpdateServiceRequest(c *gin.Context) {
|
||||||
|
var req model.ServiceRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("servicerequest"))
|
||||||
|
data, err := h.repo.UpdateServiceRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
if data != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, data)
|
||||||
|
}
|
||||||
77
internal/handler/specimen_handler.go
Normal file
77
internal/handler/specimen_handler.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/integration"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SpecimenHandler struct {
|
||||||
|
Specimen integration.SpecimenInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSpecimenHandler(specimen integration.SpecimenInterface) *SpecimenHandler {
|
||||||
|
return &SpecimenHandler{Specimen: specimen}
|
||||||
|
}
|
||||||
|
func (s *SpecimenHandler) CreateSpecimen(c *gin.Context) {
|
||||||
|
var req model.SpecimenRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("specimen"))
|
||||||
|
res, err := s.Specimen.CreateSpecimen(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SpecimenHandler) GetSpecimenByPatient(c *gin.Context) {
|
||||||
|
id := c.Query("subject")
|
||||||
|
if id == "" {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Subject is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
specimen, err := s.Specimen.GetSpecimenByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if specimen == nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"message": "Specimen not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, specimen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SpecimenHandler) UpdateSpecimen(c *gin.Context) {
|
||||||
|
var req model.SpecimenRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Id = c.Param("id")
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("specimen"))
|
||||||
|
res, err := s.Specimen.UpdateSpecimen(req)
|
||||||
|
if err != nil {
|
||||||
|
if res != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
262
internal/integration/allergancytoleran_integration.go
Normal file
262
internal/integration/allergancytoleran_integration.go
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AllergancyToleranInterface interface {
|
||||||
|
// Define methods for AllergancyToleranInterface
|
||||||
|
CreateAllergancyToleran(req model.AllergancyToleranRequest) (*model.AllergancyToleranResponse, error)
|
||||||
|
UpdateAllergancyToleran(req model.AllergancyToleranRequest) (map[string]interface{}, error)
|
||||||
|
GetAllergytoleranByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckAllergancyToleran(id string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllergancyToleranRepository struct {
|
||||||
|
// Define fields for AllergancyToleranRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllergytoleranByPatient implements AllergancyToleranInterface.
|
||||||
|
func (a *AllergancyToleranRepository) GetAllergytoleranByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := a.akses.BaseUrl + "/AllergyIntolerance?patient=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: a.akses.ClientId,
|
||||||
|
ClientSecret: a.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(a.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckAllergancyToleran implements AllergancyToleranInterface.
|
||||||
|
func (a *AllergancyToleranRepository) HandleCheckAllergancyToleran(id string) ([]string, bool, error) {
|
||||||
|
allergy, err := a.GetAllergytoleranByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := allergy["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (allergy)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAllergancyToleran implements AllergancyToleranInterface.
|
||||||
|
func (a *AllergancyToleranRepository) CreateAllergancyToleran(req model.AllergancyToleranRequest) (*model.AllergancyToleranResponse, error) {
|
||||||
|
var data *model.AllergancyToleranResponse
|
||||||
|
|
||||||
|
req.ResourceType = constant.AllergyIntoleranceResourceType
|
||||||
|
req.Identifier = append(req.Identifier, &model.IdentifierObject{
|
||||||
|
Use: "official",
|
||||||
|
System: "http://sys-ids.kemkes.go.id/allergy/" + os.Getenv("ORGANIZATION_ID"), // Set this if needed, or remove if not present in IdentifierObject
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
})
|
||||||
|
|
||||||
|
patient, err := a.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = a.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
url := a.akses.BaseUrl + "/AllergyIntolerance"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: a.akses.ClientId,
|
||||||
|
ClientSecret: a.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(a.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AllergancyToleranRepository) UpdateAllergancyToleran(req model.AllergancyToleranRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.AllergyIntoleranceResourceType
|
||||||
|
req.Identifier = append(req.Identifier, &model.IdentifierObject{
|
||||||
|
Use: "official",
|
||||||
|
System: "http://sys-ids.kemkes.go.id/allergy/" + os.Getenv("ORGANIZATION_ID"), // Set this if needed, or remove if not present in IdentifierObject
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
})
|
||||||
|
|
||||||
|
patient, err := a.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = a.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: a.akses.ClientId,
|
||||||
|
ClientSecret: a.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(a.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := a.akses.BaseUrl + fmt.Sprintf("/AllergyIntolerance/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPatient handles patient reference logic.
|
||||||
|
func (a *AllergancyToleranRepository) setupPatient(req *model.AllergancyToleranRequest) (string, error) {
|
||||||
|
if req.Patient.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(a.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Patient.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if patient != "" {
|
||||||
|
req.Patient.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupEncounter handles encounter reference logic.
|
||||||
|
func (a *AllergancyToleranRepository) setupEncounter(req *model.AllergancyToleranRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(a.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (a *AllergancyToleranRepository) setupPractitioner(req *model.AllergancyToleranRequest) error {
|
||||||
|
if req.Recorder.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
practicionerInterface := NewPracticionerRepo(a.akses)
|
||||||
|
ref, display, err := practicionerInterface.HandleCheckPartitioner(req.Recorder.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.Recorder.Reference = "Practitioner/" + ref
|
||||||
|
req.Recorder.Display = display
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAllergancyToleranRepo(akses *model.Akses) AllergancyToleranInterface {
|
||||||
|
return &AllergancyToleranRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
224
internal/integration/careplan_integration.go
Normal file
224
internal/integration/careplan_integration.go
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CarePlanInterface interface {
|
||||||
|
// Define methods for CarePlanInterface
|
||||||
|
CreateCarePlan(req model.CarePlanRequest) (map[string]interface{}, error)
|
||||||
|
UpdateCarePlan(req model.CarePlanRequest) (map[string]interface{}, error)
|
||||||
|
GetCareplanByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckCarePlan(id string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CarePlanRepository struct {
|
||||||
|
// Define fields for CarePlanRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCareplanByPatient implements CarePlanInterface.
|
||||||
|
func (c *CarePlanRepository) GetCareplanByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/CarePlan?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckCarePlan implements CarePlanInterface.
|
||||||
|
func (c *CarePlanRepository) HandleCheckCarePlan(id string) ([]string, bool, error) {
|
||||||
|
careplan, err := c.GetCareplanByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := careplan["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (careplan)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCarePlanRepo(akses *model.Akses) CarePlanInterface {
|
||||||
|
return &CarePlanRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateCarePlan implements CarePlanInterface.
|
||||||
|
func (c *CarePlanRepository) CreateCarePlan(req model.CarePlanRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.CarePlanResourceType
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/CarePlan"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CarePlanRepository) UpdateCarePlan(req model.CarePlanRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.CarePlanResourceType
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupPractitioner(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/CarePlan/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CarePlanRepository) setupPatient(req *model.CarePlanRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CarePlanRepository) setupEncounter(req *model.CarePlanRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (c *CarePlanRepository) setupPractitioner(req *model.CarePlanRequest) error {
|
||||||
|
if req.Author.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
practicionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
ref, display, err := practicionerInterface.HandleCheckPartitioner(req.Author.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.Author.Reference = "Practitioner/" + ref
|
||||||
|
req.Author.Display = display
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
326
internal/integration/clinicalImpression_integration.go
Normal file
326
internal/integration/clinicalImpression_integration.go
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClinicalImppressionInterface interface {
|
||||||
|
// Define methods for ClinicalImpressionInterface
|
||||||
|
CreateClinicalImpression(req model.ClinicalImpressionRequest) (map[string]interface{}, error)
|
||||||
|
UpdateClinicalImpression(req model.ClinicalImpressionRequest) (map[string]interface{}, error)
|
||||||
|
GetClinicalImpressionByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckClinicalImpression(id string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClinicalImpressionRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetClinicalImpressionByPatient implements ClinicalImppressionInterface.
|
||||||
|
func (c *ClinicalImpressionRepository) GetClinicalImpressionByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
url := c.akses.BaseUrl + "/ClinicalImpression?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckClinicalImpression implements ClinicalImppressionInterface.
|
||||||
|
func (c *ClinicalImpressionRepository) HandleCheckClinicalImpression(id string) ([]string, bool, error) {
|
||||||
|
clinical, err := c.GetClinicalImpressionByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := clinical["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (clinical)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateClinicalImpression implements ClinicalImppressionInterface.
|
||||||
|
func (c *ClinicalImpressionRepository) CreateClinicalImpression(req model.ClinicalImpressionRequest) (map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data map[string]interface{}
|
||||||
|
)
|
||||||
|
req.ResourceType = constant.ClinicalImpressionResourceType
|
||||||
|
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Setup Practitioner
|
||||||
|
// if req.Assessor.Reference != "" {
|
||||||
|
// practitionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
// practitionerId, _, err := practitionerInterface.HandleCheckPartitioner(req.Assessor.Reference)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// if practitionerId != "" {
|
||||||
|
// req.Assessor.Reference = "Practitioner/" + practitionerId
|
||||||
|
// } else {
|
||||||
|
// return nil, errors.New("practitioner not found")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if len(req.Investigation) > 0 {
|
||||||
|
//Setup Condition
|
||||||
|
if patient != "" {
|
||||||
|
conditionInterface := NewConditionRepo(c.akses)
|
||||||
|
conditionId, conditionExist, err := conditionInterface.HandleCheckCondition(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Problem = append(req.Problem, model.Reference{
|
||||||
|
Reference: "Condition/" + conditionId,
|
||||||
|
})
|
||||||
|
if !conditionExist {
|
||||||
|
return nil, errors.New("condition not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Observation
|
||||||
|
if patient != "" {
|
||||||
|
observationInterface := NewObservationRepo(c.akses)
|
||||||
|
observationId, observationExist, err := observationInterface.HandleCheckObservation(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, id := range observationId {
|
||||||
|
req.Investigation = append(req.Investigation, model.Investigation{
|
||||||
|
Item: []model.InvestigationItem{
|
||||||
|
{Reference: "Observation/" + id},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if !observationExist {
|
||||||
|
return nil, errors.New("observation not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/ClinicalImpression"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assuming the access token is stored in a field of the akses struct
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(c.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClinicalImpressionRepository) UpdateClinicalImpression(req model.ClinicalImpressionRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ClinicalImpressionResourceType
|
||||||
|
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Setup Practitioner
|
||||||
|
if req.Assessor.Reference != "" {
|
||||||
|
practitionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
practitionerId, _, err := practitionerInterface.HandleCheckPartitioner(req.Assessor.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if practitionerId != "" {
|
||||||
|
req.Assessor.Reference = "Practitioner/" + practitionerId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("practitioner not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Condition
|
||||||
|
if patient != "" {
|
||||||
|
conditionInterface := NewConditionRepo(c.akses)
|
||||||
|
conditionId, conditionExist, err := conditionInterface.HandleCheckCondition(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Problem = append(req.Problem, model.Reference{
|
||||||
|
Reference: "Condition/" + conditionId,
|
||||||
|
})
|
||||||
|
if !conditionExist {
|
||||||
|
return nil, errors.New("condition not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Observation
|
||||||
|
if patient != "" {
|
||||||
|
observationInterface := NewObservationRepo(c.akses)
|
||||||
|
observationId, observationExist, err := observationInterface.HandleCheckObservation(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, id := range observationId {
|
||||||
|
req.Investigation = append(req.Investigation, model.Investigation{
|
||||||
|
Item: []model.InvestigationItem{
|
||||||
|
{Reference: "Observation/" + id},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if !observationExist {
|
||||||
|
return nil, errors.New("observation not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/ClinicalImpression/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClinicalImpressionRepo(akses *model.Akses) ClinicalImppressionInterface {
|
||||||
|
return &ClinicalImpressionRepository{akses: akses}
|
||||||
|
}
|
||||||
835
internal/integration/composition_integration.go
Normal file
835
internal/integration/composition_integration.go
Normal file
@@ -0,0 +1,835 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CompositionInterface interface {
|
||||||
|
CreateComposition(req model.CompositionRequest) (map[string]interface{}, error)
|
||||||
|
UpdateComposition(req model.CompositionRequest) (map[string]interface{}, error)
|
||||||
|
GetCompositionByID(id string) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompositionRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateComposition implements CompositionInterface.
|
||||||
|
func (c *CompositionRepository) CreateComposition(req model.CompositionRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = "Composition"
|
||||||
|
req.Identifier = model.Identifier{
|
||||||
|
Use: "official",
|
||||||
|
System: "http://sys-ids.kemkes.go.id/composition/" + os.Getenv("ORGANIZATION_ID"),
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
}
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupOrganization(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// section setup
|
||||||
|
if req.Anamnesis == "" {
|
||||||
|
req.Anamnesis = "default anamnesis"
|
||||||
|
}
|
||||||
|
if req.PemeriksaanFisik == "" {
|
||||||
|
req.PemeriksaanFisik = "default pemeriksaan fisik"
|
||||||
|
}
|
||||||
|
if req.PemeriksaanPenunjang == "" {
|
||||||
|
req.PemeriksaanPenunjang = "default pemeriksaan penunjang"
|
||||||
|
}
|
||||||
|
if req.Medikamentosa == "" {
|
||||||
|
req.Medikamentosa = "default medikamentosa"
|
||||||
|
}
|
||||||
|
if req.LanjutanPenatalaksanaan == "" {
|
||||||
|
req.LanjutanPenatalaksanaan = "default lanjutan penatalaksanaan"
|
||||||
|
}
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Anamnesis",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000003",
|
||||||
|
Display: "Anamnesis",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.Anamnesis,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
allergyId := c.setupAllergyIntollerance(patient)
|
||||||
|
section := model.SectionRequest{
|
||||||
|
Title: "Riwayat Alergi",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "18776-5",
|
||||||
|
Display: "Riwayat Alergi",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if allergyId != "" {
|
||||||
|
section.Entry = []model.Reference{
|
||||||
|
{Reference: "AllergyIntolerance/" + allergyId},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.Section = append(req.Section, section)
|
||||||
|
|
||||||
|
/* Observation disabled for Now
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Pemeriksaan Fisik",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000007",
|
||||||
|
Display: "Pemeriksaan Fisik",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Section: []model.SectionRequest{
|
||||||
|
{
|
||||||
|
Title: "Tanda Vital",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "8716-3",
|
||||||
|
Display: "Vital signs",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: c.setupObservation(patient),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "Hasil Pemeriksaan",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000007",
|
||||||
|
Display: "Pemeriksaan Fisik",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.PemeriksaanFisik,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
var entry []model.Reference
|
||||||
|
clinicalId := c.setupClinicalImpression(patient)
|
||||||
|
goalId := c.setupGoal(patient)
|
||||||
|
carePlanId := c.setupCarePlan(patient)
|
||||||
|
|
||||||
|
if clinicalId != "" {
|
||||||
|
entry = append(entry, model.Reference{Reference: "ClinicalImpression/" + clinicalId})
|
||||||
|
}
|
||||||
|
if goalId != "" {
|
||||||
|
entry = append(entry, model.Reference{Reference: "Goal/" + goalId})
|
||||||
|
}
|
||||||
|
if carePlanId != "" {
|
||||||
|
entry = append(entry, model.Reference{Reference: "CarePlan/" + carePlanId})
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Perencanaan Perawatan",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "18776-5",
|
||||||
|
Display: "Plan of care note",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entry,
|
||||||
|
})
|
||||||
|
|
||||||
|
var entryLab, entryRad []model.Reference
|
||||||
|
serviceRequestIdLab := c.setupServiceRequestCategory(patient, "LAB")
|
||||||
|
specimenIdLab := c.setupSpecimenCategory(patient)
|
||||||
|
diagnosticReportIdLab := c.setupDiagnosticCategory(patient, "LAB")
|
||||||
|
observationIdLab := c.setupObservationCategory(patient, "LAB")
|
||||||
|
|
||||||
|
serviceRequestIdRad := c.setupServiceRequestCategory(patient, "RAD")
|
||||||
|
imagingStudyRad := c.setupImagingStudy(patient)
|
||||||
|
diagnosticReportIdRad := c.setupDiagnosticCategory(patient, "RAD")
|
||||||
|
observationIdRad := c.setupObservationCategory(patient, "RAD")
|
||||||
|
|
||||||
|
if serviceRequestIdLab != "" {
|
||||||
|
entryLab = append(entryLab, model.Reference{Reference: "ServiceRequest/" + serviceRequestIdLab})
|
||||||
|
}
|
||||||
|
if specimenIdLab != "" {
|
||||||
|
entryLab = append(entryLab, model.Reference{Reference: "Specimen/" + specimenIdLab})
|
||||||
|
}
|
||||||
|
if diagnosticReportIdLab != "" {
|
||||||
|
entryLab = append(entryLab, model.Reference{Reference: "DiagnosticReport/" + diagnosticReportIdLab})
|
||||||
|
}
|
||||||
|
if observationIdLab != "" {
|
||||||
|
entryLab = append(entryLab, model.Reference{Reference: "Observation/" + observationIdLab})
|
||||||
|
}
|
||||||
|
|
||||||
|
if serviceRequestIdRad != "" {
|
||||||
|
entryRad = append(entryRad, model.Reference{Reference: "ServiceRequest/" + serviceRequestIdRad})
|
||||||
|
}
|
||||||
|
if imagingStudyRad != "" {
|
||||||
|
entryRad = append(entryRad, model.Reference{Reference: "ImagingStudy/" + imagingStudyRad})
|
||||||
|
}
|
||||||
|
if diagnosticReportIdRad != "" {
|
||||||
|
entryRad = append(entryRad, model.Reference{Reference: "DiagnosticReport/" + diagnosticReportIdRad})
|
||||||
|
}
|
||||||
|
if observationIdRad != "" {
|
||||||
|
entryRad = append(entryRad, model.Reference{Reference: "Observation/" + observationIdRad})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(entryLab) != 0 && len(entryRad) != 0 {
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Pemeriksaan Penunjang",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000009",
|
||||||
|
Display: "Hasil Pemeriksaan Penunjang",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.PemeriksaanPenunjang,
|
||||||
|
},
|
||||||
|
Section: []model.SectionRequest{
|
||||||
|
{
|
||||||
|
Title: "Hasil Pemeriksaan Laboratorium",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "11502-2",
|
||||||
|
Display: "Laboratory report",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entryLab,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Title: "Hasil Pemeriksaan Radiologi",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "18782-3",
|
||||||
|
Display: "Radiology Study observation (narrative)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entryRad,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else if len(entryLab) != 0 && len(entryRad) == 0 {
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Pemeriksaan Penunjang",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000009",
|
||||||
|
Display: "Hasil Pemeriksaan Penunjang",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.PemeriksaanPenunjang,
|
||||||
|
},
|
||||||
|
Section: []model.SectionRequest{
|
||||||
|
{
|
||||||
|
Title: "Hasil Pemeriksaan Laboratorium",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "11502-2",
|
||||||
|
Display: "Laboratory report",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entryLab,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else if len(entryLab) == 0 && len(entryRad) != 0 {
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Pemeriksaan Penunjang",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000009",
|
||||||
|
Display: "Hasil Pemeriksaan Penunjang",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.PemeriksaanPenunjang,
|
||||||
|
},
|
||||||
|
Section: []model.SectionRequest{
|
||||||
|
{
|
||||||
|
Title: "Hasil Pemeriksaan Radiologi",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "18782-3",
|
||||||
|
Display: "Radiology Study observation (narrative)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entryRad,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var entryCondition []model.Reference
|
||||||
|
conditionId := c.setupCondition(patient)
|
||||||
|
if conditionId != "" {
|
||||||
|
entryCondition = append(entryCondition, model.Reference{Reference: "Condition/" + conditionId})
|
||||||
|
}
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Diagnosa",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000004",
|
||||||
|
Display: "Diagnosis",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Section: []model.SectionRequest{
|
||||||
|
{
|
||||||
|
Title: "Diagnosa Utama",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "78375-3",
|
||||||
|
Display: "Discharge diagnosis Narrative",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entryCondition,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
var entryProcedure []model.Reference
|
||||||
|
procedureId := c.setupProcedure(patient)
|
||||||
|
if procedureId != "" {
|
||||||
|
entryProcedure = append(entryProcedure, model.Reference{Reference: "Procedure/" + procedureId})
|
||||||
|
}
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Tindakan Operatif/Non Operatif Utama",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000005",
|
||||||
|
Display: "Tindakan/Prosedur Medis",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: entryProcedure,
|
||||||
|
})
|
||||||
|
var medication []model.Reference
|
||||||
|
medicationRequestId := c.setupMedicationRequest(patient)
|
||||||
|
if medicationRequestId != "" {
|
||||||
|
medication = append(medication, model.Reference{Reference: "MedicationRequest/" + medicationRequestId})
|
||||||
|
}
|
||||||
|
medicationDispenseId := c.setupMedicationDispense(patient)
|
||||||
|
if medicationDispenseId != "" {
|
||||||
|
medication = append(medication, model.Reference{Reference: "MedicationDispense/" + medicationDispenseId})
|
||||||
|
}
|
||||||
|
/* Farmasi section disabled for Now
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Farmasi",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id",
|
||||||
|
Code: "TK000013",
|
||||||
|
Display: "Obat",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Section: []model.SectionRequest{
|
||||||
|
/*{
|
||||||
|
Title: "Obat Saat Kunjungan",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "42346-7",
|
||||||
|
Display: "Medications on admission (narrative)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: []model.Reference{
|
||||||
|
{Reference: "MedicationAdministration/"},
|
||||||
|
{Reference: "MedicationRequest/"},
|
||||||
|
{Reference: "MedicationDispense/"},
|
||||||
|
},
|
||||||
|
},*/
|
||||||
|
/* {
|
||||||
|
Title: "Obat Pulang",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "75311-1",
|
||||||
|
Display: "Discharge medications Narrative",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Entry: medication,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Medikamentosa",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "18776-5",
|
||||||
|
Display: "Plan of treatment (narrative)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.Medikamentosa,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
req.Section = append(req.Section, model.SectionRequest{
|
||||||
|
Title: "Lanjutan Penatalaksanaan",
|
||||||
|
Code: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://loinc.org",
|
||||||
|
Code: "8653-8",
|
||||||
|
Display: "Hospital Discharge instructions",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: &model.SectionText{
|
||||||
|
Status: "additional",
|
||||||
|
Div: req.LanjutanPenatalaksanaan,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//remove field unused
|
||||||
|
req.Anamnesis = ""
|
||||||
|
req.PemeriksaanFisik = ""
|
||||||
|
req.PemeriksaanPenunjang = ""
|
||||||
|
req.Medikamentosa = ""
|
||||||
|
req.LanjutanPenatalaksanaan = ""
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
// b, err := json.MarshalIndent(req, "", " ")
|
||||||
|
// if err != nil {
|
||||||
|
// log.Println("error marshal:", err)
|
||||||
|
// } else {
|
||||||
|
// log.Println(string(b))
|
||||||
|
// }
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/Composition"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCompositionByID implements CompositionInterface.
|
||||||
|
func (c *CompositionRepository) GetCompositionByID(id string) (map[string]interface{}, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateComposition implements CompositionInterface.
|
||||||
|
func (c *CompositionRepository) UpdateComposition(req model.CompositionRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = "Composition"
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupOrganization(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
url := c.akses.BaseUrl + "/Composition/" + req.Id
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupPatient(req *model.CompositionRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupEncounter extracts encounter setup logic from CreateDiagnosisReport.
|
||||||
|
func (c *CompositionRepository) setupEncounter(req *model.CompositionRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
//Buat dulu encounter
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupOrganization(req *model.CompositionRequest) error {
|
||||||
|
|
||||||
|
req.Custodian.Reference = "Organization/" + os.Getenv("ORGANIZATION_ID")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupPractitioner(req *model.CompositionRequest) error {
|
||||||
|
if len(req.Author) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
practicionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
ref, display, err := practicionerInterface.HandleCheckPartitioner(req.Author[0].Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.Author[0].Reference = "Practitioner/" + ref
|
||||||
|
req.Author[0].Display = display
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupAllergyIntollerance(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
allergyInterface := NewAllergancyToleranRepo(c.akses)
|
||||||
|
allergyId, allergyExist, err := allergyInterface.HandleCheckAllergancyToleran(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if allergyExist {
|
||||||
|
return allergyId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupObservation(patient string) []model.Reference {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
observationInterface := NewObservationRepo(c.akses)
|
||||||
|
observationId, observationExist, err := observationInterface.HandleCheckObservation(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if observationExist {
|
||||||
|
var references []model.Reference
|
||||||
|
|
||||||
|
for _, id := range observationId {
|
||||||
|
references = append(references, model.Reference{Reference: "Observation/" + id})
|
||||||
|
}
|
||||||
|
return references
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupClinicalImpression(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
clinicalInterface := NewClinicalImpressionRepo(c.akses)
|
||||||
|
clinicalId, clinicalExist, err := clinicalInterface.HandleCheckClinicalImpression(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if clinicalExist {
|
||||||
|
return clinicalId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupGoal(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
goalInterface := NewGoalRepo(c.akses)
|
||||||
|
goalId, goalExist, err := goalInterface.HandleCheckGoal(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if goalExist {
|
||||||
|
return goalId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupCarePlan(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
careplanInterface := NewCarePlanRepo(c.akses)
|
||||||
|
careplanId, careplanExist, err := careplanInterface.HandleCheckCarePlan(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if careplanExist {
|
||||||
|
return careplanId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupServiceRequestCategory(patient string, category string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if category == "LAB" {
|
||||||
|
category = "108252007"
|
||||||
|
} else if category == "RAD" {
|
||||||
|
category = "363679005"
|
||||||
|
}
|
||||||
|
serviceRequestInterface := NewServiceRequestRepository(c.akses)
|
||||||
|
serviceRequestId, serviceRequestExist, err := serviceRequestInterface.HandleCheckServiceRequestByCategory(patient, category)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if serviceRequestExist {
|
||||||
|
return serviceRequestId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupSpecimenCategory(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
specimenInterface := NewSpecimenRepository(c.akses)
|
||||||
|
specimenId, specimenExist, err := specimenInterface.HandleCheckSpecimen(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if specimenExist {
|
||||||
|
return specimenId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupImagingStudy(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
imagingInterface := NewImagingStudyRepo(c.akses)
|
||||||
|
imagingId, imagingExist, err := imagingInterface.HandleCheckImagingStudy(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if imagingExist {
|
||||||
|
return imagingId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupObservationCategory(patient string, category string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if category == "LAB" {
|
||||||
|
category = "laboratory"
|
||||||
|
} else if category == "RAD" {
|
||||||
|
category = "imaging"
|
||||||
|
}
|
||||||
|
observationInterface := NewObservationRepo(c.akses)
|
||||||
|
observationId, observationExist, err := observationInterface.HandleCheckObservationCategory(patient, category)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if observationExist {
|
||||||
|
return observationId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupDiagnosticCategory(patient string, category string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if category == "LAB" {
|
||||||
|
category = "LAB"
|
||||||
|
} else if category == "RAD" {
|
||||||
|
category = "RAD"
|
||||||
|
}
|
||||||
|
observationInterface := NewObservationRepo(c.akses)
|
||||||
|
observationId, observationExist, err := observationInterface.HandleCheckObservationCategory(patient, category)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if observationExist {
|
||||||
|
return observationId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupCondition(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionInterface := NewConditionRepo(c.akses)
|
||||||
|
conditionId, conditionExist, err := conditionInterface.HandleCheckCondition(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if conditionExist {
|
||||||
|
return conditionId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupProcedure(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureInterface := NewProcedureRepo(c.akses)
|
||||||
|
procedureId, procedureExist, err := procedureInterface.HandleCheckProcedure(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if procedureExist {
|
||||||
|
return procedureId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupMedicationRequest(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
medicationRequestInterface := NewMedicationRequestRepo(c.akses)
|
||||||
|
medicationRequestId, medicationRequestExist, err := medicationRequestInterface.HandleCheckMedicationRequest(patient, "")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if medicationRequestExist {
|
||||||
|
return medicationRequestId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompositionRepository) setupMedicationDispense(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
medicationDispenseInterface := NewMedicationDispenseRepo(c.akses)
|
||||||
|
medicationDispenseId, medicationDispenseExist, err := medicationDispenseInterface.HandleCheckMedicationDispense(patient, "")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if medicationDispenseExist {
|
||||||
|
return medicationDispenseId[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCompositionRepo(akses *model.Akses) CompositionInterface {
|
||||||
|
return &CompositionRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
230
internal/integration/condition_integration.go
Normal file
230
internal/integration/condition_integration.go
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConditionInterface interface {
|
||||||
|
CreateCondition(request model.ConditionRequest) (map[string]interface{}, error)
|
||||||
|
GetConditionByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckCondition(id string) (string, bool, error)
|
||||||
|
UpdateCondition(request model.ConditionRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConditionRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckCondition implements ConditionInterface.
|
||||||
|
func (c *ConditionRepository) HandleCheckCondition(id string) (string, bool, error) {
|
||||||
|
condition, err := c.GetConditionByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can process 'encounter' here if needed
|
||||||
|
if entries, ok := condition["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (condition)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
return id, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConditionRepo(akses *model.Akses) ConditionInterface {
|
||||||
|
return &ConditionRepository{akses: akses}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement the ConditionInterface methods for ConditionRepository
|
||||||
|
func (c *ConditionRepository) CreateCondition(req model.ConditionRequest) (map[string]interface{}, error) {
|
||||||
|
// TODO: implement the logic here
|
||||||
|
var (
|
||||||
|
data map[string]interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
req.ClinicalStatus.Coding = append(req.ClinicalStatus.Coding, model.Coding{
|
||||||
|
System: "http://terminology.hl7.org/CodeSystem/condition-clinical",
|
||||||
|
Code: "active",
|
||||||
|
Display: "Active",
|
||||||
|
})
|
||||||
|
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/Condition"
|
||||||
|
method := "POST"
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(c.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ConditionRepository) GetConditionByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
// TODO: implement the logic here
|
||||||
|
var (
|
||||||
|
data map[string]interface{}
|
||||||
|
)
|
||||||
|
url := c.akses.BaseUrl + "/Condition?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(c.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ConditionRepository) UpdateCondition(req model.ConditionRequest) (map[string]interface{}, error) {
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/Condition/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
363
internal/integration/diagnosisreport_integration.go
Normal file
363
internal/integration/diagnosisreport_integration.go
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DiagnosisReportInterface interface {
|
||||||
|
// Define methods for DiagnosisReportInterface
|
||||||
|
CreateDiagnosisReport(req model.DiagnosticReportRequest) (map[string]interface{}, error)
|
||||||
|
GetDiagnosisReportByPatient(id string) (map[string]interface{}, error)
|
||||||
|
GetDiagnosisReportByPatientCategory(id string, category string) (map[string]interface{}, error)
|
||||||
|
HandleCheckDiagnosisReport(id string) (string, bool, error)
|
||||||
|
HandleCheckDiagnosisReportCategory(id string, category string) ([]string, bool, error)
|
||||||
|
UpdateDiagnosisReport(req model.DiagnosticReportRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
type DiagnosisReportRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDiagnosisReportByPatientCategory implements DiagnosisReportInterface.
|
||||||
|
func (d *DiagnosisReportRepository) GetDiagnosisReportByPatientCategory(id string, category string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := d.akses.BaseUrl + "/DiagnosticReport?subject=" + id + "&category=" + category
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: d.akses.ClientId,
|
||||||
|
ClientSecret: d.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(d.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckDiagnosisReportCategory implements DiagnosisReportInterface.
|
||||||
|
func (d *DiagnosisReportRepository) HandleCheckDiagnosisReportCategory(id string, category string) ([]string, bool, error) {
|
||||||
|
diagnosis, err := d.GetDiagnosisReportByPatientCategory(id, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := diagnosis["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (diagnosis)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDiagnosisReport implements DiagnosisReportInterface.
|
||||||
|
func (d *DiagnosisReportRepository) CreateDiagnosisReport(req model.DiagnosticReportRequest) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
req.ResourceType = constant.DiagnosticReportResourceType
|
||||||
|
req.Identifier = append(req.Identifier, model.Identifier{
|
||||||
|
Use: "official",
|
||||||
|
System: "http://sys-ids.kemkes.go.id/diagnostic/" + os.Getenv("ORGANIZATION_ID") + "/lab",
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
})
|
||||||
|
|
||||||
|
patient, err := d.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Performer
|
||||||
|
err = d.setupPractitioner(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = d.setupOrganization(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Result
|
||||||
|
err = d.setupObserver(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Specimen
|
||||||
|
err = d.setupSpecimen(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup BasedOn
|
||||||
|
|
||||||
|
url := d.akses.BaseUrl + "/DiagnosticReport"
|
||||||
|
method := "POST"
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: d.akses.ClientId,
|
||||||
|
ClientSecret: d.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(d.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDiagnosisReport implements DiagnosisReportInterface.
|
||||||
|
func (d *DiagnosisReportRepository) UpdateDiagnosisReport(req model.DiagnosticReportRequest) (map[string]interface{}, error) {
|
||||||
|
patient, err := d.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Performer
|
||||||
|
err = d.setupPractitioner(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = d.setupOrganization(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Result
|
||||||
|
err = d.setupObserver(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Specimen
|
||||||
|
err = d.setupSpecimen(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup BasedOn
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: d.akses.ClientId,
|
||||||
|
ClientSecret: d.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(d.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := d.akses.BaseUrl + fmt.Sprintf("/DiagnosticReport/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPatient extracts patient setup logic from CreateDiagnosisReport.
|
||||||
|
func (d *DiagnosisReportRepository) setupPatient(req *model.DiagnosticReportRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(d.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupEncounter extracts encounter setup logic from CreateDiagnosisReport.
|
||||||
|
func (d *DiagnosisReportRepository) setupEncounter(req *model.DiagnosticReportRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(d.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
//Buat dulu encounter
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiagnosisReportRepository) setupSpecimen(req *model.DiagnosticReportRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
specimenInterface := NewSpecimenRepository(d.akses)
|
||||||
|
ids, exist, err := specimenInterface.HandleCheckSpecimen(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exist {
|
||||||
|
for i := range req.Specimen {
|
||||||
|
req.Specimen[i].Reference = "Specimen/" + ids[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiagnosisReportRepository) setupBasedOn(req *model.DiagnosticReportRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
basedOnInterface := NewServiceRequestRepository(d.akses)
|
||||||
|
ids, exist, err := basedOnInterface.HandleCheckServiceRequest(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exist {
|
||||||
|
for i := range req.BasedOn {
|
||||||
|
req.BasedOn[i].Reference = "ServiceRequest/" + ids[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDiagnosisReportByPatient implements DiagnosisReportInterface.
|
||||||
|
func (d *DiagnosisReportRepository) GetDiagnosisReportByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckDiagnosisReport implements DiagnosisReportInterface.
|
||||||
|
func (d *DiagnosisReportRepository) HandleCheckDiagnosisReport(id string) (string, bool, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (d *DiagnosisReportRepository) setupPractitioner(req *model.DiagnosticReportRequest) error {
|
||||||
|
if len(req.Performer) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, performer := range req.Performer {
|
||||||
|
if strings.Contains(performer.Reference, "Practitioner/") {
|
||||||
|
temp := strings.Split(performer.Reference, "/")
|
||||||
|
practicionerInterface := NewPracticionerRepo(d.akses)
|
||||||
|
ref, _, err := practicionerInterface.HandleCheckPartitioner(temp[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
performer.Reference = "Practitioner/" + ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiagnosisReportRepository) setupOrganization(req *model.DiagnosticReportRequest) error {
|
||||||
|
if len(req.Performer) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, performer := range req.Performer {
|
||||||
|
if strings.Contains(performer.Reference, "Organization/") {
|
||||||
|
performer.Reference = "Organization/" + os.Getenv("ORGANIZATION_ID")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiagnosisReportRepository) setupObserver(req *model.DiagnosticReportRequest, patient string) error {
|
||||||
|
observerInterface := NewObservationRepo(d.akses)
|
||||||
|
//temp := strings.Split(req.Subject.Reference, "/")
|
||||||
|
ids, valid, err := observerInterface.HandleCheckObservation(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(ids) > 0 && valid {
|
||||||
|
for _, id := range ids {
|
||||||
|
req.Result = append(req.Result, model.Reference{Reference: "Observation/" + id})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDiagnosisReportRepo(akses *model.Akses) DiagnosisReportInterface {
|
||||||
|
return &DiagnosisReportRepository{akses: akses}
|
||||||
|
}
|
||||||
183
internal/integration/encounter_integration.go
Normal file
183
internal/integration/encounter_integration.go
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EncounterInterface interface {
|
||||||
|
// Define methods for encounter integration
|
||||||
|
CreateEncounter(req model.EncounterRequest) (map[string]interface{}, error)
|
||||||
|
GetEncounterByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckEncounter(patientID string) (string, bool, error)
|
||||||
|
UpdateEncounter(req model.EncounterUpdateRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EncounterRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckEncounter implements EncounterInterface.
|
||||||
|
func (e *EncounterRepository) HandleCheckEncounter(patientID string) (string, bool, error) {
|
||||||
|
encounter, err := e.GetEncounterByPatient(patientID)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can process 'encounter' here if needed
|
||||||
|
if entries, ok := encounter["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (encounter)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
return id, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEncounterByPatient implements EncounterInterface.
|
||||||
|
func (e *EncounterRepository) GetEncounterByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data *map[string]interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
url := e.akses.BaseUrl + "/Encounter?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: e.akses.ClientId,
|
||||||
|
ClientSecret: e.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(e.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("failed to get encounter by patient: " + res.Status)
|
||||||
|
}
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if data == nil {
|
||||||
|
return nil, errors.New("no encounter found for patient")
|
||||||
|
}
|
||||||
|
return *data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEncounterRepo(akses *model.Akses) EncounterInterface {
|
||||||
|
return &EncounterRepository{akses: akses}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateEncounter implements EncounterInterface.
|
||||||
|
func (e *EncounterRepository) CreateEncounter(req model.EncounterRequest) (map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data *map[string]interface{}
|
||||||
|
)
|
||||||
|
req.ResourceType = constant.EncounterResourceType
|
||||||
|
req.Identifier = append(req.Identifier, model.IdentifierEncounter{
|
||||||
|
System: "http://sys-ids.kemkes.go.id/encounter/" + os.Getenv("ORGANIZATION_ID"),
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
})
|
||||||
|
|
||||||
|
req.ServiceProvider.Reference = "Organization/" + os.Getenv("ORGANIZATION_ID")
|
||||||
|
|
||||||
|
url := e.akses.BaseUrl + "/Encounter"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: e.akses.ClientId,
|
||||||
|
ClientSecret: e.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(e.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEncounter implements EncounterInterface.
|
||||||
|
func (e *EncounterRepository) UpdateEncounter(req model.EncounterUpdateRequest) (map[string]interface{}, error) {
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: e.akses.ClientId,
|
||||||
|
ClientSecret: e.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(e.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := e.akses.BaseUrl + fmt.Sprintf("/Encounter/%s", req.ID)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
353
internal/integration/episodeofcare_integration.go
Normal file
353
internal/integration/episodeofcare_integration.go
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EpisodeOfCareInterface interface {
|
||||||
|
// Define methods for EpisodeOfCareInterface
|
||||||
|
CreateEpisodeOfCare(req model.EpisodeOfCareRequest) (map[string]interface{}, error)
|
||||||
|
GetEpisodeOfCareByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckEpisodeOfCare(id string) ([]string, bool, error)
|
||||||
|
UpdateEpisodeOfCare(req model.EpisodeOfCareRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EpisodeOfCareRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateEpisodeOfCare implements EpisodeOfCareInterface.
|
||||||
|
func (e *EpisodeOfCareRepository) CreateEpisodeOfCare(req model.EpisodeOfCareRequest) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
req.ResourceType = constant.EpisodeOfCareResourceType
|
||||||
|
req.Identifier = []model.Identifier{
|
||||||
|
{
|
||||||
|
System: "http://sys-ids.kemkes.go.id/episode-of-care/" + os.Getenv("ORGANIZATION_ID"),
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Patient.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(e.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Patient.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if patient != "" {
|
||||||
|
req.Patient.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Organization
|
||||||
|
req.ManagingOrganization.Reference = "Organization/" + os.Getenv("ORGANIZATION_ID")
|
||||||
|
req.ManagingOrganization.Display = os.Getenv("ORGANIZATION_NAME")
|
||||||
|
|
||||||
|
var conditionReference model.Reference
|
||||||
|
condition := e.setupCondition(patient)
|
||||||
|
if condition != "" {
|
||||||
|
conditionReference = model.Reference{
|
||||||
|
Reference: "Condition/" + condition,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("condition not found for the patient")
|
||||||
|
}
|
||||||
|
req.Diagnosis = append(req.Diagnosis, model.Diagnosis{
|
||||||
|
Condition: conditionReference,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Setup CareManager
|
||||||
|
// if req.CareManager.Reference != "" {
|
||||||
|
// careManagerInterface := NewPracticionerRepo(e.akses)
|
||||||
|
// careManagerId, _, err := careManagerInterface.HandleCheckPartitioner(req.CareManager.Reference)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// req.CareManager.Reference = "Practitioner/" + careManagerId
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Setup Type
|
||||||
|
url := e.akses.BaseUrl + "/EpisodeOfCare"
|
||||||
|
method := "POST"
|
||||||
|
jsonData, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: e.akses.ClientId,
|
||||||
|
ClientSecret: e.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(e.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
if err := json.NewDecoder(response.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasOperationOutcomeIssue(data) {
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(e.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
data["encounter"] = map[string]interface{}{
|
||||||
|
"reference": "Encounter/" + encounterId,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEpisodeOfCareByPatient implements EpisodeOfCareInterface.
|
||||||
|
func (e *EpisodeOfCareRepository) GetEpisodeOfCareByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
// Validate the patient ID
|
||||||
|
if id == "" {
|
||||||
|
return nil, errors.New("patient ID cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the URL with query parameters
|
||||||
|
url := e.akses.BaseUrl + "/EpisodeOfCare?patient=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: e.akses.ClientId,
|
||||||
|
ClientSecret: e.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(e.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
if err := json.NewDecoder(response.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckEpisodeOfCare implements EpisodeOfCareInterface.
|
||||||
|
func (e *EpisodeOfCareRepository) HandleCheckEpisodeOfCare(id string) ([]string, bool, error) {
|
||||||
|
eoc, err := e.GetEpisodeOfCareByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can process 'eoc' here if needed
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := eoc["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (eoc)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EpisodeOfCareRepository) UpdateEpisodeOfCare(req model.EpisodeOfCareRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.EpisodeOfCareResourceType
|
||||||
|
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Patient.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(e.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Patient.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if patient != "" {
|
||||||
|
req.Patient.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Organization
|
||||||
|
if req.ManagingOrganization.Reference != "" {
|
||||||
|
orgInterface := NewOrganizationRepo(e.akses)
|
||||||
|
orgName, _, err := orgInterface.HandleCheckOrganization(req.ManagingOrganization.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.ManagingOrganization.Reference = "Organization/" + req.ManagingOrganization.Reference
|
||||||
|
req.ManagingOrganization.Display = orgName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get id existing EpisodeOfCare
|
||||||
|
data, err := e.setupPutEpisodeOfCare(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data["entry"].([]interface{})) == 0 {
|
||||||
|
return nil, errors.New("episode of care not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup CareManager
|
||||||
|
// if req.CareManager.Reference != "" {
|
||||||
|
// careManagerInterface := NewPracticionerRepo(e.akses)
|
||||||
|
// careManagerId, _, err := careManagerInterface.HandleCheckPartitioner(req.CareManager.Reference)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// req.CareManager.Reference = "Practitioner/" + careManagerId
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Setup Type
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: e.akses.ClientId,
|
||||||
|
ClientSecret: e.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(e.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := e.akses.BaseUrl + fmt.Sprintf("/EpisodeOfCare/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func (e *EpisodeOfCareRepository) setupCondition(patient string) string {
|
||||||
|
if patient == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionInterface := NewConditionRepo(e.akses)
|
||||||
|
conditionId, conditionExist, err := conditionInterface.HandleCheckCondition(patient)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if conditionExist {
|
||||||
|
return conditionId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EpisodeOfCareRepository) setupPutEpisodeOfCare(req *model.EpisodeOfCareRequest, patient string) (map[string]interface{}, error) {
|
||||||
|
data, err := e.GetEpisodeOfCareByPatient(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if entries, ok := data["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (data)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
req.Id = id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasOperationOutcomeIssue returns true when the response is an OperationOutcome
|
||||||
|
// with at least one issue that includes diagnostics or details.text.
|
||||||
|
func hasOperationOutcomeIssue(resp map[string]interface{}) bool {
|
||||||
|
if resp == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
rt, ok := resp["resourceType"].(string)
|
||||||
|
if !ok || rt != "OperationOutcome" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
issues, ok := resp["issue"].([]interface{})
|
||||||
|
if !ok || len(issues) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, it := range issues {
|
||||||
|
m, ok := it.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if diag, _ := m["diagnostics"].(string); diag != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if details, ok := m["details"].(map[string]interface{}); ok {
|
||||||
|
if txt, _ := details["text"].(string); txt != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEpisodeOfCareRepo(akses *model.Akses) EpisodeOfCareInterface {
|
||||||
|
return &EpisodeOfCareRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
221
internal/integration/goal_integration.go
Normal file
221
internal/integration/goal_integration.go
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoalInterface interface {
|
||||||
|
// Define methods for GoalInterface
|
||||||
|
CreateGoal(req model.GoalRequest) (map[string]interface{}, error)
|
||||||
|
UpdateGoal(req model.GoalRequest) (map[string]interface{}, error)
|
||||||
|
GetGoalByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckGoal(id string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoalRepository struct {
|
||||||
|
// Define fields for GoalRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGoalByPatient implements GoalInterface.
|
||||||
|
func (c *GoalRepository) GetGoalByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/Goal?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckGoal implements GoalInterface.
|
||||||
|
func (c *GoalRepository) HandleCheckGoal(id string) ([]string, bool, error) {
|
||||||
|
goal, err := c.GetGoalByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := goal["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (goal)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGoalRepo(akses *model.Akses) GoalInterface {
|
||||||
|
return &GoalRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateGoal implements GoalInterface.
|
||||||
|
func (c *GoalRepository) CreateGoal(req model.GoalRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.GoalResourceType
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/Goal"
|
||||||
|
|
||||||
|
data, err := httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isOperationOutcomeError(data) {
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
data["encounter"] = map[string]interface{}{
|
||||||
|
"reference": "Encounter/" + encounterId,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GoalRepository) UpdateGoal(req model.GoalRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.GoalResourceType
|
||||||
|
|
||||||
|
_, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/Goal/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GoalRepository) setupPatient(req *model.GoalRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (c *GoalRepository) setupPractitioner(req *model.GoalRequest) error {
|
||||||
|
if req.ExpressedBy.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
practicionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
ref, display, err := practicionerInterface.HandleCheckPartitioner(req.ExpressedBy.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.ExpressedBy.Reference = "Practitioner/" + ref
|
||||||
|
req.ExpressedBy.Display = display
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
284
internal/integration/imagingstudy_integration.go
Normal file
284
internal/integration/imagingstudy_integration.go
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImagingStudyInterface interface {
|
||||||
|
// Define methods for ImagingStudyInterface
|
||||||
|
CreateImagingStudy(req model.ImagingStudyRequest) (map[string]interface{}, error)
|
||||||
|
UpdateImagingStudy(req model.ImagingStudyRequest) (map[string]interface{}, error)
|
||||||
|
GetImagingStudyByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckImagingStudy(id string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagingStudyRepository struct {
|
||||||
|
// Define fields for ImagingStudyRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImagingStudyRepo(akses *model.Akses) ImagingStudyInterface {
|
||||||
|
return &ImagingStudyRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImagingStudyByPatient implements ImagingStudyInterface.
|
||||||
|
func (c *ImagingStudyRepository) GetImagingStudyByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/ImagingStudy?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckImagingStudy implements ImagingStudyInterface.
|
||||||
|
func (c *ImagingStudyRepository) HandleCheckImagingStudy(id string) ([]string, bool, error) {
|
||||||
|
imaging, err := c.GetImagingStudyByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := imaging["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (imaging)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImagingStudy implements ImagingStudyInterface.
|
||||||
|
func (c *ImagingStudyRepository) CreateImagingStudy(req model.ImagingStudyRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ImagingStudyResourceType
|
||||||
|
|
||||||
|
if len(req.Identifier) > 0 {
|
||||||
|
identifier := []model.Identifier{}
|
||||||
|
for k, i := range req.Identifier {
|
||||||
|
if k == 0 {
|
||||||
|
identifier = append(identifier, model.Identifier{
|
||||||
|
Use: "official",
|
||||||
|
System: "http://sys-ids.kemkes.go.id/acsn/" + os.Getenv("ORGANIZATION_ID"), // Set this if needed, or remove if not present in IdentifierObject
|
||||||
|
Value: i.Value,
|
||||||
|
Type: &model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.hl7.org/CodeSystem/v2-0203",
|
||||||
|
Code: "ACSN",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// if k == 1 {
|
||||||
|
// identifier = append(identifier, model.Identifier{
|
||||||
|
// System: "urn:dicom:uid",
|
||||||
|
// Value: i.Value,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
req.Identifier = identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Service Request
|
||||||
|
err = c.setupServiceRequest(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/ImagingStudy"
|
||||||
|
data, err := httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isOperationOutcomeError(data) {
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
data["encounter"] = map[string]interface{}{
|
||||||
|
"reference": "Encounter/" + encounterId,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ImagingStudyRepository) UpdateImagingStudy(req model.ImagingStudyRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ImagingStudyResourceType
|
||||||
|
|
||||||
|
if len(req.Identifier) > 0 {
|
||||||
|
identifier := []model.Identifier{}
|
||||||
|
for k, i := range req.Identifier {
|
||||||
|
if k == 0 {
|
||||||
|
identifier = append(identifier, model.Identifier{
|
||||||
|
Use: "official",
|
||||||
|
System: "http://sys-ids.kemkes.go.id/acsn/" + os.Getenv("ORGANIZATION_ID"), // Set this if needed, or remove if not present in IdentifierObject
|
||||||
|
Value: i.Value,
|
||||||
|
Type: &model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.hl7.org/CodeSystem/v2-0203",
|
||||||
|
Code: "ACSN",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// if k == 1 {
|
||||||
|
// identifier = append(identifier, model.Identifier{
|
||||||
|
// System: "urn:dicom:uid",
|
||||||
|
// Value: i.Value,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
req.Identifier = identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Service Request
|
||||||
|
err = c.setupServiceRequest(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/ImagingStudy/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ImagingStudyRepository) setupPatient(req *model.ImagingStudyRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ImagingStudyRepository) setupServiceRequest(req *model.ImagingStudyRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
serviceReq := NewServiceRequestRepository(c.akses)
|
||||||
|
ids, _, err := serviceReq.HandleCheckServiceRequest(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(ids) > 0 {
|
||||||
|
req.BasedOn = []model.Reference{
|
||||||
|
{
|
||||||
|
Reference: "ServiceRequest/" + ids[0],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
130
internal/integration/immunization_integration.go
Normal file
130
internal/integration/immunization_integration.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImmunizationInterface interface {
|
||||||
|
// Define methods for ImmunizationInterface
|
||||||
|
CreateImmunization(req model.ImmunizationRequest) (map[string]interface{}, error)
|
||||||
|
UpdateImmunization(req model.ImmunizationRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImmunizationRepository struct {
|
||||||
|
// Define fields for ImmunizationRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImmunizationRepo(akses *model.Akses) ImmunizationInterface {
|
||||||
|
return &ImmunizationRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImmunization implements ImmunizationInterface.
|
||||||
|
func (c *ImmunizationRepository) CreateImmunization(req model.ImmunizationRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ImmunizationResourceType
|
||||||
|
//setup primarySource default true karena vaksin bersumber dari orang yg melakukan vaksin
|
||||||
|
req.PrimarySource = true
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/Immunization"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ImmunizationRepository) UpdateImmunization(req model.ImmunizationRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ImmunizationResourceType
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/Immunization/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ImmunizationRepository) setupPatient(req *model.ImmunizationRequest) (string, error) {
|
||||||
|
if req.Patient.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Patient.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Patient.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ImmunizationRepository) setupEncounter(req *model.ImmunizationRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
240
internal/integration/medicationdispense_integration.go
Normal file
240
internal/integration/medicationdispense_integration.go
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicationDispenseInterface interface {
|
||||||
|
// Define methods for MedicationDispenseInterface
|
||||||
|
CreateMedicationDispense(req model.MedicationDispenseRequest) (map[string]interface{}, error)
|
||||||
|
UpdateMedicationDispense(req model.MedicationDispenseRequest) (map[string]interface{}, error)
|
||||||
|
GetMedicationDispenseByPatient(id string, category string) (map[string]interface{}, error)
|
||||||
|
HandleCheckMedicationDispense(id string, category string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationDispenseRepository struct {
|
||||||
|
// Define fields for MedicationDispenseRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicationDispenseRepo(akses *model.Akses) MedicationDispenseInterface {
|
||||||
|
return &MedicationDispenseRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMedicationDispenseByPatient implements MedicationDispenseInterface.
|
||||||
|
func (c *MedicationDispenseRepository) GetMedicationDispenseByPatient(id string, category string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/MedicationDispense?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil,
|
||||||
|
err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckMedicationDispense implements MedicationDispenseInterface.
|
||||||
|
func (c *MedicationDispenseRepository) HandleCheckMedicationDispense(id string, category string) ([]string, bool, error) {
|
||||||
|
medicationDispense, err := c.GetMedicationDispenseByPatient(id, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := medicationDispense["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (medicationDispense)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMedicationDispense implements MedicationDispenseInterface.
|
||||||
|
func (c *MedicationDispenseRepository) CreateMedicationDispense(req model.MedicationDispenseRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.MedicationDispenseResourceType
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("prescription"))
|
||||||
|
identifierItem := common.GetIdentifier("prescription-item")
|
||||||
|
identifierItem.Value += "-1"
|
||||||
|
req.Identifier = append(req.Identifier, identifierItem)
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/MedicationDispense"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationDispenseRepository) UpdateMedicationDispense(req model.MedicationDispenseRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.MedicationDispenseResourceType
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("prescription"))
|
||||||
|
identifierItem := common.GetIdentifier("prescription-item")
|
||||||
|
identifierItem.Value += "-1"
|
||||||
|
req.Identifier = append(req.Identifier, identifierItem)
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/MedicationDispense/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationDispenseRepository) setupPatient(req *model.MedicationDispenseRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationDispenseRepository) setupEncounter(req *model.MedicationDispenseRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Context.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (c *MedicationDispenseRepository) setupPractitioner(req *model.MedicationDispenseRequest) error {
|
||||||
|
if len(req.Performer) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, performer := range req.Performer {
|
||||||
|
if strings.Contains(performer.Actor.Reference, "Practitioner/") {
|
||||||
|
temp := strings.Split(performer.Actor.Reference, "/")
|
||||||
|
practicionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
ref, _, err := practicionerInterface.HandleCheckPartitioner(temp[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.Performer[k].Actor.Reference = "Practitioner/" + ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
260
internal/integration/medicationrequest_integration.go
Normal file
260
internal/integration/medicationrequest_integration.go
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicationRequestInterface interface {
|
||||||
|
// Define methods for MedicationRequestInterface
|
||||||
|
CreateMedicationRequest(req model.MedicationRequestRequest) (map[string]interface{}, error)
|
||||||
|
UpdateMedicationRequest(req model.MedicationRequestRequest) (map[string]interface{}, error)
|
||||||
|
GetMedicationRequestByPatient(id string, category string) (map[string]interface{}, error)
|
||||||
|
HandleCheckMedicationRequest(id string, category string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationRequestRepository struct {
|
||||||
|
// Define fields for MedicationRequestRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicationRequestRepo(akses *model.Akses) MedicationRequestInterface {
|
||||||
|
return &MedicationRequestRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMedicationRequestByPatient implements MedicationRequestInterface.
|
||||||
|
func (c *MedicationRequestRepository) GetMedicationRequestByPatient(id string, category string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/MedicationRequest?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckMedicationRequest implements MedicationRequestInterface.
|
||||||
|
func (c *MedicationRequestRepository) HandleCheckMedicationRequest(id string, category string) ([]string, bool, error) {
|
||||||
|
medicationReq, err := c.GetMedicationRequestByPatient(id, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := medicationReq["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (medicationReq)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMedicationRequest implements MedicationRequestInterface.
|
||||||
|
func (c *MedicationRequestRepository) CreateMedicationRequest(req model.MedicationRequestRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.MedicationRequestResourceType
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("prescription"))
|
||||||
|
identifierItem := common.GetIdentifier("prescription-item")
|
||||||
|
identifierItem.Value += "-1"
|
||||||
|
req.Identifier = append(req.Identifier, identifierItem)
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupMedication(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.DispenseRequest.Performer.Reference = "Organization/" + os.Getenv("ORGANIZATION_ID")
|
||||||
|
|
||||||
|
req.MedicationRequest = nil
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/MedicationRequest"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationRequestRepository) UpdateMedicationRequest(req model.MedicationRequestRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.MedicationRequestResourceType
|
||||||
|
req.Identifier = append(req.Identifier, common.GetIdentifier("prescription"))
|
||||||
|
identifierItem := common.GetIdentifier("prescription-item")
|
||||||
|
identifierItem.Value += "-1"
|
||||||
|
req.Identifier = append(req.Identifier, identifierItem)
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/MedicationRequest/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationRequestRepository) setupPatient(req *model.MedicationRequestRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationRequestRepository) setupEncounter(req *model.MedicationRequestRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (c *MedicationRequestRepository) setupPractitioner(req *model.MedicationRequestRequest) error {
|
||||||
|
if req.Requester.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
practicionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
ref, display, err := practicionerInterface.HandleCheckPartitioner(req.Requester.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.Requester.Reference = "Practitioner/" + ref
|
||||||
|
req.Requester.Display = display
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationRequestRepository) setupMedication(req *model.MedicationRequestRequest) error {
|
||||||
|
if req.MedicationRequest == nil {
|
||||||
|
return errors.New("Need Medication Request")
|
||||||
|
}
|
||||||
|
MedicationInterface := NewMedicineKfaRepo(c.akses)
|
||||||
|
medication, err := MedicationInterface.MedicationCreate(*req.MedicationRequest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if idRaw, ok := medication["id"].(string); ok {
|
||||||
|
if idRaw == "" {
|
||||||
|
return errors.New("medication id is empty")
|
||||||
|
}
|
||||||
|
req.MedicationReference.Reference = "Medication/" + idRaw
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
173
internal/integration/medicationstatement_integration.go
Normal file
173
internal/integration/medicationstatement_integration.go
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/common"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicationStatementInterface interface {
|
||||||
|
// Define methods for MedicationStatementInterface
|
||||||
|
CreateMedicationStatement(req model.MedicationStatementRequest) (map[string]interface{}, error)
|
||||||
|
UpdateMedicationStatement(req model.MedicationStatementRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationStatementRepository struct {
|
||||||
|
// Define fields for MedicationStatementRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicationStatementRepo(akses *model.Akses) MedicationStatementInterface {
|
||||||
|
return &MedicationStatementRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMedicationStatement implements MedicationStatementInterface.
|
||||||
|
func (c *MedicationStatementRepository) CreateMedicationStatement(req model.MedicationStatementRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.MedicationStatementResourceType
|
||||||
|
|
||||||
|
// inject identifier to contained
|
||||||
|
if len(req.Contained) > 0 {
|
||||||
|
for k, c := range req.Contained {
|
||||||
|
identifier := common.GetIdentifier("medication")
|
||||||
|
identifier.Value = c.ID
|
||||||
|
req.Contained[k].Identifier = append(req.Contained[k].Identifier, identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupSource(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/MedicationStatement"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationStatementRepository) UpdateMedicationStatement(req model.MedicationStatementRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.MedicationStatementResourceType
|
||||||
|
|
||||||
|
// inject identifier to contained
|
||||||
|
if len(req.Contained) > 0 {
|
||||||
|
for k, c := range req.Contained {
|
||||||
|
identifier := common.GetIdentifier("medication")
|
||||||
|
identifier.Value = c.ID
|
||||||
|
req.Contained[k].Identifier = append(req.Contained[k].Identifier, identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupSource(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/MedicationStatement/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationStatementRepository) setupPatient(req *model.MedicationStatementRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationStatementRepository) setupSource(req *model.MedicationStatementRequest) error {
|
||||||
|
if req.InformationSource.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.InformationSource.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.InformationSource.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MedicationStatementRepository) setupEncounter(req *model.MedicationStatementRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Context.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
196
internal/integration/medicine_integration.go
Normal file
196
internal/integration/medicine_integration.go
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MedicineIntegrationInterface interface {
|
||||||
|
GetMedicineKfa(req model.MedicineKfaRequest) ([]model.MedicineKfaResponse, error)
|
||||||
|
MedicationCreate(req model.MedicationRequest) (map[string]interface{}, error)
|
||||||
|
GetMedicineByKfaCode(kfaCode string) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicineKfaRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMedicineByKfaCode implements MedicineIntegrationInterface.
|
||||||
|
func (m *MedicineKfaRepository) GetMedicineByKfaCode(kfaCode string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
url := m.akses.KfaUrl + "/products"
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
|
||||||
|
// Assuming the access token is stored in a field of the akses struct
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: m.akses.ClientId,
|
||||||
|
ClientSecret: m.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(m.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
q := request.URL.Query()
|
||||||
|
q.Add("code", kfaCode)
|
||||||
|
q.Add("identifier", "kfa")
|
||||||
|
request.URL.RawQuery = q.Encode()
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MedicationCreate implements MedicineIntegrationInterface.
|
||||||
|
func (m *MedicineKfaRepository) MedicationCreate(req model.MedicationRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = "Medication"
|
||||||
|
req.Meta = model.Meta{
|
||||||
|
Profile: []string{constant.FHIRMedicationProfile},
|
||||||
|
}
|
||||||
|
req.Identifier = []model.Identifier{
|
||||||
|
{
|
||||||
|
System: "http://sys-ids.kemkes.go.id/medication/" + os.Getenv("ORGANIZATION_ID"),
|
||||||
|
Value: os.Getenv("ORGANIZATION_ID"),
|
||||||
|
Use: "official",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
req.Manufacturer = model.Reference{
|
||||||
|
Reference: "Organization/" + os.Getenv("ORGANIZATION_ID"),
|
||||||
|
}
|
||||||
|
req.Extension = []model.ExtensionMedication{
|
||||||
|
{
|
||||||
|
URL: "https://fhir.kemkes.go.id/r4/StructureDefinition/MedicationType",
|
||||||
|
ValueCodeableConcept: model.CodeableConcept{
|
||||||
|
Coding: []model.Coding{
|
||||||
|
{
|
||||||
|
System: "http://terminology.kemkes.go.id/CodeSystem/medication-type",
|
||||||
|
Code: "NC",
|
||||||
|
Display: "Non-compound",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := m.akses.BaseUrl + "/Medication"
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: m.akses.ClientId,
|
||||||
|
ClientSecret: m.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(m.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMedicineKfa implements MedicineIntegrationInterface.
|
||||||
|
func (m *MedicineKfaRepository) GetMedicineKfa(req model.MedicineKfaRequest) ([]model.MedicineKfaResponse, error) {
|
||||||
|
var (
|
||||||
|
data map[string]interface{}
|
||||||
|
)
|
||||||
|
url := m.akses.KfaUrl + "/products/all"
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
|
||||||
|
// Assuming the access token is stored in a field of the akses struct
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: m.akses.ClientId,
|
||||||
|
ClientSecret: m.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(m.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
q := request.URL.Query()
|
||||||
|
q.Add("page", strconv.Itoa(req.Page))
|
||||||
|
q.Add("size", strconv.Itoa(req.Size))
|
||||||
|
q.Add("product_type", req.ProdustType)
|
||||||
|
q.Add("keyword", req.Keyword)
|
||||||
|
request.URL.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("failed to fetch data: " + res.Status)
|
||||||
|
}
|
||||||
|
var response []model.MedicineKfaResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if items, ok := data["items"].(map[string]interface{}); ok {
|
||||||
|
for _, item := range items {
|
||||||
|
if itemMap, ok := item.([]interface{}); ok {
|
||||||
|
for _, med := range itemMap {
|
||||||
|
if medMap, ok := med.(map[string]interface{}); ok {
|
||||||
|
medicine := model.MedicineKfaResponse{
|
||||||
|
Name: medMap["name"].(string),
|
||||||
|
KfaCode: medMap["kfa_code"].(string),
|
||||||
|
}
|
||||||
|
response = append(response, medicine)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("invalid item format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("invalid response format")
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMedicineKfaRepo(akses *model.Akses) MedicineIntegrationInterface {
|
||||||
|
return &MedicineKfaRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
54
internal/integration/oauth_integration.go
Normal file
54
internal/integration/oauth_integration.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OauthInterface interface {
|
||||||
|
GenerateToken(req model.OauthRequest) (*model.OauthResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type OauthRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateToken implements OauthInterface.
|
||||||
|
func (o *OauthRepository) GenerateToken(req model.OauthRequest) (*model.OauthResponse, error) {
|
||||||
|
var (
|
||||||
|
data *model.OauthResponse
|
||||||
|
)
|
||||||
|
url := o.akses.AuthUrl + "/accesstoken?grant_type=client_credentials"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
req_data := "client_id=" + req.ClientId + "&client_secret=" + req.ClientSecret
|
||||||
|
payload := strings.NewReader(req_data)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, payload)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOauthRequestRepo(akses *model.Akses) OauthInterface {
|
||||||
|
return &OauthRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
382
internal/integration/observation_intergration.go
Normal file
382
internal/integration/observation_intergration.go
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ObservationInterface interface {
|
||||||
|
CreateObservation(req model.ObservationRequest) (map[string]interface{}, error)
|
||||||
|
GetObservationByPatient(id string) (map[string]interface{}, error)
|
||||||
|
GetObservationByPatientCategory(id string, category string) (map[string]interface{}, error)
|
||||||
|
HandleCheckObservation(id string) ([]string, bool, error)
|
||||||
|
HandleCheckObservationCategory(id string, category string) ([]string, bool, error)
|
||||||
|
UpdateObservation(req model.ObservationRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ObservationRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObservationByPatientCategory implements ObservationInterface.
|
||||||
|
func (o *ObservationRepository) GetObservationByPatientCategory(id string, category string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := o.akses.BaseUrl + "/Observation?subject=" + id + "&category=" + category
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(o.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckObservationCategory implements ObservationInterface.
|
||||||
|
func (o *ObservationRepository) HandleCheckObservationCategory(id string, category string) ([]string, bool, error) {
|
||||||
|
observation, err := o.GetObservationByPatientCategory(id, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := observation["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (observation)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckObservation implements ObservationInterface.
|
||||||
|
func (o *ObservationRepository) HandleCheckObservation(id string) ([]string, bool, error) {
|
||||||
|
observation, err := o.GetObservationByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := observation["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (observation)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObservationByPatient implements ObservationInterface.
|
||||||
|
func (o *ObservationRepository) GetObservationByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data map[string]interface{}
|
||||||
|
)
|
||||||
|
url := o.akses.BaseUrl + "/Observation?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(o.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateObservation implements ObservationInterface.
|
||||||
|
func (o *ObservationRepository) CreateObservation(req model.ObservationRequest) (map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data = make(map[string]interface{})
|
||||||
|
)
|
||||||
|
req.ResourceType = constant.ObservationResourceType
|
||||||
|
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(o.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Practitioner
|
||||||
|
// if req.Performer != nil && len(req.Performer) > 0 {
|
||||||
|
// practitionerInterface := NewPracticionerRepo(o.akses)
|
||||||
|
// practitionerId, _, err := practitionerInterface.HandleCheckPartitioner(req.Performer[0].Reference)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// if practitionerId != "" {
|
||||||
|
// req.Performer = []model.Reference{
|
||||||
|
// {Reference: "Practitioner/" + practitionerId},
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// return nil, errors.New("practitioner not found")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(o.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//setup service request
|
||||||
|
err := o.setupServiceRequest(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("service request not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Category[0].Coding[0].Code == "laboratory" {
|
||||||
|
//setup specimen
|
||||||
|
err = o.setupSpecimen(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("specimen not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url := o.akses.BaseUrl + "/Observation"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(o.akses)
|
||||||
|
NewOauthRequestRepo(o.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ObservationRepository) UpdateObservation(req model.ObservationRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ObservationResourceType
|
||||||
|
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(o.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Practitioner
|
||||||
|
// if req.Performer != nil && len(req.Performer) > 0 {
|
||||||
|
// practitionerInterface := NewPracticionerRepo(o.akses)
|
||||||
|
// practitionerId, _, err := practitionerInterface.HandleCheckPartitioner(req.Performer[0].Reference)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// if practitionerId != "" {
|
||||||
|
// req.Performer = []model.Reference{
|
||||||
|
// {Reference: "Practitioner/" + practitionerId},
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// return nil, errors.New("practitioner not found")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(o.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(o.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := o.akses.BaseUrl + fmt.Sprintf("/Observation/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ObservationRepository) setupServiceRequest(req *model.ObservationRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
serviceReq := NewServiceRequestRepository(o.akses)
|
||||||
|
ids, _, err := serviceReq.HandleCheckServiceRequest(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(ids) > 0 {
|
||||||
|
req.BasedOn = []model.Reference{
|
||||||
|
{
|
||||||
|
Reference: "ServiceRequest/" + ids[0],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ObservationRepository) setupSpecimen(req *model.ObservationRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
specimenInterface := NewSpecimenRepository(o.akses)
|
||||||
|
ids, exist, err := specimenInterface.HandleCheckSpecimen(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exist {
|
||||||
|
req.Specimen = &model.Reference{}
|
||||||
|
req.Specimen.Reference = "Specimen/" + ids[0]
|
||||||
|
} else {
|
||||||
|
return errors.New("specimen not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObservationRepo(akses *model.Akses) ObservationInterface {
|
||||||
|
return &ObservationRepository{akses: akses}
|
||||||
|
}
|
||||||
164
internal/integration/organization_integration.go
Normal file
164
internal/integration/organization_integration.go
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrganizationInterface interface {
|
||||||
|
// Define methods for OrganizationInterface
|
||||||
|
CreateOrganization(req model.OrganizationRequest) (map[string]interface{}, error)
|
||||||
|
GetOrganizationPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckOrganization(id string) (string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrganizationRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrganization implements OrganizationInterface.
|
||||||
|
func (o *OrganizationRepository) CreateOrganization(req model.OrganizationRequest) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
req.ResourceType = constant.OrganizationResourceType
|
||||||
|
|
||||||
|
url := o.akses.BaseUrl + "/Organization"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(o.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDiagnosisReportByPatient implements OrganizationInterface.
|
||||||
|
func (o *OrganizationRepository) GetOrganizationPatient(id string) (map[string]interface{}, error) {
|
||||||
|
url := o.akses.BaseUrl + "/DiagnosticReport?patient=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(o.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
if response.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("failed to get diagnosis report")
|
||||||
|
}
|
||||||
|
|
||||||
|
var data map[string]interface{}
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckOrganization implements OrganizationInterface.
|
||||||
|
func (o *OrganizationRepository) HandleCheckOrganization(id string) (string, bool, error) {
|
||||||
|
url := o.akses.BaseUrl + "/Organization/" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: o.akses.ClientId,
|
||||||
|
ClientSecret: o.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(o.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
if response.StatusCode == http.StatusNotFound {
|
||||||
|
return "", false, nil
|
||||||
|
} else if response.StatusCode != http.StatusOK {
|
||||||
|
return "", false, errors.New("failed to check organization")
|
||||||
|
}
|
||||||
|
|
||||||
|
var data map[string]interface{}
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name, ok := data["name"].(string)
|
||||||
|
if !ok {
|
||||||
|
return "", false, errors.New("organization name not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return name, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOrganizationRepo(akses *model.Akses) OrganizationInterface {
|
||||||
|
return &OrganizationRepository{akses: akses}
|
||||||
|
}
|
||||||
146
internal/integration/patient_integration.go
Normal file
146
internal/integration/patient_integration.go
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PatientInterface interface {
|
||||||
|
// Define methods for PartientInterface
|
||||||
|
CreataPatient(req model.PatientRequest) (*map[string]interface{}, error)
|
||||||
|
GetPatientByNIK(identifier string) (*map[string]interface{}, error)
|
||||||
|
HandleCheckPatient(nik string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PatientRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckPatient implements PatientInterface.
|
||||||
|
func (p *PatientRepository) HandleCheckPatient(nik string) (string, error) {
|
||||||
|
nik = "https://fhir.kemkes.go.id/id/nik|" + nik
|
||||||
|
patient, err := p.GetPatientByNIK(nik)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if entries, ok := (*patient)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreataPatient implements PatientInterface.
|
||||||
|
func (p *PatientRepository) CreataPatient(req model.PatientRequest) (*map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data *map[string]interface{}
|
||||||
|
)
|
||||||
|
req.ResourceType = constant.PatientResourceType
|
||||||
|
req.Meta = model.Meta{
|
||||||
|
Profile: []string{constant.PatientProfile},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := p.akses.BaseUrl + "/Patient"
|
||||||
|
method := "POST"
|
||||||
|
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Assuming the access token is stored in a field of the akses struct
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: p.akses.ClientId,
|
||||||
|
ClientSecret: p.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(p.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPatientByNIK implements PatientInterface.
|
||||||
|
func (p *PatientRepository) GetPatientByNIK(identifier string) (*map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data *map[string]interface{}
|
||||||
|
)
|
||||||
|
url := p.akses.BaseUrl + "/Patient?identifier=" + identifier
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Assuming the access token is stored in a field of the akses struct
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: p.akses.ClientId,
|
||||||
|
ClientSecret: p.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(p.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreataPatient implements PartientInterface.
|
||||||
|
func NewPatientRepo(akses *model.Akses) PatientInterface {
|
||||||
|
return &PatientRepository{akses: akses}
|
||||||
|
}
|
||||||
105
internal/integration/practitioner_integration.go
Normal file
105
internal/integration/practitioner_integration.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PracticionerInterface interface {
|
||||||
|
// Add fields as necessary for the integration
|
||||||
|
GetPracticionerByNIK(nik string) (*map[string]interface{}, error)
|
||||||
|
HandleCheckPartitioner(nik string) (string, string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PracticionerRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckPartitioner implements PracticionerInterface.
|
||||||
|
func (p *PracticionerRepository) HandleCheckPartitioner(nik string) (string, string, error) {
|
||||||
|
practitioner, err := p.GetPracticionerByNIK("https://fhir.kemkes.go.id/id/nik|" + nik)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
if practitioner != nil {
|
||||||
|
id := ""
|
||||||
|
nameText := ""
|
||||||
|
if entriesRaw, ok := (*practitioner)["entry"]; ok {
|
||||||
|
if entries, ok := entriesRaw.([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
// Ambil id
|
||||||
|
if idRaw, ok := resource["id"].(string); ok {
|
||||||
|
id = idRaw
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil name[0].text
|
||||||
|
if namesRaw, ok := resource["name"]; ok {
|
||||||
|
if names, ok := namesRaw.([]interface{}); ok && len(names) > 0 {
|
||||||
|
if nameObj, ok := names[0].(map[string]interface{}); ok {
|
||||||
|
if text, ok := nameObj["text"].(string); ok {
|
||||||
|
nameText = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id, nameText, nil
|
||||||
|
} else {
|
||||||
|
return "", "", errors.New("practitioner not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPracticionerRepo(akses *model.Akses) PracticionerInterface {
|
||||||
|
return &PracticionerRepository{akses: akses}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PracticionerRepository) GetPracticionerByNIK(nik string) (*map[string]interface{}, error) {
|
||||||
|
var (
|
||||||
|
data *map[string]interface{}
|
||||||
|
)
|
||||||
|
url := p.akses.BaseUrl + "/Practitioner?identifier=" + nik
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: p.akses.ClientId,
|
||||||
|
ClientSecret: p.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(p.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Add("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Accept", constant.ContentTypeFHIRJSON)
|
||||||
|
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
236
internal/integration/procedure_integration.go
Normal file
236
internal/integration/procedure_integration.go
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcedureInterface interface {
|
||||||
|
CreateProcedure(req model.ProcedureRequest) (map[string]interface{}, error)
|
||||||
|
GetProcedure(id string) (map[string]interface{}, error)
|
||||||
|
UpdateProcedure(req model.ProcedureRequest) (map[string]interface{}, error)
|
||||||
|
GetProcedureByPatient(id string) (map[string]interface{}, error)
|
||||||
|
HandleCheckProcedure(id string) ([]string, bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcedureRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProcedureByPatient implements ProcedureInterface.
|
||||||
|
func (p *ProcedureRepository) GetProcedureByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
url := p.akses.BaseUrl + "/Procedure?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: p.akses.ClientId,
|
||||||
|
ClientSecret: p.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(p.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckProcedure implements ProcedureInterface.
|
||||||
|
func (p *ProcedureRepository) HandleCheckProcedure(id string) ([]string, bool, error) {
|
||||||
|
procedure, err := p.GetProcedureByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := procedure["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (procedure)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateProcedure implements ProcedureInterface.
|
||||||
|
func (p *ProcedureRepository) CreateProcedure(req model.ProcedureRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ProcedureResourceType
|
||||||
|
|
||||||
|
patient, err := p.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Performer
|
||||||
|
err = p.setupPractitioner(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: p.akses.ClientId,
|
||||||
|
ClientSecret: p.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := NewOauthRequestRepo(p.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := p.akses.BaseUrl + "/Procedure"
|
||||||
|
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProcedure implements ProcedureInterface.
|
||||||
|
func (p *ProcedureRepository) GetProcedure(id string) (map[string]interface{}, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateProcedure implements ProcedureInterface.
|
||||||
|
func (p *ProcedureRepository) UpdateProcedure(req model.ProcedureRequest) (map[string]interface{}, error) {
|
||||||
|
patient, err := p.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Performer
|
||||||
|
err = p.setupPractitioner(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: p.akses.ClientId,
|
||||||
|
ClientSecret: p.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := NewOauthRequestRepo(p.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := p.akses.BaseUrl + "/Procedure/" + req.ID
|
||||||
|
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Body: req,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProcedureRepository) setupPatient(req *model.ProcedureRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(p.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupEncounter extracts encounter setup logic from CreateDiagnosisReport.
|
||||||
|
func (p *ProcedureRepository) setupEncounter(req *model.ProcedureRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(p.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
//Buat dulu encounter
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProcedureRepository) setupPractitioner(req *model.ProcedureRequest) error {
|
||||||
|
if len(req.Performer) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, performer := range req.Performer {
|
||||||
|
if strings.Contains(performer.Actor.Reference, "Practitioner/") {
|
||||||
|
temp := strings.Split(performer.Actor.Reference, "/")
|
||||||
|
practicionerInterface := NewPracticionerRepo(p.akses)
|
||||||
|
ref, _, err := practicionerInterface.HandleCheckPartitioner(temp[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
performer.Actor.Reference = "Practitioner/" + ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcedureRepo(akses *model.Akses) ProcedureInterface {
|
||||||
|
return &ProcedureRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
181
internal/integration/questionnaireresponse_integration.go
Normal file
181
internal/integration/questionnaireresponse_integration.go
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type QuestionnaireResponseInterface interface {
|
||||||
|
// Define methods for QuestionnaireResponseInterface
|
||||||
|
CreateQuestionnaireResponse(req model.QuestionnaireResponseRequest) (map[string]interface{}, error)
|
||||||
|
UpdateQuestionnaireResponse(req model.QuestionnaireResponseRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuestionnaireResponseRepository struct {
|
||||||
|
// Define fields for QuestionnaireResponseRepository
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuestionnaireResponseRepo(akses *model.Akses) QuestionnaireResponseInterface {
|
||||||
|
return &QuestionnaireResponseRepository{
|
||||||
|
akses: akses,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateQuestionnaireResponse implements QuestionnaireResponseInterface.
|
||||||
|
func (c *QuestionnaireResponseRepository) CreateQuestionnaireResponse(req model.QuestionnaireResponseRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.QuestionnaireResponseResourceType
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupSource(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + "/QuestionnaireResponse"
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "POST",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QuestionnaireResponseRepository) UpdateQuestionnaireResponse(req model.QuestionnaireResponseRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.QuestionnaireResponseResourceType
|
||||||
|
|
||||||
|
patient, err := c.setupPatient(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupEncounter(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.setupSource(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = c.setupPractitioner(&req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: c.akses.ClientId,
|
||||||
|
ClientSecret: c.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(c.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.akses.BaseUrl + fmt.Sprintf("/QuestionnaireResponse/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
Headers: httputil.DefaultFHIRHeaders(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QuestionnaireResponseRepository) setupPatient(req *model.QuestionnaireResponseRequest) (string, error) {
|
||||||
|
if req.Subject.Reference == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return patient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QuestionnaireResponseRepository) setupSource(req *model.QuestionnaireResponseRequest) error {
|
||||||
|
if req.Source.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
patientInterface := NewPatientRepo(c.akses)
|
||||||
|
patient, err := patientInterface.HandleCheckPatient(req.Source.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient != "" {
|
||||||
|
req.Source.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QuestionnaireResponseRepository) setupEncounter(req *model.QuestionnaireResponseRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
encounterInterface := NewEncounterRepo(c.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupPractitioner handles practitioner reference logic.
|
||||||
|
func (c *QuestionnaireResponseRepository) setupPractitioner(req *model.QuestionnaireResponseRequest) error {
|
||||||
|
if req.Author.Reference == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
practicionerInterface := NewPracticionerRepo(c.akses)
|
||||||
|
ref, display, err := practicionerInterface.HandleCheckPartitioner(req.Author.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ref != "" {
|
||||||
|
req.Author.Reference = "Practitioner/" + ref
|
||||||
|
req.Author.Display = display
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
288
internal/integration/servicerequest_integration.go
Normal file
288
internal/integration/servicerequest_integration.go
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceRequestInterface interface {
|
||||||
|
CreateServiceRequest(req model.ServiceRequest) (map[string]interface{}, error)
|
||||||
|
GetServiceRequestByPatient(id string) (map[string]interface{}, error)
|
||||||
|
GetServiceRequestByPatientCategory(id string, category string) (map[string]interface{}, error)
|
||||||
|
HandleCheckServiceRequest(id string) ([]string, bool, error)
|
||||||
|
HandleCheckServiceRequestByCategory(id string, category string) ([]string, bool, error)
|
||||||
|
UpdateServiceRequest(req model.ServiceRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceRequestRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServiceRequestByPatientCategory implements ServiceRequestInterface.
|
||||||
|
func (s *ServiceRequestRepository) GetServiceRequestByPatientCategory(id string, category string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
url := s.akses.BaseUrl + "/ServiceRequest?subject=" + id + "&category=" + category
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(s.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckServiceRequestByCategory implements ServiceRequestInterface.
|
||||||
|
func (s *ServiceRequestRepository) HandleCheckServiceRequestByCategory(id string, category string) ([]string, bool, error) {
|
||||||
|
servicereq, err := s.GetServiceRequestByPatientCategory(id, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := servicereq["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (servicereq)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateServiceRequest implements ServiceRequestInterface.
|
||||||
|
func (s *ServiceRequestRepository) CreateServiceRequest(req model.ServiceRequest) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
req.ResourceType = constant.ServiceRequestResourceType
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(s.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(s.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url := s.akses.BaseUrl + "/ServiceRequest"
|
||||||
|
method := "POST"
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(s.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceRequestRepository) UpdateServiceRequest(req model.ServiceRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.ServiceRequestResourceType
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(s.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(s.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
req.Encounter.Reference = "Encounter/" + encounterId
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(s.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := s.akses.BaseUrl + fmt.Sprintf("/ServiceRequest/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServiceRequestByPatient implements ServiceRequestInterface.
|
||||||
|
func (s *ServiceRequestRepository) GetServiceRequestByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
url := s.akses.BaseUrl + "/ServiceRequest?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(s.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckServiceRequest implements ServiceRequestInterface.
|
||||||
|
func (s *ServiceRequestRepository) HandleCheckServiceRequest(id string) ([]string, bool, error) {
|
||||||
|
servicereq, err := s.GetServiceRequestByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := servicereq["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (servicereq)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceRequestRepository(akses *model.Akses) ServiceRequestInterface {
|
||||||
|
return &ServiceRequestRepository{akses: akses}
|
||||||
|
}
|
||||||
336
internal/integration/specimen_integration.go
Normal file
336
internal/integration/specimen_integration.go
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"satusehat-rssa/internal/constant"
|
||||||
|
"satusehat-rssa/internal/model"
|
||||||
|
"satusehat-rssa/pkg/httputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SpecimenInterface interface {
|
||||||
|
CreateSpecimen(req model.SpecimenRequest) (map[string]interface{}, error)
|
||||||
|
GetSpecimenByPatient(id string) (map[string]interface{}, error)
|
||||||
|
GetSpecimenByPatientCategory(id string, category string) (map[string]interface{}, error)
|
||||||
|
HandleCheckSpecimen(id string) ([]string, bool, error)
|
||||||
|
HandleCheckSpecimenCategory(id string, category string) ([]string, bool, error)
|
||||||
|
UpdateSpecimen(req model.SpecimenRequest) (map[string]interface{}, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpecimenRepository struct {
|
||||||
|
akses *model.Akses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpecimenByPatientCategory implements SpecimenInterface.
|
||||||
|
func (s *SpecimenRepository) GetSpecimenByPatientCategory(id string, category string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
url := s.akses.BaseUrl + "/Specimen?subject=" + id + "&category=" + category
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(s.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", constant.ContentTypeFHIRJSON)
|
||||||
|
res, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckSpecimenCategory implements SpecimenInterface.
|
||||||
|
func (s *SpecimenRepository) HandleCheckSpecimenCategory(id string, category string) ([]string, bool, error) {
|
||||||
|
specimen, err := s.GetSpecimenByPatientCategory(id, category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := specimen["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (specimen)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSpecimen implements SpecimenInterface.
|
||||||
|
func (s *SpecimenRepository) CreateSpecimen(req model.SpecimenRequest) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
|
||||||
|
req.ResourceType = constant.SpecimenResourceType
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(s.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Service Request
|
||||||
|
err := s.setupServiceRequest(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
url := s.akses.BaseUrl + "/Specimen"
|
||||||
|
method := "POST"
|
||||||
|
payload, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(s.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isOperationOutcomeError(data) {
|
||||||
|
// Setup Encounter
|
||||||
|
if patient != "" {
|
||||||
|
encounterInterface := NewEncounterRepo(s.akses)
|
||||||
|
encounterId, encounterExist, err := encounterInterface.HandleCheckEncounter(patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if encounterExist {
|
||||||
|
data["encounter"] = map[string]interface{}{
|
||||||
|
"reference": "Encounter/" + encounterId,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("encounter not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpecimenByPatient implements SpecimenInterface.
|
||||||
|
func (s *SpecimenRepository) GetSpecimenByPatient(id string) (map[string]interface{}, error) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
url := s.akses.BaseUrl + "/Specimen?subject=" + id
|
||||||
|
method := "GET"
|
||||||
|
client := &http.Client{}
|
||||||
|
request, err := http.NewRequest(method, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
OauthInterface := NewOauthRequestRepo(s.akses)
|
||||||
|
token, err := OauthInterface.GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
err = json.NewDecoder(response.Body).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// isOperationOutcomeError returns true when the response is an OperationOutcome
|
||||||
|
// with at least one issue that includes diagnostics or details.text.
|
||||||
|
func isOperationOutcomeError(resp map[string]interface{}) bool {
|
||||||
|
if resp == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if rt, ok := resp["resourceType"].(string); !ok || rt != "OperationOutcome" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
issues, ok := resp["issue"].([]interface{})
|
||||||
|
if !ok || len(issues) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, it := range issues {
|
||||||
|
if m, ok := it.(map[string]interface{}); ok {
|
||||||
|
if diag, ok := m["diagnostics"].(string); ok && diag != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if details, ok := m["details"].(map[string]interface{}); ok {
|
||||||
|
if txt, ok := details["text"].(string); ok && txt != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SpecimenRepository) setupServiceRequest(req *model.SpecimenRequest, patient string) error {
|
||||||
|
if patient == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
serviceReq := NewServiceRequestRepository(s.akses)
|
||||||
|
ids, _, err := serviceReq.HandleCheckServiceRequest(patient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(ids) > 0 {
|
||||||
|
req.Request = []model.Reference{
|
||||||
|
{
|
||||||
|
Reference: "ServiceRequest/" + ids[0],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleCheckSpecimen implements SpecimenInterface.
|
||||||
|
func (s *SpecimenRepository) HandleCheckSpecimen(id string) ([]string, bool, error) {
|
||||||
|
specimen, err := s.GetSpecimenByPatient(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can process 'specimen' here if needed
|
||||||
|
var ids []string
|
||||||
|
if entries, ok := specimen["entry"].([]interface{}); ok && len(entries) != 0 {
|
||||||
|
if entries, ok := (specimen)["entry"].([]interface{}); ok && len(entries) > 0 {
|
||||||
|
if entryMap, ok := entries[0].(map[string]interface{}); ok {
|
||||||
|
if resource, ok := entryMap["resource"].(map[string]interface{}); ok {
|
||||||
|
if id, ok := resource["id"].(string); ok {
|
||||||
|
//fmt.Println("resource.id:", id)
|
||||||
|
ids = append(ids, id)
|
||||||
|
return ids, true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SpecimenRepository) UpdateSpecimen(req model.SpecimenRequest) (map[string]interface{}, error) {
|
||||||
|
req.ResourceType = constant.SpecimenResourceType
|
||||||
|
// Setup Patient
|
||||||
|
var patient string
|
||||||
|
if req.Subject.Reference != "" {
|
||||||
|
patientInterface := NewPatientRepo(s.akses)
|
||||||
|
var err error
|
||||||
|
patient, err = patientInterface.HandleCheckPatient(req.Subject.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if patient == "" { // Belum ada di satu sehat
|
||||||
|
return nil, errors.New("patient not found")
|
||||||
|
} else {
|
||||||
|
req.Subject.Reference = "Patient/" + patient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Service Request
|
||||||
|
err := s.setupServiceRequest(&req, patient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth := model.OauthRequest{
|
||||||
|
ClientId: s.akses.ClientId,
|
||||||
|
ClientSecret: s.akses.ClientSecret,
|
||||||
|
}
|
||||||
|
token, err := NewOauthRequestRepo(s.akses).GenerateToken(oauth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token == nil {
|
||||||
|
return nil, errors.New(constant.ErrGenerateToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := s.akses.BaseUrl + fmt.Sprintf("/Specimen/%s", req.Id)
|
||||||
|
return httputil.DoRequest(httputil.RequestOption{
|
||||||
|
Method: "PUT",
|
||||||
|
URL: url,
|
||||||
|
Body: req,
|
||||||
|
BearerToken: token.AccessToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSpecimenRepository(akses *model.Akses) SpecimenInterface {
|
||||||
|
return &SpecimenRepository{akses: akses}
|
||||||
|
}
|
||||||
4
internal/midleware/middleware.go
Normal file
4
internal/midleware/middleware.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package midleware
|
||||||
|
|
||||||
|
type AuthMiddleware struct {
|
||||||
|
}
|
||||||
71
internal/model/allergancytoleran.go
Normal file
71
internal/model/allergancytoleran.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type AllergancyToleranRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []*IdentifierObject `json:"identifier"`
|
||||||
|
ClinicalStatus *ClinicalStatusObject `json:"clinicalStatus"`
|
||||||
|
VerificationStatus *ClinicalStatusObject `json:"verificationStatus"`
|
||||||
|
Category []string `json:"category"`
|
||||||
|
Code *CodeObject `json:"code"`
|
||||||
|
Patient *PatientObject `json:"patient"`
|
||||||
|
Encounter *PatientObject `json:"encounter"`
|
||||||
|
RecordedDate string `json:"recordedDate"`
|
||||||
|
Recorder *PatientObject `json:"recorder"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllergancyToleranResponse struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []*IdentifierObject `json:"identifier"`
|
||||||
|
ClinicalStatus *ClinicalStatusObject `json:"clinicalStatus"`
|
||||||
|
VerificationStatus *ClinicalStatusObject `json:"verificationStatus"`
|
||||||
|
Category []string `json:"category"`
|
||||||
|
Code *CodeObject `json:"code"`
|
||||||
|
Patient *PatientObject `json:"patient"`
|
||||||
|
Encounter *PatientObject `json:"encounter"`
|
||||||
|
RecordedDate string `json:"recordedDate"`
|
||||||
|
Recorder *PatientObject `json:"recorder"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Meta *MetaObject `json:"meta"`
|
||||||
|
Issue []*IssuerObject `json:"issue`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IdentifierObject struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Use string `json:"use"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClinicalStatusObject struct {
|
||||||
|
Coding []*CodingObject `json:"coding"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CodeObject struct {
|
||||||
|
Coding []*CodingObject `json:"coding"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PatientObject struct {
|
||||||
|
Reference string `json:"reference"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CodingObject struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MetaObject struct {
|
||||||
|
VersionId string `json:"versionId"`
|
||||||
|
LastUpdated string `json:"lastUpdated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IssuerObject struct {
|
||||||
|
Saverity string `json:"severity"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Details *DetailObject `json:"details"`
|
||||||
|
}
|
||||||
|
type DetailObject struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
16
internal/model/careplan.go
Normal file
16
internal/model/careplan.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type CarePlanRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
Intent string `json:"intent" binding:"required"`
|
||||||
|
Category []Category `json:"category" binding:"required"`
|
||||||
|
Title string `json:"title" binding:"required"`
|
||||||
|
Description string `json:"description" binding:"required"`
|
||||||
|
Subject Reference `json:"subject" binding:"required"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
Created string `json:"created" binding:"required"`
|
||||||
|
Author Reference `json:"author" binding:"required"`
|
||||||
|
Goal []Reference `json:"goal"`
|
||||||
|
}
|
||||||
56
internal/model/clinicalImpression.go
Normal file
56
internal/model/clinicalImpression.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
// Reference to another FHIR resource
|
||||||
|
type Reference struct {
|
||||||
|
Reference string `json:"reference"`
|
||||||
|
Display string `json:"display,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coding for codeable concepts
|
||||||
|
type Coding struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeableConcept for coded fields
|
||||||
|
type CodeableConcept struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
Text string `json:"text,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Investigation item reference
|
||||||
|
type InvestigationItem struct {
|
||||||
|
Reference string `json:"reference"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Investigation structure
|
||||||
|
type Investigation struct {
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Item []InvestigationItem `json:"item"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finding structure
|
||||||
|
type Finding struct {
|
||||||
|
ItemCodeableConcept *CodeableConcept `json:"itemCodeableConcept,omitempty"`
|
||||||
|
ItemReference *Reference `json:"itemReference,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClinicalImpressionRequest for the request body
|
||||||
|
type ClinicalImpressionRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
EffectiveDateTime string `json:"effectiveDateTime"`
|
||||||
|
Date string `json:"date"`
|
||||||
|
Assessor Reference `json:"assessor"`
|
||||||
|
Problem []Reference `json:"problem"`
|
||||||
|
Investigation []Investigation `json:"investigation"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Finding []Finding `json:"finding"`
|
||||||
|
PrognosisCodeableConcept []CodeableConcept `json:"prognosisCodeableConcept"`
|
||||||
|
}
|
||||||
40
internal/model/composition.go
Normal file
40
internal/model/composition.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type CompositionRequest struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Category []CodeableConcept `json:"category"`
|
||||||
|
Type CodeableConcept `json:"type"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Date string `json:"date"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Author []Reference `json:"author"`
|
||||||
|
Custodian Reference `json:"custodian"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
Section []SectionRequest `json:"section"`
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
Anamnesis string `json:"anamnesis,omitempty"`
|
||||||
|
PemeriksaanFisik string `json:"pemeriksaanFisik,omitempty"`
|
||||||
|
PemeriksaanPenunjang string `json:"pemeriksaanPenunjang,omitempty"`
|
||||||
|
Medikamentosa string `json:"medikamentosa,omitempty"`
|
||||||
|
LanjutanPenatalaksanaan string `json:"lanjutanPenatalaksanaan,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SectionRequest struct {
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Text *SectionText `json:"text,omitempty"`
|
||||||
|
Entry []Reference `json:"entry,omitempty"`
|
||||||
|
Section []SectionRequest `json:"section,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Section struct {
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Text SectionText `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SectionText struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Div string `json:"div"`
|
||||||
|
}
|
||||||
11
internal/model/condition.go
Normal file
11
internal/model/condition.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ConditionRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
ClinicalStatus CodeableConcept `json:"clinicalStatus"`
|
||||||
|
Category []CodeableConcept `json:"category"`
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
}
|
||||||
20
internal/model/diagnosisreport.go
Normal file
20
internal/model/diagnosisreport.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
// DiagnosticReportRequest defines the structure for a diagnostic report request
|
||||||
|
type DiagnosticReportRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Category []CodeableConcept `json:"category"`
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
EffectiveDateTime string `json:"effectiveDateTime"`
|
||||||
|
Issued string `json:"issued"`
|
||||||
|
Performer []Reference `json:"performer"`
|
||||||
|
Result []Reference `json:"result"`
|
||||||
|
Specimen []Reference `json:"specimen"`
|
||||||
|
BasedOn []Reference `json:"basedOn"`
|
||||||
|
ConclusionCode []CodeableConcept `json:"conclusionCode"`
|
||||||
|
}
|
||||||
82
internal/model/encounter.go
Normal file
82
internal/model/encounter.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type EncounterRequest struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Class Class `json:"class"`
|
||||||
|
Subject Subject `json:"subject"`
|
||||||
|
Participant []Participant `json:"participant"`
|
||||||
|
Period struct {
|
||||||
|
Start string `json:"start"`
|
||||||
|
} `json:"end"`
|
||||||
|
Location []Location `json:"location"`
|
||||||
|
StatusHistory []StatusHistory `json:"statusHistory"`
|
||||||
|
ServiceProvider struct {
|
||||||
|
Reference string `json:"reference"`
|
||||||
|
} `json:"serviceProvider"`
|
||||||
|
Identifier []IdentifierEncounter `json:"identifier"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Class struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
}
|
||||||
|
type Subject struct {
|
||||||
|
Reference string `json:"reference"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Participant struct {
|
||||||
|
Type []struct {
|
||||||
|
Coding []Class `json:"coding"`
|
||||||
|
} `json:"type"`
|
||||||
|
Individual Subject `json:"individual"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
Location Reference `json:"location"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StatusHistory struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Period struct {
|
||||||
|
Start string `json:"start"`
|
||||||
|
} `json:"period"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EncounterUpdateRequest struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Class Class `json:"class"`
|
||||||
|
Subject Subject `json:"subject"`
|
||||||
|
Participant []Participant `json:"participant"`
|
||||||
|
Period Period `json:"period"`
|
||||||
|
Location []Location `json:"location"`
|
||||||
|
StatusHistory []StatusHistory `json:"statusHistory"`
|
||||||
|
ServiceProvider struct {
|
||||||
|
Reference string `json:"reference"`
|
||||||
|
} `json:"serviceProvider"`
|
||||||
|
Identifier []IdentifierEncounter `json:"identifier"`
|
||||||
|
Hospitalization Hospitalization `json:"hospitalization"`
|
||||||
|
Diagnosis []DiagnosisEncounter `json:"diagnosis"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hospitalization struct {
|
||||||
|
DischargeDisposition struct {
|
||||||
|
Coding []Class `json:"coding"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
} `json:"dischargeDisposition"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiagnosisEncounter struct {
|
||||||
|
Condition Reference `json:"condition"`
|
||||||
|
Use Type `json:"use"`
|
||||||
|
Rank int `json:"rank"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IdentifierEncounter struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
30
internal/model/episodeofcare.go
Normal file
30
internal/model/episodeofcare.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type EpisodeOfCareRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
StatusHistory []StatusHistory `json:"statusHistory,omitempty"`
|
||||||
|
Type []Type `json:"type"`
|
||||||
|
Diagnosis []Diagnosis `json:"diagnosis"`
|
||||||
|
Patient Reference `json:"patient"`
|
||||||
|
ManagingOrganization Reference `json:"managingOrganization"`
|
||||||
|
Period Period `json:"period"`
|
||||||
|
CareManager Reference `json:"careManager"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Period struct {
|
||||||
|
Start string `json:"start"`
|
||||||
|
End string `json:"end"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Type struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Diagnosis struct {
|
||||||
|
Condition Reference `json:"condition"`
|
||||||
|
Role Type `json:"role,omitempty"`
|
||||||
|
Rank int `json:"rank,omitempty"`
|
||||||
|
}
|
||||||
20
internal/model/goal.go
Normal file
20
internal/model/goal.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type GoalRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
LifecycleStatus string `json:"lifecycleStatus"`
|
||||||
|
Category []Category `json:"category,omitempty"`
|
||||||
|
Description Category `json:"description"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Target []GoalTarget `json:"target,omitempty"`
|
||||||
|
StatusDate string `json:"statusDate,omitempty"`
|
||||||
|
ExpressedBy Reference `json:"expressedBy,omitempty"`
|
||||||
|
Addresses []Reference `json:"addresses,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GoalTarget struct {
|
||||||
|
Measure Category `json:"measure,omitempty"`
|
||||||
|
DetailCodeableConcept Category `json:"detailCodeableConcept,omitempty"`
|
||||||
|
DueDate string `json:"dueDate,omitempty"`
|
||||||
|
}
|
||||||
31
internal/model/imagingstudy.go
Normal file
31
internal/model/imagingstudy.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ImagingStudyRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier" binding:"required"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
Modality []Coding `json:"modality"`
|
||||||
|
Subject Reference `json:"subject" binding:"required"`
|
||||||
|
Started string `json:"started" binding:"required"`
|
||||||
|
BasedOn []Reference `json:"basedOn"` //binding:"required"
|
||||||
|
NumberOfSeries int `json:"numberOfSeries,omitempty"`
|
||||||
|
NumberOfInstances int `json:"numberOfInstances,omitempty"`
|
||||||
|
Series []ImagingStudySeries `json:"series,omitempty"` //binding:"required"
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagingStudySeries struct {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
Modality Coding `json:"modality"`
|
||||||
|
NumberOfInstances int `json:"numberOfInstances"`
|
||||||
|
Started string `json:"started"`
|
||||||
|
Instance []ImagingStudySeriesInstance `json:"instance"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagingStudySeriesInstance struct {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
SOPClass Coding `json:"sopClass"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
30
internal/model/immunization.go
Normal file
30
internal/model/immunization.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ImmunizationRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
VaccineCode CodeableConcept `json:"vaccineCode" binding:"required"`
|
||||||
|
Patient Reference `json:"patient" binding:"required"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
OccurrenceDateTime string `json:"occurrenceDateTime" binding:"required"`
|
||||||
|
ExpirationDate string `json:"expirationDate" binding:"required"`
|
||||||
|
Recorded string `json:"recorded" binding:"required"`
|
||||||
|
PrimarySource bool `json:"primarySource"`
|
||||||
|
Location Reference `json:"location" binding:"required"`
|
||||||
|
LotNumber string `json:"lotNumber" binding:"required"`
|
||||||
|
Route CodeableConcept `json:"route" binding:"required"`
|
||||||
|
DoseQuantity Quantity `json:"doseQuantity" binding:"required"`
|
||||||
|
Performer []Performers `json:"performer" binding:"required"`
|
||||||
|
ReasonCode []CodeableConcept `json:"reasonCode" binding:"required"`
|
||||||
|
ProtocolApplied []ProtocolApplied `json:"protocolApplied" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Performers struct {
|
||||||
|
Function CodeableConcept `json:"function"`
|
||||||
|
Actor Reference `json:"actor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProtocolApplied struct {
|
||||||
|
DoseNumberPositiveInt int `json:"doseNumberPositiveInt"`
|
||||||
|
}
|
||||||
46
internal/model/medicationdispense.go
Normal file
46
internal/model/medicationdispense.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type MedicationDispenseRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
Category Category `json:"category"`
|
||||||
|
MedicationReference Reference `json:"medicationReference" binding:"required"`
|
||||||
|
Subject Reference `json:"subject" binding:"required"`
|
||||||
|
Context Reference `json:"context"`
|
||||||
|
Performer []Performer `json:"performer"`
|
||||||
|
Location Reference `json:"location" binding:"required"`
|
||||||
|
AuthorizingPrescription []Reference `json:"authorizingPrescription" binding:"required"`
|
||||||
|
Quantity Quantity `json:"quantity" binding:"required"`
|
||||||
|
DaysSupply DaysSupply `json:"daysSupply" binding:"required"`
|
||||||
|
WhenPrepared string `json:"whenPrepared" binding:"required"`
|
||||||
|
WhenHandedOver string `json:"whenHandedOver" binding:"required"`
|
||||||
|
DosageInstruction []Dosage `json:"dosageInstruction"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DaysSupply struct {
|
||||||
|
Value float64 `json:"value"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dosage struct {
|
||||||
|
Sequence *int `json:"sequence,omitempty"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
Timing Timing `json:"timing"`
|
||||||
|
DoseAndRate []DoseAndRate `json:"doseAndRate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DoseAndRate struct {
|
||||||
|
Type Category `json:"type"`
|
||||||
|
DoseQuantity DoseQuantity `json:"doseQuantity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DoseQuantity struct {
|
||||||
|
Value float64 `json:"value"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
44
internal/model/medicationrequest.go
Normal file
44
internal/model/medicationrequest.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type MedicationRequestRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
MedicationRequest *MedicationRequest `json:"medicationRequest,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
Intent string `json:"intent" binding:"required"`
|
||||||
|
Category []Category `json:"category"`
|
||||||
|
Priority string `json:"priority" binding:"required"`
|
||||||
|
MedicationReference Reference `json:"medicationReference" binding:"required"`
|
||||||
|
Subject Reference `json:"subject" binding:"required"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
AuthoredOn string `json:"authoredOn"`
|
||||||
|
Requester Reference `json:"requester"`
|
||||||
|
ReasonCode []Category `json:"reasonCode"`
|
||||||
|
CourseOfTherapyType Category `json:"courseOfTherapyType"`
|
||||||
|
DosageInstruction []DosageMR `json:"dosageInstruction"`
|
||||||
|
DispenseRequest DispenseRequest `json:"dispenseRequest" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DosageMR struct {
|
||||||
|
Sequence int `json:"sequence"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
AdditionalInstruction []AdditionalText `json:"additionalInstruction,omitempty"`
|
||||||
|
PatientInstruction string `json:"patientInstruction,omitempty"`
|
||||||
|
Timing Timing `json:"timing"`
|
||||||
|
Route Category `json:"route,omitempty"`
|
||||||
|
DoseAndRate []DoseAndRate `json:"doseAndRate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdditionalText struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DispenseRequest struct {
|
||||||
|
DispenseInterval Quantity `json:"dispenseInterval"`
|
||||||
|
ValidityPeriod Period `json:"validityPeriod"`
|
||||||
|
NumberOfRepeatsAllowed int `json:"numberOfRepeatsAllowed"`
|
||||||
|
Quantity Quantity `json:"quantity"`
|
||||||
|
ExpectedSupplyDuration Quantity `json:"expectedSupplyDuration"`
|
||||||
|
Performer Reference `json:"performer"`
|
||||||
|
}
|
||||||
60
internal/model/medicationstatement.go
Normal file
60
internal/model/medicationstatement.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type MedicationStatementRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Contained []Medication `json:"contained" binding:"required"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
Category Category `json:"category"`
|
||||||
|
MedicationReference Reference `json:"medicationReference" binding:"required"`
|
||||||
|
Subject Reference `json:"subject" binding:"required"`
|
||||||
|
Dosage []Dosage `json:"dosage"`
|
||||||
|
EffectiveDateTime string `json:"effectiveDateTime" binding:"required"`
|
||||||
|
DateAsserted string `json:"dateAsserted" binding:"required"`
|
||||||
|
InformationSource Reference `json:"informationSource" binding:"required"`
|
||||||
|
Context Reference `json:"context"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Medication struct {
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Extension []MedicationExtension `json:"extension"`
|
||||||
|
Form CodeableConcept `json:"form"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Ingredient []MedicationIngredient `json:"ingredient"`
|
||||||
|
Batch MedicationBatch `json:"batch"`
|
||||||
|
Meta Meta `json:"meta"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationExtension struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
ValueCodeableConcept CodeableConcept `json:"valueCodeableConcept"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationIngredient struct {
|
||||||
|
IsActive bool `json:"isActive"`
|
||||||
|
ItemCodeableConcept CodeableConcept `json:"itemCodeableConcept"`
|
||||||
|
Strength MedicationStrength `json:"strength"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationStrength struct {
|
||||||
|
Denominator Quantity `json:"denominator"`
|
||||||
|
Numerator Quantity `json:"numerator"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationBatch struct {
|
||||||
|
LotNumber string `json:"lotNumber"`
|
||||||
|
ExpirationDate string `json:"expirationDate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Timing struct {
|
||||||
|
Repeat TimingRepeat `json:"repeat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimingRepeat struct {
|
||||||
|
Frequency int `json:"frequency"`
|
||||||
|
Period float64 `json:"period"`
|
||||||
|
PeriodUnit string `json:"periodUnit"`
|
||||||
|
}
|
||||||
33
internal/model/medicine.go
Normal file
33
internal/model/medicine.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type MedicineKfaRequest struct {
|
||||||
|
Page int `form:"page"`
|
||||||
|
Size int `form:"size"`
|
||||||
|
ProdustType string `form:"product_type"`
|
||||||
|
Keyword string `form:"keyword"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicineKfaResponse struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
KfaCode string `json:"kfa_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MedicationRequest struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Meta Meta `json:"meta"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Manufacturer Reference `json:"manufacturer"`
|
||||||
|
Form CodeableConcept `json:"form"`
|
||||||
|
Extension []ExtensionMedication `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExtensionMedication struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
ValueCodeableConcept CodeableConcept `json:"valueCodeableConcept"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shared types Meta, Identifier, Coding, CodeableConcept, Reference, and Extension
|
||||||
|
// are defined in other model files (e.g. patient.go and clinicalImpression.go).
|
||||||
|
// This file intentionally references those types to avoid redeclaration.
|
||||||
23
internal/model/oauth_model.go
Normal file
23
internal/model/oauth_model.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type OauthRequest struct {
|
||||||
|
ClientId string `json:"client_id"`
|
||||||
|
ClientSecret string `json:"client_secret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OauthResponse struct {
|
||||||
|
RefreshTokenExpiresIn string `json:"refresh_token_expires_in"`
|
||||||
|
APIProductList string `json:"api_product_list"`
|
||||||
|
APIProductListJson []string `json:"api_product_list_json"`
|
||||||
|
OrganizationName string `json:"organization_name"`
|
||||||
|
DeveloperEmail string `json:"developer.email"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
IssuedAt string `json:"issued_at"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
ApplicationName string `json:"application_name"`
|
||||||
|
Scope string `json:"scope"`
|
||||||
|
ExpiresIn string `json:"expires_in"`
|
||||||
|
RefreshCount string `json:"refresh_count"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
24
internal/model/observation.go
Normal file
24
internal/model/observation.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Quantity struct {
|
||||||
|
Value float64 `json:"value"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ObservationRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Category []CodeableConcept `json:"category"`
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Performer []Reference `json:"performer"`
|
||||||
|
Specimen *Reference `json:"specimen,omitempty"`
|
||||||
|
BasedOn []Reference `json:"basedOn"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
EffectiveDateTime string `json:"effectiveDateTime"`
|
||||||
|
Issued string `json:"issued"`
|
||||||
|
ValueQuantity *Quantity `json:"valueQuantity,omitempty"`
|
||||||
|
}
|
||||||
38
internal/model/organization.go
Normal file
38
internal/model/organization.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Telecom struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
Use string `json:"use"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddressExtensionValue struct {
|
||||||
|
Url string `json:"url"`
|
||||||
|
ValueCode string `json:"valueCode,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddressExtension struct {
|
||||||
|
Url string `json:"url"`
|
||||||
|
Extension []AddressExtensionValue `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Address struct {
|
||||||
|
Use string `json:"use"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Line []string `json:"line"`
|
||||||
|
City string `json:"city"`
|
||||||
|
PostalCode string `json:"postalCode"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
Extension []AddressExtension `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrganizationRequest struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Type []CodeableConcept `json:"type"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Telecom []Telecom `json:"telecom"`
|
||||||
|
Address []Address `json:"address"`
|
||||||
|
PartOf Reference `json:"partOf"`
|
||||||
|
}
|
||||||
90
internal/model/patient.go
Normal file
90
internal/model/patient.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type PatientRequest struct {
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Meta Meta `json:"meta"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
Name []HumanName `json:"name"`
|
||||||
|
Telecom []Identifier `json:"telecom"`
|
||||||
|
Gender string `json:"gender"`
|
||||||
|
BirthDate string `json:"birthDate"`
|
||||||
|
DeceasedBoolean bool `json:"deceasedBoolean"`
|
||||||
|
Address []AddressObject `json:"address"`
|
||||||
|
MaritalStatus MaritalStatus `json:"maritalStatus"`
|
||||||
|
MultipleBirthInteger int `json:"multipleBirthInteger"`
|
||||||
|
Contact []ContactObject `json:"contact"`
|
||||||
|
Communication []CommunicationObject `json:"communication"`
|
||||||
|
Extension []Extension `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Meta struct {
|
||||||
|
Profile []string `json:"profile"`
|
||||||
|
}
|
||||||
|
type Identifier struct {
|
||||||
|
Use string `json:"use,omitempty"`
|
||||||
|
Type *CodeableConcept `json:"type,omitempty"`
|
||||||
|
System string `json:"system,omitempty"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
type HumanName struct {
|
||||||
|
Use string `json:"use"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
type AddressObject struct {
|
||||||
|
Use string `json:"use"`
|
||||||
|
Line []string `json:"line"`
|
||||||
|
City string `json:"city"`
|
||||||
|
PostalCode string `json:"postalCode"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
Extension []ExtensionObject `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Extension struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Extension []struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
ValueCode string `json:"valueCode"`
|
||||||
|
} `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MaritalStatus struct {
|
||||||
|
Coding []struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
} `json:"coding"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContactObject struct {
|
||||||
|
Relationship []struct {
|
||||||
|
Coding []struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
} `json:"coding"`
|
||||||
|
}
|
||||||
|
Name HumanName `json:"name"`
|
||||||
|
Telecom []Identifier `json:"telecom"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommunicationObject struct {
|
||||||
|
Language struct {
|
||||||
|
Coding []struct {
|
||||||
|
System string `json:"system"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Display string `json:"display"`
|
||||||
|
} `json:"coding"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
} `json:"language"`
|
||||||
|
Preferred bool `json:"preferred"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExtensionObject struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
ValueCode *string `json:"valueCode"`
|
||||||
|
ValueAddress *struct {
|
||||||
|
Country string `json:"country"`
|
||||||
|
City string `json:"city"`
|
||||||
|
} `json:"valueAddress"`
|
||||||
|
}
|
||||||
1
internal/model/practitioner.go
Normal file
1
internal/model/practitioner.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package model
|
||||||
24
internal/model/procedure.go
Normal file
24
internal/model/procedure.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ProcedureRequest struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Category CodeableConcept `json:"category"`
|
||||||
|
Code CodeableConcept `json:"code"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
PerformedPeriod Period `json:"performedPeriod"`
|
||||||
|
Performer []Performer `json:"performer"`
|
||||||
|
ReasonCode []CodeableConcept `json:"reasonCode"`
|
||||||
|
BodySite []CodeableConcept `json:"bodySite"`
|
||||||
|
Note []Annotation `json:"note"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Performer struct {
|
||||||
|
Actor Reference `json:"actor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Annotation struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
24
internal/model/questionnaireresponse.go
Normal file
24
internal/model/questionnaireresponse.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type QuestionnaireResponseRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Questionnaire string `json:"questionnaire" binding:"required"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
Subject Reference `json:"subject" binding:"required"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
Authored string `json:"authored" binding:"required"`
|
||||||
|
Author Reference `json:"author" binding:"required"`
|
||||||
|
Source Reference `json:"source" binding:"required"`
|
||||||
|
Item []QRItem `json:"item" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QRItem struct {
|
||||||
|
LinkID string `json:"linkId"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
Answer []QRAnswer `json:"answer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QRAnswer struct {
|
||||||
|
ValueCoding Coding `json:"valueCoding"`
|
||||||
|
}
|
||||||
10
internal/model/satusehat_akses.go
Normal file
10
internal/model/satusehat_akses.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Akses struct {
|
||||||
|
AuthUrl string
|
||||||
|
BaseUrl string
|
||||||
|
ConsentUrl string
|
||||||
|
KfaUrl string
|
||||||
|
ClientId string
|
||||||
|
ClientSecret string
|
||||||
|
}
|
||||||
40
internal/model/servicerequest.go
Normal file
40
internal/model/servicerequest.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ServiceRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Intent string `json:"intent"`
|
||||||
|
Priority string `json:"priority"`
|
||||||
|
Category []Category `json:"category"`
|
||||||
|
Code Code `json:"code"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Encounter Reference `json:"encounter"`
|
||||||
|
OccurrenceDateTime string `json:"occurrenceDateTime"`
|
||||||
|
AuthoredOn string `json:"authoredOn"`
|
||||||
|
Requester Reference `json:"requester"`
|
||||||
|
Performer []Reference `json:"performer"`
|
||||||
|
ReasonCode []ReasonCode `json:"reasonCode"`
|
||||||
|
LocationCode []LocationCode `json:"locationCode"`
|
||||||
|
LocationReference []Reference `json:"locationReference"`
|
||||||
|
PatientInstruction string `json:"patientInstruction"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Code struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReasonCode struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LocationCode struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
}
|
||||||
33
internal/model/specimen.go
Normal file
33
internal/model/specimen.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type SpecimenRequest struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ResourceType string `json:"resourceType"`
|
||||||
|
Identifier []Identifier `json:"identifier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Type SpecimenType `json:"type"`
|
||||||
|
Collection SpecimenCollection `json:"collection"`
|
||||||
|
Subject Reference `json:"subject"`
|
||||||
|
Request []Reference `json:"request"`
|
||||||
|
ReceivedTime string `json:"receivedTime"`
|
||||||
|
Extension []SpecimenExtension `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpecimenType struct {
|
||||||
|
Coding []Coding `json:"coding"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpecimenCollection struct {
|
||||||
|
CollectedDateTime string `json:"collectedDateTime"`
|
||||||
|
Extension []SpecimenCollectionExtension `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpecimenCollectionExtension struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
ValueReference Reference `json:"valueReference"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpecimenExtension struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
ValueDateTime string `json:"valueDateTime,omitempty"`
|
||||||
|
}
|
||||||
14
internal/routes/allergancytoleran.go
Normal file
14
internal/routes/allergancytoleran.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AllergancyToleran(e *gin.Engine, allergancyToleranHandler *handler.AllergancyToleranHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("AllergyIntolerance")
|
||||||
|
r.POST("/", allergancyToleranHandler.CreateAllergancyToleran)
|
||||||
|
r.PUT("/:id", allergancyToleranHandler.UpdateAllergancyToleran)
|
||||||
|
}
|
||||||
14
internal/routes/careplan.go
Normal file
14
internal/routes/careplan.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CarePlan(e *gin.Engine, cphandler *handler.CarePlanHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("CarePlan")
|
||||||
|
r.POST("/", cphandler.CreateCarePlan)
|
||||||
|
r.PUT("/:id", cphandler.UpdateCarePlan)
|
||||||
|
}
|
||||||
15
internal/routes/clinicalimpression.go
Normal file
15
internal/routes/clinicalimpression.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ClinicalImpression(e *gin.Engine, clinicalImpressionHandler *handler.ClinicalImpressionHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("ClinicalImpression")
|
||||||
|
r.POST("/", clinicalImpressionHandler.CreateClinicalImpression)
|
||||||
|
r.PUT("/:id", clinicalImpressionHandler.UpdateClinicalImpression)
|
||||||
|
// Add more routes as needed
|
||||||
|
}
|
||||||
13
internal/routes/composition.go
Normal file
13
internal/routes/composition.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Composition(r *gin.Engine, h *handler.CompositionHandler, m midleware.AuthMiddleware) {
|
||||||
|
r.POST("/compositions/", h.CreateComposition)
|
||||||
|
r.PUT("/compositions/:id", h.UpdateComposition)
|
||||||
|
}
|
||||||
16
internal/routes/condition.go
Normal file
16
internal/routes/condition.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Condition(e *gin.Engine, conditionHandler *handler.ConditionHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("Condition")
|
||||||
|
r.POST("/", conditionHandler.CreateCondition)
|
||||||
|
r.GET("/", conditionHandler.GetConditionByPatient)
|
||||||
|
r.PUT("/:id", conditionHandler.UpdateCondition)
|
||||||
|
// Add more routes as needed
|
||||||
|
}
|
||||||
14
internal/routes/diagnosisreport.go
Normal file
14
internal/routes/diagnosisreport.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DiagnosisReport(e *gin.Engine, h *handler.DiagnosisReportHandler, m midleware.AuthMiddleware) {
|
||||||
|
group := e.Group("/diagnosis-report")
|
||||||
|
group.POST("/", h.CreateDiagnosisReport)
|
||||||
|
group.PUT("/:id", h.UpdateDiagnosisReport)
|
||||||
|
}
|
||||||
15
internal/routes/encounter.go
Normal file
15
internal/routes/encounter.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Encounter(e *gin.Engine, encounterHandler *handler.EncounterHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("Encounter")
|
||||||
|
r.POST("/", encounterHandler.CreateEncounter)
|
||||||
|
r.GET("/", encounterHandler.GetEncounterByPatient)
|
||||||
|
r.PUT("/:id", encounterHandler.UpdateEncounter)
|
||||||
|
}
|
||||||
15
internal/routes/episodeofcare.go
Normal file
15
internal/routes/episodeofcare.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func EpisodeOfCare(e *gin.Engine, episodeOfCareHandler *handler.EpisodeOfCareHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("EpisodeOfCare")
|
||||||
|
r.POST("/", episodeOfCareHandler.CreateEpisodeOfCare)
|
||||||
|
r.GET("/", episodeOfCareHandler.GetEpisodeOfCareByPatient)
|
||||||
|
r.PUT("/:id", episodeOfCareHandler.UpdateEpisodeOfCare)
|
||||||
|
}
|
||||||
14
internal/routes/goal.go
Normal file
14
internal/routes/goal.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Goal(e *gin.Engine, cphandler *handler.GoalHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("Goal")
|
||||||
|
r.POST("/", cphandler.CreateGoal)
|
||||||
|
r.PUT("/:id", cphandler.UpdateGoal)
|
||||||
|
}
|
||||||
14
internal/routes/imagingstudy.go
Normal file
14
internal/routes/imagingstudy.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ImagingStudy(e *gin.Engine, handler *handler.ImagingStudyHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("ImagingStudy")
|
||||||
|
r.POST("/", handler.CreateImagingStudy)
|
||||||
|
r.PUT("/:id", handler.UpdateImagingStudy)
|
||||||
|
}
|
||||||
14
internal/routes/immunization.go
Normal file
14
internal/routes/immunization.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Immunization(e *gin.Engine, cphandler *handler.ImmunizationHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("Immunization")
|
||||||
|
r.POST("/", cphandler.CreateImmunization)
|
||||||
|
r.PUT("/:id", cphandler.UpdateImmunization)
|
||||||
|
}
|
||||||
14
internal/routes/medicationdispense.go
Normal file
14
internal/routes/medicationdispense.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MedicationDispense(e *gin.Engine, cphandler *handler.MedicationDispenseHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("MedicationDispense")
|
||||||
|
r.POST("/", cphandler.CreateMedicationDispense)
|
||||||
|
r.PUT("/:id", cphandler.UpdateMedicationDispense)
|
||||||
|
}
|
||||||
14
internal/routes/medicationrequest.go
Normal file
14
internal/routes/medicationrequest.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"satusehat-rssa/internal/handler"
|
||||||
|
"satusehat-rssa/internal/midleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MedicationRequest(e *gin.Engine, cphandler *handler.MedicationRequestHandler, m midleware.AuthMiddleware) {
|
||||||
|
r := e.Group("MedicationRequest")
|
||||||
|
r.POST("/", cphandler.CreateMedicationRequest)
|
||||||
|
r.PUT("/:id", cphandler.UpdateMedicationRequest)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user