Send grammatically correct messages when new orders arrive

This commit is contained in:
Luca 2022-07-25 02:22:23 +02:00
parent cecd903810
commit 79b4435120
1 changed files with 82 additions and 1 deletions

View File

@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"maunium.net/go/mautrix/event"
@ -73,6 +75,7 @@ func (s Server) orderPlaced(w http.ResponseWriter, r *http.Request) {
Positions []struct{
Price string
}
Total string
}{}
err = decoder.Decode(&order)
@ -94,11 +97,89 @@ func (s Server) orderPlaced(w http.ResponseWriter, r *http.Request) {
}
if rowsAffected > 0 && order.Datetime.Add(72 * time.Hour).After(time.Now()) { // pretix retries failed webhooks for up to three days
numFree := 0
numPaid := 0
for _, position := range order.Positions {
euros, cents, err := parsePrice(position.Price)
if err != nil {
continue
}
if euros > 0 || cents > 0 {
numPaid++
} else {
numFree++
}
}
var verb, free, conjunction, paid, noun, total string
if numFree+numPaid == 1 {
verb = "wurde "
} else {
verb = "wurden "
}
if numFree == 1 {
free = "ein kostenloses "
} else if numFree > 1 {
free = fmt.Sprint(numFree, " kostenlose ")
}
if numPaid == 1 {
paid = "ein bezahltes "
} else if numPaid > 1 {
paid = fmt.Sprint(numPaid, " bezahlte ")
}
if numFree > 0 && numPaid > 0 {
conjunction = "und "
}
if numPaid == 1 || numPaid == 0 && numFree == 1 { // match number of adjective immediately before noun
noun = "Ticket "
} else {
noun = "Tickets "
}
if totalEuros, totalCents, err := parsePrice(order.Total); err == nil && (totalEuros > 0 || totalCents > 0) {
var adverb, fraction string
if numPaid > 1 {
adverb = "insgesamt "
}
if totalCents > 0 {
fraction = fmt.Sprintf(",%02d", totalCents)
}
total = fmt.Sprint("für ", adverb, totalEuros, fraction, " Euro ")
}
message := event.MessageEventContent{
MsgType: event.MsgText,
Body: fmt.Sprintf("%+v", order),
Body: fmt.Sprint("Es ", verb, free, conjunction, paid, noun, total, "bestellt."),
}
s.matrix.Broadcast(&message)
}
}
func parsePrice(price string) (euros uint64, cents uint64, err error) {
parts := strings.Split(price, ".")
euros, err = strconv.ParseUint(parts[0], 10, 64)
if err != nil {
return 0, 0, err
}
if len(parts) > 1 {
for len(parts[1]) < 2 {
parts[1] += "0"
}
parts[1] = parts[1][:2]
parts[1] = strings.TrimLeft(parts[1], "0")
if parts[1] == "" {
parts[1] = "0"
}
cents, err = strconv.ParseUint(parts[1], 10, 64)
if err != nil {
return 0, 0, err
}
}
return euros, cents, nil
}