Files
simrsx-be/internal/use-case/main-use-case/patient/helper.go
T
2025-10-07 09:31:48 +07:00

138 lines
3.1 KiB
Go

/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package patient
import (
"fmt"
"path/filepath"
"strconv"
"strings"
"time"
e "simrs-vx/internal/domain/main-entities/patient"
pl "simrs-vx/pkg/logger"
pmh "simrs-vx/pkg/minio-helper"
puh "simrs-vx/pkg/upload-helper"
dg "github.com/karincake/apem/db-gorm-pg"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Patient) error {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
if data.Id == 0 {
medRecNum, err := GenerateNextMedicalRecordNumber()
if err != nil {
return err
}
data.Number = &medRecNum
}
data.Person_Id = inputSrc.Person_Id
data.RegisteredAt = inputSrc.RegisteredAt
data.Status_Code = inputSrc.Status_Code
data.NewBornStatus = inputSrc.NewBornStatus
return nil
}
func GenerateNextMedicalRecordNumber() (string, error) {
var last string
err := dg.I.
Table("\"Patient\"").
Select("\"Number\"").
Where("\"Number\" IS NOT NULL AND \"Number\" ~ '^[0-9]+$'"). // Only numeric strings
Order("\"Number\"::bigint DESC").
Limit(1).
Scan(&last).Error
if err != nil {
return "", err
}
var nextInt int64
var format string
if last == "" {
// No existing records, start with 10 digits
nextInt = 1
format = "%010d"
} else {
n, err := strconv.ParseInt(last, 10, 64)
if err != nil {
return "", err
}
nextInt = n + 1
// Dynamically determine format based on existing number
digitCount := len(last)
// If the incremented number needs more digits, expand format
nextStr := strconv.FormatInt(nextInt, 10)
if len(nextStr) > digitCount {
digitCount = len(nextStr)
}
// Ensure minimum 10 digits as per requirement
if digitCount < 10 {
digitCount = 10
}
format = fmt.Sprintf("%%0%dd", digitCount)
}
return fmt.Sprintf(format, nextInt), nil
}
func uploadAndGenerateFileUrl(input e.UploadDto, event *pl.Event) (string, error) {
pl.SetLogInfo(event, input, "started", "uploadAndGenerateFileUrl")
bucket := string(input.Code)
ext := strings.ToLower(filepath.Ext(input.Filename))
if !puh.IsValidFileType(ext, bucket) {
return "", fmt.Errorf("invalid file type: %s", input.Filename)
}
objectName := fmt.Sprintf("%s%d%s", input.MedRecNumber, time.Now().UnixNano(), ext)
uploadInput := pmh.UploadReaderInput{
BucketName: bucket,
Name: objectName,
File: input.File,
Size: input.Size,
ContentType: input.MimeType,
}
_, err := pmh.I.PutObject(uploadInput)
if err != nil {
return "", err
}
// Build URL for access
publicUrl := pmh.I.GenerateUrl(bucket, objectName)
pl.SetLogInfo(event, nil, "complete")
return publicUrl, nil
}
func removeUploadedFile(bucket, fileUrl string, event *pl.Event) error {
pl.SetLogInfo(event, nil, "started", "removeUploadedFile")
filename, err := pmh.GetFilename(fileUrl)
if err != nil {
return err
}
err = pmh.I.RemoveObject(bucket, filename)
if err != nil {
return err
}
pl.SetLogInfo(event, nil, "complete")
return nil
}