Compare commits
2 Commits
44dc3fa61c
...
3696451dc6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3696451dc6 | ||
|
|
0a44135fb6 |
@ -20,7 +20,7 @@ type Database struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Database) DSN() string {
|
func (c Database) DSN() string {
|
||||||
return fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=%s TimeZone=UTC", c.Host, c.Port, c.DB, c.Username, c.Password, c.SslMode)
|
return fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=%s TimeZone=Asia/Jakarta", c.Host, c.Port, c.DB, c.Username, c.Password, c.SslMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Database) ConnectionMaxLifetime() time.Duration {
|
func (c Database) ConnectionMaxLifetime() time.Duration {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package db
|
|||||||
import (
|
import (
|
||||||
"apskel-pos-be/config"
|
"apskel-pos-be/config"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
_ "gopkg.in/yaml.v3"
|
_ "gopkg.in/yaml.v3"
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// Pagination represents pagination information
|
|
||||||
type Pagination struct {
|
type Pagination struct {
|
||||||
Page int `json:"page"`
|
Page int `json:"page"`
|
||||||
Limit int `json:"limit"`
|
Limit int `json:"limit"`
|
||||||
Total int64 `json:"total"`
|
Total int64 `json:"total_count"`
|
||||||
TotalPages int `json:"total_pages"`
|
TotalPages int `json:"total_pages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaginatedResponse represents a paginated response
|
|
||||||
type PaginatedResponse[T any] struct {
|
type PaginatedResponse[T any] struct {
|
||||||
Data []T `json:"data"`
|
Data []T `json:"data"`
|
||||||
Pagination Pagination `json:"pagination"`
|
Pagination Pagination `json:"pagination"`
|
||||||
|
|||||||
@ -3,30 +3,22 @@ package transformer
|
|||||||
import (
|
import (
|
||||||
"apskel-pos-be/internal/contract"
|
"apskel-pos-be/internal/contract"
|
||||||
"apskel-pos-be/internal/models"
|
"apskel-pos-be/internal/models"
|
||||||
|
"apskel-pos-be/internal/util"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ddmmyyyy = "02-01-2006"
|
|
||||||
|
|
||||||
// PaymentMethodAnalyticsContractToModel converts contract request to model
|
// PaymentMethodAnalyticsContractToModel converts contract request to model
|
||||||
func PaymentMethodAnalyticsContractToModel(req *contract.PaymentMethodAnalyticsRequest) *models.PaymentMethodAnalyticsRequest {
|
func PaymentMethodAnalyticsContractToModel(req *contract.PaymentMethodAnalyticsRequest) *models.PaymentMethodAnalyticsRequest {
|
||||||
var dateFrom, dateTo time.Time
|
var dateFrom, dateTo time.Time
|
||||||
if req.DateFrom != "" {
|
|
||||||
df, err := time.Parse(ddmmyyyy, req.DateFrom)
|
|
||||||
if err == nil {
|
|
||||||
dateFrom = df
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if req.DateTo != "" {
|
|
||||||
dt, err := time.Parse(ddmmyyyy, req.DateTo)
|
|
||||||
if err == nil {
|
|
||||||
dateTo = dt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.DateFrom == req.DateTo {
|
if fromTime, toTime, err := util.ParseDateRangeToJakartaTime(req.DateFrom, req.DateTo); err == nil {
|
||||||
dateTo = dateTo.AddDate(0, 0, 1)
|
if fromTime != nil {
|
||||||
|
dateFrom = *fromTime
|
||||||
|
}
|
||||||
|
if toTime != nil {
|
||||||
|
dateTo = *toTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &models.PaymentMethodAnalyticsRequest{
|
return &models.PaymentMethodAnalyticsRequest{
|
||||||
@ -75,21 +67,14 @@ func PaymentMethodAnalyticsModelToContract(resp *models.PaymentMethodAnalyticsRe
|
|||||||
|
|
||||||
func SalesAnalyticsContractToModel(req *contract.SalesAnalyticsRequest) *models.SalesAnalyticsRequest {
|
func SalesAnalyticsContractToModel(req *contract.SalesAnalyticsRequest) *models.SalesAnalyticsRequest {
|
||||||
var dateFrom, dateTo time.Time
|
var dateFrom, dateTo time.Time
|
||||||
if req.DateFrom != "" {
|
|
||||||
df, err := time.Parse(ddmmyyyy, req.DateFrom)
|
|
||||||
if err == nil {
|
|
||||||
dateFrom = df
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if req.DateTo != "" {
|
|
||||||
dt, err := time.Parse(ddmmyyyy, req.DateTo)
|
|
||||||
if err == nil {
|
|
||||||
dateTo = dt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.DateFrom == req.DateTo {
|
if fromTime, toTime, err := util.ParseDateRangeToJakartaTime(req.DateFrom, req.DateTo); err == nil {
|
||||||
dateTo = dateTo.AddDate(0, 0, 1)
|
if fromTime != nil {
|
||||||
|
dateFrom = *fromTime
|
||||||
|
}
|
||||||
|
if toTime != nil {
|
||||||
|
dateTo = *toTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &models.SalesAnalyticsRequest{
|
return &models.SalesAnalyticsRequest{
|
||||||
@ -142,21 +127,14 @@ func SalesAnalyticsModelToContract(resp *models.SalesAnalyticsResponse) *contrac
|
|||||||
// ProductAnalyticsContractToModel converts contract request to model
|
// ProductAnalyticsContractToModel converts contract request to model
|
||||||
func ProductAnalyticsContractToModel(req *contract.ProductAnalyticsRequest) *models.ProductAnalyticsRequest {
|
func ProductAnalyticsContractToModel(req *contract.ProductAnalyticsRequest) *models.ProductAnalyticsRequest {
|
||||||
var dateFrom, dateTo time.Time
|
var dateFrom, dateTo time.Time
|
||||||
if req.DateFrom != "" {
|
|
||||||
df, err := time.Parse(ddmmyyyy, req.DateFrom)
|
|
||||||
if err == nil {
|
|
||||||
dateFrom = df
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if req.DateTo != "" {
|
|
||||||
dt, err := time.Parse(ddmmyyyy, req.DateTo)
|
|
||||||
if err == nil {
|
|
||||||
dateTo = dt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.DateFrom == req.DateTo {
|
if fromTime, toTime, err := util.ParseDateRangeToJakartaTime(req.DateFrom, req.DateTo); err == nil {
|
||||||
dateTo = dateTo.AddDate(0, 0, 1)
|
if fromTime != nil {
|
||||||
|
dateFrom = *fromTime
|
||||||
|
}
|
||||||
|
if toTime != nil {
|
||||||
|
dateTo = *toTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &models.ProductAnalyticsRequest{
|
return &models.ProductAnalyticsRequest{
|
||||||
@ -200,21 +178,15 @@ func ProductAnalyticsModelToContract(resp *models.ProductAnalyticsResponse) *con
|
|||||||
// DashboardAnalyticsContractToModel converts contract request to model
|
// DashboardAnalyticsContractToModel converts contract request to model
|
||||||
func DashboardAnalyticsContractToModel(req *contract.DashboardAnalyticsRequest) *models.DashboardAnalyticsRequest {
|
func DashboardAnalyticsContractToModel(req *contract.DashboardAnalyticsRequest) *models.DashboardAnalyticsRequest {
|
||||||
var dateFrom, dateTo time.Time
|
var dateFrom, dateTo time.Time
|
||||||
if req.DateFrom != "" {
|
|
||||||
df, err := time.Parse(ddmmyyyy, req.DateFrom)
|
|
||||||
if err == nil {
|
|
||||||
dateFrom = df
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if req.DateTo != "" {
|
|
||||||
dt, err := time.Parse(ddmmyyyy, req.DateTo)
|
|
||||||
if err == nil {
|
|
||||||
dateTo = dt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.DateFrom == req.DateTo {
|
// Parse date range using utility function
|
||||||
dateTo = dateTo.AddDate(0, 0, 1)
|
if fromTime, toTime, err := util.ParseDateRangeToJakartaTime(req.DateFrom, req.DateTo); err == nil {
|
||||||
|
if fromTime != nil {
|
||||||
|
dateFrom = *fromTime
|
||||||
|
}
|
||||||
|
if toTime != nil {
|
||||||
|
dateTo = *toTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &models.DashboardAnalyticsRequest{
|
return &models.DashboardAnalyticsRequest{
|
||||||
@ -296,21 +268,21 @@ func ProfitLossAnalyticsContractToModel(req *contract.ProfitLossAnalyticsRequest
|
|||||||
return nil, fmt.Errorf("request cannot be nil")
|
return nil, fmt.Errorf("request cannot be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
dateFrom, err := time.Parse("02-01-2006", req.DateFrom)
|
// Parse date range using utility function
|
||||||
|
dateFrom, dateTo, err := util.ParseDateRangeToJakartaTime(req.DateFrom, req.DateTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid date_from format: %w", err)
|
return nil, fmt.Errorf("invalid date format: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dateTo, err := time.Parse("02-01-2006", req.DateTo)
|
if dateFrom == nil || dateTo == nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("both date_from and date_to are required")
|
||||||
return nil, fmt.Errorf("invalid date_to format: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &models.ProfitLossAnalyticsRequest{
|
return &models.ProfitLossAnalyticsRequest{
|
||||||
OrganizationID: req.OrganizationID,
|
OrganizationID: req.OrganizationID,
|
||||||
OutletID: req.OutletID,
|
OutletID: req.OutletID,
|
||||||
DateFrom: dateFrom,
|
DateFrom: *dateFrom,
|
||||||
DateTo: dateTo,
|
DateTo: *dateTo,
|
||||||
GroupBy: req.GroupBy,
|
GroupBy: req.GroupBy,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import (
|
|||||||
"apskel-pos-be/internal/constants"
|
"apskel-pos-be/internal/constants"
|
||||||
"apskel-pos-be/internal/contract"
|
"apskel-pos-be/internal/contract"
|
||||||
"apskel-pos-be/internal/models"
|
"apskel-pos-be/internal/models"
|
||||||
|
"apskel-pos-be/internal/util"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
@ -212,7 +212,6 @@ func ListOrdersQueryToModel(query *contract.ListOrdersQuery) *models.ListOrdersR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse enum fields
|
|
||||||
if query.OrderType != "" {
|
if query.OrderType != "" {
|
||||||
orderType := constants.OrderType(query.OrderType)
|
orderType := constants.OrderType(query.OrderType)
|
||||||
req.OrderType = &orderType
|
req.OrderType = &orderType
|
||||||
@ -240,21 +239,9 @@ func ListOrdersQueryToModel(query *contract.ListOrdersQuery) *models.ListOrdersR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if query.DateFrom != "" {
|
if dateFrom, dateTo, err := util.ParseDateRangeToJakartaTime(query.DateFrom, query.DateTo); err == nil {
|
||||||
if dateFrom, err := time.Parse(ddmmyyyy, query.DateFrom); err == nil {
|
req.DateFrom = dateFrom
|
||||||
req.DateFrom = &dateFrom
|
req.DateTo = dateTo
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if query.DateTo != "" {
|
|
||||||
if dateTo, err := time.Parse(ddmmyyyy, query.DateTo); err == nil {
|
|
||||||
req.DateTo = &dateTo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if query.DateFrom == query.DateTo {
|
|
||||||
newDate := req.DateTo.AddDate(0, 0, 1)
|
|
||||||
req.DateTo = &newDate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return req
|
return req
|
||||||
|
|||||||
72
internal/util/date_util.go
Normal file
72
internal/util/date_util.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const DateFormatDDMMYYYY = "02-01-2006"
|
||||||
|
|
||||||
|
// ParseDateToJakartaTime parses a date string in DD-MM-YYYY format and converts it to Jakarta timezone
|
||||||
|
// Returns start of day (00:00:00) in Jakarta timezone
|
||||||
|
func ParseDateToJakartaTime(dateStr string) (*time.Time, error) {
|
||||||
|
if dateStr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
date, err := time.Parse(DateFormatDDMMYYYY, dateStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jakartaLoc, err := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jakartaTime := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, jakartaLoc)
|
||||||
|
return &jakartaTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDateToJakartaTimeEndOfDay parses a date string in DD-MM-YYYY format and converts it to Jakarta timezone
|
||||||
|
// Returns end of day (23:59:59.999999999) in Jakarta timezone
|
||||||
|
func ParseDateToJakartaTimeEndOfDay(dateStr string) (*time.Time, error) {
|
||||||
|
if dateStr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
date, err := time.Parse(DateFormatDDMMYYYY, dateStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jakartaLoc, err := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jakartaTime := time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 999999999, jakartaLoc)
|
||||||
|
return &jakartaTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDateRangeToJakartaTime parses date_from and date_to strings and returns them in Jakarta timezone
|
||||||
|
// date_from will be start of day (00:00:00), date_to will be end of day (23:59:59.999999999)
|
||||||
|
func ParseDateRangeToJakartaTime(dateFrom, dateTo string) (*time.Time, *time.Time, error) {
|
||||||
|
var fromTime, toTime *time.Time
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if dateFrom != "" {
|
||||||
|
fromTime, err = ParseDateToJakartaTime(dateFrom)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dateTo != "" {
|
||||||
|
toTime, err = ParseDateToJakartaTimeEndOfDay(dateTo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromTime, toTime, nil
|
||||||
|
}
|
||||||
211
internal/util/date_util_test.go
Normal file
211
internal/util/date_util_test.go
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseDateToJakartaTime(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
dateStr string
|
||||||
|
expected *time.Time
|
||||||
|
hasError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid date",
|
||||||
|
dateStr: "06-08-2025",
|
||||||
|
expected: nil, // Will be set during test
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty string",
|
||||||
|
dateStr: "",
|
||||||
|
expected: nil,
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid date format",
|
||||||
|
dateStr: "2025-08-06",
|
||||||
|
hasError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result, err := ParseDateToJakartaTime(tt.dateStr)
|
||||||
|
|
||||||
|
if tt.hasError {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error but got none")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expected == nil && tt.dateStr == "" {
|
||||||
|
if result != nil {
|
||||||
|
t.Errorf("Expected nil but got %v", result)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if result == nil && tt.dateStr != "" {
|
||||||
|
t.Errorf("Expected time but got nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's in Jakarta timezone
|
||||||
|
jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if result.Location().String() != jakartaLoc.String() {
|
||||||
|
t.Errorf("Expected Jakarta timezone but got %v", result.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's start of day
|
||||||
|
if result.Hour() != 0 || result.Minute() != 0 || result.Second() != 0 {
|
||||||
|
t.Errorf("Expected start of day but got %v", result.Format("15:04:05"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseDateToJakartaTimeEndOfDay(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
dateStr string
|
||||||
|
expected *time.Time
|
||||||
|
hasError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid date",
|
||||||
|
dateStr: "06-08-2025",
|
||||||
|
expected: nil, // Will be set during test
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty string",
|
||||||
|
dateStr: "",
|
||||||
|
expected: nil,
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result, err := ParseDateToJakartaTimeEndOfDay(tt.dateStr)
|
||||||
|
|
||||||
|
if tt.hasError {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error but got none")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expected == nil && tt.dateStr == "" {
|
||||||
|
if result != nil {
|
||||||
|
t.Errorf("Expected nil but got %v", result)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if result == nil && tt.dateStr != "" {
|
||||||
|
t.Errorf("Expected time but got nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's in Jakarta timezone
|
||||||
|
jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if result.Location().String() != jakartaLoc.String() {
|
||||||
|
t.Errorf("Expected Jakarta timezone but got %v", result.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's end of day
|
||||||
|
if result.Hour() != 23 || result.Minute() != 59 || result.Second() != 59 {
|
||||||
|
t.Errorf("Expected end of day but got %v", result.Format("15:04:05"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseDateRangeToJakartaTime(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
dateFrom string
|
||||||
|
dateTo string
|
||||||
|
hasError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid date range",
|
||||||
|
dateFrom: "06-08-2025",
|
||||||
|
dateTo: "06-08-2025",
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty strings",
|
||||||
|
dateFrom: "",
|
||||||
|
dateTo: "",
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only date_from",
|
||||||
|
dateFrom: "06-08-2025",
|
||||||
|
dateTo: "",
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only date_to",
|
||||||
|
dateFrom: "",
|
||||||
|
dateTo: "06-08-2025",
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fromTime, toTime, err := ParseDateRangeToJakartaTime(tt.dateFrom, tt.dateTo)
|
||||||
|
|
||||||
|
if tt.hasError {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error but got none")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If dateFrom is provided, check it's start of day
|
||||||
|
if tt.dateFrom != "" && fromTime != nil {
|
||||||
|
jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if fromTime.Location().String() != jakartaLoc.String() {
|
||||||
|
t.Errorf("Expected Jakarta timezone for date_from but got %v", fromTime.Location())
|
||||||
|
}
|
||||||
|
if fromTime.Hour() != 0 || fromTime.Minute() != 0 || fromTime.Second() != 0 {
|
||||||
|
t.Errorf("Expected start of day for date_from but got %v", fromTime.Format("15:04:05"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If dateTo is provided, check it's end of day
|
||||||
|
if tt.dateTo != "" && toTime != nil {
|
||||||
|
jakartaLoc, _ := time.LoadLocation("Asia/Jakarta")
|
||||||
|
if toTime.Location().String() != jakartaLoc.String() {
|
||||||
|
t.Errorf("Expected Jakarta timezone for date_to but got %v", toTime.Location())
|
||||||
|
}
|
||||||
|
if toTime.Hour() != 23 || toTime.Minute() != 59 || toTime.Second() != 59 {
|
||||||
|
t.Errorf("Expected end of day for date_to but got %v", toTime.Format("15:04:05"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user