budgeteer/server/reconcile.go

88 lines
2.6 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
}
}
err = tx.Commit()
if err != nil {
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("commit: %w", err))
return
}
var reconciliationTransaction *postgres.DisplayTransaction
if !request.ReconcilationTransactionAmount.IsZero() {
createTransaction := postgres.CreateTransactionParams{
Date: time.Now(),
Memo: "Reconciliation Transaction",
Amount: request.ReconcilationTransactionAmount,
AccountID: accountUUID,
Status: "Reconciled",
}
newTransaction, err := h.Service.CreateTransaction(c.Request.Context(), createTransaction)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("insert new transaction: %w", err))
return
}
transaction, err := h.Service.GetTransaction(c.Request.Context(), newTransaction.ID)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("get created transaction: %w", err))
return
}
reconciliationTransaction = &transaction
}
c.JSON(http.StatusOK, ReconcileTransactionsResponse{
Message: fmt.Sprintf("Set status for %d transactions", len(request.TransactionIDs)),
ReconciliationTransaction: reconciliationTransaction,
})
}