feat (vclaim-sep-control-letter): add delete and detail by control letter number

This commit is contained in:
dpurbosakti
2025-12-15 13:14:59 +07:00
parent 44b37e2d49
commit a87eed7eaa
8 changed files with 260 additions and 174 deletions
@@ -40,8 +40,9 @@ type UpdateDto struct {
} }
type DeleteDto struct { type DeleteDto struct {
Id uint `json:"id"` Id uint `json:"id"`
Number *string `json:"number"` Number *string `json:"number"`
RequestPayload string `json:"requestPayload" validate:"maxLength=1024"`
} }
type MetaDto struct { type MetaDto struct {
@@ -52,10 +53,11 @@ type MetaDto struct {
type ResponseDto struct { type ResponseDto struct {
ecore.Main ecore.Main
VclaimSep_Number *string `json:"vclaimSep_number"` VclaimSep_Number *string `json:"vclaimSep_number"`
Number *string `json:"number"` Number *string `json:"number"`
Value *string `json:"value"` Value *string `json:"value"`
FileUrl *string `json:"fileUrl"` FileUrl *string `json:"fileUrl"`
Detail *FullResponse `json:"detail,omitempty"`
} }
func (d VclaimSepControlLetter) ToResponse() ResponseDto { func (d VclaimSepControlLetter) ToResponse() ResponseDto {
@@ -64,6 +66,7 @@ func (d VclaimSepControlLetter) ToResponse() ResponseDto {
Number: d.Number, Number: d.Number,
Value: d.Value, Value: d.Value,
FileUrl: d.FileUrl, FileUrl: d.FileUrl,
Detail: d.Detail,
} }
resp.Main = d.Main resp.Main = d.Main
return resp return resp
@@ -77,6 +80,15 @@ func ToResponseList(data []VclaimSepControlLetter) []ResponseDto {
return resp return resp
} }
func (d DeleteDto) RequestPayloadIntoJson() ([]byte, error) {
payload := map[string]interface{}{}
err := json.Unmarshal([]byte(d.RequestPayload), &payload)
if err != nil {
return nil, err
}
return json.Marshal(payload)
}
func (c CreateDto) RequestPayloadIntoJson() ([]byte, error) { func (c CreateDto) RequestPayloadIntoJson() ([]byte, error) {
payload := map[string]interface{}{} payload := map[string]interface{}{}
err := json.Unmarshal([]byte(c.RequestPayload), &payload) err := json.Unmarshal([]byte(c.RequestPayload), &payload)
@@ -122,3 +134,154 @@ func (v ResponseForPDF) GenerateBirthDate() string {
t, _ := time.Parse("2006-01-02", v.VclaimSep.VclaimMember.BirthDate) t, _ := time.Parse("2006-01-02", v.VclaimSep.VclaimMember.BirthDate)
return pu.FormatIndonesianDate(t) return pu.FormatIndonesianDate(t)
} }
type SuratKontrol struct {
NoSuratKontrol string `json:"noSuratKontrol"`
TglRencanaKontrol string `json:"tglRencanaKontrol"`
TglTerbit string `json:"tglTerbit"`
JnsKontrol string `json:"jnsKontrol"`
PoliTujuan string `json:"poliTujuan"`
NamaPoliTujuan string `json:"namaPoliTujuan"`
KodeDokter string `json:"kodeDokter"`
NamaDokter string `json:"namaDokter"`
FlagKontrol string `json:"flagKontrol"`
KodeDokterPembuat *string `json:"kodeDokterPembuat"`
NamaDokterPembuat *string `json:"namaDokterPembuat"`
NamaJnsKontrol string `json:"namaJnsKontrol"`
Sep Sep `json:"sep"`
}
type Sep struct {
NoSep string `json:"noSep"`
TglSep string `json:"tglSep"`
JnsPelayanan string `json:"jnsPelayanan"`
Poli string `json:"poli"`
Diagnosa string `json:"diagnosa"`
Peserta Peserta `json:"peserta"`
ProvUmum ProvUmum `json:"provUmum"`
ProvPerujuk ProvPerujuk `json:"provPerujuk"`
}
type Peserta struct {
NoKartu string `json:"noKartu"`
Nama string `json:"nama"`
TglLahir string `json:"tglLahir"`
Kelamin string `json:"kelamin"`
HakKelas string `json:"hakKelas"`
}
type ProvUmum struct {
KdProvider string `json:"kdProvider"`
NmProvider string `json:"nmProvider"`
}
type ProvPerujuk struct {
KdProviderPerujuk string `json:"kdProviderPerujuk"`
NmProviderPerujuk string `json:"nmProviderPerujuk"`
AsalRujukan string `json:"asalRujukan"`
NoRujukan string `json:"noRujukan"`
TglRujukan string `json:"tglRujukan"`
}
type VclaimResponse struct {
MetaData MetaData `json:"metaData"`
Response *SuratKontrol `json:"response"` // nullable
}
type DetailVclaimResponse struct {
MetaData MetaData `json:"metaData"`
Response *FullResponse `json:"response"` // nullable
}
type MetaData struct {
Code string `json:"code"`
Message string `json:"message"`
}
func (r VclaimResponse) ToPDFNeeds() ([]byte, error) {
response := ResponseForPDF{
Number: r.Response.Sep.NoSep,
PlannedControlDate: r.Response.TglRencanaKontrol,
IssuedDate: r.Response.TglTerbit,
Doctor_Name: r.Response.NamaDokter,
DstUnit_Name: r.Response.NamaPoliTujuan,
ResponsibleDoctor_Name: *r.Response.NamaDokterPembuat,
VclaimSep: VclaimSep{
VclaimMember: VclaimMember{
CardNumber: r.Response.Sep.Peserta.NoKartu,
Name: r.Response.Sep.Peserta.Nama,
BirthDate: r.Response.Sep.Peserta.TglLahir,
Gender: r.Response.Sep.Peserta.Kelamin,
},
Diagnose: r.Response.Sep.Diagnosa,
Number: r.Response.Sep.NoSep,
},
}
return json.Marshal(response)
}
type FullResponse struct {
NoSuratKontrol string `json:"noSuratKontrol"`
TglRencanaKontrol string `json:"tglRencanaKontrol"`
TglTerbit string `json:"tglTerbit"`
JnsKontrol string `json:"jnsKontrol"`
PoliTujuan string `json:"poliTujuan"`
NamaPoliTujuan string `json:"namaPoliTujuan"`
KodeDokter string `json:"kodeDokter"`
NamaDokter string `json:"namaDokter"`
FlagKontrol string `json:"flagKontrol"`
KodeDokterPembuat string `json:"kodeDokterPembuat"`
NamaDokterPembuat string `json:"namaDokterPembuat"`
NamaJnsKontrol string `json:"namaJnsKontrol"`
Sep Sep `json:"sep"`
FormPRB FormPRB `json:"formPRB"`
}
type Provider struct {
KdProvider string `json:"kdProvider"`
NmProvider string `json:"nmProvider"`
}
type FormPRB struct {
KdStatusPRB *string `json:"kdStatusPRB"`
Data PRBData `json:"data"`
}
type PRBData struct {
HBA1C *string `json:"HBA1C"`
GDP *string `json:"GDP"`
GD2JPP *string `json:"GD2JPP"`
EGFR *string `json:"eGFR"`
TD_Sistolik *string `json:"TD_Sistolik"`
TD_Diastolik *string `json:"TD_Diastolik"`
LDL *string `json:"LDL"`
Rata_TD_Sistolik *string `json:"Rata_TD_Sistolik"`
Rata_TD_Diastolik *string `json:"Rata_TD_Diastolik"`
JantungKoroner *string `json:"JantungKoroner"`
Stroke *string `json:"Stroke"`
VaskularPerifer *string `json:"VaskularPerifer"`
Aritmia *string `json:"Aritmia"`
AtrialFibrilasi *string `json:"AtrialFibrilasi"`
SesakNapas3Bulan *string `json:"SesakNapas3Bulan"`
NyeriDada3Bulan *string `json:"NyeriDada3Bulan"`
Terkontrol *string `json:"Terkontrol"`
Gejala2xMinggu *string `json:"Gejala2xMinggu"`
BangunMalam *string `json:"BangunMalam"`
KeterbatasanFisik *string `json:"KeterbatasanFisik"`
FungsiParu *string `json:"FungsiParu"`
SkorMMRC *string `json:"SkorMMRC"`
Eksaserbasi1Tahun *string `json:"Eksaserbasi1Tahun"`
MampuAktivitas *string `json:"MampuAktivitas"`
Epileptik6Bulan *string `json:"Epileptik6Bulan"`
EfekSampingOAB *string `json:"EfekSampingOAB"`
HamilMenyusui *string `json:"HamilMenyusui"`
Remisi *string `json:"Remisi"`
TerapiRumatan *string `json:"TerapiRumatan"`
Usia *string `json:"Usia"`
AsamUrat *string `json:"AsamUrat"`
RemisiSLE *string `json:"RemisiSLE"`
Hamil *string `json:"Hamil"`
NadiIstirahat *string `json:"NadiIstirahat"`
SesakNapasAktivitas *string `json:"SesakNapasAktivitas"`
NyeriDadaAktivitas *string `json:"NyeriDadaAktivitas"`
}
@@ -10,4 +10,6 @@ type VclaimSepControlLetter struct {
Number *string `json:"number" gorm:"unique;size:20"` Number *string `json:"number" gorm:"unique;size:20"`
Value *string `json:"value"` Value *string `json:"value"`
FileUrl *string `json:"fileUrl" gorm:"unique;size:1024"` FileUrl *string `json:"fileUrl" gorm:"unique;size:1024"`
Detail *FullResponse `json:"detail,omitempty" gorm:"-"`
} }
@@ -434,7 +434,9 @@ func SetRoutes() http.Handler {
}) })
hk.GroupRoutes("/v1/vclaim-sep-control-letter", r, hk.MapHandlerFunc{ hk.GroupRoutes("/v1/vclaim-sep-control-letter", r, hk.MapHandlerFunc{
"POST /": vclaimsepcontrolletter.O.Create, "POST /": vclaimsepcontrolletter.O.Create,
"GET /{number}": vclaimsepcontrolletter.O.GetDetail,
"DELETE /{number}": vclaimsepcontrolletter.O.Delete,
}) })
hk.GroupRoutes("/v1/vclaim-sep-hist", r, hk.MapHandlerFunc{ hk.GroupRoutes("/v1/vclaim-sep-hist", r, hk.MapHandlerFunc{
@@ -29,16 +29,16 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
// rw.DataResponse(w, res, err) // rw.DataResponse(w, res, err)
// } // }
// func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
// number := rw.ValidateString(w, "number", r.PathValue("number")) number := rw.ValidateString(w, "number", r.PathValue("number"))
// if number <= "" { if number == "" {
// return return
// } }
// dto := e.ReadDetailDto{} dto := e.ReadDetailDto{}
// dto.Number = &number dto.Number = &number
// res, err := u.ReadDetail(dto) res, err := u.ReadDetail(dto)
// rw.DataResponse(w, res, err) rw.DataResponse(w, res, err)
// } }
// func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { // func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
// number := rw.ValidateString(w, "number", r.PathValue("number")) // number := rw.ValidateString(w, "number", r.PathValue("number"))
@@ -55,13 +55,13 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
// rw.DataResponse(w, res, err) // rw.DataResponse(w, res, err)
// } // }
// func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
// id := rw.ValidateInt(w, "id", r.PathValue("id")) number := rw.ValidateString(w, "number", r.PathValue("number"))
// if id <= 0 { if number == "" {
// return return
// } }
// dto := e.DeleteDto{} dto := e.DeleteDto{}
// dto.Id = uint(id) dto.Number = &number
// res, err := u.Delete(dto) res, err := u.Delete(dto)
// rw.DataResponse(w, res, err) rw.DataResponse(w, res, err)
// } }
@@ -35,7 +35,7 @@ func CreateSepControlLetter(input *e.CreateDto, data *e.VclaimSepControlLetter,
return err return err
} }
var vresp Response var vresp e.VclaimResponse
if err := json.Unmarshal(body, &vresp); err != nil { if err := json.Unmarshal(body, &vresp); err != nil {
return fmt.Errorf("failed to parse response JSON: %w", err) return fmt.Errorf("failed to parse response JSON: %w", err)
} }
@@ -55,71 +55,68 @@ func CreateSepControlLetter(input *e.CreateDto, data *e.VclaimSepControlLetter,
return nil return nil
} }
// func ReadDetailSep(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error { func DeleteSepControlLetter(input *e.DeleteDto, data *e.VclaimSepControlLetter, tx *gorm.DB) error {
// endpoint := fmt.Sprintf("sep/%s", input.Number) payload, err := input.RequestPayloadIntoJson()
// req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+endpoint, nil) if err != nil {
// if err != nil { return err
// return err }
// } req, err := http.NewRequest("DELETE", ibpjs.O.BaseUrl+"RencanaKontrol/Delete", bytes.NewBuffer(payload))
// req.Header.Set("Content-Type", "application/json") if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
// resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)
// if err != nil { if err != nil {
// return err return err
// } }
// defer resp.Body.Close() defer resp.Body.Close()
// body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
// if err != nil { if err != nil {
// return err return err
// } }
// var detail e.SepResponse var vresp e.VclaimResponse
// if err := json.Unmarshal(body, &detail); err != nil { if err := json.Unmarshal(body, &vresp); err != nil {
// return fmt.Errorf("failed to parse response JSON: %w", err) return fmt.Errorf("failed to parse response JSON: %w", err)
// } }
// data.Detail = detail.Response if vresp.MetaData.Code != "200" {
return fmt.Errorf("failed to delete sep control letter: %s", vresp.MetaData.Message)
}
// return nil return nil
// } }
// func DeleteSep(input *e.DeleteDto, data *e.VclaimSep, tx *gorm.DB) error { func GetDetailSepControlLetterByNumber(input *e.ReadDetailDto, data *e.VclaimSepControlLetter, tx *gorm.DB) error {
// payload := e.SepDeleteRequest{} req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+"RencanaKontrol/noSuratKontrol/"+*input.Number, nil)
// payload.Request.TSep.NoSep = *input.Number if err != nil {
// payload.Request.TSep.User = "Coba Ws" return err
}
req.Header.Set("Content-Type", "application/json")
// jsonPayload, err := json.Marshal(payload) resp, err := http.DefaultClient.Do(req)
// if err != nil { if err != nil {
// return err return err
// } }
defer resp.Body.Close()
// req, err := http.NewRequest("DELETE", ibpjs.O.BaseUrl+"sep", bytes.NewBuffer(jsonPayload)) body, err := io.ReadAll(resp.Body)
// if err != nil { if err != nil {
// return err return err
// } }
// req.Header.Set("Content-Type", "application/json") var vresp e.DetailVclaimResponse
if err := json.Unmarshal(body, &vresp); err != nil {
return fmt.Errorf("failed to parse response JSON: %w", err)
}
// resp, err := http.DefaultClient.Do(req) if vresp.MetaData.Code != "200" {
// if err != nil { return fmt.Errorf("failed to get detail sep control letter by number: %s", vresp.MetaData.Message)
// return err }
// }
// defer resp.Body.Close()
// body, err := io.ReadAll(resp.Body) data.Detail = vresp.Response
// if err != nil {
// return err
// }
// var detail e.SepResponse return nil
// if err := json.Unmarshal(body, &detail); err != nil { }
// return fmt.Errorf("failed to parse response JSON: %w", err)
// }
// if detail.MetaData.Message == SepNotFound {
// return fmt.Errorf("sep with number %s not found", *data.Number)
// }
// return nil
// }
@@ -1,87 +0,0 @@
package vclaimsepcontrolletter
import (
"encoding/json"
e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-control-letter"
)
type SuratKontrol struct {
NoSuratKontrol string `json:"noSuratKontrol"`
TglRencanaKontrol string `json:"tglRencanaKontrol"`
TglTerbit string `json:"tglTerbit"`
JnsKontrol string `json:"jnsKontrol"`
PoliTujuan string `json:"poliTujuan"`
NamaPoliTujuan string `json:"namaPoliTujuan"`
KodeDokter string `json:"kodeDokter"`
NamaDokter string `json:"namaDokter"`
FlagKontrol string `json:"flagKontrol"`
KodeDokterPembuat *string `json:"kodeDokterPembuat"`
NamaDokterPembuat *string `json:"namaDokterPembuat"`
NamaJnsKontrol string `json:"namaJnsKontrol"`
Sep Sep `json:"sep"`
}
type Sep struct {
NoSep string `json:"noSep"`
TglSep string `json:"tglSep"`
JnsPelayanan string `json:"jnsPelayanan"`
Poli string `json:"poli"`
Diagnosa string `json:"diagnosa"`
Peserta Peserta `json:"peserta"`
ProvUmum ProvUmum `json:"provUmum"`
ProvPerujuk ProvPerujuk `json:"provPerujuk"`
}
type Peserta struct {
NoKartu string `json:"noKartu"`
Nama string `json:"nama"`
TglLahir string `json:"tglLahir"`
Kelamin string `json:"kelamin"`
HakKelas string `json:"hakKelas"`
}
type ProvUmum struct {
KdProvider string `json:"kdProvider"`
NmProvider string `json:"nmProvider"`
}
type ProvPerujuk struct {
KdProviderPerujuk string `json:"kdProviderPerujuk"`
NmProviderPerujuk string `json:"nmProviderPerujuk"`
AsalRujukan string `json:"asalRujukan"`
NoRujukan string `json:"noRujukan"`
TglRujukan string `json:"tglRujukan"`
}
type Response struct {
MetaData MetaData `json:"metaData"`
Response *SuratKontrol `json:"response"` // nullable
}
type MetaData struct {
Code string `json:"code"`
Message string `json:"message"`
}
func (r Response) ToPDFNeeds() ([]byte, error) {
response := e.ResponseForPDF{
Number: r.Response.Sep.NoSep,
PlannedControlDate: r.Response.TglRencanaKontrol,
IssuedDate: r.Response.TglTerbit,
Doctor_Name: r.Response.NamaDokter,
DstUnit_Name: r.Response.NamaPoliTujuan,
ResponsibleDoctor_Name: *r.Response.NamaDokterPembuat,
VclaimSep: e.VclaimSep{
VclaimMember: e.VclaimMember{
CardNumber: r.Response.Sep.Peserta.NoKartu,
Name: r.Response.Sep.Peserta.Nama,
BirthDate: r.Response.Sep.Peserta.TglLahir,
Gender: r.Response.Sep.Peserta.Kelamin,
},
Diagnose: r.Response.Sep.Diagnosa,
Number: r.Response.Sep.NoSep,
},
}
return json.Marshal(response)
}
@@ -9,4 +9,10 @@ func init() {
createPreMw = append(createPreMw, createPreMw = append(createPreMw,
createMw{Name: "create-sep-control-letter", Func: pvscl.CreateSepControlLetter}, createMw{Name: "create-sep-control-letter", Func: pvscl.CreateSepControlLetter},
) )
readDetailPreMw = append(readDetailPreMw,
readDetailMw{Name: "get-detail-sep-control-letter-by-number", Func: pvscl.GetDetailSepControlLetterByNumber},
)
deletePreMw = append(deletePreMw,
DeleteMw{Name: "delete-sep-control-letter", Func: pvscl.DeleteSepControlLetter},
)
} }
@@ -30,7 +30,10 @@ type readDetailMw struct {
} }
type UpdateMw = readDetailMw type UpdateMw = readDetailMw
type DeleteMw = readDetailMw type DeleteMw struct {
Name string
Func func(input *e.DeleteDto, data *e.VclaimSepControlLetter, tx *gorm.DB) error
}
var createPreMw []createMw // preprocess middleware var createPreMw []createMw // preprocess middleware
var createPostMw []createMw // postprocess middleware var createPostMw []createMw // postprocess middleware
@@ -40,5 +43,5 @@ var readDetailPreMw []readDetailMw
var readDetailPostMw []readDetailMw var readDetailPostMw []readDetailMw
var updatePreMw []readDetailMw var updatePreMw []readDetailMw
var updatePostMw []readDetailMw var updatePostMw []readDetailMw
var deletePreMw []readDetailMw var deletePreMw []DeleteMw
var deletePostMw []readDetailMw var deletePostMw []DeleteMw