Add MCU report endpoint and deployment tooling
This commit is contained in:
@@ -64,6 +64,10 @@ type DokterRepository interface {
|
||||
ListDokter(ctx context.Context, params repository.DokterListParams) (repository.DokterPage, error)
|
||||
}
|
||||
|
||||
type LaporanMCURepository interface {
|
||||
ListLaporanMCU(ctx context.Context, params repository.LaporanMCUParams) ([]repository.LaporanMCURow, error)
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
layananRepo LayananRepository
|
||||
labRepo LabRegistrationRepository
|
||||
@@ -76,6 +80,7 @@ type Handler struct {
|
||||
periodeTarifDetailRepo PeriodeTarifDetailRepository
|
||||
perusahaanRepo PerusahaanRepository
|
||||
dokterRepo DokterRepository
|
||||
laporanMCURepo LaporanMCURepository
|
||||
hospitalCode string
|
||||
departmentID string
|
||||
}
|
||||
@@ -95,12 +100,19 @@ type CPONERepository interface {
|
||||
}
|
||||
|
||||
func NewHandler(repo CPONERepository) Handler {
|
||||
return Handler{
|
||||
handler := Handler{
|
||||
layananRepo: repo, labRepo: repo, patientRepo: repo, registrationRepo: repo,
|
||||
labResultRepo: repo, paketRepo: repo, tarifRepo: repo,
|
||||
periodeTarifRepo: repo, periodeTarifDetailRepo: repo, perusahaanRepo: repo,
|
||||
dokterRepo: repo,
|
||||
}
|
||||
// Keep NewHandler source-compatible with repositories created before the
|
||||
// MCU report was added. The concrete MySQL repository implements this
|
||||
// optional capability and the dynamic production handler uses it.
|
||||
if reportRepo, ok := any(repo).(LaporanMCURepository); ok {
|
||||
handler.laporanMCURepo = reportRepo
|
||||
}
|
||||
return handler
|
||||
}
|
||||
|
||||
func NewDynamicHandler(hospitalCode string, departmentID string) Handler {
|
||||
@@ -187,6 +199,13 @@ func (h Handler) dokterRepository(ctx context.Context) DokterRepository {
|
||||
return h.dokterRepo
|
||||
}
|
||||
|
||||
func (h Handler) laporanMCURepository(ctx context.Context) LaporanMCURepository {
|
||||
if repo, ok := selectedRepository(ctx); ok {
|
||||
return repo
|
||||
}
|
||||
return h.laporanMCURepo
|
||||
}
|
||||
|
||||
func (h Handler) MappingHarga(w http.ResponseWriter, r *http.Request) {
|
||||
layananIDs := parseLayananIDs(r)
|
||||
if len(layananIDs) == 0 {
|
||||
|
||||
72
internal/http/laporan_mcu.go
Normal file
72
internal/http/laporan_mcu.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"primaya-api/cpone-middleware/internal/repository"
|
||||
)
|
||||
|
||||
// ListLaporanMCU exposes the data formerly produced as mcu.xls by
|
||||
// docs/lap_mcu.php. The API keeps the same lower-case date parameters as the
|
||||
// PHP script and returns the spreadsheet rows as JSON data.
|
||||
func (h Handler) ListLaporanMCU(w http.ResponseWriter, r *http.Request) {
|
||||
tanggal, ok := firstQueryValue(r, "tanggal", "Tanggal")
|
||||
if !ok || strings.TrimSpace(tanggal) == "" {
|
||||
WriteJSON(w, http.StatusUnprocessableEntity, Response{
|
||||
Success: false, Message: "Parameter tanggal wajib diisi", Data: nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
tanggal2, ok := firstQueryValue(r, "tanggal2", "Tanggal2")
|
||||
if !ok || strings.TrimSpace(tanggal2) == "" {
|
||||
WriteJSON(w, http.StatusUnprocessableEntity, Response{
|
||||
Success: false, Message: "Parameter tanggal2 wajib diisi", Data: nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
start, err := parseReportDate(tanggal)
|
||||
if err != nil {
|
||||
WriteJSON(w, http.StatusUnprocessableEntity, Response{
|
||||
Success: false, Message: "Parameter tanggal harus format Y-m-d", Data: nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
end, err := parseReportDate(tanggal2)
|
||||
if err != nil {
|
||||
WriteJSON(w, http.StatusUnprocessableEntity, Response{
|
||||
Success: false, Message: "Parameter tanggal2 harus format Y-m-d", Data: nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
if end.Before(start) {
|
||||
WriteJSON(w, http.StatusUnprocessableEntity, Response{
|
||||
Success: false, Message: "Parameter tanggal2 tidak boleh lebih kecil dari tanggal", Data: nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := h.laporanMCURepository(r.Context()).ListLaporanMCU(r.Context(), repository.LaporanMCUParams{
|
||||
Tanggal: start.Format("2006-01-02"), Tanggal2: end.Format("2006-01-02"),
|
||||
})
|
||||
if err != nil {
|
||||
WriteJSON(w, http.StatusInternalServerError, Response{
|
||||
Success: false, Message: "internal server error", Data: nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
WriteJSON(w, http.StatusOK, Response{Success: true, Message: "ok", Data: rows})
|
||||
}
|
||||
|
||||
// GetLaporanMCU is an explicit alias for callers that use the Get naming
|
||||
// convention for report endpoints.
|
||||
func (h Handler) GetLaporanMCU(w http.ResponseWriter, r *http.Request) {
|
||||
h.ListLaporanMCU(w, r)
|
||||
}
|
||||
|
||||
func parseReportDate(value string) (time.Time, error) {
|
||||
return time.Parse("2006-01-02", strings.TrimSpace(value))
|
||||
}
|
||||
74
internal/http/laporan_mcu_test.go
Normal file
74
internal/http/laporan_mcu_test.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"primaya-api/cpone-middleware/internal/repository"
|
||||
)
|
||||
|
||||
type fakeLaporanMCURepository struct {
|
||||
rows []repository.LaporanMCURow
|
||||
err error
|
||||
params repository.LaporanMCUParams
|
||||
}
|
||||
|
||||
func (f *fakeLaporanMCURepository) ListLaporanMCU(_ context.Context, params repository.LaporanMCUParams) ([]repository.LaporanMCURow, error) {
|
||||
f.params = params
|
||||
return f.rows, f.err
|
||||
}
|
||||
|
||||
func TestListLaporanMCUResponseAndDateRange(t *testing.T) {
|
||||
regID := "MCU260900001"
|
||||
repo := &fakeLaporanMCURepository{rows: []repository.LaporanMCURow{{No: 1, RegID: ®ID}}}
|
||||
handler := Handler{laporanMCURepo: repo}
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodGet, "/api/cpone/reports/mcu?tanggal=2026-09-01&tanggal2=2026-09-07", nil)
|
||||
|
||||
handler.ListLaporanMCU(recorder, request)
|
||||
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if repo.params.Tanggal != "2026-09-01" || repo.params.Tanggal2 != "2026-09-07" {
|
||||
t.Fatalf("params=%+v", repo.params)
|
||||
}
|
||||
for _, expected := range []string{`"success":true`, `"message":"ok"`, `"No":1`, `"RegID":"MCU260900001"`} {
|
||||
if !strings.Contains(recorder.Body.String(), expected) {
|
||||
t.Fatalf("response missing %s: %s", expected, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestListLaporanMCUValidatesDateRange(t *testing.T) {
|
||||
repo := &fakeLaporanMCURepository{}
|
||||
handler := Handler{laporanMCURepo: repo}
|
||||
for target := range map[string]struct{}{
|
||||
"/api/cpone/reports/mcu": {},
|
||||
"/api/cpone/reports/mcu?tanggal=01-09-2026&tanggal2=2026-09-07": {},
|
||||
"/api/cpone/reports/mcu?tanggal=2026-09-08&tanggal2=2026-09-07": {},
|
||||
"/api/cpone/reports/mcu?tanggal=2026-09-01&tanggal2=not-a-date": {},
|
||||
} {
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.ListLaporanMCU(recorder, httptest.NewRequest(http.MethodGet, target, nil))
|
||||
if recorder.Code != http.StatusUnprocessableEntity {
|
||||
t.Fatalf("target=%s status=%d body=%s", target, recorder.Code, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
if repo.params != (repository.LaporanMCUParams{}) {
|
||||
t.Fatalf("repository should not be called for invalid dates: %+v", repo.params)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListLaporanMCUInternalError(t *testing.T) {
|
||||
handler := Handler{laporanMCURepo: &fakeLaporanMCURepository{err: errors.New("database unavailable")}}
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.ListLaporanMCU(recorder, httptest.NewRequest(http.MethodGet, "/api/cpone/reports/mcu?tanggal=2026-09-01&tanggal2=2026-09-01", nil))
|
||||
if recorder.Code != http.StatusInternalServerError {
|
||||
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
326
internal/repository/laporan_mcu.go
Normal file
326
internal/repository/laporan_mcu.go
Normal file
@@ -0,0 +1,326 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// LaporanMCUParams is the date range used by docs/lap_mcu.php. The bounds are
|
||||
// deliberately second-based because the legacy report queried
|
||||
// "tanggal 00:00:01" through "tanggal2 23:59:59".
|
||||
type LaporanMCUParams struct {
|
||||
Tanggal string
|
||||
Tanggal2 string
|
||||
}
|
||||
|
||||
// LaporanMCURow contains the columns that the legacy Excel report writes.
|
||||
// Nullable values remain pointers so an absent HIS record is represented as
|
||||
// null by the API, while values for which the PHP report supplied a fallback
|
||||
// are always non-null.
|
||||
type LaporanMCURow struct {
|
||||
No int `json:"No"`
|
||||
RegID *string `json:"RegID"`
|
||||
MEDRECID *string `json:"MEDRECID"`
|
||||
NamaPasien *string `json:"NamaPasien"`
|
||||
JenisKelamin *string `json:"JenisKelamin"`
|
||||
TanggalLahir *string `json:"TanggalLahir"`
|
||||
Umur *int64 `json:"Umur"`
|
||||
TanggalMCU *string `json:"TanggalMCU"`
|
||||
NamaPenanggung *string `json:"NamaPenanggung"`
|
||||
DokterMCU *string `json:"DokterMCU"`
|
||||
InstansiKerja *string `json:"InstansiKerja"`
|
||||
TinggiBadan *string `json:"TinggiBadan"`
|
||||
BeratBadan *string `json:"BeratBadan"`
|
||||
TekananDarah *string `json:"TekananDarah"`
|
||||
Nadi *string `json:"Nadi"`
|
||||
Suhu *string `json:"Suhu"`
|
||||
Pernafasan *string `json:"Pernafasan"`
|
||||
Diabetes *string `json:"Diabetes"`
|
||||
Hipertensi *string `json:"Hipertensi"`
|
||||
Dyslipidemia *string `json:"Dyslipidemia"`
|
||||
Jantung *string `json:"Jantung"`
|
||||
Stroke *string `json:"Stroke"`
|
||||
Asma *string `json:"Asma"`
|
||||
Paru *string `json:"Paru"`
|
||||
RiwayatCidera *string `json:"RiwayatCidera"`
|
||||
RiwayatRawatInap *string `json:"RiwayatRawatInap"`
|
||||
RiwayatOperasi *string `json:"RiwayatOperasi"`
|
||||
LainLain *string `json:"LainLain"`
|
||||
DiabetesKeluarga *string `json:"DiabetesKeluarga"`
|
||||
HipertensiKeluarga *string `json:"HipertensiKeluarga"`
|
||||
DyslipidemiaKeluarga *string `json:"DyslipidemiaKeluarga"`
|
||||
JantungKeluarga *string `json:"JantungKeluarga"`
|
||||
StrokeKeluarga *string `json:"StrokeKeluarga"`
|
||||
AsmaKeluarga *string `json:"AsmaKeluarga"`
|
||||
ParuKeluarga *string `json:"ParuKeluarga"`
|
||||
RiwayatCideraKeluarga *string `json:"RiwayatCideraKeluarga"`
|
||||
RiwayatRawatInapKeluarga *string `json:"RiwayatRawatInapKeluarga"`
|
||||
RiwayatOperasiKeluarga *string `json:"RiwayatOperasiKeluarga"`
|
||||
LainLainKeluarga *string `json:"LainLainKeluarga"`
|
||||
AlergiObat *string `json:"AlergiObat"`
|
||||
AlergiMakanan *string `json:"AlergiMakanan"`
|
||||
AlergiLain *string `json:"AlergiLain"`
|
||||
Merokok *string `json:"Merokok"`
|
||||
Alkohol *string `json:"Alkohol"`
|
||||
Olahraga *string `json:"Olahraga"`
|
||||
KeadaanUmum *string `json:"KeadaanUmum"`
|
||||
KeadaanSakit *string `json:"KeadaanSakit"`
|
||||
StatusGizi *string `json:"StatusGizi"`
|
||||
Kesadaran *string `json:"Kesadaran"`
|
||||
ColourBlindness *string `json:"ColourBlindness"`
|
||||
VisusDekat *string `json:"VisusDekat"`
|
||||
KelainananMataLain *string `json:"KelainananMataLain"`
|
||||
Faring *string `json:"Faring"`
|
||||
Tonsil *string `json:"Tonsil"`
|
||||
MulutLainLain *string `json:"MulutLainLain"`
|
||||
KelainanGigi *string `json:"KelainanGigi"`
|
||||
ParuLain *string `json:"ParuLain"`
|
||||
JantungLain *string `json:"JantungLain"`
|
||||
Hernia *string `json:"Hernia"`
|
||||
KeluhanUtama *string `json:"KeluhanUtama"`
|
||||
PenyakitSekarang *string `json:"PenyakitSekarang"`
|
||||
PenyakitDahulu *string `json:"PenyakitDahulu"`
|
||||
ECG *string `json:"ECG"`
|
||||
Audiometri *string `json:"Audiometri"`
|
||||
Spirometri *string `json:"Spirometri"`
|
||||
PemeriksaanLainLain *string `json:"PemeriksaanLainLain"`
|
||||
SaranKesehatanKerja *string `json:"SaranKesehatanKerja"`
|
||||
Kebisingan *string `json:"Kebisingan"`
|
||||
SuhuPanas *string `json:"SuhuPanas"`
|
||||
SuhuDingin *string `json:"SuhuDingin"`
|
||||
RadiasiBukanPengion *string `json:"RadiasiBukanPengion"`
|
||||
RadiasiPengion *string `json:"RadiasiPengion"`
|
||||
GetaranLokal *string `json:"GetaranLokal"`
|
||||
GetaranSeluruhTubuh *string `json:"GetaranSeluruhTubuh"`
|
||||
Ketinggian *string `json:"Ketinggian"`
|
||||
LainLainAkibatKerja *string `json:"LainLainAkibatKerja"`
|
||||
DebuOrganik *string `json:"DebuOrganik"`
|
||||
DebuAnorganik *string `json:"DebuAnorganik"`
|
||||
Asap *string `json:"Asap"`
|
||||
LogamBerat *string `json:"LogamBerat"`
|
||||
PelarutOrganik *string `json:"PelarutOrganik"`
|
||||
IritanAsam *string `json:"IritanAsam"`
|
||||
IritanBasa *string `json:"IritanBasa"`
|
||||
CairanPembersih *string `json:"CairanPembersih"`
|
||||
Pestisida *string `json:"Pestisida"`
|
||||
UapLogam *string `json:"UapLogam"`
|
||||
BahayaKimiaLain *string `json:"BahayaKimiaLain"`
|
||||
Bakteri *string `json:"Bakteri"`
|
||||
CairanTubuh *string `json:"CairanTubuh"`
|
||||
Serangga *string `json:"Serangga"`
|
||||
Limbah *string `json:"Limbah"`
|
||||
BiologiLain *string `json:"BiologiLain"`
|
||||
Overload *string `json:"Overload"`
|
||||
Mismatch *string `json:"Mismatch"`
|
||||
KetidakJelasan *string `json:"KetidakJelasan"`
|
||||
HambatanJenjangKarir *string `json:"HambatanJenjangKarir"`
|
||||
KerjaShift *string `json:"KerjaShift"`
|
||||
KonflikTeman *string `json:"KonflikTeman"`
|
||||
KonflikKeluarga *string `json:"KonflikKeluarga"`
|
||||
PsikologisLain *string `json:"PsikologisLain"`
|
||||
TanganBergerakUlang *string `json:"TanganBergerakUlang"`
|
||||
AngkatBerat *string `json:"AngkatBerat"`
|
||||
DudukLama *string `json:"DudukLama"`
|
||||
BerdiriLama *string `json:"BerdiriLama"`
|
||||
PosisiTubuhTidakErgonomis *string `json:"PosisiTubuhTidakErgonomis"`
|
||||
PencahayaanTidakSesuai *string `json:"PencahayaanTidakSesuai"`
|
||||
LihatMonitorLama *string `json:"LihatMonitorLama"`
|
||||
ErgonomisLain *string `json:"ErgonomisLain"`
|
||||
VisusJauhTanpaKoreksiVOD *string `json:"VisusJauhTanpaKoreksiVOD"`
|
||||
VisusJauhTanpaKoreksiVOS *string `json:"VisusJauhTanpaKoreksiVOS"`
|
||||
VisusJauhDenganKoreksiVOD *string `json:"VisusJauhDenganKoreksiVOD"`
|
||||
VisusJauhDenganKoreksiVOS *string `json:"VisusJauhDenganKoreksiVOS"`
|
||||
Pekerjaan *string `json:"Pekerjaan"`
|
||||
DokterPemeriksa *string `json:"DokterPemeriksa"`
|
||||
}
|
||||
|
||||
func (r MySQLLayananRepository) ListLaporanMCU(ctx context.Context, params LaporanMCUParams) ([]LaporanMCURow, error) {
|
||||
rows, err := r.db.QueryContext(ctx, laporanMCUQuery, params.Tanggal+" 00:00:01", params.Tanggal2+" 23:59:59")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
result := make([]LaporanMCURow, 0)
|
||||
for rows.Next() {
|
||||
row, err := scanLaporanMCURow(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
row.No = len(result) + 1
|
||||
result = append(result, row)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
const laporanMCUQuery = `
|
||||
SELECT
|
||||
r.RegID, r.MEDRECID, r.Nama,
|
||||
CASE WHEN m.Kelamin = 'L' THEN 'Laki - Laki' ELSE 'Perempuan' END,
|
||||
DATE_FORMAT(m.TanggalLahir, '%Y-%m-%d'), TIMESTAMPDIFF(YEAR, m.TanggalLahir, CURDATE()),
|
||||
DATE_FORMAT(r.Tanggal, '%Y-%m-%d %H:%i:%s'),
|
||||
COALESCE(NULLIF(p.Nama, ''), 'UMUM'), d.Nama, pm.DepartemenKerja,
|
||||
rd.TinggiBadan, rd.BeratBadan, tv.Tekanandarah, tv.Nadi, tv.Suhu, tv.Pernafasan,
|
||||
COALESCE(NULLIF(rpd.DiabetesDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.HipertensiDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.KelebihanLemakDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.JantungDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.StrokeDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.AsmaDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.ParuDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.CideraDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.RawatInapDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.OperasiDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpd.LainLainDahuluAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.DiabetesAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.HypertensiAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.KelebihanLemakAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.JantungAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.StrokeAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.AsmaAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.ParuAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.CideraAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.RawatInapAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.OperasiAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(rpk.LainLainAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(ra.AlergiObatAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(ra.AlergiMakananAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(ra.AlergiLainAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(gl.SejakKapanMerokok, ''), 'Tidak Merokok'),
|
||||
COALESCE(NULLIF(gl.SejakKapanAlkohol, ''), 'Tidak Minum ALkohol'),
|
||||
COALESCE(NULLIF(gl.KebiasaanOlahragaAda, ''), 'Tidak Olahraga'),
|
||||
pfu.KeadaanUmum, pfu.KeadaanSakit, pfu.StatusGizi, pfu.Kesadaran,
|
||||
pmata.ColourBlindness,
|
||||
COALESCE(NULLIF(pmata.VisusDekatKelainan, ''), 'Normal'),
|
||||
COALESCE(NULLIF(pmata.MataLainLainAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(ptg.FaringKelainan, ''), 'Normal'),
|
||||
COALESCE(NULLIF(ptg.TonsilKelainan, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(pmulut.MulutLainLainAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(pgigi.KelainanGigiAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(pparu.ParuLainLainAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(pjantung.JantungLainLainAda, ''), 'Tidak Ada'),
|
||||
COALESCE(NULLIF(pabd.HerniaAda, ''), 'Tidak Ada'),
|
||||
pm.KeluhanUtamaRingkasan, pm.PenyakitSekarangRingkasan, pm.PenyakitDahuluRingkasan,
|
||||
ph.ECG, ph.Audiometri, ph.Spirometri, pm.PemeriksaanLainLainRingkasan,
|
||||
pm.SaranKesehatanKerjaRingkasan,
|
||||
COALESCE(NULLIF(pak.KebisinganAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.SuhuPanasAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.SuhuDinginAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.RadiasiBukanPengionAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.RadiasiPengionAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.GetaranLokalAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.GetaranSeluruhTubuhAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.KetinggianAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.FisikLainLainAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.DebuOrganikAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.DebuAnorganikAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.AsapAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.LogamBeratAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.PelarutOrganikAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.IritanAsamAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.IritanBasaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.CairanPembersihAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.PestisidaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.UapLogamAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.BahanKimiaBerbahayaLainLainAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.BakteriAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.CairanTubuhAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.SeranggaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.LimbahAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.BiologiLainLainAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.OverLoadKerjaanAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.MismatchKerjaanAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.KetidakjelasanTugasAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.HambatanJenjangKarirAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.KerjaShiftAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.KonflikTemanKerjaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.KonflikKeluargaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.PsikologisLainLainAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.TanganBergerakBerulangAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.AngkatBebanBeratAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.DudukLamaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.BerdiriLamaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.PosisiTubuhTidakErgonomisAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.PencahayaanTidakSesuaiAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.LihatMonitorLamaAda, ''), 'TidakAda'),
|
||||
COALESCE(NULLIF(pak.ErgonomisLainLainAda, ''), 'TidakAda'),
|
||||
pmata.VisusJauhTanpaKoreksiVOD, pmata.VisusJauhTanpaKoreksiVOS,
|
||||
pmata.VisusJauhDenganKoreksiVOD, pmata.VisusJauhDenganKoreksiVOS,
|
||||
m.Pekerjaan, dp.Nama
|
||||
FROM regpas AS r
|
||||
LEFT JOIN medrec AS m ON m.MEDRECID = r.MEDRECID
|
||||
LEFT JOIN pengkajianmcu AS pm ON pm.RegID = r.RegID
|
||||
LEFT JOIN dokter AS d ON d.DokterID = r.DokterID
|
||||
LEFT JOIN dokter AS dp ON dp.DokterID = pm.DokterIDPengkaji
|
||||
LEFT JOIN perusahaan AS p ON p.PerusahaanID = r.AsuransiID
|
||||
LEFT JOIN tandavital_pasien AS tv ON tv.RegID = r.RegID AND tv.TekananDarah NOT LIKE ''
|
||||
LEFT JOIN regpas_detail AS rd ON rd.RegID = r.RegID
|
||||
LEFT JOIN gayahidup AS gl ON gl.RegID = r.RegID
|
||||
LEFT JOIN riwayatpenyakitdahulu AS rpd ON rpd.RegID = r.RegID
|
||||
LEFT JOIN riwayatpenyakitkeluarga AS rpk ON rpk.RegID = r.RegID
|
||||
LEFT JOIN riwayatalergi AS ra ON ra.MEDRECID = r.MEDRECID
|
||||
LEFT JOIN pemeriksaanfisik_umum AS pfu ON pfu.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_mata AS pmata ON pmata.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_tenggorokan AS ptg ON ptg.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_mulut AS pmulut ON pmulut.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_gigi AS pgigi ON pgigi.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_paru AS pparu ON pparu.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_jantung AS pjantung ON pjantung.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaanfisik_abdomen AS pabd ON pabd.RegID = r.RegID
|
||||
LEFT JOIN pemeriksaankhusus AS ph ON ph.RegID = r.RegID
|
||||
LEFT JOIN penyakitakibatkerja AS pak ON pak.RegID = r.RegID
|
||||
WHERE r.Tanggal BETWEEN ? AND ? AND r.JenisRegID = '2' AND r.NA = 'N'
|
||||
ORDER BY r.Tanggal, r.RegID`
|
||||
|
||||
func scanLaporanMCURow(scanner rowScanner) (LaporanMCURow, error) {
|
||||
var row LaporanMCURow
|
||||
var regID, medrecID, nama, jenisKelamin, tanggalLahir, tanggalMCU, namaPenanggung, dokterMCU, instansiKerja sql.NullString
|
||||
var umur sql.NullInt64
|
||||
var fields [103]sql.NullString
|
||||
args := []any{
|
||||
®ID, &medrecID, &nama, &jenisKelamin, &tanggalLahir, &umur, &tanggalMCU,
|
||||
&namaPenanggung, &dokterMCU, &instansiKerja,
|
||||
}
|
||||
for i := range fields {
|
||||
args = append(args, &fields[i])
|
||||
}
|
||||
if err := scanner.Scan(args...); err != nil {
|
||||
return LaporanMCURow{}, err
|
||||
}
|
||||
|
||||
row.RegID = nullStringPtr(regID)
|
||||
row.MEDRECID = nullStringPtr(medrecID)
|
||||
row.NamaPasien = nullStringPtr(nama)
|
||||
row.JenisKelamin = nullStringPtr(jenisKelamin)
|
||||
row.TanggalLahir = nullStringPtr(tanggalLahir)
|
||||
row.Umur = nullInt64Ptr(umur)
|
||||
row.TanggalMCU = nullStringPtr(tanggalMCU)
|
||||
row.NamaPenanggung = nullStringPtr(namaPenanggung)
|
||||
row.DokterMCU = nullStringPtr(dokterMCU)
|
||||
row.InstansiKerja = nullStringPtr(instansiKerja)
|
||||
|
||||
values := make([]*string, len(fields))
|
||||
for i := range fields {
|
||||
values[i] = nullStringPtr(fields[i])
|
||||
}
|
||||
assignLaporanMCUFields(&row, values)
|
||||
return row, nil
|
||||
}
|
||||
|
||||
func assignLaporanMCUFields(row *LaporanMCURow, v []*string) {
|
||||
// The SELECT order intentionally mirrors the legacy spreadsheet column
|
||||
// order after the ten patient/header columns above.
|
||||
row.TinggiBadan, row.BeratBadan, row.TekananDarah, row.Nadi, row.Suhu, row.Pernafasan = v[0], v[1], v[2], v[3], v[4], v[5]
|
||||
row.Diabetes, row.Hipertensi, row.Dyslipidemia, row.Jantung, row.Stroke, row.Asma, row.Paru, row.RiwayatCidera, row.RiwayatRawatInap, row.RiwayatOperasi, row.LainLain = v[6], v[7], v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15], v[16]
|
||||
row.DiabetesKeluarga, row.HipertensiKeluarga, row.DyslipidemiaKeluarga, row.JantungKeluarga, row.StrokeKeluarga, row.AsmaKeluarga, row.ParuKeluarga, row.RiwayatCideraKeluarga, row.RiwayatRawatInapKeluarga, row.RiwayatOperasiKeluarga, row.LainLainKeluarga = v[17], v[18], v[19], v[20], v[21], v[22], v[23], v[24], v[25], v[26], v[27]
|
||||
row.AlergiObat, row.AlergiMakanan, row.AlergiLain, row.Merokok, row.Alkohol, row.Olahraga = v[28], v[29], v[30], v[31], v[32], v[33]
|
||||
row.KeadaanUmum, row.KeadaanSakit, row.StatusGizi, row.Kesadaran, row.ColourBlindness, row.VisusDekat, row.KelainananMataLain = v[34], v[35], v[36], v[37], v[38], v[39], v[40]
|
||||
row.Faring, row.Tonsil, row.MulutLainLain, row.KelainanGigi, row.ParuLain, row.JantungLain, row.Hernia = v[41], v[42], v[43], v[44], v[45], v[46], v[47]
|
||||
row.KeluhanUtama, row.PenyakitSekarang, row.PenyakitDahulu, row.ECG, row.Audiometri, row.Spirometri, row.PemeriksaanLainLain, row.SaranKesehatanKerja = v[48], v[49], v[50], v[51], v[52], v[53], v[54], v[55]
|
||||
row.Kebisingan, row.SuhuPanas, row.SuhuDingin, row.RadiasiBukanPengion, row.RadiasiPengion, row.GetaranLokal, row.GetaranSeluruhTubuh, row.Ketinggian, row.LainLainAkibatKerja, row.DebuOrganik, row.DebuAnorganik, row.Asap, row.LogamBerat, row.PelarutOrganik, row.IritanAsam, row.IritanBasa, row.CairanPembersih, row.Pestisida, row.UapLogam, row.BahayaKimiaLain = v[56], v[57], v[58], v[59], v[60], v[61], v[62], v[63], v[64], v[65], v[66], v[67], v[68], v[69], v[70], v[71], v[72], v[73], v[74], v[75]
|
||||
row.Bakteri, row.CairanTubuh, row.Serangga, row.Limbah, row.BiologiLain, row.Overload, row.Mismatch, row.KetidakJelasan, row.HambatanJenjangKarir, row.KerjaShift, row.KonflikTeman, row.KonflikKeluarga, row.PsikologisLain, row.TanganBergerakUlang, row.AngkatBerat, row.DudukLama, row.BerdiriLama, row.PosisiTubuhTidakErgonomis, row.PencahayaanTidakSesuai, row.LihatMonitorLama, row.ErgonomisLain = v[76], v[77], v[78], v[79], v[80], v[81], v[82], v[83], v[84], v[85], v[86], v[87], v[88], v[89], v[90], v[91], v[92], v[93], v[94], v[95], v[96]
|
||||
row.VisusJauhTanpaKoreksiVOD, row.VisusJauhTanpaKoreksiVOS, row.VisusJauhDenganKoreksiVOD, row.VisusJauhDenganKoreksiVOS, row.Pekerjaan, row.DokterPemeriksa = v[97], v[98], v[99], v[100], v[101], v[102]
|
||||
}
|
||||
Reference in New Issue
Block a user