97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
package server
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.javil.eu/jacob1123/budgeteer/postgres"
|
|
"git.javil.eu/jacob1123/budgeteer/postgres/numeric"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type ReconcileTransactionsRequest struct {
|
|
TransactionIDs []uuid.UUID `json:"transactionIds"`
|
|
ReconcilationTransactionAmount numeric.Numeric `json:"reconciliationTransactionAmount"`
|
|
}
|
|
|
|
type ReconcileTransactionsResponse struct {
|
|
Message string
|
|
ReconciliationTransaction *postgres.DisplayTransaction
|
|
}
|
|
|
|
func (h *Handler) reconcileTransactions(c *gin.Context) {
|
|
accountID := c.Param("accountid")
|
|
accountUUID, err := uuid.Parse(accountID)
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
var request ReconcileTransactionsRequest
|
|
err = c.BindJSON(&request)
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusBadRequest, fmt.Errorf("parse request: %w", err))
|
|
return
|
|
}
|
|
|
|
tx, err := h.Service.BeginTx(c.Request.Context(), &sql.TxOptions{})
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("begin tx: %w", err))
|
|
return
|
|
}
|
|
|
|
db := h.Service.WithTx(tx)
|
|
for _, transactionID := range request.TransactionIDs {
|
|
err := db.SetTransactionReconciled(c.Request.Context(), transactionID)
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("update transaction: %w", err))
|
|
return
|
|
}
|
|
}
|
|
|
|
reconciliationTransaction, err := h.CreateReconcilationTransaction(request, accountUUID, db, c)
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("insert new transaction: %w", err))
|
|
return
|
|
}
|
|
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("commit: %w", err))
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, ReconcileTransactionsResponse{
|
|
Message: fmt.Sprintf("Set status for %d transactions", len(request.TransactionIDs)),
|
|
ReconciliationTransaction: reconciliationTransaction,
|
|
})
|
|
}
|
|
|
|
func (*Handler) CreateReconcilationTransaction(request ReconcileTransactionsRequest, accountUUID uuid.UUID, db *postgres.Queries, c *gin.Context) (*postgres.DisplayTransaction, error) {
|
|
if request.ReconcilationTransactionAmount.IsZero() {
|
|
return nil, nil //nolint: nilnil
|
|
}
|
|
|
|
createTransaction := postgres.CreateTransactionParams{
|
|
Date: time.Now(),
|
|
Memo: "Reconciliation Transaction",
|
|
Amount: request.ReconcilationTransactionAmount,
|
|
AccountID: accountUUID,
|
|
Status: "Reconciled",
|
|
}
|
|
newTransaction, err := db.CreateTransaction(c.Request.Context(), createTransaction)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("insert new transaction: %w", err)
|
|
}
|
|
|
|
transaction, err := db.GetTransaction(c.Request.Context(), newTransaction.ID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get created transaction: %w", err)
|
|
}
|
|
|
|
return &transaction, nil
|
|
}
|