Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Commit

Permalink
reports on per center base, delete operators
Browse files Browse the repository at this point in the history
  • Loading branch information
dreske committed Aug 16, 2022
1 parent 8839b6d commit 319e555
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 7 deletions.
11 changes: 11 additions & 0 deletions resources/db/migration/V1.4.0.1__add_center_statistics.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
create table report_center_statistics
(
operator_uuid varchar(36) not null
references operators on delete cascade on update cascade,
center_uuid varchar(36) not null
references centers on delete cascade on update cascade,
subject varchar(128) not null,
count integer not null,
constraint report_center_statistics_pk
primary key (operator_uuid, center_uuid, subject)
);
68 changes: 68 additions & 0 deletions src/api/operators.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import (
"bytes"
"com.t-systems-mms.cwa/api/model"
"com.t-systems-mms.cwa/core/api"
"com.t-systems-mms.cwa/core/security"
"com.t-systems-mms.cwa/core/util"
"com.t-systems-mms.cwa/repositories"
"com.t-systems-mms.cwa/services"
"encoding/csv"
"github.com/go-chi/chi"
"github.com/go-chi/jwtauth"
"github.com/go-playground/validator"
Expand Down Expand Up @@ -63,6 +65,13 @@ func NewOperatorsAPI(operatorsRepository repositories.Operators, operatorsServic
r.Use(jwtauth.Authenticator)
r.Get("/current", api.Handle(operators.GetCurrentOperator))
r.Put("/current", api.Handle(operators.SaveCurrentOperator))

r.Group(func(r chi.Router) {
r.Use(api.RequireRole(security.RoleAdmin))
r.Get("/", api.Handle(operators.GetAllOperators))
r.Get("/csv", operators.GetAllOperatorsAsCSV)
r.Delete("/{operator}", api.Handle(operators.DeleteOperator))
})
})

return operators
Expand Down Expand Up @@ -159,3 +168,62 @@ func (c *Operators) GetOperatorLogo(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusNotFound)
}

func (c *Operators) GetAllOperators(w http.ResponseWriter, r *http.Request) (interface{}, error) {
operators, err := c.operatorsRepository.FindAll(r.Context())
if err != nil {
return nil, err
}

response := make([]model.OperatorDTO, len(operators))
for i, operator := range operators {
response[i] = *model.MapToOperatorDTO(&operator)
}

return response, nil
}

func (c *Operators) GetAllOperatorsAsCSV(w http.ResponseWriter, r *http.Request) {
operators, err := c.operatorsRepository.FindAll(r.Context())
if err != nil {
logrus.WithError(err).Error("Error getting operators")
api.WriteError(w, r, err)
return
}

w.Header().Set("Content-Type", "text/csv")
if _, err := w.Write([]byte{0xEF, 0xBB, 0xBF}); err != nil {
logrus.WithError(err).Error("Error writing BOM")
return
}

csvWriter := csv.NewWriter(w)
csvWriter.Comma = ';'

if err := csvWriter.Write([]string{"uuid", "subject", "number", "name", "email", "receiver"}); err != nil {
logrus.WithError(err).Error("Error writing response")
return
}

for _, operator := range operators {
if err := csvWriter.Write([]string{
operator.UUID,
util.PtrToString(operator.Subject, ""),
util.PtrToString(operator.OperatorNumber, ""),
operator.Name,
util.PtrToString(operator.Email, ""),
util.PtrToString(operator.BugReportsReceiver, ""),
}); err != nil {
logrus.WithError(err).Error("Error writing response")
return
}
}
csvWriter.Flush()
}

func (c *Operators) DeleteOperator(w http.ResponseWriter, r *http.Request) (interface{}, error) {
id := chi.URLParam(r, "operator")
logrus.WithField("operator", id).Info("Deleting operator")

return nil, c.operatorsRepository.Delete(r.Context(), id)
}
80 changes: 79 additions & 1 deletion src/api/statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,88 @@ func NewStatisticsAPI(reportsRepository repositories.BugReports, auth *jwtauth.J
r.Use(api.RequireRole(security.RoleAdmin))

r.Get("/reports", statistics.getReportStatistics)
r.Get("/reports/centers", statistics.getCenterReportsStatistics)
})
return statistics
}

func (c *Statistics) getCenterReportsStatistics(w http.ResponseWriter, r *http.Request) {
stats, err := c.reportsRepository.GetCenterStatistics(r.Context())
if err != nil {
logrus.WithError(err).Error("Error getting report statistics")
w.WriteHeader(http.StatusInternalServerError)
return
}

subjects := make([]string, 0)
operators := make(map[string]domain.Operator)
centers := make(map[string]domain.Center)
data := make(map[string]map[string]map[string]uint)
for _, value := range stats {
knownSubject := false
for _, s := range subjects {
if s == value.Subject {
knownSubject = true
break
}
}

if !knownSubject {
subjects = append(subjects, value.Subject)
}

if _, ok := data[value.OperatorUUID]; !ok {
data[value.OperatorUUID] = make(map[string]map[string]uint)
operators[value.OperatorUUID] = *value.Operator
}

if _, ok := data[value.OperatorUUID][value.CenterUUID]; !ok {
data[value.OperatorUUID][value.CenterUUID] = make(map[string]uint)
centers[value.CenterUUID] = *value.Center
}

data[value.OperatorUUID][value.CenterUUID][value.Subject] = value.Count
}

w.Header().Set("Content-Type", "text/csv")
if _, err := w.Write([]byte{0xEF, 0xBB, 0xBF}); err != nil {
logrus.WithError(err).Error("Error writing BOM")
return
}

csvWriter := csv.NewWriter(w)
csvWriter.Comma = ';'

headers := []string{"partner_uuid", "partner_number", "partner_name", "center_uuid", "center_name"}
headers = append(headers, subjects...)
if err := csvWriter.Write(headers); err != nil {
logrus.WithError(err).Error("Error writing response")
return
}

for operator, operatorCenters := range data {
for center, entry := range operatorCenters {
columns := []string{
operator,
util.PtrToString(operators[operator].OperatorNumber, ""),
operators[operator].Name,
center,
centers[center].Name,
}
for _, subject := range subjects {
columns = append(columns, strconv.Itoa(int(entry[subject])))
}

if err := csvWriter.Write(columns); err != nil {
logrus.WithError(err).Error("Error writing response")
return
}
}
}

csvWriter.Flush()
}

func (c *Statistics) getReportStatistics(w http.ResponseWriter, r *http.Request) {
stats, err := c.reportsRepository.GetStatistics(r.Context())
if err != nil {
Expand Down Expand Up @@ -97,7 +175,7 @@ func (c *Statistics) getReportStatistics(w http.ResponseWriter, r *http.Request)
csvWriter := csv.NewWriter(w)
csvWriter.Comma = ';'

headers := []string{"partner_uuid", "partner_name", "partner_number"}
headers := []string{"partner_uuid", "partner_number", "partner_name"}
headers = append(headers, subjects...)
if err := csvWriter.Write(headers); err != nil {
logrus.WithError(err).Error("Error writing response")
Expand Down
37 changes: 34 additions & 3 deletions src/repositories/bugreports.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ type ReportStatistics struct {
Count uint
}

type ReportCenterStatistics struct {
Subject string
OperatorUUID string
Operator *domain.Operator `gorm:"foreignKey:OperatorUUID"`
CenterUUID string
Center *domain.Center `gorm:"foreignKey:CenterUUID"`
Count uint
}

type BugReports interface {
Repository
Save(ctx context.Context, center *domain.BugReport) error
Expand All @@ -47,8 +56,9 @@ type BugReports interface {
FindAllByLeader(ctx context.Context, leader string) ([]domain.BugReport, error)
ResetLeader(ctx context.Context, leader string) error

IncrementReportCount(ctx context.Context, operatorUUID, subject string) error
IncrementReportCount(ctx context.Context, operatorUUID, centerUUID, subject string) error
GetStatistics(ctx context.Context) ([]ReportStatistics, error)
GetCenterStatistics(ctx context.Context) ([]ReportCenterStatistics, error)
}

type bugReportsRepository struct {
Expand Down Expand Up @@ -105,11 +115,20 @@ func (b *bugReportsRepository) FindAll(ctx context.Context) ([]domain.BugReport,
return reports, err
}

func (b *bugReportsRepository) IncrementReportCount(ctx context.Context, operatorUUID, subject string) error {
return b.GetTX(ctx).Exec("insert into report_statistics (operator_uuid, subject, count)"+
func (b *bugReportsRepository) IncrementReportCount(ctx context.Context, operatorUUID, centerUUID, subject string) error {
err := b.GetTX(ctx).Exec("insert into report_statistics (operator_uuid, subject, count) "+
"VALUES (?, ?, 1)"+
"on conflict on constraint report_statistics_pk "+
"do update set count = report_statistics.count + 1", operatorUUID, subject).Error

if err != nil {
return err
}

return b.GetTX(ctx).Exec("insert into report_center_statistics (operator_uuid, center_uuid, subject, count) "+
"VALUES (?, ?, ?, 1)"+
"on conflict on constraint report_center_statistics_pk "+
"do update set count = report_center_statistics.count + 1", operatorUUID, centerUUID, subject).Error
}

func (b *bugReportsRepository) GetStatistics(ctx context.Context) ([]ReportStatistics, error) {
Expand All @@ -122,3 +141,15 @@ func (b *bugReportsRepository) GetStatistics(ctx context.Context) ([]ReportStati

return statistics, err
}

func (b *bugReportsRepository) GetCenterStatistics(ctx context.Context) ([]ReportCenterStatistics, error) {
var statistics []ReportCenterStatistics
err := b.GetTX(ctx).
Preload("Operator").
Preload("Center").
Order("operator_uuid").
Find(&statistics).
Error

return statistics, err
}
21 changes: 19 additions & 2 deletions src/repositories/operators.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,22 @@ type OperatorsStatistics struct {
}

type Operators interface {
Repository
FindById(ctx context.Context, id string) (domain.Operator, error)
GetOrCreateByToken(ctx context.Context, subject jwt.Token) (domain.Operator, error)
Save(ctx context.Context, operator domain.Operator) (domain.Operator, error)
FindStatistics(ctx context.Context) (OperatorsStatistics, error)
FindAll(ctx context.Context) ([]domain.Operator, error)
Delete(ctx context.Context, id string) error
}

type operatorsRepository struct {
db *gorm.DB
postgresqlRepository
}

func NewOperatorsRepository(db *gorm.DB) Operators {
return &operatorsRepository{
db: db,
postgresqlRepository{db: db},
}
}

Expand Down Expand Up @@ -129,3 +132,17 @@ func (r *operatorsRepository) FindStatistics(ctx context.Context) (OperatorsStat
Error
return statistics, err
}

func (r *operatorsRepository) FindAll(ctx context.Context) ([]domain.Operator, error) {
var result []domain.Operator
err := r.db.
Model(&domain.Operator{}).
Order("uuid").
Find(&result).Error

return result, err
}

func (r *operatorsRepository) Delete(ctx context.Context, id string) error {
return r.GetTX(ctx).Exec("DELETE FROM operators WHERE uuid = ?", id).Error
}
2 changes: 1 addition & 1 deletion src/services/bugreports.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (s *bugReportsService) CreateBugReport(ctx context.Context, centerUUID, sub
return report, err
}

if err := s.bugReportsRepository.IncrementReportCount(ctx, center.OperatorUUID, report.Subject); err != nil {
if err := s.bugReportsRepository.IncrementReportCount(ctx, center.OperatorUUID, center.UUID, report.Subject); err != nil {
logrus.WithError(err).Error("Error updating report statistics")
}

Expand Down

0 comments on commit 319e555

Please sign in to comment.