Files
financial-tracking-service/internal/service/transaction_proto.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
}