Files
cpone_midleware/internal/repository/perusahaan.go

291 lines
11 KiB
Go

package repository
import (
"context"
"database/sql"
"fmt"
)
type PerusahaanListParams struct {
Search string
Page int
PerPage int
}
type PerusahaanPage struct {
Items []PerusahaanSummary
Total int
}
type PerusahaanSummary struct {
PerusahaanID string `json:"PerusahaanID"`
KodePerusahaan string `json:"KodePerusahaan"`
Nama string `json:"Nama"`
}
type PerusahaanDetail struct {
PerusahaanID string `json:"PerusahaanID"`
KodePerusahaan string `json:"KodePerusahaan"`
Nama string `json:"Nama"`
JenisPerusahaanID int64 `json:"JenisPerusahaanID"`
Penjamin string `json:"Penjamin"`
Asuransi string `json:"Asuransi"`
Provider string `json:"Provider"`
COB string `json:"COB"`
MataUangID string `json:"MataUangID"`
Penanggungjawab *string `json:"Penanggungjawab"`
TeleponPenanggungjawab *string `json:"TeleponPenanggungjawab"`
EmailPenanggungjawab *string `json:"EmailPenanggungjawab"`
Alamat *string `json:"Alamat"`
Kota *string `json:"Kota"`
KodePos *string `json:"KodePos"`
Propinsi *string `json:"Propinsi"`
Negara *string `json:"Negara"`
Telepon *string `json:"Telepon"`
Fax *string `json:"Fax"`
Email *string `json:"Email"`
Website *string `json:"Website"`
NamaBank *string `json:"NamaBank"`
NamaRekening *string `json:"NamaRekening"`
NomerRekening *string `json:"nomerRekening"`
DefaultLamaPembayaran int64 `json:"DefaultLamaPembayaran"`
DefaultDiskon string `json:"DefaultDiskon"`
PPN string `json:"ppn"`
Catatan *string `json:"Catatan"`
NPWP *string `json:"NPWP"`
FlagDiskon string `json:"FlagDiskon"`
VerifikasiBilling string `json:"VerifikasiBilling"`
PICMarketing *string `json:"PIC_Marketing"`
NA string `json:"NA"`
}
type PerusahaanGroupTarifDetail struct {
PerusahaanID string `json:"PerusahaanID"`
KodePerusahaan string `json:"KodePerusahaan"`
NamaPerusahaan string `json:"NamaPerusahaan"`
GroupTarif []PerusahaanGroupTarif `json:"GroupTarif"`
}
type PerusahaanGroupTarif struct {
GroupTarifID int64 `json:"GroupTarifID"`
NamaGroupTarif string `json:"NamaGroupTarif"`
TanggalBerlaku string `json:"TanggalBerlaku"`
TanggalBerakhir string `json:"TanggalBerakhir"`
PeriodeTarifID int64 `json:"PeriodeTarifID"`
Keterangan string `json:"Keterangan"`
DetailLayanan []PerusahaanGroupTarifLayanan `json:"DetailLayanan"`
}
type PerusahaanGroupTarifLayanan struct {
TarifLayananID int64 `json:"TarifLayananID"`
LayananID string `json:"LayananID"`
NamaLayanan *string `json:"NamaLayanan"`
JenisLayananID int64 `json:"JenisLayananID"`
NamaJenisLayanan *string `json:"NamaJenisLayanan"`
Kelas string `json:"Kelas"`
NamaKelas string `json:"NamaKelas"`
Harga string `json:"Harga"`
TipeDiskonRJ string `json:"TipeDiskonRJ"`
DiskonRJ string `json:"DiskonRJ"`
TipeDiskonRI string `json:"TipeDiskonRI"`
DiskonRI string `json:"DiskonRI"`
TipeShare string `json:"TipeShare"`
ShareDokter string `json:"ShareDokter"`
ShareRS string `json:"ShareRS"`
ShareExt string `json:"ShareExt"`
ShareLain string `json:"ShareLain"`
AsalTarif string `json:"AsalTarif"`
}
func (r MySQLLayananRepository) ListPerusahaan(ctx context.Context, params PerusahaanListParams) (PerusahaanPage, error) {
where := "WHERE NA = 'N'"
args := make([]any, 0, 5)
if params.Search != "" {
where += " AND (Nama LIKE ? OR KodePerusahaan LIKE ? OR PerusahaanID LIKE ?)"
like := "%" + params.Search + "%"
args = append(args, like, like, like)
}
var total int
if err := r.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM perusahaan "+where, args...).Scan(&total); err != nil {
return PerusahaanPage{}, err
}
queryArgs := append(append([]any{}, args...), params.PerPage, (params.Page-1)*params.PerPage)
rows, err := r.db.QueryContext(ctx, `SELECT PerusahaanID, KodePerusahaan, Nama
FROM perusahaan `+where+` ORDER BY Nama LIMIT ? OFFSET ?`, queryArgs...)
if err != nil {
return PerusahaanPage{}, err
}
defer rows.Close()
items := make([]PerusahaanSummary, 0)
for rows.Next() {
var item PerusahaanSummary
if err := rows.Scan(&item.PerusahaanID, &item.KodePerusahaan, &item.Nama); err != nil {
return PerusahaanPage{}, err
}
items = append(items, item)
}
if err := rows.Err(); err != nil {
return PerusahaanPage{}, err
}
return PerusahaanPage{Items: items, Total: total}, nil
}
func (r MySQLLayananRepository) GetPerusahaan(ctx context.Context, id string) (*PerusahaanDetail, error) {
row := r.db.QueryRowContext(ctx, `SELECT PerusahaanID, KodePerusahaan, Nama, JenisPerusahaanID,
Penjamin, Asuransi, Provider, COB, MataUangID, Penanggungjawab, TeleponPenanggungjawab,
EmailPenanggungjawab, Alamat, Kota, KodePos, Propinsi, Negara, Telepon, Fax, Email,
Website, NamaBank, NamaRekening, NomerRekening, DefaultLamaPembayaran,
CAST(DefaultDiskon AS CHAR), CAST(ppn AS CHAR), Catatan, NPWP, FlagDiskon,
VerifikasiBilling, PIC_Marketing, NA
FROM perusahaan WHERE NA = 'N' AND (PerusahaanID = ? OR KodePerusahaan = ?) LIMIT 1`, id, id)
detail, err := scanPerusahaanDetail(row)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
return &detail, nil
}
func (r MySQLLayananRepository) GetPerusahaanGroupTarif(ctx context.Context, id, groupTarifID string) (*PerusahaanGroupTarifDetail, error) {
var result PerusahaanGroupTarifDetail
err := r.db.QueryRowContext(ctx, `SELECT PerusahaanID, KodePerusahaan, Nama FROM perusahaan
WHERE PerusahaanID = ? OR KodePerusahaan = ? LIMIT 1`, id, id).
Scan(&result.PerusahaanID, &result.KodePerusahaan, &result.NamaPerusahaan)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
query := `SELECT pg.GroupTarifID, CAST(pg.TanggalBerlaku AS CHAR), CAST(pg.TanggalBerakhir AS CHAR),
pg.PeriodeTarifID, pg.Keterangan
FROM perusahaan_grouptarif pg
INNER JOIN perusahaan_tarif pt ON pt.Perusahaan_TarifID = pg.Perusahaan_TarifID
WHERE pt.PerusahaanID = ? AND pg.NA = 'N'
AND CURDATE() BETWEEN pg.TanggalBerlaku AND pg.TanggalBerakhir`
args := []any{result.PerusahaanID}
if groupTarifID != "" {
query += " AND pg.GroupTarifID = ?"
args = append(args, groupTarifID)
}
query += " ORDER BY pg.Keterangan"
rows, err := r.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
result.GroupTarif = make([]PerusahaanGroupTarif, 0)
for rows.Next() {
var group PerusahaanGroupTarif
if err := rows.Scan(&group.GroupTarifID, &group.TanggalBerlaku, &group.TanggalBerakhir,
&group.PeriodeTarifID, &group.Keterangan); err != nil {
return nil, err
}
if group.Keterangan != "" {
group.NamaGroupTarif = group.Keterangan
} else {
group.NamaGroupTarif = fmt.Sprintf("Group Tarif %d", group.GroupTarifID)
}
group.DetailLayanan, err = r.perusahaanGroupTarifLayanan(ctx, group.GroupTarifID)
if err != nil {
return nil, err
}
result.GroupTarif = append(result.GroupTarif, group)
}
if err := rows.Err(); err != nil {
return nil, err
}
return &result, nil
}
func (r MySQLLayananRepository) perusahaanGroupTarifLayanan(ctx context.Context, groupTarifID int64) ([]PerusahaanGroupTarifLayanan, error) {
tableName := fmt.Sprintf("perusahaan_tarif_layanan_%d", groupTarifID)
exists, err := r.tableExists(ctx, tableName)
if err != nil {
return nil, err
}
if !exists {
return []PerusahaanGroupTarifLayanan{}, nil
}
query := fmt.Sprintf(`SELECT tarif.TarifLayananID, tarif.LayananID, layanan.Nama,
tarif.JenisLayananID, jenis.Nama, tarif.KelasID, kelas.Nama,
CAST(tarif.Harga AS CHAR), tarif.TipeDiskon, CAST(tarif.Diskon AS CHAR),
tarif.TipeDiskonRI, CAST(tarif.DiskonRI AS CHAR), tarif.TipeShare,
CAST(tarif.ShareDokter AS CHAR), CAST(tarif.ShareRS AS CHAR),
CAST(tarif.ShareExternal AS CHAR), CAST(tarif.ShareLain AS CHAR), tarif.AsalTarif
FROM %s tarif
LEFT JOIN masterlayanan layanan ON layanan.LayananID = tarif.LayananID
LEFT JOIN jenislayanan jenis ON jenis.JenisLayananID = tarif.JenisLayananID
LEFT JOIN kelas kelas ON kelas.KelasID = tarif.KelasID
WHERE tarif.NA = 'N'
ORDER BY layanan.Nama, tarif.KelasID`, tableName)
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
return nil, err
}
defer rows.Close()
result := make([]PerusahaanGroupTarifLayanan, 0)
for rows.Next() {
var item PerusahaanGroupTarifLayanan
var namaLayanan, namaJenisLayanan, namaKelas sql.NullString
if err := rows.Scan(&item.TarifLayananID, &item.LayananID, &namaLayanan,
&item.JenisLayananID, &namaJenisLayanan, &item.Kelas, &namaKelas,
&item.Harga, &item.TipeDiskonRJ, &item.DiskonRJ, &item.TipeDiskonRI,
&item.DiskonRI, &item.TipeShare, &item.ShareDokter, &item.ShareRS,
&item.ShareExt, &item.ShareLain, &item.AsalTarif); err != nil {
return nil, err
}
item.NamaLayanan = nullStringPtr(namaLayanan)
item.NamaJenisLayanan = nullStringPtr(namaJenisLayanan)
if namaKelas.Valid && namaKelas.String != "" {
item.NamaKelas = namaKelas.String
} else {
item.NamaKelas = item.Kelas
}
result = append(result, item)
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func scanPerusahaanDetail(row interface{ Scan(...any) error }) (PerusahaanDetail, error) {
var result PerusahaanDetail
var penanggungjawab, teleponPJ, emailPJ, alamat, kota, kodePos, propinsi, negara sql.NullString
var telepon, fax, email, website, namaBank, namaRekening, nomerRekening sql.NullString
var catatan, npwp, picMarketing sql.NullString
err := row.Scan(&result.PerusahaanID, &result.KodePerusahaan, &result.Nama,
&result.JenisPerusahaanID, &result.Penjamin, &result.Asuransi, &result.Provider,
&result.COB, &result.MataUangID, &penanggungjawab, &teleponPJ, &emailPJ,
&alamat, &kota, &kodePos, &propinsi, &negara, &telepon, &fax, &email, &website,
&namaBank, &namaRekening, &nomerRekening, &result.DefaultLamaPembayaran,
&result.DefaultDiskon, &result.PPN, &catatan, &npwp, &result.FlagDiskon,
&result.VerifikasiBilling, &picMarketing, &result.NA)
if err != nil {
return PerusahaanDetail{}, err
}
result.Penanggungjawab = nullStringPtr(penanggungjawab)
result.TeleponPenanggungjawab = nullStringPtr(teleponPJ)
result.EmailPenanggungjawab = nullStringPtr(emailPJ)
result.Alamat = nullStringPtr(alamat)
result.Kota = nullStringPtr(kota)
result.KodePos = nullStringPtr(kodePos)
result.Propinsi = nullStringPtr(propinsi)
result.Negara = nullStringPtr(negara)
result.Telepon = nullStringPtr(telepon)
result.Fax = nullStringPtr(fax)
result.Email = nullStringPtr(email)
result.Website = nullStringPtr(website)
result.NamaBank = nullStringPtr(namaBank)
result.NamaRekening = nullStringPtr(namaRekening)
result.NomerRekening = nullStringPtr(nomerRekening)
result.Catatan = nullStringPtr(catatan)
result.NPWP = nullStringPtr(npwp)
result.PICMarketing = nullStringPtr(picMarketing)
return result, nil
}