package gst import ( "testing" ) func TestCalculateLineItem(t *testing.T) { c := NewCalculator() product := Product{ SKU: "TEST01", BasePrice: 100, WholesalePrice: 90, GSTRate: Rate18, } // Case 1: Retail, Intra-state item := c.CalculateLineItem(product, 2, CustomerRetail, false) if item.UnitPrice != 100 { t.Errorf("Expected UnitPrice 100, got %f", item.UnitPrice) } if item.TaxableVal != 200 { t.Errorf("Expected TaxableVal 200, got %f", item.TaxableVal) } if item.CGSTAmount != 18 { // 9% of 200 t.Errorf("Expected CGST 18, got %f", item.CGSTAmount) } if item.IGSTAmount != 0 { t.Errorf("Expected IGST 0, got %f", item.IGSTAmount) } if item.TotalAmount != 236 { // 200 + 18 + 18 t.Errorf("Expected Total 236, got %f", item.TotalAmount) } // Case 2: Wholesale, Inter-state item = c.CalculateLineItem(product, 10, CustomerWholesale, true) if item.UnitPrice != 90 { t.Errorf("Expected UnitPrice 90, got %f", item.UnitPrice) } if item.TaxableVal != 900 { t.Errorf("Expected TaxableVal 900, got %f", item.TaxableVal) } if item.CGSTAmount != 0 { t.Errorf("Expected CGST 0, got %f", item.CGSTAmount) } if item.IGSTAmount != 162 { // 18% of 900 t.Errorf("Expected IGST 162, got %f", item.IGSTAmount) } if item.TotalAmount != 1062 { // 900 + 162 t.Errorf("Expected Total 1062, got %f", item.TotalAmount) } } func TestCalculateInvoice(t *testing.T) { c := NewCalculator() product := Product{SKU: "TEST01", BasePrice: 100, GSTRate: Rate18} item1 := c.CalculateLineItem(product, 1, CustomerRetail, false) item2 := c.CalculateLineItem(product, 1, CustomerRetail, false) // Test with convenience fee (intra-state) invoice := c.CalculateInvoice([]LineItem{item1, item2}, 50, false) // Convenience fee is taxed at 18% // SubTotal should include convenience fee: 100 + 100 + 50 = 250 expectedSubTotal := 250.0 if invoice.SubTotal != expectedSubTotal { t.Errorf("Expected SubTotal %f, got %f", expectedSubTotal, invoice.SubTotal) } // Convenience fee tax: 50 * 0.18 = 9 expectedFeeTax := 9.0 if invoice.ConvenienceFeeTax != expectedFeeTax { t.Errorf("Expected ConvenienceFeeTax %f, got %f", expectedFeeTax, invoice.ConvenienceFeeTax) } // Total CGST: 9 + 9 + 4.5 = 22.5 (from items + half of fee tax) expectedCGST := 22.5 if invoice.TotalCGST != expectedCGST { t.Errorf("Expected TotalCGST %f, got %f", expectedCGST, invoice.TotalCGST) } // GrandTotal: SubTotal + CGST + SGST = 250 + 22.5 + 22.5 = 295 expectedTotal := 295.0 if invoice.GrandTotal != expectedTotal { t.Errorf("Expected GrandTotal %f, got %f", expectedTotal, invoice.GrandTotal) } } func TestCalculateInvoiceInterState(t *testing.T) { c := NewCalculator() product := Product{SKU: "TEST01", BasePrice: 100, GSTRate: Rate18} item := c.CalculateLineItem(product, 1, CustomerRetail, true) // Test with convenience fee (inter-state) invoice := c.CalculateInvoice([]LineItem{item}, 50, true) // SubTotal: 100 + 50 = 150 expectedSubTotal := 150.0 if invoice.SubTotal != expectedSubTotal { t.Errorf("Expected SubTotal %f, got %f", expectedSubTotal, invoice.SubTotal) } // Convenience fee tax: 50 * 0.18 = 9 expectedFeeTax := 9.0 if invoice.ConvenienceFeeTax != expectedFeeTax { t.Errorf("Expected ConvenienceFeeTax %f, got %f", expectedFeeTax, invoice.ConvenienceFeeTax) } // Total IGST: 18 + 9 = 27 (from item + fee tax) expectedIGST := 27.0 if invoice.TotalIGST != expectedIGST { t.Errorf("Expected TotalIGST %f, got %f", expectedIGST, invoice.TotalIGST) } // GrandTotal: SubTotal + IGST = 150 + 27 = 177 expectedTotal := 177.0 if invoice.GrandTotal != expectedTotal { t.Errorf("Expected GrandTotal %f, got %f", expectedTotal, invoice.GrandTotal) } }