Implement transfer creation
This commit is contained in:
		@@ -130,7 +130,7 @@ func (q *Queries) GetAccountsWithBalance(ctx context.Context, budgetID uuid.UUID
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const searchAccounts = `-- name: SearchAccounts :many
 | 
					const searchAccounts = `-- name: SearchAccounts :many
 | 
				
			||||||
SELECT accounts.id, accounts.budget_id, accounts.name FROM accounts
 | 
					SELECT accounts.id, accounts.budget_id, accounts.name, true as is_account FROM accounts
 | 
				
			||||||
WHERE accounts.budget_id = $1
 | 
					WHERE accounts.budget_id = $1
 | 
				
			||||||
AND accounts.name LIKE $2
 | 
					AND accounts.name LIKE $2
 | 
				
			||||||
ORDER BY accounts.name
 | 
					ORDER BY accounts.name
 | 
				
			||||||
@@ -142,9 +142,10 @@ type SearchAccountsParams struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SearchAccountsRow struct {
 | 
					type SearchAccountsRow struct {
 | 
				
			||||||
	ID       uuid.UUID
 | 
						ID        uuid.UUID
 | 
				
			||||||
	BudgetID uuid.UUID
 | 
						BudgetID  uuid.UUID
 | 
				
			||||||
	Name     string
 | 
						Name      string
 | 
				
			||||||
 | 
						IsAccount bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *Queries) SearchAccounts(ctx context.Context, arg SearchAccountsParams) ([]SearchAccountsRow, error) {
 | 
					func (q *Queries) SearchAccounts(ctx context.Context, arg SearchAccountsParams) ([]SearchAccountsRow, error) {
 | 
				
			||||||
@@ -156,7 +157,12 @@ func (q *Queries) SearchAccounts(ctx context.Context, arg SearchAccountsParams)
 | 
				
			|||||||
	var items []SearchAccountsRow
 | 
						var items []SearchAccountsRow
 | 
				
			||||||
	for rows.Next() {
 | 
						for rows.Next() {
 | 
				
			||||||
		var i SearchAccountsRow
 | 
							var i SearchAccountsRow
 | 
				
			||||||
		if err := rows.Scan(&i.ID, &i.BudgetID, &i.Name); err != nil {
 | 
							if err := rows.Scan(
 | 
				
			||||||
 | 
								&i.ID,
 | 
				
			||||||
 | 
								&i.BudgetID,
 | 
				
			||||||
 | 
								&i.Name,
 | 
				
			||||||
 | 
								&i.IsAccount,
 | 
				
			||||||
 | 
							); err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		items = append(items, i)
 | 
							items = append(items, i)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,6 +83,10 @@ func (n Numeric) Sub(other Numeric) Numeric {
 | 
				
			|||||||
	panic("Cannot subtract with different exponents")
 | 
						panic("Cannot subtract with different exponents")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n Numeric) Neg() Numeric {
 | 
				
			||||||
 | 
						return Numeric{pgtype.Numeric{Exp: n.Exp, Int: big.NewInt(-1 * n.Int.Int64()), Status: n.Status}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n Numeric) Add(other Numeric) Numeric {
 | 
					func (n Numeric) Add(other Numeric) Numeric {
 | 
				
			||||||
	left := n
 | 
						left := n
 | 
				
			||||||
	right := other
 | 
						right := other
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ GROUP BY accounts.id, accounts.name
 | 
				
			|||||||
ORDER BY accounts.name;
 | 
					ORDER BY accounts.name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- name: SearchAccounts :many
 | 
					-- name: SearchAccounts :many
 | 
				
			||||||
SELECT accounts.id, accounts.budget_id, accounts.name FROM accounts
 | 
					SELECT accounts.id, accounts.budget_id, accounts.name, true as is_account FROM accounts
 | 
				
			||||||
WHERE accounts.budget_id = @budget_id
 | 
					WHERE accounts.budget_id = @budget_id
 | 
				
			||||||
AND accounts.name LIKE @search
 | 
					AND accounts.name LIKE @search
 | 
				
			||||||
ORDER BY accounts.name;
 | 
					ORDER BY accounts.name;
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package server
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -14,8 +15,9 @@ import (
 | 
				
			|||||||
type NewTransactionPayload struct {
 | 
					type NewTransactionPayload struct {
 | 
				
			||||||
	Date  JSONDate `json:"date"`
 | 
						Date  JSONDate `json:"date"`
 | 
				
			||||||
	Payee struct {
 | 
						Payee struct {
 | 
				
			||||||
		ID   uuid.NullUUID
 | 
							ID        uuid.NullUUID
 | 
				
			||||||
		Name string
 | 
							Name      string
 | 
				
			||||||
 | 
							IsAccount bool
 | 
				
			||||||
	} `json:"payee"`
 | 
						} `json:"payee"`
 | 
				
			||||||
	Category struct {
 | 
						Category struct {
 | 
				
			||||||
		ID   uuid.NullUUID
 | 
							ID   uuid.NullUUID
 | 
				
			||||||
@@ -36,39 +38,40 @@ func (h *Handler) newTransaction(c *gin.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amount := numeric.Numeric{}
 | 
						amount, err := numeric.Parse(payload.Amount)
 | 
				
			||||||
	err = amount.Set(payload.Amount)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.AbortWithError(http.StatusBadRequest, fmt.Errorf("amount: %w", err))
 | 
							c.AbortWithError(http.StatusBadRequest, fmt.Errorf("amount: %w", err))
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	payeeID := payload.Payee.ID
 | 
						newTransaction := postgres.CreateTransactionParams{
 | 
				
			||||||
	if !payeeID.Valid && payload.Payee.Name != "" {
 | 
							Memo:   payload.Memo,
 | 
				
			||||||
		newPayee := postgres.CreatePayeeParams{
 | 
							Date:   time.Time(payload.Date),
 | 
				
			||||||
			Name:     payload.Payee.Name,
 | 
							Amount: amount,
 | 
				
			||||||
			BudgetID: payload.BudgetID,
 | 
							Status: postgres.TransactionStatus(payload.State),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if payload.Payee.IsAccount {
 | 
				
			||||||
 | 
							newTransaction.GroupID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
 | 
				
			||||||
 | 
							newTransaction.Amount = amount.Neg()
 | 
				
			||||||
 | 
							newTransaction.AccountID = payload.Payee.ID.UUID
 | 
				
			||||||
 | 
							newTransaction.CategoryID = uuid.NullUUID{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_, err = h.Service.CreateTransaction(c.Request.Context(), newTransaction)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create transfer transaction: %w", err))
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		payee, err := h.Service.CreatePayee(c.Request.Context(), newPayee)
 | 
						} else {
 | 
				
			||||||
 | 
							payeeID, err := GetPayeeID(c.Request.Context(), payload, h)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create payee: %w", err))
 | 
								c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create payee: %w", err))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							newTransaction.PayeeID = payeeID
 | 
				
			||||||
		payeeID = uuid.NullUUID{
 | 
					 | 
				
			||||||
			UUID:  payee.ID,
 | 
					 | 
				
			||||||
			Valid: true,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newTransaction := postgres.CreateTransactionParams{
 | 
						newTransaction.CategoryID = payload.Category.ID
 | 
				
			||||||
		Memo:       payload.Memo,
 | 
						newTransaction.AccountID = payload.AccountID
 | 
				
			||||||
		Date:       time.Time(payload.Date),
 | 
					 | 
				
			||||||
		Amount:     amount,
 | 
					 | 
				
			||||||
		AccountID:  payload.AccountID,
 | 
					 | 
				
			||||||
		PayeeID:    payeeID,
 | 
					 | 
				
			||||||
		CategoryID: payload.Category.ID,
 | 
					 | 
				
			||||||
		Status:     postgres.TransactionStatus(payload.State),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	transaction, err := h.Service.CreateTransaction(c.Request.Context(), newTransaction)
 | 
						transaction, err := h.Service.CreateTransaction(c.Request.Context(), newTransaction)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err))
 | 
							c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err))
 | 
				
			||||||
@@ -77,3 +80,25 @@ func (h *Handler) newTransaction(c *gin.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	c.JSON(http.StatusOK, transaction)
 | 
						c.JSON(http.StatusOK, transaction)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetPayeeID(context context.Context, payload NewTransactionPayload, h *Handler) (uuid.NullUUID, error) {
 | 
				
			||||||
 | 
						payeeID := payload.Payee.ID
 | 
				
			||||||
 | 
						if payeeID.Valid {
 | 
				
			||||||
 | 
							return payeeID, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if payload.Payee.Name == "" {
 | 
				
			||||||
 | 
							return uuid.NullUUID{}, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						newPayee := postgres.CreatePayeeParams{
 | 
				
			||||||
 | 
							Name:     payload.Payee.Name,
 | 
				
			||||||
 | 
							BudgetID: payload.BudgetID,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						payee, err := h.Service.CreatePayee(context, newPayee)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return uuid.NullUUID{}, fmt.Errorf("create payee: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return uuid.NullUUID{UUID: payee.ID, Valid: true}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user