110 lines
3.6 KiB
Go
110 lines
3.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"git.kocoder.xyz/vt/financial-tracking-service/internal/config"
|
|
"git.kocoder.xyz/vt/financial-tracking-service/internal/database"
|
|
transactionv1 "git.kocoder.xyz/vt/financial-tracking-service/internal/proto/transaction/v1"
|
|
"git.kocoder.xyz/vt/financial-tracking-service/internal/proto/transaction/v1/transactionv1connect"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
type TransactionService struct {
|
|
conf *config.Config
|
|
db *database.Queries
|
|
}
|
|
|
|
func NewTransactionService(conf *config.Config, db *database.Queries) transactionv1connect.TransactionServiceHandler {
|
|
return &TransactionService{
|
|
conf: conf,
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func (s *TransactionService) CreateTransaction(ctx context.Context, req *transactionv1.CreateTransactionRequest) (*transactionv1.CreateTransactionResponse, error) {
|
|
txDate := time.Now()
|
|
if req.TransactionDate != nil {
|
|
txDate = req.TransactionDate.AsTime()
|
|
}
|
|
|
|
tx, err := s.db.CreateTransaction(ctx, database.CreateTransactionParams{
|
|
Description: req.Description,
|
|
Amount: req.Amount,
|
|
Category: req.Category,
|
|
TransactionDate: txDate,
|
|
})
|
|
if err != nil {
|
|
slog.ErrorContext(ctx, "failed to create transaction", slog.String("err", err.Error()))
|
|
return nil, err
|
|
}
|
|
|
|
return &transactionv1.CreateTransactionResponse{
|
|
Transaction: &transactionv1.Transaction{
|
|
TransactionId: tx.TransactionID,
|
|
Description: tx.Description,
|
|
Amount: tx.Amount,
|
|
Category: tx.Category,
|
|
TransactionDate: timestamppb.New(tx.TransactionDate),
|
|
CreatedAt: timestamppb.New(tx.CreatedAt),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (s *TransactionService) ListTransactions(ctx context.Context, req *transactionv1.ListTransactionsRequest) (*transactionv1.ListTransactionsResponse, error) {
|
|
txs, err := s.db.ListTransactions(ctx)
|
|
if err != nil {
|
|
slog.ErrorContext(ctx, "failed to list transactions", slog.String("err", err.Error()))
|
|
return nil, err
|
|
}
|
|
|
|
var protoTxs []*transactionv1.Transaction
|
|
for _, tx := range txs {
|
|
protoTxs = append(protoTxs, &transactionv1.Transaction{
|
|
TransactionId: tx.TransactionID,
|
|
Description: tx.Description,
|
|
Amount: tx.Amount,
|
|
Category: tx.Category,
|
|
TransactionDate: timestamppb.New(tx.TransactionDate),
|
|
CreatedAt: timestamppb.New(tx.CreatedAt),
|
|
})
|
|
}
|
|
|
|
return &transactionv1.ListTransactionsResponse{
|
|
Transactions: protoTxs,
|
|
}, nil
|
|
}
|
|
|
|
func (s *TransactionService) GetTransaction(ctx context.Context, req *transactionv1.GetTransactionRequest) (*transactionv1.GetTransactionResponse, error) {
|
|
tx, err := s.db.GetTransaction(ctx, req.TransactionId)
|
|
if err != nil {
|
|
slog.ErrorContext(ctx, "failed to get transaction", slog.Int("id", int(req.TransactionId)), slog.String("err", err.Error()))
|
|
return nil, err
|
|
}
|
|
|
|
return &transactionv1.GetTransactionResponse{
|
|
Transaction: &transactionv1.Transaction{
|
|
TransactionId: tx.TransactionID,
|
|
Description: tx.Description,
|
|
Amount: tx.Amount,
|
|
Category: tx.Category,
|
|
TransactionDate: timestamppb.New(tx.TransactionDate),
|
|
CreatedAt: timestamppb.New(tx.CreatedAt),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (s *TransactionService) DeleteTransaction(ctx context.Context, req *transactionv1.DeleteTransactionRequest) (*transactionv1.DeleteTransactionResponse, error) {
|
|
err := s.db.DeleteTransaction(ctx, req.TransactionId)
|
|
if err != nil {
|
|
slog.ErrorContext(ctx, "failed to delete transaction", slog.Int("id", int(req.TransactionId)), slog.String("err", err.Error()))
|
|
return &transactionv1.DeleteTransactionResponse{Ok: false}, err
|
|
}
|
|
|
|
return &transactionv1.DeleteTransactionResponse{
|
|
Ok: true,
|
|
}, nil
|
|
}
|