Files
MyClub/internal/controllers/expense_controller.go
T
Tomas Dvorak dfc079288f hot fix #1
2026-01-26 08:13:18 +01:00

112 lines
2.8 KiB
Go

package controllers
import (
"fmt"
"net/http"
"path/filepath"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// ExpenseController handles expense-related operations
type ExpenseController struct {
db *gorm.DB
}
// NewExpenseController creates a new expense controller
func NewExpenseController(db *gorm.DB) *ExpenseController {
return &ExpenseController{db: db}
}
// UploadReceipt handles receipt upload and OCR processing
func (ec *ExpenseController) UploadReceipt(c *gin.Context) {
// Get the uploaded file
file, header, err := c.Request.FormFile("receipt")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "No file uploaded"})
return
}
defer file.Close()
// Validate file type
allowedTypes := []string{"image/jpeg", "image/jpg", "image/png", "application/pdf"}
if !contains(allowedTypes, header.Header.Get("Content-Type")) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid file type. Only JPEG, PNG, and PDF files are allowed"})
return
}
// Generate unique filename
ext := filepath.Ext(header.Filename)
filename := fmt.Sprintf("receipt_%d%s", time.Now().UnixNano(), ext)
// Save file to uploads directory
filePath := filepath.Join("uploads", "receipts", filename)
if err := c.SaveUploadedFile(header, filePath); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file"})
return
}
// Perform OCR processing (placeholder)
ocrData, accuracy, err := ec.performOCR(filePath)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "OCR processing failed"})
return
}
// Parse receipt data (placeholder)
parsedData := parseReceiptData(ocrData)
response := gin.H{
"file_path": filePath,
"file_name": filename,
"file_size": header.Size,
"ocr_data": ocrData,
"ocr_accuracy": accuracy,
"parsed_data": parsedData,
}
c.JSON(http.StatusOK, gin.H{
"receipt": response,
})
}
// performOCR performs OCR on the uploaded file
func (ec *ExpenseController) performOCR(filePath string) (string, float64, error) {
// This is a placeholder for OCR implementation
// In a real implementation, you would use Tesseract or another OCR service
return "Sample OCR text", 95.0, nil
}
// parseReceiptData parses OCR text to extract structured data
func parseReceiptData(ocrText string) map[string]interface{} {
// This is a placeholder for receipt parsing logic
// In a real implementation, you would use regex patterns or ML to extract:
// - Merchant name
// - Date
// - Total amount
// - VAT
// - Items
parsed := map[string]interface{}{
"merchant": "",
"date": "",
"total": 0,
"vat": 0,
"items": []map[string]interface{}{},
}
return parsed
}
// Helper function to check if slice contains string
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
}