init
This commit is contained in:
172
internal/repository/ledger_repository.go
Normal file
172
internal/repository/ledger_repository.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"accounting-app/internal/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Common ledger repository errors
|
||||
var (
|
||||
ErrLedgerNotFound = errors.New("ledger not found")
|
||||
ErrLedgerInUse = errors.New("ledger is in use and cannot be deleted")
|
||||
)
|
||||
|
||||
// LedgerRepository handles database operations for ledgers
|
||||
type LedgerRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewLedgerRepository creates a new LedgerRepository instance
|
||||
func NewLedgerRepository(db *gorm.DB) *LedgerRepository {
|
||||
return &LedgerRepository{db: db}
|
||||
}
|
||||
|
||||
// Create creates a new ledger in the database
|
||||
func (r *LedgerRepository) Create(ledger *models.Ledger) error {
|
||||
if err := r.db.Create(ledger).Error; err != nil {
|
||||
return fmt.Errorf("failed to create ledger: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByID retrieves a ledger by its ID
|
||||
func (r *LedgerRepository) GetByID(userID uint, id uint) (*models.Ledger, error) {
|
||||
var ledger models.Ledger
|
||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).First(&ledger).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrLedgerNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get ledger: %w", err)
|
||||
}
|
||||
return &ledger, nil
|
||||
}
|
||||
|
||||
// GetAll retrieves all ledgers from the database (excluding soft-deleted)
|
||||
func (r *LedgerRepository) GetAll(userID uint) ([]models.Ledger, error) {
|
||||
var ledgers []models.Ledger
|
||||
if err := r.db.Where("user_id = ?", userID).Order("sort_order ASC, created_at DESC").Find(&ledgers).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get ledgers: %w", err)
|
||||
}
|
||||
return ledgers, nil
|
||||
}
|
||||
|
||||
// Update updates an existing ledger in the database
|
||||
func (r *LedgerRepository) Update(userID uint, ledger *models.Ledger) error {
|
||||
// First check if the ledger exists and belongs to the user
|
||||
var existing models.Ledger
|
||||
if err := r.db.Where("id = ? AND user_id = ?", ledger.ID, userID).First(&existing).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrLedgerNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to check ledger existence: %w", err)
|
||||
}
|
||||
|
||||
// Update the ledger
|
||||
if err := r.db.Save(ledger).Error; err != nil {
|
||||
return fmt.Errorf("failed to update ledger: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete soft-deletes a ledger by its ID
|
||||
func (r *LedgerRepository) Delete(userID uint, id uint) error {
|
||||
// First check if the ledger exists and belongs to the user
|
||||
var ledger models.Ledger
|
||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).First(&ledger).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrLedgerNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to check ledger existence: %w", err)
|
||||
}
|
||||
|
||||
// Soft delete the ledger
|
||||
if err := r.db.Delete(&ledger).Error; err != nil {
|
||||
return fmt.Errorf("failed to delete ledger: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Count returns the total number of ledgers (excluding soft-deleted)
|
||||
func (r *LedgerRepository) Count(userID uint) (int64, error) {
|
||||
var count int64
|
||||
if err := r.db.Model(&models.Ledger{}).Where("user_id = ?", userID).Count(&count).Error; err != nil {
|
||||
return 0, fmt.Errorf("failed to count ledgers: %w", err)
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// GetDefault retrieves the default ledger
|
||||
func (r *LedgerRepository) GetDefault(userID uint) (*models.Ledger, error) {
|
||||
var ledger models.Ledger
|
||||
if err := r.db.Where("user_id = ? AND is_default = ?", userID, true).First(&ledger).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrLedgerNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get default ledger: %w", err)
|
||||
}
|
||||
return &ledger, nil
|
||||
}
|
||||
|
||||
// SetDefault sets a ledger as the default ledger
|
||||
func (r *LedgerRepository) SetDefault(userID uint, id uint) error {
|
||||
// Start a transaction
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
// First, unset all other default ledgers for this user
|
||||
if err := tx.Model(&models.Ledger{}).Where("user_id = ? AND is_default = ?", userID, true).Update("is_default", false).Error; err != nil {
|
||||
return fmt.Errorf("failed to unset default ledgers: %w", err)
|
||||
}
|
||||
|
||||
// Then set the specified ledger as default (must belong to the user)
|
||||
result := tx.Model(&models.Ledger{}).Where("id = ? AND user_id = ?", id, userID).Update("is_default", true)
|
||||
if result.Error != nil {
|
||||
return fmt.Errorf("failed to set default ledger: %w", result.Error)
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return ErrLedgerNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetDeleted retrieves all soft-deleted ledgers
|
||||
// Feature: accounting-feature-upgrade
|
||||
// Validates: Requirements 3.9
|
||||
// GetDeleted retrieves all soft-deleted ledgers
|
||||
func (r *LedgerRepository) GetDeleted(userID uint) ([]models.Ledger, error) {
|
||||
var ledgers []models.Ledger
|
||||
if err := r.db.Unscoped().Where("user_id = ? AND deleted_at IS NOT NULL", userID).Order("deleted_at DESC").Find(&ledgers).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get deleted ledgers: %w", err)
|
||||
}
|
||||
return ledgers, nil
|
||||
}
|
||||
|
||||
// Restore restores a soft-deleted ledger by its ID
|
||||
// Feature: accounting-feature-upgrade
|
||||
// Validates: Requirements 3.9
|
||||
// Restore restores a soft-deleted ledger by its ID
|
||||
func (r *LedgerRepository) Restore(userID uint, id uint) error {
|
||||
// First check if the ledger exists and is deleted and belongs to the user
|
||||
var ledger models.Ledger
|
||||
if err := r.db.Unscoped().Where("id = ? AND user_id = ?", id, userID).First(&ledger).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrLedgerNotFound
|
||||
}
|
||||
return fmt.Errorf("failed to check ledger existence: %w", err)
|
||||
}
|
||||
|
||||
// Check if the ledger is actually deleted
|
||||
if ledger.DeletedAt.Time.IsZero() {
|
||||
return fmt.Errorf("ledger is not deleted")
|
||||
}
|
||||
|
||||
// Restore the ledger by setting deleted_at to NULL
|
||||
if err := r.db.Unscoped().Model(&ledger).Update("deleted_at", nil).Error; err != nil {
|
||||
return fmt.Errorf("failed to restore ledger: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user