Fix coa summary zero
This commit is contained in:
parent
7c8c7fb7db
commit
b90a3cde4a
@ -3,6 +3,7 @@ package processor
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"apskel-pos-be/internal/models"
|
||||
@ -480,7 +481,14 @@ func (p *AnalyticsProcessorImpl) GetProfitLossAnalytics(ctx context.Context, req
|
||||
|
||||
var todayTotalOps float64
|
||||
var mtdTotalOps float64
|
||||
var todayGaji float64
|
||||
var mtdGaji float64
|
||||
for _, cat := range categoryMap {
|
||||
if isSalaryExpenseCategory(cat.Name) {
|
||||
todayGaji += cat.TodayAmt
|
||||
mtdGaji += cat.MtdAmt
|
||||
continue
|
||||
}
|
||||
todayTotalOps += cat.TodayAmt
|
||||
mtdTotalOps += cat.MtdAmt
|
||||
}
|
||||
@ -488,8 +496,11 @@ func (p *AnalyticsProcessorImpl) GetProfitLossAnalytics(ctx context.Context, req
|
||||
todayGrossProfit := result.TodayRevenue - result.TodayCost
|
||||
mtdGrossProfit := result.MtdRevenue - result.MtdCost
|
||||
|
||||
todayNetProfit := todayGrossProfit - todayTotalOps
|
||||
mtdNetProfit := mtdGrossProfit - mtdTotalOps
|
||||
todayProfitBeforeGaji := todayGrossProfit - todayTotalOps
|
||||
mtdProfitBeforeGaji := mtdGrossProfit - mtdTotalOps
|
||||
|
||||
todayNetProfit := todayProfitBeforeGaji - todayGaji
|
||||
mtdNetProfit := mtdProfitBeforeGaji - mtdGaji
|
||||
|
||||
todayPct := func(nominal float64) float64 {
|
||||
if result.TodayRevenue == 0 {
|
||||
@ -505,11 +516,16 @@ func (p *AnalyticsProcessorImpl) GetProfitLossAnalytics(ctx context.Context, req
|
||||
}
|
||||
|
||||
opsSubItems := make([]models.ProfitLossSummaryRow, 0, len(categoryOrder)+1)
|
||||
for i, name := range categoryOrder {
|
||||
opsCategoryCount := 0
|
||||
for _, name := range categoryOrder {
|
||||
cat := categoryMap[name]
|
||||
if isSalaryExpenseCategory(cat.Name) {
|
||||
continue
|
||||
}
|
||||
opsCategoryCount++
|
||||
opsSubItems = append(opsSubItems, models.ProfitLossSummaryRow{
|
||||
ID: fmt.Sprintf("by_%s", slugify(name)),
|
||||
Label: fmt.Sprintf("%d. %s", i+1, cat.Name),
|
||||
Label: fmt.Sprintf("%d. %s", opsCategoryCount, cat.Name),
|
||||
TodayNominal: cat.TodayAmt,
|
||||
TodayPct: todayPct(cat.TodayAmt),
|
||||
MtdNominal: cat.MtdAmt,
|
||||
@ -518,7 +534,7 @@ func (p *AnalyticsProcessorImpl) GetProfitLossAnalytics(ctx context.Context, req
|
||||
}
|
||||
opsSubItems = append(opsSubItems, models.ProfitLossSummaryRow{
|
||||
ID: "total_biaya_ops",
|
||||
Label: fmt.Sprintf("Total Biaya OPS (%d kategori)", len(categoryOrder)),
|
||||
Label: fmt.Sprintf("Total Biaya OPS (%d kategori)", opsCategoryCount),
|
||||
IsBold: true,
|
||||
TodayNominal: todayTotalOps,
|
||||
TodayPct: todayPct(todayTotalOps),
|
||||
@ -549,7 +565,17 @@ func (p *AnalyticsProcessorImpl) GetProfitLossAnalytics(ctx context.Context, req
|
||||
SubItems: opsSubItems,
|
||||
},
|
||||
{
|
||||
ID: "laba_rugi", Label: "Laba/Rugi Bersih (3-4)", IsBold: true,
|
||||
ID: "laba_rugi_sblm_gaji", Label: "Laba/Rugi sblm Gaji (3-4)",
|
||||
TodayNominal: todayProfitBeforeGaji, TodayPct: todayPct(todayProfitBeforeGaji),
|
||||
MtdNominal: mtdProfitBeforeGaji, MtdPct: mtdPct(mtdProfitBeforeGaji),
|
||||
},
|
||||
{
|
||||
ID: "biaya_gaji", Label: "BIAYA GAJI",
|
||||
TodayNominal: todayGaji, TodayPct: todayPct(todayGaji),
|
||||
MtdNominal: mtdGaji, MtdPct: mtdPct(mtdGaji),
|
||||
},
|
||||
{
|
||||
ID: "laba_rugi", Label: "Laba/Rugi (5-6)", IsBold: true,
|
||||
TodayNominal: todayNetProfit, TodayPct: todayPct(todayNetProfit),
|
||||
MtdNominal: mtdNetProfit, MtdPct: mtdPct(mtdNetProfit),
|
||||
},
|
||||
@ -592,6 +618,11 @@ func (p *AnalyticsProcessorImpl) GetProfitLossAnalytics(ctx context.Context, req
|
||||
}, nil
|
||||
}
|
||||
|
||||
func isSalaryExpenseCategory(name string) bool {
|
||||
name = strings.ToLower(name)
|
||||
return strings.Contains(name, "gaji") || strings.Contains(name, "salary")
|
||||
}
|
||||
|
||||
func slugify(s string) string {
|
||||
result := make([]byte, 0, len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
|
||||
@ -200,7 +200,7 @@ func TestAnalyticsProcessorGetProfitLossAnalyticsDynamicExpenseCategories(t *tes
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result)
|
||||
|
||||
require.Len(t, result.MainSummary, 5)
|
||||
require.Len(t, result.MainSummary, 7)
|
||||
|
||||
require.Equal(t, "total_omset", result.MainSummary[0].ID)
|
||||
require.Equal(t, float64(10000), result.MainSummary[0].TodayNominal)
|
||||
@ -215,29 +215,33 @@ func TestAnalyticsProcessorGetProfitLossAnalyticsDynamicExpenseCategories(t *tes
|
||||
require.Equal(t, float64(12000), result.MainSummary[2].MtdNominal)
|
||||
|
||||
require.Equal(t, "biaya_ops", result.MainSummary[3].ID)
|
||||
require.Equal(t, float64(2300), result.MainSummary[3].TodayNominal)
|
||||
require.Equal(t, float64(4600), result.MainSummary[3].MtdNominal)
|
||||
require.Len(t, result.MainSummary[3].SubItems, 4) // 3 categories + 1 total
|
||||
require.Equal(t, float64(800), result.MainSummary[3].TodayNominal)
|
||||
require.Equal(t, float64(1600), result.MainSummary[3].MtdNominal)
|
||||
require.Len(t, result.MainSummary[3].SubItems, 3) // 2 operational categories + 1 total
|
||||
|
||||
require.Equal(t, "by_gaji", result.MainSummary[3].SubItems[0].ID)
|
||||
require.Equal(t, float64(1500), result.MainSummary[3].SubItems[0].TodayNominal)
|
||||
require.Equal(t, float64(3000), result.MainSummary[3].SubItems[0].MtdNominal)
|
||||
require.Equal(t, "by_promosi", result.MainSummary[3].SubItems[0].ID)
|
||||
require.Equal(t, float64(300), result.MainSummary[3].SubItems[0].TodayNominal)
|
||||
require.Equal(t, float64(600), result.MainSummary[3].SubItems[0].MtdNominal)
|
||||
|
||||
require.Equal(t, "by_promosi", result.MainSummary[3].SubItems[1].ID)
|
||||
require.Equal(t, float64(300), result.MainSummary[3].SubItems[1].TodayNominal)
|
||||
require.Equal(t, float64(600), result.MainSummary[3].SubItems[1].MtdNominal)
|
||||
require.Equal(t, "by_sewa", result.MainSummary[3].SubItems[1].ID)
|
||||
require.Equal(t, float64(500), result.MainSummary[3].SubItems[1].TodayNominal)
|
||||
require.Equal(t, float64(1000), result.MainSummary[3].SubItems[1].MtdNominal)
|
||||
|
||||
require.Equal(t, "by_sewa", result.MainSummary[3].SubItems[2].ID)
|
||||
require.Equal(t, float64(500), result.MainSummary[3].SubItems[2].TodayNominal)
|
||||
require.Equal(t, float64(1000), result.MainSummary[3].SubItems[2].MtdNominal)
|
||||
require.Equal(t, "total_biaya_ops", result.MainSummary[3].SubItems[2].ID)
|
||||
require.True(t, result.MainSummary[3].SubItems[2].IsBold)
|
||||
require.Equal(t, float64(800), result.MainSummary[3].SubItems[2].TodayNominal)
|
||||
require.Equal(t, float64(1600), result.MainSummary[3].SubItems[2].MtdNominal)
|
||||
|
||||
require.Equal(t, "total_biaya_ops", result.MainSummary[3].SubItems[3].ID)
|
||||
require.True(t, result.MainSummary[3].SubItems[3].IsBold)
|
||||
require.Equal(t, float64(2300), result.MainSummary[3].SubItems[3].TodayNominal)
|
||||
require.Equal(t, float64(4600), result.MainSummary[3].SubItems[3].MtdNominal)
|
||||
require.Equal(t, "laba_rugi_sblm_gaji", result.MainSummary[4].ID)
|
||||
require.Equal(t, float64(5200), result.MainSummary[4].TodayNominal)
|
||||
require.Equal(t, float64(10400), result.MainSummary[4].MtdNominal)
|
||||
|
||||
require.Equal(t, "laba_rugi", result.MainSummary[4].ID)
|
||||
require.Equal(t, float64(3700), result.MainSummary[4].TodayNominal)
|
||||
require.Equal(t, float64(7400), result.MainSummary[4].MtdNominal)
|
||||
require.True(t, result.MainSummary[4].IsBold)
|
||||
require.Equal(t, "biaya_gaji", result.MainSummary[5].ID)
|
||||
require.Equal(t, float64(1500), result.MainSummary[5].TodayNominal)
|
||||
require.Equal(t, float64(3000), result.MainSummary[5].MtdNominal)
|
||||
|
||||
require.Equal(t, "laba_rugi", result.MainSummary[6].ID)
|
||||
require.Equal(t, float64(3700), result.MainSummary[6].TodayNominal)
|
||||
require.Equal(t, float64(7400), result.MainSummary[6].MtdNominal)
|
||||
require.True(t, result.MainSummary[6].IsBold)
|
||||
}
|
||||
|
||||
@ -22,8 +22,6 @@ const (
|
||||
MetadataKeyLastSplitQuantities = "last_split_quantities"
|
||||
)
|
||||
|
||||
|
||||
|
||||
type SplitBillValidation struct {
|
||||
OrderItems map[uuid.UUID]*entities.OrderItem
|
||||
PaidQuantities map[uuid.UUID]int
|
||||
|
||||
@ -637,7 +637,7 @@ func (r *AnalyticsRepositoryImpl) getExpenseByCategory(ctx context.Context, orga
|
||||
|
||||
query := r.db.WithContext(ctx).
|
||||
Table("expense_items ei").
|
||||
Select(`COALESCE(parent_coa.name, 'Lain-lain') as category_name, COALESCE(SUM(ei.amount), 0) as amount`).
|
||||
Select(`COALESCE(parent_coa.name, coa.name, 'Lain-lain') as category_name, COALESCE(SUM(ei.amount), 0) as amount`).
|
||||
Joins("JOIN expenses e ON ei.expense_id = e.id").
|
||||
Joins("JOIN chart_of_accounts coa ON ei.chart_of_account_id = coa.id").
|
||||
Joins("LEFT JOIN chart_of_accounts parent_coa ON coa.parent_id = parent_coa.id").
|
||||
@ -650,8 +650,8 @@ func (r *AnalyticsRepositoryImpl) getExpenseByCategory(ctx context.Context, orga
|
||||
}
|
||||
|
||||
err := query.
|
||||
Group("parent_coa.name").
|
||||
Order("parent_coa.name").
|
||||
Group("COALESCE(parent_coa.name, coa.name, 'Lain-lain')").
|
||||
Order("COALESCE(parent_coa.name, coa.name, 'Lain-lain')").
|
||||
Scan(&results).Error
|
||||
|
||||
return results, err
|
||||
|
||||
@ -173,4 +173,3 @@ func (r *IngredientUnitConverterRepositoryImpl) ConvertQuantity(ctx context.Cont
|
||||
// If no converter found, return error
|
||||
return 0, fmt.Errorf("no conversion found between units %s and %s for ingredient %s", fromUnitID, toUnitID, ingredientID)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user