Established Participants and Tickets model. Migrated concepts.
This commit is contained in:
parent
0df93e1886
commit
cd8e1e3b3b
22 changed files with 1345 additions and 191 deletions
|
|
@ -8,9 +8,9 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// handleGenerateTokens creates volunteer_token values for all attendees that don't have one.
|
||||
// handleGenerateTokens creates codes for all tickets that don't have one.
|
||||
func (app *App) handleGenerateTokens(w http.ResponseWriter, r *http.Request) {
|
||||
count, err := app.generateTokensForAll()
|
||||
count, err := app.generateCodesForAll()
|
||||
if err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -21,7 +21,7 @@ func (app *App) handleGenerateTokens(w http.ResponseWriter, r *http.Request) {
|
|||
// handleExportTokenLinks streams a CSV download with token signup links,
|
||||
// compatible with MailChimp / Zeffy bulk-send workflows.
|
||||
func (app *App) handleExportTokenLinks(w http.ResponseWriter, r *http.Request) {
|
||||
attendees, err := app.listAttendees("", "", "")
|
||||
tickets, err := app.listTickets(nil, "")
|
||||
if err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -37,55 +37,62 @@ func (app *App) handleExportTokenLinks(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("Content-Disposition", `attachment; filename="volunteer-tokens.csv"`)
|
||||
wr := csv.NewWriter(w)
|
||||
wr.Write([]string{"Email Address", "First Name", "Token", "Signup Link"})
|
||||
for _, a := range attendees {
|
||||
if a.VolunteerToken == nil {
|
||||
for _, tk := range tickets {
|
||||
if tk.Code == nil || tk.ParticipantID == nil {
|
||||
continue
|
||||
}
|
||||
firstName := a.Name
|
||||
if parts := strings.Fields(a.Name); len(parts) > 0 {
|
||||
p, _ := app.getParticipant(*tk.ParticipantID)
|
||||
if p == nil || p.Email == "" {
|
||||
continue
|
||||
}
|
||||
firstName := p.PreferredName
|
||||
if firstName == "" {
|
||||
firstName = tk.Name
|
||||
}
|
||||
if parts := strings.Fields(firstName); len(parts) > 0 {
|
||||
firstName = parts[0]
|
||||
}
|
||||
link := fmt.Sprintf("%s/v/%s", baseURL, *a.VolunteerToken)
|
||||
wr.Write([]string{a.Email, firstName, *a.VolunteerToken, link})
|
||||
link := fmt.Sprintf("%s/v/%s", baseURL, *tk.Code)
|
||||
wr.Write([]string{p.Email, firstName, *tk.Code, link})
|
||||
}
|
||||
wr.Flush()
|
||||
}
|
||||
|
||||
// handleEmailToken sends a token email to a single attendee.
|
||||
// handleEmailToken sends a token email to a single ticket's participant.
|
||||
func (app *App) handleEmailToken(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.Atoi(r.PathValue("id"))
|
||||
if err != nil {
|
||||
writeError(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
a, err := app.getAttendee(id)
|
||||
if err != nil || a == nil {
|
||||
tk, err := app.getTicket(id)
|
||||
if err != nil || tk == nil {
|
||||
writeError(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err := app.sendTokenEmail(*a); err != nil {
|
||||
if err := app.sendTicketTokenEmail(*tk); err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
writeJSON(w, map[string]any{"ok": true})
|
||||
}
|
||||
|
||||
// handleEmailAllTokens bulk-sends token emails to all attendees that have both a token and email.
|
||||
// handleEmailAllTokens bulk-sends token emails to all tickets that have a code and participant email.
|
||||
func (app *App) handleEmailAllTokens(w http.ResponseWriter, r *http.Request) {
|
||||
attendees, err := app.listAttendees("", "", "")
|
||||
tickets, err := app.listTickets(nil, "")
|
||||
if err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var sent, skipped int
|
||||
var errors []string
|
||||
for _, a := range attendees {
|
||||
if a.Email == "" || a.VolunteerToken == nil {
|
||||
for _, tk := range tickets {
|
||||
if tk.Code == nil || tk.ParticipantID == nil {
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
if err := app.sendTokenEmail(a); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("%s: %v", a.Name, err))
|
||||
if err := app.sendTicketTokenEmail(tk); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("ticket %d: %v", tk.ID, err))
|
||||
skipped++
|
||||
} else {
|
||||
sent++
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue