package controller import ( "bytes" "testing" "time" approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto" "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/dto" locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto" supplierDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/dto" "github.com/xuri/excelize/v2" ) func TestBuildExpenseExportWorkbookHeadersAndRows(t *testing.T) { realizationDate := time.Date(2026, time.April, 22, 0, 0, 0, 0, time.UTC) content, err := buildExpenseExportWorkbook([]dto.ExpenseListDTO{ { ExpenseBaseDTO: dto.ExpenseBaseDTO{ PoNumber: "PO-00011", ReferenceNumber: "EXP-00011", RealizationDate: &realizationDate, TransactionDate: time.Date(2026, time.April, 22, 0, 0, 0, 0, time.UTC), Category: "BOP", Supplier: &supplierDTO.SupplierRelationDTO{ Name: "Supplier A", }, Location: &locationDTO.LocationRelationDTO{ Name: "Farm A", }, }, GrandTotal: 1234567, LatestApproval: &approvalDTO.ApprovalRelationDTO{ StepName: "Finance", }, }, { ExpenseBaseDTO: dto.ExpenseBaseDTO{ PoNumber: "", ReferenceNumber: "", Category: "", }, GrandTotal: 75000, LatestApproval: &approvalDTO.ApprovalRelationDTO{ StepName: "Head Area", Action: expenseStrPtr("REJECTED"), }, }, { ExpenseBaseDTO: dto.ExpenseBaseDTO{}, GrandTotal: 0, LatestApproval: nil, }, }) if err != nil { t.Fatalf("buildExpenseExportWorkbook returned error: %v", err) } file, err := excelize.OpenReader(bytes.NewReader(content)) if err != nil { t.Fatalf("failed to open workbook bytes: %v", err) } defer file.Close() sheets := file.GetSheetList() if len(sheets) != 1 || sheets[0] != expenseExportSheetName { t.Fatalf("expected single sheet %q, got %+v", expenseExportSheetName, sheets) } expectedHeaders := map[string]string{ "A1": "No", "B1": "No. PO", "C1": "No. Referensi", "D1": "Tanggal Realisasi", "E1": "Tanggal Transaksi", "F1": "Kategori", "G1": "Supplier", "H1": "Lokasi", "I1": "Grand Total", "J1": "Status", } for cell, expected := range expectedHeaders { got, err := file.GetCellValue(expenseExportSheetName, cell) if err != nil { t.Fatalf("GetCellValue(%s) failed: %v", cell, err) } if got != expected { t.Fatalf("expected %s=%q, got %q", cell, expected, got) } } assertExpenseCellEquals(t, file, "A2", "1") assertExpenseCellEquals(t, file, "B2", "PO-00011") assertExpenseCellEquals(t, file, "C2", "EXP-00011") assertExpenseCellEquals(t, file, "D2", "22-04-2026") assertExpenseCellEquals(t, file, "E2", "22-04-2026") assertExpenseCellEquals(t, file, "F2", "BOP") assertExpenseCellEquals(t, file, "G2", "Supplier A") assertExpenseCellEquals(t, file, "H2", "Farm A") assertExpenseCellEquals(t, file, "J2", "Finance") rawGrandTotal, err := file.GetCellValue(expenseExportSheetName, "I2", excelize.Options{RawCellValue: true}) if err != nil { t.Fatalf("GetCellValue(I2, RawCellValue) failed: %v", err) } if rawGrandTotal != "1234567" { t.Fatalf("expected raw I2 grand total 1234567, got %q", rawGrandTotal) } assertExpenseCellEquals(t, file, "B3", "-") assertExpenseCellEquals(t, file, "C3", "-") assertExpenseCellEquals(t, file, "D3", "-") assertExpenseCellEquals(t, file, "E3", "-") assertExpenseCellEquals(t, file, "F3", "-") assertExpenseCellEquals(t, file, "G3", "-") assertExpenseCellEquals(t, file, "H3", "-") assertExpenseCellEquals(t, file, "J3", "Ditolak") assertExpenseCellEquals(t, file, "J4", "-") } func assertExpenseCellEquals(t *testing.T, file *excelize.File, cell, expected string) { t.Helper() got, err := file.GetCellValue(expenseExportSheetName, cell) if err != nil { t.Fatalf("GetCellValue(%s) failed: %v", cell, err) } if got != expected { t.Fatalf("expected %s=%q, got %q", cell, expected, got) } } func expenseStrPtr(value string) *string { return &value }