package medicationdispense import ( "context" "database/sql" "fmt" "service/internal/infrastructure/database" "service/pkg/logger" "service/pkg/utils/query" ) type Repository interface { GetNextMedicationDispense(ctx context.Context, lastID int64) (*MedicationDispenseDB, error) SaveSatuSehatID(ctx context.Context, idx int64, fhirID string) error SaveSyncLog(ctx context.Context, logData MedicationDispenseSyncLog) error } type repository struct { dbManager database.Service } func NewRepository(dbManager database.Service) Repository { return &repository{dbManager: dbManager} } func (r *repository) GetNextMedicationDispense(ctx context.Context, lastID int64) (*MedicationDispenseDB, error) { var md MedicationDispenseDB 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"` NoJual sql.NullString `db:"no_jual"` IdxDaftar int64 `db:"idxdaftar"` KdDokter sql.NullString `db:"kddokter"` JmlhKeluar sql.NullFloat64 `db:"jmlh_keluar"` Sediaan sql.NullString `db:"sediaan"` CreatedAd sql.NullTime `db:"created_at"` TglPesan sql.NullTime `db:"tgl_pesan"` TglKeluar sql.NullTime `db:"tgl_keluar"` } var row simrsRow qSimrs := query.DynamicQuery{ From: "public.t_permintaan_apotek_rajal", Fields: []query.SelectField{ {Expression: "idxpesanobat"}, {Expression: "no_jual"}, {Expression: "idxdaftar"}, {Expression: "kddokter"}, {Expression: "jmlh_keluar"}, {Expression: "sediaan"}, {Expression: "created_at"}, {Expression: "tgl_pesan"}, {Expression: "tgl_keluar"}, }, 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 } md.IdxPesanObat = row.IdxPesanObat md.NoJual = row.NoJual.String md.IdxDaftar = row.IdxDaftar md.JmlhKeluar = row.JmlhKeluar.Float64 md.Sediaan = row.Sediaan.String if row.CreatedAd.Valid { md.PreparedDate = row.CreatedAd.Time } else if row.TglPesan.Valid { md.PreparedDate = row.TglPesan.Time } else { md.PreparedDate = logger.LocalNow() } if row.CreatedAd.Valid { md.HandedOverDate = row.CreatedAd.Time } else if row.TglKeluar.Valid { md.HandedOverDate = row.TglKeluar.Time } else if row.TglPesan.Valid { md.HandedOverDate = row.TglPesan.Time } else { md.HandedOverDate = logger.LocalNow() } satudataDB, err := r.dbManager.GetSQLXDB("satudata") if err != nil { return nil, fmt.Errorf("gagal koneksi ke database satudata: %w", err) } if md.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"`, md.IdxDaftar)}}, }, Limit: 1, } qb.ExecuteQueryRow(ctx, satudataDB, qKunjungan, &kRow) md.PatientID = kRow.PatientID.String md.EncounterID = kRow.EncounterID.String } if row.KdDokter.Valid && row.KdDokter.String != "" { 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"`, row.KdDokter.String)}}, }, Limit: 1, } qb.ExecuteQueryRow(ctx, satudataDB, qPegawai, &pRow) md.PractitionerID = pRow.PractitionerID.String } return &md, 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_dispense", "idxpesanobat"}) _, err = qb.ExecuteUpdate(ctx, simrsDB, "public.t_permintaan_apotek_rajal", query.UpdateData{Columns: []string{"status_bridging_dispense"}, Values: []interface{}{fhirID}}, []query.FilterGroup{query.CreateAndFilterGroup([]query.DynamicFilter{query.CreateEqualFilter("idxpesanobat", idx)})}) return err } func (r *repository) SaveSyncLog(ctx context.Context, logData MedicationDispenseSyncLog) 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", "medicationdispense_id", "request_payload", "response_payload", "status", "error_message"}) insertData := query.InsertData{ Columns: []string{"idxpesanobat", "medicationdispense_id", "request_payload", "response_payload", "status", "error_message"}, Values: []interface{}{logData.IdxPesanObat, logData.MedicationDispenseID, logData.RequestPayload, logData.ResponsePayload, logData.Status, logData.ErrorMessage}, } _, err = qb.ExecuteUpsert(ctx, simrsDB, "public.log_satusehat_medicationdispense", insertData, []string{"idxpesanobat"}, []string{"medicationdispense_id", "request_payload", "response_payload", "status", "error_message"}) return err }