Skip to content

Commit

Permalink
Merge branch 'deploy' of github.com:go-park-mail-ru/2023_2_Hamster in…
Browse files Browse the repository at this point in the history
…to deploy
  • Loading branch information
DmitriyKomarovCoder committed Dec 19, 2023
2 parents d2b2c26 + ae86702 commit 63dd28b
Show file tree
Hide file tree
Showing 10 changed files with 541 additions and 2 deletions.
1 change: 1 addition & 0 deletions cmd/api/init/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func InitRouter(auth *auth.Handler,
transactionRouter.Use(authMid.Authentication)
//transactionRouter.Use(csrfMid.CheckCSRF)
{
transactionRouter.Methods("GET").Path("/export").HandlerFunc(transaction.ExportTransactions)
transactionRouter.Methods("GET").Path("/feed").HandlerFunc(transaction.GetFeed)
transactionRouter.Methods("GET").Path("/count").HandlerFunc(transaction.GetCount)
// transactionRouter.Methods("GET").Path("/{transaction_id}/").HandlerFunc(transaction.Get)
Expand Down
73 changes: 73 additions & 0 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,79 @@ const docTemplate = `{
}
}
},
"/api/transaction/export": {
"get": {
"description": "Sends a .csv file with transactions based on the specified criteria.",
"produces": [
"text/plain"
],
"tags": [
"Transaction"
],
"summary": "Export .csv Transactions",
"parameters": [
{
"type": "string",
"description": "Start date (format: 'YYYY-MM-DD')",
"name": "startDate",
"in": "query",
"required": true
},
{
"type": "string",
"description": "End date (format: 'YYYY-MM-DD')",
"name": "endDate",
"in": "query",
"required": true
},
{
"type": "string",
"description": "session_id",
"name": "authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "Successfully exported transactions\" {example: \"TransactionID,Amount,Date\\n1,100,2023-01-01\\n2,150,2023-01-02\\n\"}",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad request - Transaction error",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"401": {
"description": "Unauthorized - User unauthorized",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"403": {
"description": "Forbidden - User doesn't have rights",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"404": {
"description": "Not Found - No transactions found for the specified criteria",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"500": {
"description": "Internal Server Error - Server error",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
}
}
}
},
"/api/transaction/feed": {
"get": {
"description": "Get User all transaction",
Expand Down
73 changes: 73 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,79 @@
}
}
},
"/api/transaction/export": {
"get": {
"description": "Sends a .csv file with transactions based on the specified criteria.",
"produces": [
"text/plain"
],
"tags": [
"Transaction"
],
"summary": "Export .csv Transactions",
"parameters": [
{
"type": "string",
"description": "Start date (format: 'YYYY-MM-DD')",
"name": "startDate",
"in": "query",
"required": true
},
{
"type": "string",
"description": "End date (format: 'YYYY-MM-DD')",
"name": "endDate",
"in": "query",
"required": true
},
{
"type": "string",
"description": "session_id",
"name": "authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "Successfully exported transactions\" {example: \"TransactionID,Amount,Date\\n1,100,2023-01-01\\n2,150,2023-01-02\\n\"}",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad request - Transaction error",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"401": {
"description": "Unauthorized - User unauthorized",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"403": {
"description": "Forbidden - User doesn't have rights",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"404": {
"description": "Not Found - No transactions found for the specified criteria",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
},
"500": {
"description": "Internal Server Error - Server error",
"schema": {
"$ref": "#/definitions/http.ResponseError"
}
}
}
}
},
"/api/transaction/feed": {
"get": {
"description": "Get User all transaction",
Expand Down
49 changes: 49 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,55 @@ paths:
summary: Create transaction
tags:
- Transaction
/api/transaction/export:
get:
description: Sends a .csv file with transactions based on the specified criteria.
parameters:
- description: 'Start date (format: ''YYYY-MM-DD'')'
in: query
name: startDate
required: true
type: string
- description: 'End date (format: ''YYYY-MM-DD'')'
in: query
name: endDate
required: true
type: string
- description: session_id
in: header
name: authorization
required: true
type: string
produces:
- text/plain
responses:
"200":
description: 'Successfully exported transactions" {example: "TransactionID,Amount,Date\n1,100,2023-01-01\n2,150,2023-01-02\n"}'
schema:
type: string
"400":
description: Bad request - Transaction error
schema:
$ref: '#/definitions/http.ResponseError'
"401":
description: Unauthorized - User unauthorized
schema:
$ref: '#/definitions/http.ResponseError'
"403":
description: Forbidden - User doesn't have rights
schema:
$ref: '#/definitions/http.ResponseError'
"404":
description: Not Found - No transactions found for the specified criteria
schema:
$ref: '#/definitions/http.ResponseError'
"500":
description: Internal Server Error - Server error
schema:
$ref: '#/definitions/http.ResponseError'
summary: Export .csv Transactions
tags:
- Transaction
/api/transaction/feed:
get:
description: Get User all transaction
Expand Down
111 changes: 111 additions & 0 deletions internal/microservices/transaction/delivery/http/handlers.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package http

import (
"bytes"
"encoding/csv"
"encoding/json"
"errors"
"io"
"log"
"mime/multipart"
"net/http"
"os"
"reflect"

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"
Expand Down Expand Up @@ -245,5 +252,109 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
}
}
commonHttp.SuccessResponse(w, http.StatusOK, commonHttp.NilBody{})
}

// @Summary Export .csv Transactions
// @Tags Transaction
// @Description Sends a .csv file with transactions based on the specified criteria.
// @Produce plain
// @Failure 400 {object} ResponseError "Bad request - Transaction error"
// @Failure 401 {object} ResponseError "Unauthorized - User unauthorized"
// @Failure 403 {object} ResponseError "Forbidden - User doesn't have rights"
// @Failure 404 {object} ResponseError "Not Found - No transactions found for the specified criteria"
// @Failure 500 {object} ResponseError "Internal Server Error - Server error"
// @Router /api/transaction/export [get]
// @Param startDate query string true "Start date (format: 'YYYY-MM-DD')"
// @Param endDate query string true "End date (format: 'YYYY-MM-DD')"
// @Param authorization header string true "session_id"
// @Success 200 {string} "Successfully exported transactions" {example: "TransactionID,Amount,Date\n1,100,2023-01-01\n2,150,2023-01-02\n"}
func (h *Handler) ExportTransactions(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
}

query, err := commonHttp.GetQueryParam(r)
if err != nil {
commonHttp.ErrorResponse(w, http.StatusBadRequest, err, commonHttp.InvalidURLParameter, h.logger)
return
}

var errNoSuchTransaction *models.NoSuchTransactionError
dataFeed, err := h.transactionService.GetTransactionForExport(r.Context(), user.ID, query)
if errors.As(err, &errNoSuchTransaction) {
commonHttp.ErrorResponse(w, http.StatusNotFound, err, "no transactions found", h.logger)
return
} else if err != nil {
commonHttp.ErrorResponse(w, http.StatusInternalServerError, err, transfer_models.UserFeedServerError, h.logger)
return
}

fileName := "Transactions_" + user.Login + query.StartDate.String() + "-" + query.EndDate.String() + ".csv"

// 1. Create a CSV file and write the `dataFeed` into it.
csvFile, err := os.Create(fileName)
if err != nil {
h.logger.Error("can't crete datafile")
commonHttp.ErrorResponse(w, http.StatusInternalServerError, err, "can't create .csv file", h.logger)
return
}
defer csvFile.Close()

var csvHeader []string

t := reflect.TypeOf(dataFeed[0])
for i := 1; i < t.NumField(); i++ {
field := t.Field(i)
csvHeader = append(csvHeader, field.Name)
}

csvWriter := csv.NewWriter(csvFile)
if err = csvWriter.Write(csvHeader); err != nil {
h.logger.Errorf("Error in csv writing")
}

for _, row := range dataFeed {
record := row.String()
if err := csvWriter.Write(record); err != nil {
log.Fatalln("error writing record to csv:", err)
}
}

csvWriter.Flush()
if err := csvWriter.Error(); err != nil {
log.Fatal(err)
}

// 2. Create a new multipart form writer.
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

// 3. Create a new form file where the CSV file will be written.
part, err := writer.CreateFormFile("file", "dataFeed.csv")
if err != nil {
log.Fatal(err)
}

// 4. Write the CSV file into the form file.
_, err = csvFile.Seek(0, 0)
if err != nil {
h.logger.Errorf("Error in csv set start")
}

_, err = io.Copy(part, csvFile)
if err != nil {
h.logger.Errorf("Error in csv writing")
}

// 5. Write the multipart form's boundary to the response header.
w.Header().Set("Content-Type", writer.FormDataContentType())

// 6. Write the multipart form to the response.
writer.Close()
_, err = io.Copy(w, body)
if err != nil {
h.logger.Errorf("Error in csv writing")
}
}
30 changes: 30 additions & 0 deletions internal/microservices/transaction/mocks/transaction_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 63dd28b

Please sign in to comment.