Compare commits
3
Commits
142ac841ff
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec2f340e13 | ||
|
|
a6af3d5f3f | ||
|
|
cc6abb00ac |
No files matched your search
@@ -1,5 +1,6 @@
|
||||
# Database Configuration
|
||||
DB_HOST=host.docker.internal
|
||||
DB_HOST=db
|
||||
# DB_HOST=host.docker.internal
|
||||
DB_PORT=5432
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=gakbikinkembung25
|
||||
|
||||
@@ -228,6 +228,7 @@ type BillingRequest struct {
|
||||
Ruangan string `json:"ruangan" binding:"required"`
|
||||
Kelas string `json:"kelas" binding:"required"`
|
||||
Tindakan_RS []string `json:"tindakan_rs" binding:"required"`
|
||||
Tanggal_Masuk string `json:"tanggal_masuk"` // ← Added: Tanggal masuk dari frontend (format: YYYY-MM-DD)
|
||||
Tanggal_Keluar string `json:"tanggal_keluar"`
|
||||
Billing_sign string `json:"billing_sign"`
|
||||
ICD9 []string `json:"icd9"`
|
||||
|
||||
@@ -68,10 +68,10 @@ func SendEmailToMultiple(to []string, subject, body string) error {
|
||||
smtpPort := os.Getenv("SMTP_PORT")
|
||||
|
||||
if from == "" {
|
||||
from = "asikmahdi@gmail.com"
|
||||
from = "careit565@gmail.com"
|
||||
}
|
||||
if password == "" {
|
||||
password = "njom rhxb prrj tuoj"
|
||||
password = "gkhz bjax uamw xydf"
|
||||
}
|
||||
if smtpHost == "" {
|
||||
smtpHost = "smtp.gmail.com"
|
||||
|
||||
@@ -314,6 +314,30 @@ func DataFromFE(input models.BillingRequest) (
|
||||
|
||||
now := time.Now()
|
||||
|
||||
// Parse Tanggal_Masuk - accept multiple formats
|
||||
var masukPtr *time.Time
|
||||
if input.Tanggal_Masuk != "" && input.Tanggal_Masuk != "null" {
|
||||
s := input.Tanggal_Masuk
|
||||
var parsed time.Time
|
||||
var err error
|
||||
layouts := []string{time.RFC3339, "2006-01-02 15:04:05", "2006-01-02"}
|
||||
for _, layout := range layouts {
|
||||
parsed, err = time.Parse(layout, s)
|
||||
if err == nil {
|
||||
t := parsed
|
||||
masukPtr = &t
|
||||
break
|
||||
}
|
||||
}
|
||||
if masukPtr == nil {
|
||||
tx.Rollback()
|
||||
return nil, nil, nil, nil, nil, fmt.Errorf("invalid tanggal_masuk format: %s", input.Tanggal_Masuk)
|
||||
}
|
||||
} else {
|
||||
// Jika tidak ada input, default ke hari ini
|
||||
masukPtr = &now
|
||||
}
|
||||
|
||||
// Parse Tanggal_Keluar (frontend sends string). Accept multiple formats.
|
||||
var keluarPtr *time.Time
|
||||
if input.Tanggal_Keluar != "" && input.Tanggal_Keluar != "null" {
|
||||
@@ -355,7 +379,7 @@ func DataFromFE(input models.BillingRequest) (
|
||||
billing = models.BillingPasien{
|
||||
ID_Pasien: pasien.ID_Pasien,
|
||||
Cara_Bayar: input.Cara_Bayar,
|
||||
Tanggal_masuk: &now,
|
||||
Tanggal_masuk: masukPtr,
|
||||
Tanggal_keluar: keluarPtr,
|
||||
Total_Tarif_RS: input.Total_Tarif_RS,
|
||||
Total_Klaim: input.Total_Klaim_BPJS, // ← Changed: Use input value instead of hardcoded 0
|
||||
|
||||
@@ -46,6 +46,7 @@ func GetRiwayatPasienAll(db *gorm.DB) ([]models.Riwayat_Pasien_all, error) {
|
||||
if err := db.Table("\"billing_tindakan\"").
|
||||
Where("\"ID_Billing\" IN ?", billingIDs).
|
||||
Select("\"ID_Billing\", \"ID_Tarif_RS\" as \"Kode\"").
|
||||
Order("\"ID_Billing\" ASC, \"tanggal_tindakan\" ASC").
|
||||
Scan(&tindakanRows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -54,7 +55,7 @@ func GetRiwayatPasienAll(db *gorm.DB) ([]models.Riwayat_Pasien_all, error) {
|
||||
tindakanMap[t.ID_Billing] = append(tindakanMap[t.ID_Billing], t.Kode)
|
||||
}
|
||||
|
||||
// Ambil tanggal tindakan dari tabel billing_tindakan
|
||||
// Ambil tanggal tindakan dari tabel billing_tindakan (ambil yang pertama aja per billing supaya konsisten)
|
||||
tindakanDateMap := make(map[int]*time.Time)
|
||||
var tindakanDateRows []struct {
|
||||
ID_Billing int
|
||||
@@ -64,12 +65,13 @@ func GetRiwayatPasienAll(db *gorm.DB) ([]models.Riwayat_Pasien_all, error) {
|
||||
if err := db.Table("\"billing_tindakan\"").
|
||||
Where("\"ID_Billing\" IN ?", billingIDs).
|
||||
Select("\"ID_Billing\", \"tanggal_tindakan\"").
|
||||
Order("\"ID_Billing\" ASC, \"tanggal_tindakan\" ASC").
|
||||
Scan(&tindakanDateRows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, t := range tindakanDateRows {
|
||||
if t.Tanggal_Tindakan != nil {
|
||||
if t.Tanggal_Tindakan != nil && tindakanDateMap[t.ID_Billing] == nil {
|
||||
tindakanDateMap[t.ID_Billing] = t.Tanggal_Tindakan
|
||||
}
|
||||
}
|
||||
@@ -262,6 +264,7 @@ func GetAllRiwayatpasien(db *gorm.DB) ([]models.Request_Admin_Inacbg, error) {
|
||||
if err := db.Table("\"billing_tindakan\"").
|
||||
Where("\"ID_Billing\" IN ?", billingIDs).
|
||||
Select("\"ID_Billing\", \"ID_Tarif_RS\" as \"Kode\"").
|
||||
Order("\"ID_Billing\" ASC, \"tanggal_tindakan\" ASC").
|
||||
Scan(&tindakanRows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Users\rengginang\Desktop\CAREIT_V4\frontendcareit_v4\public\assets\LOGO_CAREIT.ico,0
|
||||
[ViewState]
|
||||
Mode=
|
||||
Vid=
|
||||
FolderType=Generic
|
||||
Generated
+5
-5
@@ -23,8 +23,8 @@
|
||||
"@capacitor/cli": "^8.0.0",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vercel/speed-insights": "^1.3.1",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
@@ -2611,9 +2611,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
||||
"version": "19.2.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
"@capacitor/cli": "^8.0.0",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vercel/speed-insights": "^1.3.1",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
@@ -52,4 +52,4 @@
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,6 +441,13 @@ const INACBG_Admin_Ruangan = ({
|
||||
const totalKlaim = data.total_klaim || 0;
|
||||
setTotalKlaimOriginal(totalKlaim);
|
||||
console.log(`💰 Set totalKlaimOriginal: ${totalKlaim}`);
|
||||
|
||||
// Seed liveBillingSign dari nilai tersimpan di DB, supaya display awal sesuai dengan BE
|
||||
// Akan di-overwrite otomatis oleh useEffect saat user mengubah kode INACBG
|
||||
if (data.billing_sign) {
|
||||
setLiveBillingSign(data.billing_sign);
|
||||
console.log(`🎨 Seeded liveBillingSign from DB: ${data.billing_sign}`);
|
||||
}
|
||||
// DONT set totalKlaimBPJS here - biarkan useEffect calculate yang set nilai dengan benar
|
||||
// Jadi jangan: setTotalKlaimBPJS(totalKlaim);
|
||||
|
||||
@@ -777,15 +784,15 @@ const INACBG_Admin_Ruangan = ({
|
||||
const percentage = (totalTarifRS / totalKlaimBPJS) * 100;
|
||||
console.log(`📊 Percentage: ${percentage.toFixed(2)}% `);
|
||||
|
||||
if (percentage <= 25) {
|
||||
console.log("✅ Returning: Hijau (<=25%)");
|
||||
return "Hijau"; // Tarif RS <=25% dari Klaim BPJS Efektif = AMAN
|
||||
} else if (percentage <= 50) {
|
||||
console.log("✅ Returning: Kuning (26-50%)");
|
||||
return "Kuning"; // 26%-50% = PERLU PERHATIAN
|
||||
if (percentage <= 70) {
|
||||
console.log("✅ Returning: Hijau (<=70%)");
|
||||
return "Hijau"; // Tarif RS <=70% dari Klaim BPJS Efektif = AMAN
|
||||
} else if (percentage > 70 && percentage <= 99) {
|
||||
console.log("✅ Returning: Kuning (71-99%)");
|
||||
return "Kuning"; // 71%-99% = PERLU PERHATIAN
|
||||
} else {
|
||||
console.log("✅ Returning: Merah (>50%)");
|
||||
return "Merah"; // >50% = WASPADA
|
||||
console.log("✅ Returning: Merah (>99%)");
|
||||
return "Merah"; // >99% = WASPADA
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1581,9 +1588,9 @@ rounded - lg text - left transition - all
|
||||
} `}
|
||||
>
|
||||
{liveBillingSign === "" && "Belum bisa dihitung (isi data klaim & tarif dulu)"}
|
||||
{liveBillingSign === "Hijau" && "Hijau - AMAN (<= 25%)"}
|
||||
{liveBillingSign === "Kuning" && "Kuning - PERHATIAN (26% - 50%)"}
|
||||
{liveBillingSign === "Merah" && "Merah - WASPADA (> 50%)"}
|
||||
{liveBillingSign === "Hijau" && "Hijau - AMAN (<= 70%)"}
|
||||
{liveBillingSign === "Kuning" && "Kuning - PERHATIAN (71% - 99%)"}
|
||||
{liveBillingSign === "Merah" && "Merah - WASPADA (>= 100%)"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load diff
@@ -188,17 +188,18 @@ const RiwayatBillingPasien = ({ onLogout, userRole, onEdit, selectedRuangan }: R
|
||||
};
|
||||
|
||||
// Hitung warning sign secara dinamis berdasarkan current tarif RS vs existing klaim
|
||||
// This ensures warning updates even if INACBG hasn't been input yet
|
||||
// Threshold harus konsisten dengan calculateBillingSign di billing-pasien & INACBG_Admin_Ruangan:
|
||||
// <=70% = Hijau, 71-99% = Kuning, >=100% = Merah
|
||||
const calculateDynamicWarningSign = (totalTarifRS: number | undefined, totalKlaim: number | undefined): string => {
|
||||
if (!totalTarifRS || !totalKlaim || totalTarifRS <= 0 || totalKlaim <= 0) {
|
||||
return ""; // No data to calculate
|
||||
}
|
||||
|
||||
const percentage = (totalTarifRS / totalKlaim) * 100;
|
||||
|
||||
if (percentage <= 25) {
|
||||
|
||||
if (percentage <= 70) {
|
||||
return "Hijau"; // Safe
|
||||
} else if (percentage <= 50) {
|
||||
} else if (percentage <= 99) {
|
||||
return "Kuning"; // Warning
|
||||
} else {
|
||||
return "Merah"; // Alert
|
||||
|
||||
Reference in New Issue
Block a user