package medicationrequest import ( "context" "database/sql" "fmt" "service/internal/infrastructure/database" "service/pkg/logger" "service/pkg/utils/query" ) type Repository interface { GetNextMedicationRequest(ctx context.Context, lastID int64) (*MedicationRequestDB, error) SaveSatuSehatID(ctx context.Context, idx int64, fhirID string) error SaveSyncLog(ctx context.Context, logData MedicationRequestSyncLog) error } type repository struct { dbManager database.Service } func NewRepository(dbManager database.Service) Repository { return &repository{dbManager: dbManager} } func (r *repository) GetNextMedicationRequest(ctx context.Context, lastID int64) (*MedicationRequestDB, error) { var mr MedicationRequestDB simrsDB, err := r.dbManager.GetSQLXDB("simrs") if err != nil { return nil, err } qb := query.NewSQLQueryBuilder(query.DBTypePostgreSQL). SetSecurityOptions(false, 0). SetQueryLogging(false). SetAllowedColumns([]string{"idxpesanobat", `"IDXDAFTAR"`, `"KDDOKTER"`}) type simrsRow struct { IdxPesanObat int64 `db:"idxpesanobat"` No sql.NullString `db:"no"` IdxDaftar int64 `db:"idxdaftar"` KdDokter sql.NullString `db:"kddokter"` JmlhKeluar sql.NullFloat64 `db:"jmlh_keluar"` Sediaan sql.NullString `db:"sediaan"` CreatedAt sql.NullTime `db:"created_at"` TglPesan sql.NullTime `db:"tgl_pesan"` AturanPakai sql.NullString `db:"aturan_pakai"` } var row simrsRow qSimrs := query.DynamicQuery{ From: "public.t_permintaan_apotek_rajal", Fields: []query.SelectField{ {Expression: "idxpesanobat"}, {Expression: "no"}, {Expression: "idxdaftar"}, {Expression: "kddokter"}, {Expression: "jmlh_keluar"}, {Expression: "sediaan"}, {Expression: "created_at"}, {Expression: "tgl_pesan"}, {Expression: "aturan_pakai"}, }, Filters: []query.FilterGroup{ { Filters: []query.DynamicFilter{ query.CreateFilter("idxpesanobat", query.OpGreaterThan, lastID), }, }, }, Sort: []query.SortField{ query.CreateAscSort("idxpesanobat"), }, Limit: 1, } err = qb.ExecuteQueryRow(ctx, simrsDB, qSimrs, &row) if err != nil { return nil, err } mr.IdxPesanObat = row.IdxPesanObat mr.No = row.No.String mr.IdxDaftar = row.IdxDaftar mr.KdDokter = row.KdDokter.String mr.JmlhKeluar = row.JmlhKeluar.Float64 mr.Sediaan = row.Sediaan.String mr.AturanPakai = row.AturanPakai.String if row.CreatedAt.Valid { mr.CreatedAt = row.CreatedAt.Time } else if row.TglPesan.Valid { mr.CreatedAt = row.TglPesan.Time } else { mr.CreatedAt = logger.LocalNow() } satudataDB, err := r.dbManager.GetSQLXDB("satudata") if err != nil { return nil, fmt.Errorf("gagal koneksi ke database satudata: %w", err) } // Ambil PatientID dan EncounterID dari tabel public.data_kunjungan_pasien di database satudata if mr.IdxDaftar > 0 { type kunjunganRow struct { PatientID sql.NullString `db:"Nomor_satusehat_pasien"` EncounterID sql.NullString `db:"IDXDAFTAR_satusehat"` } var kRow kunjunganRow qKunjungan := query.DynamicQuery{ From: "public.data_kunjungan_pasien", Fields: []query.SelectField{ {Expression: `"Nomor_satusehat_pasien"`}, {Expression: `"IDXDAFTAR_satusehat"`}, }, Filters: []query.FilterGroup{ {Filters: []query.DynamicFilter{query.CreateEqualFilter(`"IDXDAFTAR"`, mr.IdxDaftar)}}, }, Limit: 1, } qb.ExecuteQueryRow(ctx, satudataDB, qKunjungan, &kRow) mr.PatientID = kRow.PatientID.String mr.EncounterID = kRow.EncounterID.String } // Ambil PractitionerID dari tabel public.data_pegawai di database satudata if mr.KdDokter != "" { type pegawaiRow struct { PractitionerID sql.NullString `db:"Kode_satusehat"` } var pRow pegawaiRow qPegawai := query.DynamicQuery{ From: "public.data_pegawai", Fields: []query.SelectField{ {Expression: `"Kode_satusehat"`}, }, Filters: []query.FilterGroup{ {Filters: []query.DynamicFilter{query.CreateEqualFilter(`"KDDOKTER"`, mr.KdDokter)}}, }, Limit: 1, } qb.ExecuteQueryRow(ctx, satudataDB, qPegawai, &pRow) mr.PractitionerID = pRow.PractitionerID.String } return &mr, nil } func (r *repository) SaveSatuSehatID(ctx context.Context, idx int64, fhirID string) error { simrsDB, err := r.dbManager.GetSQLXDB("simrs") if err != nil { return err } qb := query.NewSQLQueryBuilder(query.DBTypePostgreSQL). SetSecurityOptions(false, 0). SetQueryLogging(false). SetAllowedColumns([]string{"status_bridging", "idxpesanobat"}) _, err = qb.ExecuteUpdate(ctx, simrsDB, "public.t_permintaan_apotek_rajal", query.UpdateData{Columns: []string{"status_bridging"}, Values: []interface{}{fhirID}}, []query.FilterGroup{query.CreateAndFilterGroup([]query.DynamicFilter{query.CreateEqualFilter("idxpesanobat", idx)})}) return err } func (r *repository) SaveSyncLog(ctx context.Context, logData MedicationRequestSyncLog) error { simrsDB, err := r.dbManager.GetSQLXDB("simrs") if err != nil { return err } qb := query.NewSQLQueryBuilder(query.DBTypePostgreSQL). SetSecurityOptions(false, 0). SetQueryLogging(false). SetAllowedColumns([]string{"idxpesanobat", "medicationrequest_id", "request_payload", "response_payload", "status", "error_message"}) insertData := query.InsertData{ Columns: []string{"idxpesanobat", "medicationrequest_id", "request_payload", "response_payload", "status", "error_message"}, Values: []interface{}{logData.IdxPesanObat, logData.MedicationRequestID, logData.RequestPayload, logData.ResponsePayload, logData.Status, logData.ErrorMessage}, } _, err = qb.ExecuteUpsert(ctx, simrsDB, "public.log_satusehat_medicationrequest", insertData, []string{"idxpesanobat"}, []string{"medicationrequest_id", "request_payload", "response_payload", "status", "error_message"}) return err }