100 lines
3.1 KiB
Go
100 lines
3.1 KiB
Go
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
|
|
}
|