From a87eed7eaa38e9cbde26db09699a8cbb068fa057 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 15 Dec 2025 13:14:59 +0700 Subject: [PATCH] feat (vclaim-sep-control-letter): add delete and detail by control letter number --- .../vclaim-sep-control-letter/dto.go | 175 +++++++++++++++++- .../vclaim-sep-control-letter/entity.go | 2 + .../interface/main-handler/main-handler.go | 4 +- .../vclaim-sep-control-letter/handler.go | 40 ++-- .../vclaim-sep-control-letter/plugin.go | 111 ++++++----- .../vclaim-sep-control-letter/tycovar.go | 87 --------- .../vclaim-sep-control-letter/middleware.go | 6 + .../vclaim-sep-control-letter/tycovar.go | 9 +- 8 files changed, 260 insertions(+), 174 deletions(-) delete mode 100644 internal/use-case/bpjs-plugin/vclaim-sep-control-letter/tycovar.go diff --git a/internal/domain/bpjs-entities/vclaim-sep-control-letter/dto.go b/internal/domain/bpjs-entities/vclaim-sep-control-letter/dto.go index 1974e66c..516fb131 100644 --- a/internal/domain/bpjs-entities/vclaim-sep-control-letter/dto.go +++ b/internal/domain/bpjs-entities/vclaim-sep-control-letter/dto.go @@ -40,8 +40,9 @@ type UpdateDto struct { } type DeleteDto struct { - Id uint `json:"id"` - Number *string `json:"number"` + Id uint `json:"id"` + Number *string `json:"number"` + RequestPayload string `json:"requestPayload" validate:"maxLength=1024"` } type MetaDto struct { @@ -52,10 +53,11 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - VclaimSep_Number *string `json:"vclaimSep_number"` - Number *string `json:"number"` - Value *string `json:"value"` - FileUrl *string `json:"fileUrl"` + VclaimSep_Number *string `json:"vclaimSep_number"` + Number *string `json:"number"` + Value *string `json:"value"` + FileUrl *string `json:"fileUrl"` + Detail *FullResponse `json:"detail,omitempty"` } func (d VclaimSepControlLetter) ToResponse() ResponseDto { @@ -64,6 +66,7 @@ func (d VclaimSepControlLetter) ToResponse() ResponseDto { Number: d.Number, Value: d.Value, FileUrl: d.FileUrl, + Detail: d.Detail, } resp.Main = d.Main return resp @@ -77,6 +80,15 @@ func ToResponseList(data []VclaimSepControlLetter) []ResponseDto { 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) { payload := map[string]interface{}{} 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) 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"` +} diff --git a/internal/domain/bpjs-entities/vclaim-sep-control-letter/entity.go b/internal/domain/bpjs-entities/vclaim-sep-control-letter/entity.go index 57f758fb..8f5f65be 100644 --- a/internal/domain/bpjs-entities/vclaim-sep-control-letter/entity.go +++ b/internal/domain/bpjs-entities/vclaim-sep-control-letter/entity.go @@ -10,4 +10,6 @@ type VclaimSepControlLetter struct { Number *string `json:"number" gorm:"unique;size:20"` Value *string `json:"value"` FileUrl *string `json:"fileUrl" gorm:"unique;size:1024"` + + Detail *FullResponse `json:"detail,omitempty" gorm:"-"` } diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 6eb106da..bea0467f 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -434,7 +434,9 @@ func SetRoutes() http.Handler { }) 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{ diff --git a/internal/interface/main-handler/vclaim-sep-control-letter/handler.go b/internal/interface/main-handler/vclaim-sep-control-letter/handler.go index d26cc633..4bdd3d5d 100644 --- a/internal/interface/main-handler/vclaim-sep-control-letter/handler.go +++ b/internal/interface/main-handler/vclaim-sep-control-letter/handler.go @@ -29,16 +29,16 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { // rw.DataResponse(w, res, err) // } -// func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { -// number := rw.ValidateString(w, "number", r.PathValue("number")) -// if number <= "" { -// return -// } -// dto := e.ReadDetailDto{} -// dto.Number = &number -// res, err := u.ReadDetail(dto) -// rw.DataResponse(w, res, err) -// } +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + number := rw.ValidateString(w, "number", r.PathValue("number")) + if number == "" { + return + } + dto := e.ReadDetailDto{} + dto.Number = &number + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} // func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { // 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) // } -// func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { -// id := rw.ValidateInt(w, "id", r.PathValue("id")) -// if id <= 0 { -// return -// } -// dto := e.DeleteDto{} -// dto.Id = uint(id) -// res, err := u.Delete(dto) -// rw.DataResponse(w, res, err) -// } +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + number := rw.ValidateString(w, "number", r.PathValue("number")) + if number == "" { + return + } + dto := e.DeleteDto{} + dto.Number = &number + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/plugin.go b/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/plugin.go index 3ad81f74..cedb3dc9 100644 --- a/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/plugin.go +++ b/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/plugin.go @@ -35,7 +35,7 @@ func CreateSepControlLetter(input *e.CreateDto, data *e.VclaimSepControlLetter, return err } - var vresp Response + var vresp e.VclaimResponse if err := json.Unmarshal(body, &vresp); err != nil { return fmt.Errorf("failed to parse response JSON: %w", err) } @@ -55,71 +55,68 @@ func CreateSepControlLetter(input *e.CreateDto, data *e.VclaimSepControlLetter, return nil } -// func ReadDetailSep(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error { -// endpoint := fmt.Sprintf("sep/%s", input.Number) -// req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+endpoint, nil) -// if err != nil { -// return err -// } -// req.Header.Set("Content-Type", "application/json") +func DeleteSepControlLetter(input *e.DeleteDto, data *e.VclaimSepControlLetter, tx *gorm.DB) error { + payload, err := input.RequestPayloadIntoJson() + if err != nil { + return err + } + req, err := http.NewRequest("DELETE", ibpjs.O.BaseUrl+"RencanaKontrol/Delete", bytes.NewBuffer(payload)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") -// resp, err := http.DefaultClient.Do(req) -// if err != nil { -// return err -// } -// defer resp.Body.Close() + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() -// body, err := io.ReadAll(resp.Body) -// if err != nil { -// return err -// } + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } -// var detail e.SepResponse -// if err := json.Unmarshal(body, &detail); err != nil { -// return fmt.Errorf("failed to parse response JSON: %w", err) -// } + var vresp e.VclaimResponse + if err := json.Unmarshal(body, &vresp); err != nil { + 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 { -// payload := e.SepDeleteRequest{} -// payload.Request.TSep.NoSep = *input.Number -// payload.Request.TSep.User = "Coba Ws" +func GetDetailSepControlLetterByNumber(input *e.ReadDetailDto, data *e.VclaimSepControlLetter, tx *gorm.DB) error { + req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+"RencanaKontrol/noSuratKontrol/"+*input.Number, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") -// jsonPayload, err := json.Marshal(payload) -// if err != nil { -// return err -// } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() -// req, err := http.NewRequest("DELETE", ibpjs.O.BaseUrl+"sep", bytes.NewBuffer(jsonPayload)) -// if err != nil { -// return err -// } + body, err := io.ReadAll(resp.Body) + if err != nil { + 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 err != nil { -// return err -// } -// defer resp.Body.Close() + if vresp.MetaData.Code != "200" { + return fmt.Errorf("failed to get detail sep control letter by number: %s", vresp.MetaData.Message) + } -// body, err := io.ReadAll(resp.Body) -// if err != nil { -// return err -// } + data.Detail = vresp.Response -// var detail e.SepResponse -// 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 -// } + return nil +} diff --git a/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/tycovar.go b/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/tycovar.go deleted file mode 100644 index c732afa5..00000000 --- a/internal/use-case/bpjs-plugin/vclaim-sep-control-letter/tycovar.go +++ /dev/null @@ -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) -} diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/middleware.go b/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/middleware.go index 0cca1159..c9785da8 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/middleware.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/middleware.go @@ -9,4 +9,10 @@ func init() { createPreMw = append(createPreMw, 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}, + ) } diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/tycovar.go index 2e921ae9..ee2e73f1 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/tycovar.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep-control-letter/tycovar.go @@ -30,7 +30,10 @@ type readDetailMw struct { } 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 createPostMw []createMw // postprocess middleware @@ -40,5 +43,5 @@ var readDetailPreMw []readDetailMw var readDetailPostMw []readDetailMw var updatePreMw []readDetailMw var updatePostMw []readDetailMw -var deletePreMw []readDetailMw -var deletePostMw []readDetailMw +var deletePreMw []DeleteMw +var deletePostMw []DeleteMw