221 lines
4.6 KiB
Go
221 lines
4.6 KiB
Go
package usecasehelper
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
|
|
pl "simrs-vx/pkg/logger"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func SafeToResponse[T any](data *T) any {
|
|
if data == nil {
|
|
return nil
|
|
}
|
|
|
|
// Use type assertion to call ToResponse if the type has it
|
|
if converter, ok := any(data).(interface{ ToResponse() any }); ok {
|
|
return converter.ToResponse()
|
|
}
|
|
|
|
if converter, ok := any(*data).(interface{ ToResponse() any }); ok {
|
|
return converter.ToResponse()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func HandleReadError(err error, event *pl.Event, itemType string, id interface{}, data any) error {
|
|
if err == nil {
|
|
pl.SetLogInfo(event, data, "complete")
|
|
return nil
|
|
}
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: "data-notFound",
|
|
Detail: fmt.Sprintf("%s with ID %v not found", itemType, id),
|
|
Raw: err,
|
|
}
|
|
} else {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: "data-read-detail-fail",
|
|
Detail: fmt.Sprintf("%s read failed", itemType),
|
|
Raw: err,
|
|
}
|
|
}
|
|
|
|
return pl.SetLogError(event, nil)
|
|
}
|
|
|
|
func HandleSearchError(err error, event *pl.Event, itemType string, query interface{}, data any) error {
|
|
if err == nil {
|
|
pl.SetLogInfo(event, data, "complete")
|
|
return nil
|
|
}
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: "data-notFound",
|
|
Detail: fmt.Sprintf("%s with query '%v' not found", itemType, query),
|
|
Raw: err,
|
|
}
|
|
} else {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: "data-search-fail",
|
|
Detail: fmt.Sprintf("%s search failed", itemType),
|
|
Raw: err,
|
|
}
|
|
}
|
|
|
|
return pl.SetLogError(event, nil)
|
|
}
|
|
|
|
func GetMiddlewareErrorCode(mwType MWType) string {
|
|
if strings.Contains(string(mwType), "Pre") {
|
|
return "MW_PRE_FAILED"
|
|
}
|
|
return "MW_POST_FAILED"
|
|
}
|
|
|
|
// GetLogData returns whichever of data or input is non-nil (prefers data)
|
|
func GetLogData(input interface{}, data interface{}) interface{} {
|
|
if data != nil {
|
|
return data
|
|
}
|
|
return input
|
|
}
|
|
|
|
func HandleMiddlewareError(event *pl.Event, mwType, mwName string, logData interface{}, err error) error {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: GetMiddlewareErrorCode(MWType(mwType)),
|
|
Detail: fmt.Sprintf("%s middleware %s failed: %s", mwType, mwName, err.Error()),
|
|
Raw: err,
|
|
}
|
|
return pl.SetLogError(event, logData)
|
|
}
|
|
|
|
func IsDataNotFoundError(err error) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
return strings.Contains(err.Error(), "code: data-notFound")
|
|
}
|
|
|
|
func AddPrefix(prefix string, str string) string {
|
|
return prefix + str
|
|
}
|
|
|
|
func GetPreloads(input string) []string {
|
|
result := []string{}
|
|
parts := strings.Split(input, ",")
|
|
for _, p := range parts {
|
|
subParts := strings.Split(p, "-")
|
|
for i := range subParts {
|
|
subParts[i] = kebabToPascal(subParts[i])
|
|
}
|
|
result = append(result, strings.Join(subParts, "."))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func kebabToPascal(input string) string {
|
|
parts := strings.Split(input, "-")
|
|
for i, p := range parts {
|
|
if len(p) > 0 {
|
|
r := []rune(p)
|
|
r[0] = []rune(strings.ToUpper(string(r[0])))[0]
|
|
parts[i] = string(r)
|
|
}
|
|
}
|
|
return strings.Join(parts, "")
|
|
}
|
|
|
|
func GetTimeNow() *time.Time {
|
|
tmp := time.Now()
|
|
return &tmp
|
|
}
|
|
|
|
func IsDateBeforeNow(t *time.Time) bool {
|
|
if t == nil {
|
|
return false
|
|
}
|
|
return t.Before(time.Now())
|
|
}
|
|
|
|
// Contains reports whether v is present in s.
|
|
func Contains[S ~[]E, E comparable](s S, v E) bool {
|
|
return index(s, v) >= 0
|
|
}
|
|
|
|
// Index returns the index of the first occurrence of v in s,
|
|
// or -1 if not present.
|
|
func index[S ~[]E, E comparable](s S, v E) int {
|
|
for i := range s {
|
|
if v == s[i] {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func FormatIndonesianDate(t time.Time) string {
|
|
monthNames := [...]string{
|
|
"", // dummy index 0
|
|
"Januari",
|
|
"Februari",
|
|
"Maret",
|
|
"April",
|
|
"Mei",
|
|
"Juni",
|
|
"Juli",
|
|
"Agustus",
|
|
"September",
|
|
"Oktober",
|
|
"November",
|
|
"Desember",
|
|
}
|
|
|
|
return fmt.Sprintf("%d %s %d", t.Day(), monthNames[int(t.Month())], t.Year())
|
|
}
|
|
|
|
func GetLastTwoPathSegments(s string) string {
|
|
u, err := url.Parse(s)
|
|
var path string
|
|
|
|
if err == nil && u.Path != "" {
|
|
path = u.Path
|
|
} else {
|
|
path = s
|
|
}
|
|
|
|
parts := strings.Split(strings.Trim(path, "/"), "/")
|
|
n := len(parts)
|
|
|
|
if n >= 2 {
|
|
return parts[n-2] + "/" + parts[n-1]
|
|
}
|
|
|
|
// fallback: return entire string if less than 2 segments
|
|
return strings.Trim(path, "/")
|
|
}
|
|
|
|
func FormatPlaceAndDate(place string, t time.Time) string {
|
|
// Ensure place is uppercase
|
|
place = strings.ToUpper(strings.TrimSpace(place))
|
|
|
|
// Format date: DD-MM-YYYY
|
|
dateStr := t.Format("02-01-2006")
|
|
|
|
return place + ", " + dateStr
|
|
}
|