package database import ( "billit/internal/models" "database/sql" "encoding/json" "fmt" "time" ) // GetNextInvoiceNumber generates the next invoice ID in format PREFIX/MMM-YYYY/XXX and increments the counter func (s *service) GetNextInvoiceNumber(userID string) (string, error) { var prefix string var counter int // Get current prefix and counter err := s.db.QueryRow(`SELECT COALESCE(invoice_prefix, 'INV'), COALESCE(invoice_counter, 0) FROM users WHERE id = ?`, userID). Scan(&prefix, &counter) if err != nil { return "", err } // Increment counter counter++ // Update counter in database _, err = s.db.Exec(`UPDATE users SET invoice_counter = ? WHERE id = ?`, counter, userID) if err != nil { return "", err } // Generate formatted invoice ID: PREFIX/MMM-YYYY/XXX now := time.Now() humanReadableID := fmt.Sprintf("%s/%s-%d/%03d", prefix, now.Month().String()[:3], now.Year(), counter) return humanReadableID, nil } // CreateInvoice stores an invoice with UUID and human-readable ID for a user func (s *service) CreateInvoice(id string, humanReadableID string, data interface{}, userID string) error { jsonData, err := json.Marshal(data) if err != nil { return err } _, err = s.db.Exec(`INSERT INTO invoices (id, human_readable_id, data, user_id) VALUES (?, ?, ?, ?)`, id, humanReadableID, string(jsonData), userID) return err } // GetInvoice retrieves an invoice by ID for a user func (s *service) GetInvoice(id string, userID string) (*models.Invoice, error) { var inv models.Invoice err := s.db.QueryRow(`SELECT id, COALESCE(human_readable_id, ''), data, user_id, created_at FROM invoices WHERE id=? AND user_id=?`, id, userID). Scan(&inv.ID, &inv.HumanReadableID, &inv.Data, &inv.UserID, &inv.CreatedAt) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &inv, nil } // GetAllInvoices retrieves all invoices for a user func (s *service) GetAllInvoices(userID string) ([]models.Invoice, error) { rows, err := s.db.Query(`SELECT id, COALESCE(human_readable_id, ''), data, user_id, created_at FROM invoices WHERE user_id=? ORDER BY created_at DESC`, userID) if err != nil { return nil, err } defer rows.Close() var invoices []models.Invoice for rows.Next() { var inv models.Invoice if err := rows.Scan(&inv.ID, &inv.HumanReadableID, &inv.Data, &inv.UserID, &inv.CreatedAt); err != nil { return nil, err } invoices = append(invoices, inv) } return invoices, nil } // GetRecentInvoices returns the most recently generated invoices for a user func (s *service) GetRecentInvoices(userID string, limit int) ([]models.Invoice, error) { rows, err := s.db.Query(`SELECT id, COALESCE(human_readable_id, ''), data, user_id, created_at FROM invoices WHERE user_id=? ORDER BY created_at DESC LIMIT ?`, userID, limit) if err != nil { return nil, err } defer rows.Close() var invoices []models.Invoice for rows.Next() { var inv models.Invoice if err := rows.Scan(&inv.ID, &inv.HumanReadableID, &inv.Data, &inv.UserID, &inv.CreatedAt); err != nil { return nil, err } invoices = append(invoices, inv) } return invoices, nil }