API detail antrian operasi

This commit is contained in:
renaldybrada
2026-02-09 08:56:28 +07:00
parent 1f7a11ea53
commit e0fbc4531a
9 changed files with 587 additions and 9 deletions
+75
View File
@@ -111,6 +111,37 @@ const docTemplate = `{
}
}
},
"/antrian-operasi/{id}": {
"get": {
"tags": [
"Antrian Operasi"
],
"summary": "Detail List Antrian Operasi",
"parameters": [
{
"type": "string",
"description": "id antrian",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/antrianoperasi.DetailPasienOperasiResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/shared.BaseErrorResponse"
}
}
}
}
},
"/dashboard/antrian-per-kategori/": {
"get": {
"tags": [
@@ -452,6 +483,44 @@ const docTemplate = `{
}
}
},
"antrianoperasi.DetailPasienOperasiResponse": {
"type": "object",
"required": [
"diagnosisItems",
"tindakanItems"
],
"properties": {
"diagnosisItems": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/antrianoperasi.DiagnosisItemRequest"
}
},
"dokterPelaksanaItems": {
"type": "array",
"items": {
"$ref": "#/definitions/antrianoperasi.DokterPelaksanaItemRequest"
}
},
"formData": {
"$ref": "#/definitions/antrianoperasi.FormDataRequest"
},
"rencanaOperasiData": {
"$ref": "#/definitions/antrianoperasi.RencanaOperasiRequest"
},
"statusPasienData": {
"$ref": "#/definitions/antrianoperasi.StatusPasienRequest"
},
"tindakanItems": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/antrianoperasi.TindakanItemRequest"
}
}
}
},
"antrianoperasi.DiagnosisItemRequest": {
"type": "object",
"required": [
@@ -596,9 +665,15 @@ const docTemplate = `{
"spesialis": {
"type": "integer"
},
"spesialisName": {
"type": "string"
},
"subSpesialis": {
"type": "integer"
},
"subSpesialisName": {
"type": "string"
},
"tanggalDaftar": {
"type": "string"
}
+75
View File
@@ -105,6 +105,37 @@
}
}
},
"/antrian-operasi/{id}": {
"get": {
"tags": [
"Antrian Operasi"
],
"summary": "Detail List Antrian Operasi",
"parameters": [
{
"type": "string",
"description": "id antrian",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/antrianoperasi.DetailPasienOperasiResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/shared.BaseErrorResponse"
}
}
}
}
},
"/dashboard/antrian-per-kategori/": {
"get": {
"tags": [
@@ -446,6 +477,44 @@
}
}
},
"antrianoperasi.DetailPasienOperasiResponse": {
"type": "object",
"required": [
"diagnosisItems",
"tindakanItems"
],
"properties": {
"diagnosisItems": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/antrianoperasi.DiagnosisItemRequest"
}
},
"dokterPelaksanaItems": {
"type": "array",
"items": {
"$ref": "#/definitions/antrianoperasi.DokterPelaksanaItemRequest"
}
},
"formData": {
"$ref": "#/definitions/antrianoperasi.FormDataRequest"
},
"rencanaOperasiData": {
"$ref": "#/definitions/antrianoperasi.RencanaOperasiRequest"
},
"statusPasienData": {
"$ref": "#/definitions/antrianoperasi.StatusPasienRequest"
},
"tindakanItems": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/antrianoperasi.TindakanItemRequest"
}
}
}
},
"antrianoperasi.DiagnosisItemRequest": {
"type": "object",
"required": [
@@ -590,9 +659,15 @@
"spesialis": {
"type": "integer"
},
"spesialisName": {
"type": "string"
},
"subSpesialis": {
"type": "integer"
},
"subSpesialisName": {
"type": "string"
},
"tanggalDaftar": {
"type": "string"
}
+50
View File
@@ -26,6 +26,32 @@ definitions:
- diagnosisItems
- tindakanItems
type: object
antrianoperasi.DetailPasienOperasiResponse:
properties:
diagnosisItems:
items:
$ref: '#/definitions/antrianoperasi.DiagnosisItemRequest'
minItems: 1
type: array
dokterPelaksanaItems:
items:
$ref: '#/definitions/antrianoperasi.DokterPelaksanaItemRequest'
type: array
formData:
$ref: '#/definitions/antrianoperasi.FormDataRequest'
rencanaOperasiData:
$ref: '#/definitions/antrianoperasi.RencanaOperasiRequest'
statusPasienData:
$ref: '#/definitions/antrianoperasi.StatusPasienRequest'
tindakanItems:
items:
$ref: '#/definitions/antrianoperasi.TindakanItemRequest'
minItems: 1
type: array
required:
- diagnosisItems
- tindakanItems
type: object
antrianoperasi.DiagnosisItemRequest:
properties:
diagnosa:
@@ -119,8 +145,12 @@ definitions:
type: string
spesialis:
type: integer
spesialisName:
type: string
subSpesialis:
type: integer
subSpesialisName:
type: string
tanggalDaftar:
type: string
required:
@@ -381,6 +411,26 @@ paths:
summary: Create Antrian Operasi
tags:
- Antrian Operasi
/antrian-operasi/{id}:
get:
parameters:
- description: id antrian
in: path
name: id
required: true
type: string
responses:
"200":
description: OK
schema:
$ref: '#/definitions/antrianoperasi.DetailPasienOperasiResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/shared.BaseErrorResponse'
summary: Detail List Antrian Operasi
tags:
- Antrian Operasi
/dashboard/antrian-per-kategori/:
get:
responses:
@@ -106,3 +106,28 @@ func (h AntrianOperasiHandler) GetListAntrianOperasi(c *gin.Context) {
res.Data, res.Paging, true, 200, "success get list antrian operasi",
))
}
// DetailAntrianOperasi godoc
// @Summary Detail List Antrian Operasi
// @Tags Antrian Operasi
// @Param id path string true "id antrian"
// @Success 200 {object} DetailPasienOperasiResponse
// @Failure 500 {object} shared.BaseErrorResponse
// @Router /antrian-operasi/{id} [get]
func (h AntrianOperasiHandler) GetDetailAntrianOperasi(c *gin.Context) {
id := c.Param("id")
res, err := h.repo.GetAntrianOperasiById(c, id)
if err != nil {
c.JSON(500, shared.BaseErrorResponse{
Success: false,
Code: 500,
Message: err.Error(),
})
return
}
c.JSON(200,
shared.ToBaseResponse(
res.MapToResponse(), true, 200, "success get antrian operasi",
))
}
+42
View File
@@ -36,3 +36,45 @@ type DiagnosaOperasiModel struct {
JenisDiagnosa string `db:"Jenis_diagnosa"`
AntrianId string `db:"antrian_id"`
}
type TindakanOperasiModel struct {
ID string `db:"id"`
KodeTindakan string `db:"Kode_tindakan"`
Tindakan *string `db:"Tindakan"`
TindakanTambahan *string `db:"Tindakan_tambahan"`
}
type TeleponPasienModel struct {
ID string `db:"id"`
NomorTelepon string `db:"Nomor_telepon"`
}
type DokterOperasiModel struct {
ID string `db:"id"`
Nip string `db:"nip"`
NamaDepan string `db:"nama_depan"`
NamaBelakang string `db:"nama_belakang"`
SatuanKerja string `db:"satker"`
}
type DetailPasienOperasi struct {
ID string `db:"id" json:"id"`
TglDaftar time.Time `db:"tanggal_daftar"`
TglSelesai *time.Time `db:"tanggal_selesai"`
TglLahir *time.Time `db:"tanggal_lahir"`
Umur *string `db:"umur"`
Alamat *string `db:"alamat"`
NoKtp *string `db:"no_ktp"`
NoRekamMedis *string `db:"no_rekam_medis"`
NamaPasien *string `db:"nama_pasien"`
IdSpesialis int `db:"id_spesialis"`
IdSubSpesialis int `db:"id_sub_spesialis"`
IdKategori int `db:"id_kategori"`
Spesialis *string `db:"spesialis"`
SubSpesialis *string `db:"subspesialis"`
Kategori *string `db:"kategori"`
StatusOperasi *string `db:"status_operasi"`
JenisKelamin *string `db:"jenis_kelamin"`
Keterangan *string `db:"keterangan"`
RencanaOperasi *string `db:"rencana_operasi"`
}
+213 -3
View File
@@ -20,6 +20,7 @@ const TBL_DIAGNOSA_OPERASI = "data_diagnosa_pasien_operasi"
type IAntrianOperasiRepository interface {
CreateAntrianOperasi(c *gin.Context, req CreatePasienOperasiRequest) (CreatePasienOperasiRequest, error)
SearchableListAntrianOperasi(c *gin.Context) (ListPasienOperasiPaginate, error)
GetAntrianOperasiById(c *gin.Context, id string) (DetailPasienOperasiResultQuery, error)
}
type antrianOperasiRepo struct {
@@ -36,10 +37,10 @@ func NewRepository(dbService database.Service) IAntrianOperasiRepository {
"\"Spesialis\"", "\"Sub_spesialis\"", "\"Keterangan_status_pasien\"",
"\"Nomor_spesialis\"", "\"Nomor_sub_spesialis\"",
"\"Nomor_telepon\"",
"\"FK_pasien_operasi_telepon_pasien_operasi_ID\"",
"\"FK_pasien_operasi_telepon_pasien_operasi_ID\"", "FK_pasien_operasi_telepon_pasien_operasi_ID",
"\"Kode_diagnosa\"", "\"Diagnosa\"", "\"Jenis_diagnosa\"", "\"FK_pasien_operasi_diagnosa_pasien_operasi_ID\"", "FK_pasien_operasi_diagnosa_pasien_operasi_ID",
"\"Kode_tindakan\"", "\"Tindakan\"", "\"Tindakan_tambahan\"", "\"FK_pasien_operasi_tindakan_pasien_operasi_ID\"",
"\"data_pasien_operasi_id\"", "\"data_pegawai_id\"",
"\"Kode_tindakan\"", "\"Tindakan\"", "\"Tindakan_tambahan\"", "\"FK_pasien_operasi_tindakan_pasien_operasi_ID\"", "FK_pasien_operasi_tindakan_pasien_operasi_ID",
"\"data_pasien_operasi_id\"", "\"data_pegawai_id\"", "data_pasien_operasi_id",
}).
SetAllowedTables([]string{TBL_NAME, TBL_DIAGNOSA_OPERASI})
queryBuilder.SetSecurityOptions(false, 100)
@@ -477,3 +478,212 @@ func (r antrianOperasiRepo) SearchableListAntrianOperasi(c *gin.Context) (ListPa
return result, nil
}
func (r antrianOperasiRepo) GetAntrianOperasiById(c *gin.Context, id string) (DetailPasienOperasiResultQuery, error) {
var result DetailPasienOperasiResultQuery
// main query
query := queryUtils.DynamicQuery{
From: TBL_NAME,
Aliases: "dpo",
Fields: []queryUtils.SelectField{
{Expression: "dpo.id"},
{Expression: "dpo.Tanggal_daftar", Alias: "tanggal_daftar"},
{Expression: "dpo.Tanggal_selesai_operasi", Alias: "tanggal_selesai"},
{Expression: "dpo.Tanggal_lahir", Alias: "tanggal_lahir"},
{Expression: "dpo.Umur", Alias: "umur"},
{Expression: "dpo.Alamat", Alias: "alamat"},
{Expression: "dpo.No_KTP", Alias: "no_ktp"},
{Expression: "dpo.No_rekam_medis", Alias: "no_rekam_medis"},
{Expression: "dpo.Nama_pasien", Alias: "nama_pasien"},
{Expression: "dpo.Status_operasi", Alias: "status_operasi"},
{Expression: "dpo.Jenis_kelamin", Alias: "jenis_kelamin"},
{Expression: "dpo.Spesialis", Alias: "id_spesialis"},
{Expression: "dpo.Sub_spesialis", Alias: "id_sub_spesialis"},
{Expression: "dpo.Kategori_operasi", Alias: "id_kategori"},
{Expression: "ds.Spesialis", Alias: "spesialis"},
{Expression: "dss.Subspesialis", Alias: "subspesialis"},
{Expression: "dko.Kategori", Alias: "kategori"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "dpo.id", Operator: queryUtils.OpEqual, Value: id},
}, LogicOp: "AND",
},
},
Joins: []queryUtils.Join{
{
Type: "LEFT",
Table: "daftar_spesialis",
Alias: "ds",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "ds.id", Operator: queryUtils.OpEqual, Value: "dpo.Spesialis",
},
},
},
},
{
Type: "LEFT",
Table: "daftar_subspesialis",
Alias: "dss",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "dpo.Sub_spesialis", Operator: queryUtils.OpEqual, Value: "dss.id",
},
},
},
},
{
Type: "LEFT",
Table: "daftar_kategori_operasi",
Alias: "dko",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "dpo.Kategori_operasi", Operator: queryUtils.OpEqual, Value: "dko.id",
},
},
},
},
},
}
dbconn, err := r.db.GetSQLXDB(DB_NAME)
if err != nil {
log.Printf("Unable to connect db : %s", err)
return result, err
}
err = r.queryBuilder.ExecuteQueryRow(c, dbconn, query, &result.ResultMain)
if err != nil {
log.Printf("Unable to execute main query : %s", err)
return result, err
}
// query diagnosa
queryDiagnosa := queryUtils.DynamicQuery{
From: "data_diagnosa_pasien_operasi",
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "Kode_diagnosa"},
{Expression: "Diagnosa"},
{Expression: "Jenis_diagnosa"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "FK_pasien_operasi_diagnosa_pasien_operasi_ID", Operator: queryUtils.OpEqual, Value: result.ResultMain.ID},
}, LogicOp: "AND",
},
},
}
err = r.queryBuilder.ExecuteQuery(c, dbconn, queryDiagnosa, &result.ResultDiagnosa)
if err != nil {
log.Printf("Unable to execute diagnosa query : %s", err)
return result, err
}
// query tindakan
queryTindakan := queryUtils.DynamicQuery{
From: "data_tindakan_pasien_operasi",
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "Kode_tindakan"},
{Expression: "Tindakan"},
{Expression: "Tindakan_tambahan"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "FK_pasien_operasi_tindakan_pasien_operasi_ID", Operator: queryUtils.OpEqual, Value: result.ResultMain.ID},
}, LogicOp: "AND",
},
},
}
err = r.queryBuilder.ExecuteQuery(c, dbconn, queryTindakan, &result.ResultTindakan)
if err != nil {
log.Printf("Unable to execute tindakan query : %s", err)
return result, err
}
// query telepon
queryTelepon := queryUtils.DynamicQuery{
From: "data_telepon_pasien_operasi",
Fields: []queryUtils.SelectField{
{Expression: "id"},
{Expression: "Nomor_telepon"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "FK_pasien_operasi_telepon_pasien_operasi_ID", Operator: queryUtils.OpEqual, Value: result.ResultMain.ID},
}, LogicOp: "AND",
},
},
}
err = r.queryBuilder.ExecuteQuery(c, dbconn, queryTelepon, &result.ResultTeleponOperasi)
if err != nil {
log.Printf("Unable to execute telepon query : %s", err)
return result, err
}
// query dokter
queryDokter := queryUtils.DynamicQuery{
From: "data_pasien_operasi_data_pegawai_2",
Aliases: "dpodp",
Fields: []queryUtils.SelectField{
{Expression: "dpodp.id"},
{Expression: "dp.NIP", Alias: "nip"},
{Expression: "dp.Nama_depan", Alias: "nama_depan"},
{Expression: "dp.Nama_belakang", Alias: "nama_belakang"},
{Expression: "dk.Nama_ksm", Alias: "satker"},
},
Filters: []queryUtils.FilterGroup{
{
Filters: []queryUtils.DynamicFilter{
{Column: "data_pasien_operasi_id", Operator: queryUtils.OpEqual, Value: result.ResultMain.ID},
}, LogicOp: "AND",
},
},
Joins: []queryUtils.Join{
{
Type: "LEFT",
Table: "data_pegawai",
Alias: "dp",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "dpodp.data_pegawai_id", Operator: queryUtils.OpEqual, Value: "dp.id",
},
},
},
},
{
Type: "LEFT",
Table: "daftar_ksm",
Alias: "dk",
OnConditions: queryUtils.FilterGroup{
Filters: []queryUtils.DynamicFilter{
{
Column: "dp.KSM", Operator: queryUtils.OpEqual, Value: "dk.id",
},
},
},
},
},
}
err = r.queryBuilder.ExecuteQuery(c, dbconn, queryDokter, &result.ResultDokterOperasi)
if err != nil {
log.Printf("Unable to execute dokter query : %s", err)
return result, err
}
return result, nil
}
+8 -6
View File
@@ -28,12 +28,14 @@ type TindakanItemRequest struct {
}
type RencanaOperasiRequest struct {
Spesialis int `json:"spesialis" binding:"required"`
SubSpesialis int `json:"subSpesialis" binding:"required"`
TanggalDaftar *time.Time `json:"tanggalDaftar"`
KategoriOperasi int `json:"kategoriOperasi"`
RencanaOperasi *string `json:"rencanaOperasi"`
Keterangan *string `json:"keterangan"`
Spesialis int `json:"spesialis" binding:"required"`
SpesialisName *string
SubSpesialis int `json:"subSpesialis" binding:"required"`
SubSpesialisName *string
TanggalDaftar *time.Time `json:"tanggalDaftar"`
KategoriOperasi int `json:"kategoriOperasi"`
RencanaOperasi *string `json:"rencanaOperasi"`
Keterangan *string `json:"keterangan"`
}
type DokterPelaksanaItemRequest struct {
@@ -0,0 +1,98 @@
package antrianoperasi
import (
"strings"
)
type DetailPasienOperasiResultQuery struct {
ResultMain DetailPasienOperasi
ResultDiagnosa []DiagnosaOperasiModel
ResultTindakan []TindakanOperasiModel
ResultTeleponOperasi []TeleponPasienModel
ResultDokterOperasi []DokterOperasiModel
}
type DetailPasienOperasiResponse struct {
FormData FormDataRequest `json:"formData"`
DiagnosisItem []DiagnosisItemRequest `json:"diagnosisItems" binding:"required,min=1,dive"`
TindakanItems []TindakanItemRequest `json:"tindakanItems" binding:"required,min=1,dive"`
RencanaOperasiData RencanaOperasiRequest `json:"rencanaOperasiData"`
DokterPelaksanaItems []DokterPelaksanaItemRequest `json:"dokterPelaksanaItems"`
StatusPasienData StatusPasienRequest `json:"statusPasienData"`
}
func handleStringPointer(str *string) string {
var result string
if str != nil {
result = *str
}
return result
}
func (model DetailPasienOperasiResultQuery) MapToResponse() DetailPasienOperasiResponse {
var result DetailPasienOperasiResponse
// map main data
var tglLahir string
if model.ResultMain.TglLahir != nil {
tglLahir = model.ResultMain.TglLahir.Format("2006-01-02")
}
result.FormData = FormDataRequest{
NoRekamMedis: handleStringPointer(model.ResultMain.NoRekamMedis),
NoKtp: model.ResultMain.NoKtp,
NamaPasien: model.ResultMain.NamaPasien,
JenisKelamin: model.ResultMain.JenisKelamin,
TglLahir: &tglLahir,
Umur: model.ResultMain.Umur,
Alamat: model.ResultMain.Alamat,
}
for _, tlp := range model.ResultTeleponOperasi {
result.FormData.NoTelepon = append(result.FormData.NoTelepon, tlp.NomorTelepon)
}
for _, d := range model.ResultDiagnosa {
result.DiagnosisItem = append(result.DiagnosisItem, DiagnosisItemRequest{
KodeDiagnosa: d.KodeDiagnosa,
Diagnosa: d.Diagnosa.String,
JenisDiagnosa: d.JenisDiagnosa,
})
}
for _, t := range model.ResultTindakan {
result.TindakanItems = append(result.TindakanItems, TindakanItemRequest{
KodeTindakan: &t.KodeTindakan,
Tindakan: t.Tindakan,
TindakanTambahan: t.TindakanTambahan,
})
}
result.RencanaOperasiData = RencanaOperasiRequest{
Spesialis: model.ResultMain.IdSpesialis,
SpesialisName: model.ResultMain.Spesialis,
SubSpesialis: model.ResultMain.IdSubSpesialis,
SubSpesialisName: model.ResultMain.SubSpesialis,
TanggalDaftar: &model.ResultMain.TglDaftar,
KategoriOperasi: model.ResultMain.IdKategori,
RencanaOperasi: model.ResultMain.RencanaOperasi,
Keterangan: model.ResultMain.Keterangan,
}
for _, dk := range model.ResultDokterOperasi {
joinedName := strings.ToUpper(dk.NamaDepan) + " " + strings.ToUpper(dk.NamaBelakang)
result.DokterPelaksanaItems = append(result.DokterPelaksanaItems, DokterPelaksanaItemRequest{
Id: dk.ID,
Nip: &dk.Nip,
Nama: &joinedName,
SatuanKerja: &dk.SatuanKerja,
})
}
result.StatusPasienData = StatusPasienRequest{
TglSelesai: model.ResultMain.TglSelesai,
StatusOperasi: model.ResultMain.StatusOperasi,
KeteranganStatus: model.ResultMain.Keterangan,
}
return result
}
@@ -20,4 +20,5 @@ func RegisterRoutes(r *gin.RouterGroup, dbService database.Service) {
r.POST("/antrian-operasi", antrianOperasiHandler.CreateAntrianOperasi)
r.GET("/antrian-operasi", antrianOperasiHandler.GetListAntrianOperasi)
r.GET("/antrian-operasi/:id", antrianOperasiHandler.GetDetailAntrianOperasi)
}