package controller import ( "bytes" "testing" "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" "github.com/xuri/excelize/v2" ) func TestBuildPurchaseExportWorkbookHeadersAndRows(t *testing.T) { content, err := buildPurchaseExportWorkbook([]entity.Purchase{ buildPurchaseForExportTest( 1, "PR-00011", "PO-00011", time.Date(2026, time.April, 22, 0, 0, 0, 0, time.UTC), "Supplier A", "Manager Purchase", nil, "catatan", []entity.PurchaseItem{ buildPurchaseItemForExportTest(11, "Pakan Starter", 1000000), buildPurchaseItemForExportTest(12, "Vitamin A", 350000), buildPurchaseItemForExportTest(11, "Pakan Starter", 0), }, ), buildPurchaseForExportTest( 2, "PR-00012", "", time.Time{}, "Supplier B", "Manager Purchase", ptrApprovalAction(entity.ApprovalActionRejected), "", []entity.PurchaseItem{ buildPurchaseItemForExportTest(21, "Obat X", 75000), }, ), }) if err != nil { t.Fatalf("buildPurchaseExportWorkbook 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() expectedHeaders := map[string]string{ "A1": "PR Number", "B1": "PO Number", "C1": "Tanggal PO", "D1": "Supplier", "E1": "Status", "F1": "Grand Total", "G1": "Products", "H1": "Notes", } for cell, expected := range expectedHeaders { got, err := file.GetCellValue(purchaseExportSheetName, 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) } } assertPurchaseCellEquals(t, file, "A2", "PR-00011") assertPurchaseCellEquals(t, file, "B2", "PO-00011") assertPurchaseCellEquals(t, file, "C2", "22-04-2026") assertPurchaseCellEquals(t, file, "D2", "Supplier A") assertPurchaseCellEquals(t, file, "E2", "Manager Purchase") assertPurchaseCellEquals(t, file, "F2", "Rp 1.350.000") assertPurchaseCellEquals(t, file, "G2", "Pakan Starter, Vitamin A") assertPurchaseCellEquals(t, file, "H2", "catatan") assertPurchaseCellEquals(t, file, "A3", "PR-00012") assertPurchaseCellEquals(t, file, "B3", "-") assertPurchaseCellEquals(t, file, "C3", "-") assertPurchaseCellEquals(t, file, "E3", "Ditolak") assertPurchaseCellEquals(t, file, "F3", "Rp 75.000") assertPurchaseCellEquals(t, file, "G3", "Obat X") assertPurchaseCellEquals(t, file, "H3", "-") } func assertPurchaseCellEquals(t *testing.T, file *excelize.File, cell, expected string) { t.Helper() got, err := file.GetCellValue(purchaseExportSheetName, 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 buildPurchaseForExportTest( id uint, prNumber, poNumber string, poDate time.Time, supplierName, stepName string, action *entity.ApprovalAction, notes string, items []entity.PurchaseItem, ) entity.Purchase { var poNumberRef *string if poNumber != "" { poNumberRef = &poNumber } var poDateRef *time.Time if !poDate.IsZero() { poDateRef = &poDate } var notesRef *string if notes != "" { notesRef = ¬es } return entity.Purchase{ Id: id, PrNumber: prNumber, PoNumber: poNumberRef, PoDate: poDateRef, Notes: notesRef, Supplier: entity.Supplier{ Id: id + 100, Name: supplierName, }, LatestApproval: &entity.Approval{ Id: id + 1000, StepName: stepName, Action: action, }, Items: items, } } func buildPurchaseItemForExportTest(productID uint, productName string, totalPrice float64) entity.PurchaseItem { return entity.PurchaseItem{ ProductId: productID, TotalPrice: totalPrice, Product: &entity.Product{ Id: productID, Name: productName, }, } } func ptrApprovalAction(value entity.ApprovalAction) *entity.ApprovalAction { return &value }