185 lines
5.6 KiB
Go
185 lines
5.6 KiB
Go
package transformer
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"apskel-pos-be/internal/contract"
|
|
"apskel-pos-be/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPurchasingAnalyticsContractToModelParsesDateRangeAndOutlet(t *testing.T) {
|
|
orgID := uuid.New()
|
|
outletID := uuid.New().String()
|
|
|
|
req := &contract.PurchasingAnalyticsRequest{
|
|
OrganizationID: orgID,
|
|
OutletID: &outletID,
|
|
DateFrom: "01-05-2026",
|
|
DateTo: "02-05-2026",
|
|
GroupBy: "week",
|
|
}
|
|
|
|
result := PurchasingAnalyticsContractToModel(req)
|
|
|
|
require.Equal(t, orgID, result.OrganizationID)
|
|
require.NotNil(t, result.OutletID)
|
|
require.Equal(t, outletID, result.OutletID.String())
|
|
require.Equal(t, "week", result.GroupBy)
|
|
|
|
location, err := time.LoadLocation("Asia/Jakarta")
|
|
require.NoError(t, err)
|
|
require.Equal(t, time.Date(2026, 5, 1, 0, 0, 0, 0, location), result.DateFrom)
|
|
require.Equal(t, time.Date(2026, 5, 2, 23, 59, 59, int(time.Second-time.Nanosecond), location), result.DateTo)
|
|
}
|
|
|
|
func TestPurchasingAnalyticsContractToModelIgnoresInvalidOutlet(t *testing.T) {
|
|
outletID := "not-a-uuid"
|
|
|
|
result := PurchasingAnalyticsContractToModel(&contract.PurchasingAnalyticsRequest{
|
|
OutletID: &outletID,
|
|
DateFrom: "01-05-2026",
|
|
DateTo: "02-05-2026",
|
|
})
|
|
|
|
require.Nil(t, result.OutletID)
|
|
}
|
|
|
|
func TestPurchasingAnalyticsModelToContractCopiesOutletName(t *testing.T) {
|
|
outletID := uuid.New()
|
|
outletName := "Main Outlet"
|
|
now := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC)
|
|
|
|
result := PurchasingAnalyticsModelToContract(&models.PurchasingAnalyticsResponse{
|
|
OrganizationID: uuid.New(),
|
|
OutletID: &outletID,
|
|
OutletName: &outletName,
|
|
Summary: models.PurchasingSummary{
|
|
TotalPurchases: 300,
|
|
RawMaterialPurchases: 125,
|
|
NonInventoryPurchases: 175,
|
|
TotalPurchaseOrders: 3,
|
|
RawMaterialPurchaseOrders: 1,
|
|
NonInventoryExpenseCount: 2,
|
|
},
|
|
Data: []models.PurchasingAnalyticsData{
|
|
{
|
|
Date: now,
|
|
Purchases: 300,
|
|
RawMaterialPurchases: 125,
|
|
NonInventoryPurchases: 175,
|
|
PurchaseOrders: 3,
|
|
RawMaterialPurchaseOrders: 1,
|
|
NonInventoryExpenseCount: 2,
|
|
},
|
|
},
|
|
})
|
|
|
|
require.NotNil(t, result)
|
|
require.Equal(t, &outletID, result.OutletID)
|
|
require.NotNil(t, result.OutletName)
|
|
require.Equal(t, outletName, *result.OutletName)
|
|
require.Equal(t, float64(300), result.Summary.TotalPurchases)
|
|
require.Equal(t, float64(125), result.Summary.RawMaterialPurchases)
|
|
require.Equal(t, float64(175), result.Summary.NonInventoryPurchases)
|
|
require.Equal(t, int64(3), result.Summary.TotalPurchaseOrders)
|
|
require.Equal(t, int64(1), result.Summary.RawMaterialPurchaseOrders)
|
|
require.Equal(t, int64(2), result.Summary.NonInventoryExpenseCount)
|
|
require.Len(t, result.Data, 1)
|
|
require.Equal(t, float64(300), result.Data[0].Purchases)
|
|
require.Equal(t, float64(125), result.Data[0].RawMaterialPurchases)
|
|
require.Equal(t, float64(175), result.Data[0].NonInventoryPurchases)
|
|
}
|
|
|
|
func TestPurchasingAnalyticsModelToContractOmitsNilOutletName(t *testing.T) {
|
|
result := PurchasingAnalyticsModelToContract(&models.PurchasingAnalyticsResponse{
|
|
OrganizationID: uuid.New(),
|
|
})
|
|
|
|
payload, err := json.Marshal(result)
|
|
require.NoError(t, err)
|
|
require.NotContains(t, string(payload), "outlet_name")
|
|
}
|
|
|
|
func TestProfitLossAnalyticsContractToModelParsesDateRange(t *testing.T) {
|
|
orgID := uuid.New()
|
|
outletID := uuid.New().String()
|
|
|
|
result, err := ProfitLossAnalyticsContractToModel(&contract.ProfitLossAnalyticsRequest{
|
|
OrganizationID: orgID,
|
|
OutletID: &outletID,
|
|
DateFrom: "01-05-2026",
|
|
DateTo: "29-05-2026",
|
|
GroupBy: "week",
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, orgID, result.OrganizationID)
|
|
require.NotNil(t, result.OutletID)
|
|
require.Equal(t, outletID, result.OutletID.String())
|
|
require.Equal(t, "week", result.GroupBy)
|
|
|
|
location, err := time.LoadLocation("Asia/Jakarta")
|
|
require.NoError(t, err)
|
|
require.Equal(t, time.Date(2026, 5, 1, 0, 0, 0, 0, location), result.DateFrom)
|
|
require.Equal(t, time.Date(2026, 5, 29, 23, 59, 59, int(time.Second-time.Nanosecond), location), result.DateTo)
|
|
}
|
|
|
|
func TestProfitLossAnalyticsModelToContractCopiesDateRange(t *testing.T) {
|
|
dateFrom := time.Date(2026, 5, 1, 0, 0, 0, 0, time.UTC)
|
|
dateTo := time.Date(2026, 5, 29, 23, 59, 59, int(time.Second-time.Nanosecond), time.UTC)
|
|
productID := uuid.New()
|
|
categoryID := uuid.New()
|
|
|
|
result := ProfitLossAnalyticsModelToContract(&models.ProfitLossAnalyticsResponse{
|
|
OrganizationID: uuid.New(),
|
|
DateFrom: dateFrom,
|
|
DateTo: dateTo,
|
|
GroupBy: "month",
|
|
Summary: models.ProfitLossSummary{
|
|
TotalRevenue: 1000,
|
|
NetProfit: 500,
|
|
},
|
|
Data: []models.ProfitLossData{
|
|
{
|
|
Date: dateFrom,
|
|
Revenue: 1000,
|
|
NetProfit: 500,
|
|
},
|
|
},
|
|
ProductData: []models.ProductProfitData{
|
|
{
|
|
ProductID: productID,
|
|
ProductName: "Nasi",
|
|
CategoryID: categoryID,
|
|
CategoryName: "Food",
|
|
Revenue: 1000,
|
|
GrossProfit: 500,
|
|
},
|
|
},
|
|
MainSummary: []models.ProfitLossSummaryRow{
|
|
{
|
|
ID: "total_omset",
|
|
Label: "TOTAL OMSET",
|
|
TodayNominal: 1000,
|
|
},
|
|
},
|
|
})
|
|
|
|
require.NotNil(t, result)
|
|
require.Equal(t, dateFrom, result.DateFrom)
|
|
require.Equal(t, dateTo, result.DateTo)
|
|
require.Equal(t, "month", result.GroupBy)
|
|
require.Equal(t, float64(1000), result.Summary.TotalRevenue)
|
|
require.Len(t, result.Data, 1)
|
|
require.Equal(t, float64(500), result.Data[0].NetProfit)
|
|
require.Len(t, result.ProductData, 1)
|
|
require.Equal(t, productID, result.ProductData[0].ProductID)
|
|
require.Len(t, result.MainSummary, 1)
|
|
require.Equal(t, "total_omset", result.MainSummary[0].ID)
|
|
}
|