Merge branch 'feature/exclusive-summary-revise' into feature/exclusive-summary

This commit is contained in:
2026-06-17 18:32:11 +07:00
12 changed files with 1277 additions and 0 deletions
@@ -15,6 +15,8 @@ import (
type analyticsRepositoryStub struct {
purchasingResult *entities.PurchasingAnalytics
profitLossResult *entities.ProfitLossAnalytics
exclusiveResult *entities.ExclusiveSummaryAnalytics
bankBalances []entities.ExclusiveSummaryBankBalance
profitLossGroup string
}
@@ -47,6 +49,14 @@ func (s analyticsRepositoryStub) GetProfitLossAnalytics(_ context.Context, _ uui
return s.profitLossResult, nil
}
func (s analyticsRepositoryStub) GetExclusiveSummaryAnalytics(context.Context, uuid.UUID, *uuid.UUID, time.Time, time.Time) (*entities.ExclusiveSummaryAnalytics, error) {
return s.exclusiveResult, nil
}
func (s analyticsRepositoryStub) GetExclusiveSummaryBankBalances(context.Context, uuid.UUID, *uuid.UUID) ([]entities.ExclusiveSummaryBankBalance, error) {
return s.bankBalances, nil
}
type expenseRepositoryStub struct{}
func (expenseRepositoryStub) Create(context.Context, *entities.Expense) error { return nil }
@@ -273,3 +283,91 @@ func TestAnalyticsProcessorGetProfitLossAnalyticsDynamicExpenseCategories(t *tes
require.Equal(t, float64(7400), result.MainSummary[6].MtdNominal)
require.True(t, result.MainSummary[6].IsBold)
}
func TestAnalyticsProcessorGetExclusiveSummaryPeriodCalculatesSummaryAndReimburse(t *testing.T) {
now := time.Date(2026, 5, 26, 0, 0, 0, 0, time.UTC)
processor := NewAnalyticsProcessorImpl(analyticsRepositoryStub{
exclusiveResult: &entities.ExclusiveSummaryAnalytics{
SalesTotal: 35619000,
HPPBreakdown: []entities.ExclusiveSummaryCategoryTotal{
{CategoryCode: "hpp_nusantara", CategoryName: "Nusantara", Amount: 19010552},
},
OperationalExpenseBreakdown: []entities.ExclusiveSummaryCategoryTotal{
{CategoryCode: "biaya_gaji_staff", CategoryName: "Gaji Staff", Amount: 48203333},
{CategoryCode: "biaya_gaji_dw", CategoryName: "Gaji DW", Amount: 3555000},
{CategoryCode: "biaya_lain", CategoryName: "Biaya Lain-lain", Amount: 1608605},
},
DailyTransactions: []entities.ExclusiveSummaryDailyTransaction{
{Date: now, CategoryCode: "biaya_gaji_staff", CategoryName: "Gaji Staff", Description: "gaji kary", Amount: 48203333, Source: "purchase_order"},
{Date: now, CategoryCode: "biaya_gaji_dw", CategoryName: "Gaji DW", Description: "DW", Amount: 3555000, Source: "purchase_order"},
},
},
}, expenseRepositoryStub{})
result, err := processor.GetExclusiveSummaryPeriod(context.Background(), &models.ExclusiveSummaryPeriodRequest{
OrganizationID: uuid.New(),
DateFrom: now,
DateTo: now,
ExcludeGajiStaffFromReimburse: true,
})
require.NoError(t, err)
require.NotNil(t, result)
require.Equal(t, float64(35619000), result.Summary.Sales)
require.Equal(t, float64(19010552), result.Summary.HPP)
require.Equal(t, float64(16608448), result.Summary.GrossProfit)
require.Equal(t, float64(51758333), result.Summary.SalaryTotal)
require.Equal(t, float64(3555000), result.Summary.SalaryDW)
require.Equal(t, float64(48203333), result.Summary.SalaryStaff)
require.Equal(t, float64(53366938), result.Summary.OperationalExpensesTotal)
require.Equal(t, float64(72377490), result.Summary.TotalCost)
require.Equal(t, float64(-36758490), result.Summary.NetProfit)
require.Equal(t, float64(48203333), result.Reimburse.ExcludedSalaryStaff)
require.Equal(t, float64(24174157), result.Reimburse.TotalReimburse)
}
func TestAnalyticsProcessorGetExclusiveSummaryMonthlyBuildsCalendarBucketsAndBankTemplate(t *testing.T) {
location, err := time.LoadLocation("Asia/Jakarta")
require.NoError(t, err)
month := time.Date(2026, 5, 1, 0, 0, 0, 0, location)
processor := NewAnalyticsProcessorImpl(analyticsRepositoryStub{
exclusiveResult: &entities.ExclusiveSummaryAnalytics{
SalesTotal: 1000,
HPPBreakdown: []entities.ExclusiveSummaryCategoryTotal{
{CategoryCode: "hpp", CategoryName: "HPP", Amount: 400},
},
OperationalExpenseBreakdown: []entities.ExclusiveSummaryCategoryTotal{
{CategoryCode: "ops", CategoryName: "OPS", Amount: 100},
},
},
bankBalances: []entities.ExclusiveSummaryBankBalance{
{Bank: "Rekening Bank", AccountType: "wallet", OpeningBalance: 1000, ClosingBalance: 2500},
{Bank: "Kas Utama", AccountType: "cash", OpeningBalance: 3000, ClosingBalance: 3500},
},
}, expenseRepositoryStub{})
result, err := processor.GetExclusiveSummaryMonthly(context.Background(), &models.ExclusiveSummaryMonthlyRequest{
OrganizationID: uuid.New(),
Month: month,
})
require.NoError(t, err)
require.NotNil(t, result)
require.Equal(t, "2026-05", result.Month)
require.Equal(t, float64(1000), result.Summary.TotalSales)
require.Equal(t, float64(500), result.Summary.NetProfit)
require.Len(t, result.Periods, 5)
require.Equal(t, "1 - 3 Mei", result.Periods[0].Label)
require.Equal(t, "25 - 31 Mei", result.Periods[4].Label)
require.Len(t, result.BankBalance, 2)
require.Equal(t, "Rekening Bank", result.BankBalance[0].Bank)
require.NotNil(t, result.BankBalance[0].OpeningBalance)
require.Equal(t, float64(1000), *result.BankBalance[0].OpeningBalance)
require.NotNil(t, result.BankBalance[0].ClosingBalance)
require.Equal(t, float64(2500), *result.BankBalance[0].ClosingBalance)
require.NotNil(t, result.BankBalance[0].Notes)
require.Equal(t, "wallet", *result.BankBalance[0].Notes)
require.Nil(t, result.BankBalance[0].IncomingMutation)
require.Nil(t, result.BankBalance[0].OutgoingMutation)
require.Equal(t, "Kas Utama", result.BankBalance[1].Bank)
}