Files
satusehat-bridging/internal/integration/medicine_integration.go
2025-11-24 09:13:08 +07:00

197 lines
5.2 KiB
Go

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,
}
}