From 6455b409ce387228a2b750ab4f14e5690c353b9b Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sat, 9 Dec 2023 16:22:00 +0100 Subject: [PATCH] [raffle] Add functionality to reset a raffle in order to re-use the same raffle by wiping the entrants, resetting time-fields to their default value and resetting status to draft Signed-off-by: Knut Ahlers --- internal/apimodules/raffle/api.go | 19 +++++++++++++++ internal/apimodules/raffle/database.go | 28 ++++++++++++++++++++++ src/raffle.vue | 33 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/internal/apimodules/raffle/api.go b/internal/apimodules/raffle/api.go index 2f4c07a..9f6a2a7 100644 --- a/internal/apimodules/raffle/api.go +++ b/internal/apimodules/raffle/api.go @@ -117,6 +117,25 @@ var apiRoutes = []plugins.HTTPRouteRegistrationArgs{ }, }, + { + Description: "Resets the raffle (remove entries, reset status & start/close time) given by its ID", + HandlerFunc: handleWrap(func(w http.ResponseWriter, r *http.Request, ids map[string]uint64) (any, error) { + return nil, errors.Wrap(dbc.Reset(ids["id"]), "resetting raffle") + }, []string{"id"}), + Method: http.MethodPut, + Module: moduleName, + Name: "Reset Raffle", + Path: "/{id}/reset", + RequiresWriteAuth: true, + ResponseType: plugins.HTTPRouteResponseTypeNo200, + RouteParams: []plugins.HTTPRouteParamDocumentation{ + { + Description: "ID of the raffle to reset", + Name: "id", + }, + }, + }, + { Description: "Duplicates the raffle given by its ID", HandlerFunc: handleWrap(func(w http.ResponseWriter, r *http.Request, ids map[string]uint64) (any, error) { diff --git a/internal/apimodules/raffle/database.go b/internal/apimodules/raffle/database.go index ff717bc..48c0700 100644 --- a/internal/apimodules/raffle/database.go +++ b/internal/apimodules/raffle/database.go @@ -194,6 +194,7 @@ func (d *dbClient) Clone(raffleID uint64) error { return errors.Wrap(err, "getting raffle") } + raffle.AutoStartAt = nil raffle.CloseAt = nil raffle.Entries = nil raffle.ID = 0 @@ -528,6 +529,33 @@ func (d *dbClient) Reopen(raffleID uint64, duration time.Duration) error { return nil } +// Reset resets the raffle participants, the status, start / close +// times while preserving the rest of the settings +func (d *dbClient) Reset(raffleID uint64) error { + raffle, err := d.Get(raffleID) + if err != nil { + return errors.Wrap(err, "getting raffle") + } + + raffle.AutoStartAt = nil + raffle.CloseAt = nil + raffle.Entries = nil + raffle.Status = raffleStatusPlanned + + if err = helpers.RetryTransaction(d.db.DB(), func(tx *gorm.DB) error { + if err = tx.Delete(&raffleEntry{}, "raffle_id = ?", raffleID).Error; err != nil { + return errors.Wrap(err, "deleting raffle entries") + } + + return tx.Save(raffle).Error + }); err != nil { + return errors.Wrap(err, "saving cleaned raffle") + } + + frontendNotify(frontendNotifyEventRaffleChange) + return nil +} + // Start fetches the given raffle, updates its CloseAt attribute // in case it is not already set, sets the raffle to active, updates // the raffle in the database and notes its channel/keyword combo diff --git a/src/raffle.vue b/src/raffle.vue index 2c4c27f..f07104e 100644 --- a/src/raffle.vue +++ b/src/raffle.vue @@ -79,6 +79,18 @@ /> + + + + this.$root.toastError('Could not re-pick winner!')) }, + resetRaffle(id) { + this.$bvModal.msgBoxConfirm('Do you really want to reset this raffle?', { + buttonSize: 'sm', + cancelTitle: 'NO', + centered: true, + okTitle: 'YES', + okVariant: 'danger', + size: 'sm', + title: 'Please Confirm', + }) + .then(val => { + if (!val) { + return + } + + return axios.put(`raffle/${id}/reset`, {}, this.$root.axiosOptions) + .then(() => this.$root.toastSuccess('Raffle reset')) + .catch(err => this.$bus.$emit(constants.NOTIFY_FETCH_ERROR, err)) + }) + }, + saveRaffle() { if (this.models.raffle.id) { return axios.put(`raffle/${this.models.raffle.id}`, this.transformRaffleToDB(this.models.raffle), this.$root.axiosOptions)