Skip to content

Commit

Permalink
import to develop
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeMaster482 committed Dec 19, 2023
1 parent 63dd28b commit 06c98ed
Showing 1 changed file with 152 additions and 0 deletions.
152 changes: 152 additions & 0 deletions internal/microservices/transaction/delivery/http/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ import (
"net/http"
"os"
"reflect"
"strconv"
"sync"
"time"

genAccount "github.com/go-park-mail-ru/2023_2_Hamster/internal/microservices/account/delivery/grpc/generated"

commonHttp "github.com/go-park-mail-ru/2023_2_Hamster/internal/common/http"
"github.com/go-park-mail-ru/2023_2_Hamster/internal/common/logger"
"github.com/go-park-mail-ru/2023_2_Hamster/internal/microservices/transaction"
"github.com/go-park-mail-ru/2023_2_Hamster/internal/microservices/user/delivery/http/transfer_models"
"github.com/go-park-mail-ru/2023_2_Hamster/internal/models"
"github.com/google/uuid"
)

type Handler struct {
Expand Down Expand Up @@ -358,3 +364,149 @@ func (h *Handler) ExportTransactions(w http.ResponseWriter, r *http.Request) {
h.logger.Errorf("Error in csv writing")
}
}

func (h *Handler) ImportTransactions(w http.ResponseWriter, r *http.Request) {
user, err := commonHttp.GetUserFromRequest(r)
if err != nil {
commonHttp.ErrorResponse(w, http.StatusUnauthorized, err, commonHttp.ErrUnauthorized.Error(), h.logger)
return
}

// Parse the multipart form in the request
err = r.ParseMultipartForm(10 << 20) // Max memory 10MB
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, "Error parsing the request", h.logger)
return
}

// Get the file from the form
file, header, err := r.FormFile("csv")
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, "Error getting the file", h.logger)
return
}
defer file.Close()

if header.Header.Get("Content-Type") != "text/csv" {
commonHttp.ErrorResponse(w, http.StatusUnsupportedMediaType, nil, "File must be a CSV", h.logger)
return
}

const maxFileSize = 10 << 20 // 10MB
if header.Size > maxFileSize {
commonHttp.ErrorResponse(w, http.StatusRequestEntityTooLarge, nil, "File is too large", h.logger)
return
}
// Create a new CSV reader reading from the file
reader := csv.NewReader(file)

var errNoSuchAccounts *models.NoSuchAccounts
accounts, err := h.userService.GetAccounts(r.Context(), user.ID)

Check failure on line 404 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

h.userService undefined (type *Handler has no field or method userService)

Check failure on line 404 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

h.userService undefined (type *Handler has no field or method userService)
if errors.As(err, &errNoSuchAccounts) {
h.logger.Println(errNoSuchAccounts)
} else if err != nil {
commonHttp.ErrorResponse(w, http.StatusInternalServerError, err, "Error getting accounts", h.logger)
return
}

accountCache := sync.Map{}
if len(accounts) != 0 {
for _, account := range accounts {
accountCache.Store(account.MeanPayment, account.ID)
}
}

// Iterate through the records
for {
// Read each record from csv
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, "Error reading the CSV file", h.logger)
return
}

accountIncome := record[0]
accountOutcome := record[1]

income, err := strconv.ParseFloat(record[2], 64)
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, "Error converting the amount to float", h.logger)
return
}
if income == 0 {
income = 0
}

outcome, err := strconv.ParseFloat(record[3], 64)
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, "Error converting the amount to float", h.logger)
return
}
if outcome == 0 {
outcome = 0
}

date, err := time.Parse(record[4], time.RFC3339Nano)
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, "Error wrong time format", h.logger)
return
}

payer := record[5]
description := record[6]

var accountIncomeId uuid.UUID
if value, ok := accountCache.Load(accountIncome); ok {
accountIncome = value.(string)
} else {
account, err := h.client.Create(r.Context(), &genAccount.CreateRequest{

Check failure on line 465 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

account declared and not used

Check failure on line 465 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

h.client undefined (type *Handler has no field or method client)

Check failure on line 465 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

account declared and not used

Check failure on line 465 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

h.client undefined (type *Handler has no field or method client)
UserId: user.ID.String(),
Balance: float32(accountInput.Balance),

Check failure on line 467 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

undefined: accountInput

Check failure on line 467 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

undefined: accountInput
Accumulation: accountInput.Accumulation,

Check failure on line 468 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

undefined: accountInput

Check failure on line 468 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

undefined: accountInput
BalanceEnabled: accountInput.BalanceEnabled,

Check failure on line 469 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

undefined: accountInput

Check failure on line 469 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

undefined: accountInput
MeanPayment: accountInput.MeanPayment,

Check failure on line 470 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

undefined: accountInput

Check failure on line 470 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

undefined: accountInput
})
if err != nil {
commonHttp.ErrorResponse(w, http.StatusInternalServerError, err, "Import error account add failed", h.logger)
return
}
accountCache.Store(accountIncome, accountIncomeId)
}

var accountOutcomeId uuid.UUID
if value, ok := accountCache.Load(accountOutcome); ok {
accountOutcome = value.(string)
} else {
accountOutcomeId, err = h.accountService.CreateAccount(r.Context(), user.ID, &models.Accounts{

Check failure on line 483 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / linter

h.accountService undefined (type *Handler has no field or method accountService)

Check failure on line 483 in internal/microservices/transaction/delivery/http/handlers.go

View workflow job for this annotation

GitHub Actions / test

h.accountService undefined (type *Handler has no field or method accountService)
MeanPayment: accountOutcome,
Balance: 0,
})
if err != nil {
commonHttp.ErrorResponse(w, http.StatusInternalServerError, err, "Import error account add failed", h.logger)
return
}
accountCache.Store(accountOutcome, accountOutcomeId)
}

// Parse the record to a Transaction struct
transaction := models.Transaction{
AccountIncomeID: accountIncomeId,
AccountOutcomeID: accountOutcomeId,
Income: income,
Outcome: outcome,
Date: date,
Payer: payer,
Description: description,
}

// Create the transaction in the database
_, err = h.transactionService.CreateTransaction(r.Context(), &transaction)
if err != nil {
commonHttp.ErrorResponse(w, http.StatusInternalServerError, err, "Error creating the transaction", h.logger)
return
}
}
}

0 comments on commit 06c98ed

Please sign in to comment.