This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/context_utils"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
@@ -14,17 +15,21 @@ type BudgetEntity struct {
|
||||
Name string
|
||||
StartDay int
|
||||
MonthlyLimit int
|
||||
Categories []*category.CategoryEntity
|
||||
}
|
||||
|
||||
type BudgetService struct {
|
||||
db *pgxpool.Pool
|
||||
db *pgxpool.Pool
|
||||
categoryService *category.CategoryService
|
||||
}
|
||||
|
||||
func NewBudgetService(
|
||||
db *pgxpool.Pool,
|
||||
categoryService *category.CategoryService,
|
||||
) *BudgetService {
|
||||
return &BudgetService{
|
||||
db: db,
|
||||
db: db,
|
||||
categoryService: categoryService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +60,23 @@ func (s *BudgetService) AddBudget(ctx context.Context, budget *BudgetEntity) (*B
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defaultCategories := []*category.CategoryEntity{
|
||||
{
|
||||
Name: "Транспорт",
|
||||
BudgetId: budget.Id,
|
||||
},
|
||||
{
|
||||
Name: "Продукты",
|
||||
BudgetId: budget.Id,
|
||||
},
|
||||
}
|
||||
for _, category := range defaultCategories {
|
||||
_, err = s.categoryService.AddCategory(ctx, category)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -83,6 +105,7 @@ func (s *BudgetService) GetBudgets(ctx context.Context) ([]*BudgetEntity, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
budget.Categories, err = s.GetBudgetCategories(ctx, budget.Id)
|
||||
budgets = append(budgets, budget)
|
||||
}
|
||||
|
||||
@@ -105,3 +128,29 @@ func (s *BudgetService) AddUserToBudget(
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (s *BudgetService) GetBudgetCategories(
|
||||
ctx context.Context,
|
||||
budgetId int,
|
||||
) ([]*category.CategoryEntity, error) {
|
||||
query := `SELECT id, name, favorite, monthly_limit FROM categories WHERE budget_id = @budget_id`
|
||||
args := pgx.NamedArgs{
|
||||
"budget_id": budgetId,
|
||||
}
|
||||
rows, err := s.db.Query(ctx, query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
categories := []*category.CategoryEntity{}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
category := &category.CategoryEntity{}
|
||||
err = rows.Scan(&category.Id, &category.Name, &category.Favorite, &category.MonthlyLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
categories = append(categories, category)
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
|
||||
@@ -2,29 +2,20 @@ package category
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/context_utils"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type CategoryEntity struct {
|
||||
Id int
|
||||
Name string
|
||||
UserId int
|
||||
BudgetId int
|
||||
Favorite bool
|
||||
MonthlyLimit int
|
||||
}
|
||||
|
||||
type CategoryAlreadyExistsErr struct{}
|
||||
|
||||
func (e *CategoryAlreadyExistsErr) Error() string {
|
||||
return "category already exists error"
|
||||
}
|
||||
|
||||
type CategoryService struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
@@ -38,24 +29,14 @@ func NewCategoryService(
|
||||
}
|
||||
|
||||
func (s *CategoryService) AddCategory(ctx context.Context, category *CategoryEntity) (*CategoryEntity, error) {
|
||||
userId, err := context_utils.GetUserId(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := `INSERT INTO categories (name, user_id, favorite, monthly_limit) VALUES (@name, @user_id, @favorite, @monthly_limit) RETURNING id`
|
||||
query := `INSERT INTO categories (name, budget_id, favorite, monthly_limit) VALUES (@name, @budget_id, @favorite, @monthly_limit) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"name": category.Name,
|
||||
"user_id": userId,
|
||||
"budget_id": category.BudgetId,
|
||||
"favorite": category.Favorite,
|
||||
"monthly_limit": category.MonthlyLimit,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&category.Id); err != nil {
|
||||
var pgErr *pgconn.PgError
|
||||
if errors.As(err, &pgErr) {
|
||||
if pgErr.Code == "23505" && pgErr.ConstraintName == "categories_user_id_name_key" { // unique_violation
|
||||
return nil, &CategoryAlreadyExistsErr{}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
return category, nil
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user