Skip to content

Commit

Permalink
PFS-195 Fix cypress tests, generate CSV the slow way
Browse files Browse the repository at this point in the history
  • Loading branch information
josephsmith0705 committed Nov 20, 2024
1 parent baff20d commit 2d301e0
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 142 deletions.
6 changes: 2 additions & 4 deletions db/queries/aged_debt.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
SELECT
'test' AS "Customer Name",
'test' AS "Customer Number"

FROM supervision_finance.finance_client
'Joseph Smith' AS "Customer Name",
'12345678' AS "Customer Number"
141 changes: 21 additions & 120 deletions finance-admin-api/api/download.go
Original file line number Diff line number Diff line change
@@ -1,142 +1,43 @@
package api

import (
"bytes"
"context"
"encoding/csv"
"encoding/json"
"errors"
"fmt"
"github.com/aws/smithy-go"
"github.com/opg-sirius-finance-admin/apierror"
"github.com/opg-sirius-finance-admin/shared"
"io"
"net/http"
"os"
)

func (s *Server) download(w http.ResponseWriter, r *http.Request) error {
ctx := context.Background()
ctx := r.Context()
uid := r.URL.Query().Get("uid")

var download shared.Download
defer r.Body.Close()

if err := json.NewDecoder(r.Body).Decode(&download); err != nil {
return err
}

c, err := os.ReadFile("/app/db/queries/aged_debt.sql")
if err != nil {
return err
}
sql := string(c)

rows, err := s.conn.Query(ctx, sql)

if err != nil {
return err
}

defer rows.Close()
var items [][]string
for rows.Next() {
var i []string
var stringValue string

values, err := rows.Values()
if err != nil {
return err
}
for _, value := range values {
stringValue, _ = value.(string)
i = append(i, stringValue)
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return err
}

f, err := os.Create("test.csv")
var downloadRequest shared.DownloadRequest
err := downloadRequest.Decode(uid)
if err != nil {
return err
}
writer := csv.NewWriter(f)

agedDebtHeaders := []string{
"Customer Name",
"Customer number",
"SOP number",
"Deputy type",
"Active case?",
"Entity",
"Receivable cost centre",
"Receivable cost centre description",
"Receivable account code",
"Revenue cost centre",
"Revenue cost centre description",
"Revenue account code",
"Revenue account code description",
"Invoice type",
"Trx number",
"Transaction Description",
"Invoice date",
"Due date",
"Financial year",
"Payment terms",
"Original amount",
"Outstanding amount",
"Current",
"0-1 years",
"1-2 years",
"2-3 years",
"3-5 years",
"5+ years",
"Debt impairment years",
}

err = writer.Write(agedDebtHeaders)
result, err := s.filestorage.GetFile(ctx, os.Getenv("REPORTS_S3_BUCKET"), downloadRequest.Key, downloadRequest.VersionId)
if err != nil {
return err
}

for _, item := range items {
err = writer.Write(item)
if err != nil {
return err
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
if apiErr.ErrorCode() == "NoSuchKey" {
return apierror.NotFoundError(err)
}
}
return fmt.Errorf("failed to get object from S3: %w", err)
}
defer result.Body.Close()

writer.Flush()
if writer.Error() != nil {
return writer.Error()
}

c, err = os.ReadFile("test.csv")
if err != nil {
return err
}

err = s.filestorage.PutFile(
ctx,
os.Getenv("ASYNC_S3_BUCKET"),
fmt.Sprintf("%s/%s", s3Directory, "test.csv"),
bytes.NewReader(c))

if err != nil {
return err
}

payload := NotifyPayload{
EmailAddress: "[email protected]",
TemplateId: "8c85cf6c-695f-493a-a25f-77b4fb5f6a8e",
Personalisation: struct {
Filename string `json:"upload_type"`
}{
"test",
},
}
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", downloadRequest.Key))
w.Header().Set("Content-Type", *result.ContentType)

err = s.SendEmailToNotify(ctx, payload)
if err != nil {
return err
}
// Stream the S3 object to the response writer using io.Copy
_, err = io.Copy(w, result.Body)

return nil
return err
}
154 changes: 154 additions & 0 deletions finance-admin-api/api/request_report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package api

import (
"context"
"encoding/csv"
"encoding/json"
"fmt"
"github.com/opg-sirius-finance-admin/shared"
"net/http"
"os"
)

func (s *Server) requestReport(w http.ResponseWriter, r *http.Request) error {
ctx := context.Background()

var download shared.Download
defer r.Body.Close()

if err := json.NewDecoder(r.Body).Decode(&download); err != nil {
return err
}

c, err := os.ReadFile("/app/db/queries/aged_debt.sql")
if err != nil {
return err
}

agedDebtHeaders := []string{
"Customer Name",
"Customer number",
"SOP number",
"Deputy type",
"Active case?",
"Entity",
"Receivable cost centre",
"Receivable cost centre description",
"Receivable account code",
"Revenue cost centre",
"Revenue cost centre description",
"Revenue account code",
"Revenue account code description",
"Invoice type",
"Trx number",
"Transaction Description",
"Invoice date",
"Due date",
"Financial year",
"Payment terms",
"Original amount",
"Outstanding amount",
"Current",
"0-1 years",
"1-2 years",
"2-3 years",
"3-5 years",
"5+ years",
"Debt impairment years",
}

ef, err := os.Create("test.csv")
if err != nil {
return err
}

ef.Close()

query := string(c)

rows, err := s.conn.Query(ctx, query)
if err != nil {
return err
}

defer rows.Close()
var items [][]string
for rows.Next() {
var i []string
var stringValue string

values, err := rows.Values()
if err != nil {
return err
}
for _, value := range values {
stringValue, _ = value.(string)
i = append(i, stringValue)
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return err
}

writer := csv.NewWriter(ef)

err = writer.Write(agedDebtHeaders)
if err != nil {
return err
}

for _, item := range items {
err = writer.Write(item)
if err != nil {
return err
}
}

writer.Flush()
if writer.Error() != nil {
return writer.Error()
}

versionId, err := s.filestorage.PutFile(
ctx,
os.Getenv("ASYNC_S3_BUCKET"),
fmt.Sprintf("%s/%s", s3Directory, "test.csv"),
ef,
)

if err != nil {
return err
}

if versionId == nil {
return fmt.Errorf("S3 version ID not found")
}

downloadRequest := shared.DownloadRequest{
Key: fmt.Sprintf("%s/%s", s3Directory, "test.csv"),
VersionId: *versionId,
}

uid, err := downloadRequest.Encode()
if err != nil {
return err
}

payload := NotifyPayload{
EmailAddress: "[email protected]",
TemplateId: "8c85cf6c-695f-493a-a25f-77b4fb5f6a8e",
Personalisation: struct {
Uid string `json:"upload_type"`
}{
uid,
},
}

err = s.SendEmailToNotify(ctx, payload)
if err != nil {
return err
}

return nil
}
6 changes: 4 additions & 2 deletions finance-admin-api/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Dispatch interface {

type FileStorage interface {
GetFile(ctx context.Context, bucketName string, filename string, versionID string) (*s3.GetObjectOutput, error)
PutFile(ctx context.Context, bucketName string, fileName string, file io.Reader) error
PutFile(ctx context.Context, bucketName string, fileName string, file io.Reader) (*string, error)
FileExists(ctx context.Context, bucketName string, filename string, versionID string) bool
}

Expand Down Expand Up @@ -52,8 +52,10 @@ func (s *Server) SetupRoutes(logger *slog.Logger) http.Handler {
mux.Handle(pattern, handler)
}

handleFunc("GET /downloads", s.download)
handleFunc("GET /download", s.download)
handleFunc("HEAD /download", s.checkDownload)

handleFunc("POST /downloads", s.requestReport)
handleFunc("POST /uploads", s.upload)

handleFunc("POST /events", s.handleEvents)
Expand Down
4 changes: 2 additions & 2 deletions finance-admin-api/api/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ func (m *MockFileStorage) GetFile(ctx context.Context, bucketName string, fileNa
return m.outgoingObject, m.err
}

func (m *MockFileStorage) PutFile(ctx context.Context, bucketName string, fileName string, file io.Reader) error {
func (m *MockFileStorage) PutFile(ctx context.Context, bucketName string, fileName string, file io.Reader) (*string, error) {
m.bucketname = bucketName
m.filename = fileName
m.file = file

return nil
return nil, nil
}

// add a FileExists method to the MockFileStorage struct
Expand Down
2 changes: 1 addition & 1 deletion finance-admin-api/api/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (s *Server) upload(w http.ResponseWriter, r *http.Request) error {
return err
}

err = s.filestorage.PutFile(
_, err = s.filestorage.PutFile(
ctx,
os.Getenv("ASYNC_S3_BUCKET"),
fmt.Sprintf("%s/%s", s3Directory, upload.Filename),
Expand Down
6 changes: 3 additions & 3 deletions finance-admin-api/filestorage/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ func (c *Client) GetFile(ctx context.Context, bucketName string, filename string
})
}

func (c *Client) PutFile(ctx context.Context, bucketName string, fileName string, file io.Reader) error {
_, err := c.s3.PutObject(ctx, &s3.PutObjectInput{
func (c *Client) PutFile(ctx context.Context, bucketName string, fileName string, file io.Reader) (*string, error) {
output, err := c.s3.PutObject(ctx, &s3.PutObjectInput{
Bucket: &bucketName,
Key: &fileName,
Body: file,
ServerSideEncryption: "aws:kms",
SSEKMSKeyId: aws.String(os.Getenv("S3_ENCRYPTION_KEY")),
})

return err
return output.VersionId, err
}

func (c *Client) FileExists(ctx context.Context, bucketName string, filename string, versionID string) bool {
Expand Down
Loading

0 comments on commit 2d301e0

Please sign in to comment.