diff --git a/cmd/export.go b/cmd/export.go new file mode 100644 index 0000000..d94f27f --- /dev/null +++ b/cmd/export.go @@ -0,0 +1,30 @@ +package cmd + +import ( + "github.com/devmegablaster/bashform/internal/styles" + "github.com/spf13/cobra" +) + +func (c *CLI) exportResponses() *cobra.Command { + formCmd := &cobra.Command{ + Use: "export [code]", + Short: "Exports responses for a form using form code to CSV", + Args: cobra.ExactArgs(1), + Aliases: []string{"e"}, + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + formCSV, err := c.formSvc.GetResponsesCSV(args[0], c.user) + if err != nil { + c.logger.Error("Error getting form", "error", err) + cmd.Println(styles.Error.Render(err.Error())) + } + + c.logger.Info("Form exported to CSV") + + cmd.Println(formCSV) + return nil + }, + } + + return formCmd +} diff --git a/cmd/root.go b/cmd/root.go index 2520b93..c61a974 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -68,6 +68,7 @@ func (c *CLI) Init() { c.AddCommand(c.fillForm()) c.AddCommand(c.createForm()) c.AddCommand(c.getForms()) + c.AddCommand(c.exportResponses()) } func (c *CLI) Run() error { diff --git a/internal/models/response.go b/internal/models/response.go index 95d7eb9..6d18b5e 100644 --- a/internal/models/response.go +++ b/internal/models/response.go @@ -26,3 +26,11 @@ func (r *ResponseRequest) ToResponse(formID uuid.UUID, userID uuid.UUID) Respons Answers: r.Answers, } } + +func (r *Response) ToCSV() []string { + csv := []string{} + for _, answer := range r.Answers { + csv = append(csv, answer.Value) + } + return csv +} diff --git a/internal/repository/form.go b/internal/repository/form.go index fd6ae1c..c8c83e4 100644 --- a/internal/repository/form.go +++ b/internal/repository/form.go @@ -62,3 +62,13 @@ func (r *FormRepository) GetWithResponses(userID, formID string) (*models.Form, return &form, nil } + +func (r *FormRepository) GetWithResponsesUsingCode(userID, code string) (*models.Form, error) { + var form models.Form + + if err := r.db.DB.Preload("Responses.Answers").Preload("Questions").First(&form, "code = ? AND user_id = ?", code, userID).Error; err != nil { + return nil, err + } + + return &form, nil +} diff --git a/internal/services/form.go b/internal/services/form.go index 4b8c189..cc45086 100644 --- a/internal/services/form.go +++ b/internal/services/form.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "github.com/devmegablaster/bashform/internal/config" "github.com/devmegablaster/bashform/internal/database" @@ -114,3 +115,24 @@ func (f *FormService) GetWithResponses(formID string, user *models.User) (*model return formWithResponses, nil } + +func (f *FormService) GetResponsesCSV(formCode string, user *models.User) (string, error) { + form, err := f.fr.GetWithResponsesUsingCode(user.ID.String(), formCode) + if err != nil { + return "", err + } + + rows := []string{} + questions := []string{} + for _, question := range form.Questions { + questions = append(questions, question.Text) + } + + rows = append(rows, strings.Join(questions, ",")) + + for _, response := range form.Responses { + rows = append(rows, strings.Join(response.ToCSV(), ",")) + } + + return strings.Join(rows, "\n"), nil +}