add post formdata for sendreport

This commit is contained in:
pasha1coil 2023-11-29 22:01:14 +03:00
parent 213e18d383
commit 9b2633b474
4 changed files with 154 additions and 46 deletions

@ -1,15 +1,15 @@
package client
import (
"bytes"
"context"
"fmt"
"encoding/json"
"go.uber.org/zap"
"log"
"net/url"
"path"
"mime/multipart"
"net/http"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
)
type TemplateClientDeps struct {
@ -38,25 +38,51 @@ func NewTemplateClient(deps TemplateClientDeps) *TemplateClient {
}
}
func (receiver *TemplateClient) SendData(ctx context.Context, data models.TemplateGenData) errors.Error {
tmplURL, err := url.Parse(receiver.urls.Templategen)
if err != nil {
return errors.New(
fmt.Errorf("failed to parse URL on <PostToTemplategen>: %w", err),
errors.ErrInternalError,
)
}
func (receiver *TemplateClient) SendData(ctx context.Context, data models.RespGeneratorService, fileContents []byte, email string) errors.Error {
tmplURL := receiver.urls.Templategen
tmplURL.Path = path.Join(tmplURL.Path)
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
_, err = client.Post[interface{}, models.FastifyError](ctx, &client.RequestSettings{
URL: tmplURL.String(),
Headers: map[string]string{"Content-Type": "multipart/form-data"},
Body: data,
})
err := writer.WriteField("email", email)
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
jsonData, err := json.Marshal(data)
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
err = writer.WriteField("data", string(jsonData))
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
fileWriter, err := writer.CreateFormFile("file", "report.docx")
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
_, err = fileWriter.Write(fileContents)
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
err = writer.Close()
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
req, err := http.NewRequestWithContext(ctx, "POST", tmplURL, body)
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := http.DefaultClient.Do(req)
if err != nil {
return errors.New(err, errors.ErrInternalError)
}
defer resp.Body.Close()
return nil
}

@ -183,3 +183,58 @@ func (receiver *HistoryRepository) GetHistoryById(ctx context.Context, historyID
return history, nil
}
// TODO:tests
func (receiver *HistoryRepository) GetDocNumber(ctx context.Context, userID string) (map[string]int, errors.Error) {
findOptions := options.Find()
findOptions.SetSort(bson.D{{Key: "createdAt", Value: 1}})
filter := bson.M{
fields.History.UserID: userID,
}
cursor, err := receiver.mongoDB.Find(ctx, filter, findOptions)
if err != nil {
receiver.logger.Error("failed to get DocNumber list on <GetDocNumber> of <HistoryRepository>",
zap.String("userId", userID),
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("failed to get DocNumber list on <GetDocNumber> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
defer cursor.Close(ctx)
result := make(map[string]int)
var count int
for cursor.Next(ctx) {
var history models.History
if err := cursor.Decode(&history); err != nil {
receiver.logger.Error("failed to decode history on <GetDocNumber> of <HistoryRepository>",
zap.String("userId", userID),
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("failed to decode history on <GetDocNumber> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
result[history.ID] = count
count++
}
if err := cursor.Err(); err != nil {
receiver.logger.Error("cursor error on <GetDocNumber> of <HistoryRepository>",
zap.String("userId", userID),
zap.Error(err),
)
return nil, errors.New(
fmt.Errorf("cursor error on <GetDocNumber> of <HistoryRepository>: %w", err),
errors.ErrInternalError,
)
}
return result, nil
}

@ -1,14 +1,12 @@
package models
import "io"
type TemplateGenData struct {
Email string `json:"email"`
Data Data `json:"data"`
File io.Reader `json:"file"`
}
type Data struct {
TaxNumber string `json:"taxnumber"`
History *ReportHistory `json:"history"`
type RespGeneratorService struct {
DocNumber int `json:"docnumber"`
Date string `json:"date"`
OrgTaxNum string `json:"orgtaxnum"`
OrgName Name `json:"orgname"`
Name string `json:"name"`
Amount uint64 `json:"amount"`
Price int64 `json:"price"`
Sum int64 `json:"sum"`
}

@ -1,11 +1,12 @@
package history
import (
"bytes"
"context"
"fmt"
"log"
"math"
"os"
"time"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/dto"
@ -19,6 +20,7 @@ type historyRepository interface {
Insert(context.Context, *models.History) (*models.History, errors.Error)
GetRecentTariffs(context.Context, string) ([]models.TariffID, errors.Error) // new
GetHistoryById(context.Context, string) (*models.ReportHistory, errors.Error)
GetDocNumber(context.Context, string) (map[string]int, errors.Error)
}
type authClient interface {
@ -30,7 +32,7 @@ type verificationClient interface {
}
type temlategenClient interface {
SendData(ctx context.Context, data models.TemplateGenData) errors.Error
SendData(ctx context.Context, data models.RespGeneratorService, fileContents []byte, email string) errors.Error
}
type Deps struct {
@ -168,6 +170,16 @@ func (receiver *Service) GetHistoryById(ctx context.Context, historyID string) e
return err
}
HistoryMap, err := receiver.repository.GetDocNumber(ctx, tariffs.UserID)
if err != nil {
receiver.logger.Error(
"failed to get history of sorting by date created in <GetDocNumber> of <HistoryService>",
zap.String("historyID", historyID),
zap.Error(err),
)
return err
}
verifuser, err := receiver.VerificationClient.GetUser(ctx, tariffs.UserID)
if err != nil {
receiver.logger.Error("failed to get user verification on <GetHistoryById> of <HistoryService>",
@ -195,22 +207,39 @@ func (receiver *Service) GetHistoryById(ctx context.Context, historyID string) e
return err
}
data := models.TemplateGenData{
Email: authuser.Email,
Data: models.Data{
TaxNumber: verifuser.TaxNumber,
History: tariffs,
},
File: bytes.NewReader([]byte("./report.docx")),
}
err = receiver.TemlategenClient.SendData(ctx, data)
if err != nil {
receiver.logger.Error("failed to send report to user on <GetHistoryById> of <HistoryService>",
zap.Error(err),
zap.String("userID", tariffs.UserID),
)
return err
fileContents, readerr := os.ReadFile("./report.docx")
if readerr != nil {
return errors.New(
fmt.Errorf("failed to read file: %w", errors.ErrInternalError),
errors.ErrInternalError,
)
}
for _, tariff := range tariffs.RawDetails.Tariffs {
totalAmount := uint64(0)
for _, privilege := range tariff.Privileges {
totalAmount += privilege.Amount
}
data := models.RespGeneratorService{
DocNumber: HistoryMap[historyID] + 1,
Date: time.Now().Format("2006-01-02"),
OrgTaxNum: verifuser.TaxNumber,
OrgName: models.Name{Orgname: "Orgname"},
Name: tariff.Name,
Amount: totalAmount,
Price: tariffs.RawDetails.Price,
Sum: tariffs.RawDetails.Price,
}
err = receiver.TemlategenClient.SendData(ctx, data, fileContents, authuser.Email)
if err != nil {
receiver.logger.Error("failed to send report to user on <GetHistoryById> of <HistoryService>",
zap.Error(err),
zap.String("userID", tariffs.UserID),
)
return err
}
}
return nil
}