feat(view): add view and backend for regulars tables
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful

This commit is contained in:
nikurasu 2024-05-26 01:14:46 +02:00
parent 3fde58c143
commit 8206d16be0
Signed by: Nikurasu
GPG key ID: 9E7F14C03EF1F271
16 changed files with 198 additions and 40 deletions

3
.gitignore vendored
View file

@ -1,4 +1,5 @@
go.sum go.sum
.env .env
pretix-proxy pretix-proxy
main.db main.db
src/db.db

View file

@ -95,11 +95,15 @@ func GetAttendiesByEventPublicTable(c *fiber.Ctx) error {
"No": localizer.MustLocalize(&i18n.LocalizeConfig{ "No": localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "No", MessageID: "No",
}), }),
"AfterParty": localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "AfterParty",
PluralCount: 1,
}),
} }
return c.Render("app/views/index", fiber.Map{ return c.Render("app/views/index", fiber.Map{
"Event Name": event.Name, "EventName": *(event).Name,
"Attendies": attendies, "Attendies": attendies,
"Locals": localizations, "Locals": localizations,
"EventType": *(event).EventType, "EventType": *(event).EventType,
}) })
} }

View file

@ -14,17 +14,10 @@ func PostPretixRoleQuestion(c *fiber.Ctx) error {
if err := c.BodyParser(data); err != nil { if err := c.BodyParser(data); err != nil {
return c.Status(fiber.ErrBadRequest.Code).SendString(err.Error()) return c.Status(fiber.ErrBadRequest.Code).SendString(err.Error())
} }
pretixOrders, err := util.GetPretixOrders(&data.Organizer, &data.Event) pretixOrders, err := getAllPretixOrders(&data.Organizer, &data.Event)
if err != nil { if err != nil {
return c.Status(500).SendString("Internal Server Error") fmt.Println(err)
} return c.SendStatus(fiber.StatusInternalServerError)
for link := pretixOrders.Next; link != nil; {
next_page, err := util.GetPretixOrdersByLink(link)
if err != nil {
return c.Status(500).SendString("Internal Server Error")
}
pretixOrders.Results = append(pretixOrders.Results, next_page.Results...)
link = next_page.Next
} }
event, err := service.Get_db_event_by_event(data.Event) event, err := service.Get_db_event_by_event(data.Event)
if err != nil { if err != nil {
@ -33,13 +26,16 @@ func PostPretixRoleQuestion(c *fiber.Ctx) error {
attendies, err := util.GetAttendiesFromPretixJsonWithRoleQuestion(pretixOrders, &event) attendies, err := util.GetAttendiesFromPretixJsonWithRoleQuestion(pretixOrders, &event)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return c.SendStatus(fiber.StatusInternalServerError)
} }
if err := service.DeleteAttendiesByEvent(event); err != nil { if err := service.DeleteAttendiesByEvent(event); err != nil {
fmt.Println(err) fmt.Println(err)
return c.SendStatus(fiber.StatusInternalServerError)
} }
for _, attendie := range attendies { for _, attendie := range attendies {
if err := service.CreateNewAttendie(attendie); err != nil { if err := service.CreateNewAttendie(attendie); err != nil {
fmt.Print(err) fmt.Print(err)
return c.SendStatus(fiber.StatusInternalServerError)
} }
} }
return c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)
@ -50,9 +46,7 @@ func PostPretixRoleProduct(c *fiber.Ctx) error {
if err := c.BodyParser(data); err != nil { if err := c.BodyParser(data); err != nil {
return c.Status(fiber.ErrBadRequest.Code).SendString(err.Error()) return c.Status(fiber.ErrBadRequest.Code).SendString(err.Error())
} }
//TODO: Update attendies from pretix pretixOrders, err := getAllPretixOrders(&data.Organizer, &data.Event)
pretixOrders, err := util.GetPretixOrders(&data.Organizer, &data.Event)
_ = pretixOrders
if err != nil { if err != nil {
return c.Status(500).SendString("Internal Server Error") return c.Status(500).SendString("Internal Server Error")
} }
@ -63,14 +57,61 @@ func PostPretixRoleProduct(c *fiber.Ctx) error {
attendies, err := util.GetAttendiesFromPretixJsonWithRoleProduct(pretixOrders, &event) attendies, err := util.GetAttendiesFromPretixJsonWithRoleProduct(pretixOrders, &event)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return c.SendStatus(fiber.StatusInternalServerError)
} }
if err := service.DeleteAttendiesByEvent(event); err != nil { if err := service.DeleteAttendiesByEvent(event); err != nil {
fmt.Println(err) fmt.Println(err)
return c.SendStatus(fiber.StatusInternalServerError)
} }
for _, attendie := range attendies { for _, attendie := range attendies {
if err := service.CreateNewAttendie(attendie); err != nil { if err := service.CreateNewAttendie(attendie); err != nil {
fmt.Print(err) fmt.Print(err)
return c.SendStatus(fiber.StatusInternalServerError)
} }
} }
return c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)
} }
func PostPretixRegularsTable(c *fiber.Ctx) error {
data := new(entities.Pretix_Webhook)
if err := c.BodyParser(data); err != nil {
return c.Status(fiber.ErrBadGateway.Code).SendString(err.Error())
}
pretixOrders, err := getAllPretixOrders(&data.Organizer, &data.Event)
if err != nil {
return c.Status(500).SendString("Internal Server Error")
}
event, err := service.Get_db_event_by_event(data.Event)
if err != nil {
return c.Status(fiber.StatusNotFound).SendString("Event not found")
}
attendies, err := util.GetAttendiesFromPretixJsonWithSeperateSubProducts(pretixOrders, &event)
if err != nil {
fmt.Println(err)
return c.SendStatus(fiber.StatusInternalServerError)
}
if err := service.DeleteAttendiesByEvent(event); err != nil {
fmt.Println(err)
return c.SendStatus(fiber.StatusInternalServerError)
}
for _, attendie := range attendies {
if err := service.CreateNewAttendie(attendie); err != nil {
fmt.Print(err)
return c.SendStatus(fiber.StatusInternalServerError)
}
}
return c.SendStatus(fiber.StatusOK)
}
func getAllPretixOrders(organizer, event *string) (*entities.Pretix_Event, error) {
pretixOrders, err := util.GetPretixOrders(organizer, event)
for link := pretixOrders.Next; link != nil; {
next_page, err := util.GetPretixOrdersByLink(link)
if err != nil {
return nil, err
}
pretixOrders.Results = append(pretixOrders.Results, next_page.Results...)
link = next_page.Next
}
return pretixOrders, err
}

View file

@ -15,8 +15,9 @@ func PrivateRoutes(app *fiber.App) {
event.Get("/:id", controller.ReturnEventById) event.Get("/:id", controller.ReturnEventById)
event.Delete("/:id", controller.DeleteEventById) event.Delete("/:id", controller.DeleteEventById)
event.Put("/:id", controller.UpdateEventById) event.Put("/:id", controller.UpdateEventById)
event.Put("", controller.CreateEvent) event.Post("", controller.CreateEvent)
role := apiv1.Group("/role") role := apiv1.Group("/role")
role.Use(config.JwtMiddleware)
role.Get("", controller.ReturnAllRoles) role.Get("", controller.ReturnAllRoles)
role.Get("/:id", controller.ReturnRoleById) role.Get("/:id", controller.ReturnRoleById)
role.Delete("/:id", controller.DeleteRoleById) role.Delete("/:id", controller.DeleteRoleById)
@ -24,5 +25,5 @@ func PrivateRoutes(app *fiber.App) {
role.Put("", controller.CreateRole) role.Put("", controller.CreateRole)
user := apiv1.Group("/user") user := apiv1.Group("/user")
user.Use(config.AuthMiddleware) user.Use(config.AuthMiddleware)
user.Put("", controller.CreateUser) user.Post("", controller.CreateUser)
} }

View file

@ -14,6 +14,7 @@ func PublicRoutes(app *fiber.App) {
webhooks := apiv1.Group("/webhooks") webhooks := apiv1.Group("/webhooks")
webhooks.Post("/pretix/role_question", controller.PostPretixRoleQuestion) webhooks.Post("/pretix/role_question", controller.PostPretixRoleQuestion)
webhooks.Post("/pretix/role_product", controller.PostPretixRoleProduct) webhooks.Post("/pretix/role_product", controller.PostPretixRoleProduct)
webhooks.Post("/pretix/subproduct", controller.PostPretixRegularsTable)
apiv1.Post("/login", controller.LoginUser) apiv1.Post("/login", controller.LoginUser)
apiv1.Get("/event", controller.ReturnAllEventsPublic) apiv1.Get("/event", controller.ReturnAllEventsPublic)
apiv1.Get("/ping", controller.Ping) apiv1.Get("/ping", controller.Ping)

View file

@ -2,6 +2,7 @@ package service
import ( import (
"errors" "errors"
"fmt"
"gorm.io/gorm" "gorm.io/gorm"
"ulmer-furs.de/pretix-proxy/v2/config" "ulmer-furs.de/pretix-proxy/v2/config"
@ -46,7 +47,7 @@ func GetAttendiesByEvent(event entities.Db_Event) ([]entities.Db_Attendies, erro
func GetAttendiesByEventPrivacy(event entities.Db_Event, privacy bool) (entities.AttendiesList, error) { func GetAttendiesByEventPrivacy(event entities.Db_Event, privacy bool) (entities.AttendiesList, error) {
var attendies []entities.Db_Attendies var attendies []entities.Db_Attendies
result := config.Database.Model(&entities.Db_Attendies{}).Preload("Event").Preload("Role").Where("event_id = ?", event.ID).Where("privacy = ?", privacy).Find(&attendies) result := config.Database.Model(&entities.Db_Attendies{}).Preload("Role").Where("event_id = ?", event.ID).Where("privacy = ?", privacy).Find(&attendies)
if result.Error != nil { if result.Error != nil {
return attendies, result.Error return attendies, result.Error
} }
@ -54,6 +55,11 @@ func GetAttendiesByEventPrivacy(event entities.Db_Event, privacy bool) (entities
} }
func CreateNewAttendie(attendie entities.Db_Attendies) error { func CreateNewAttendie(attendie entities.Db_Attendies) error {
if attendie.Privacy {
fmt.Println("Privacy activated")
} else {
fmt.Println("Noone needs privacy")
}
result := config.Database.Create(&attendie) result := config.Database.Create(&attendie)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error

View file

@ -100,16 +100,16 @@ func GetAttendieListFromPretixJson(pretixEvent entities.Pretix_Event, event enti
return attendies return attendies
} }
func GetAttendiesFromPretixJsonWithRoleQuestion(pretixEvent *entities.Pretix_Event, event *entities.Db_Event) ([]entities.Db_Attendies, error) { func GetAttendiesFromPretixJsonWithRoleQuestion(pretixEvent *entities.Pretix_Event, event *entities.Db_Event) (entities.AttendiesList, error) {
var attendies entities.AttendiesList var attendies entities.AttendiesList
for _, order := range pretixEvent.Results { for _, order := range pretixEvent.Results {
if order.Status == "c" || order.Status == "e" { if order.Status == "c" || order.Status == "e" {
continue continue
} }
var attendie entities.Db_Attendies var attendie entities.Db_Attendies
attendie.Event = *event attendie.Event = event
if event.ItemIdParticipation == nil { if event.ItemIdParticipation == nil {
return attendies, errors.New("no participation found") return attendies, errors.New("event has no ItemIdParticipation")
} }
indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdParticipation }) indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdParticipation })
if indexParticipation == -1 { if indexParticipation == -1 {
@ -160,16 +160,16 @@ func GetAttendiesFromPretixJsonWithRoleQuestion(pretixEvent *entities.Pretix_Eve
return attendies, nil return attendies, nil
} }
func GetAttendiesFromPretixJsonWithRoleProduct(pretixEvent *entities.Pretix_Event, event *entities.Db_Event) ([]entities.Db_Attendies, error) { func GetAttendiesFromPretixJsonWithRoleProduct(pretixEvent *entities.Pretix_Event, event *entities.Db_Event) (entities.AttendiesList, error) {
var attendies entities.AttendiesList var attendies entities.AttendiesList
for _, order := range pretixEvent.Results { for _, order := range pretixEvent.Results {
if order.Status == "c" || order.Status == "e" { if order.Status == "c" || order.Status == "e" {
continue continue
} }
var attendie entities.Db_Attendies var attendie entities.Db_Attendies
attendie.Event = *event attendie.Event = event
if event.ItemIdParticipation == nil { if event.ItemIdParticipation == nil {
return attendies, errors.New("no participation found") return attendies, errors.New("event has no ItemIdParticipation")
} }
indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdParticipation }) indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdParticipation })
if event.ItemIdRestaurant == nil { if event.ItemIdRestaurant == nil {
@ -215,3 +215,55 @@ func GetAttendiesFromPretixJsonWithRoleProduct(pretixEvent *entities.Pretix_Even
MarkWatingListAttendies(&attendies, (*event).SuiterPerSpotter, suiter, spotter, specialAnimal) MarkWatingListAttendies(&attendies, (*event).SuiterPerSpotter, suiter, spotter, specialAnimal)
return attendies, nil return attendies, nil
} }
func GetAttendiesFromPretixJsonWithSeperateSubProducts(pretixEvent *entities.Pretix_Event, event *entities.Db_Event) (entities.AttendiesList, error) {
var attendies entities.AttendiesList
for _, order := range pretixEvent.Results {
if order.Status == "c" || order.Status == "e" {
continue
}
var attendie entities.Db_Attendies
attendie.Event = event
if event.ItemIdParticipation == nil {
return attendies, errors.New("event has no ItemIdParticipation")
}
indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdParticipation })
if event.ItemIdRestaurant == nil {
attendie.AttendsRestaurant = false
} else {
indexRestaurant := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdRestaurant })
if indexRestaurant != -1 {
attendie.AttendsRestaurant = true
} else {
attendie.AttendsRestaurant = false
}
}
if event.ItemIdBar == nil {
attendie.AttendsBar = false
} else {
indexBar := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdRestaurant })
if indexBar != -1 {
attendie.AttendsBar = true
} else {
attendie.AttendsBar = false
}
}
indexName := slices.IndexFunc(order.Positions[indexParticipation].Answers, func(a entities.Pretix_Answer) bool { return a.QuestionsIdentififer == *event.QuestionIdName })
indexPrivacy := slices.IndexFunc(order.Positions[indexParticipation].Answers, func(a entities.Pretix_Answer) bool { return a.QuestionsIdentififer == *event.QuestionIdPrivacy })
attendie.Nickname = order.Positions[indexParticipation].Answers[indexName].Answer
var err error
attendie.Privacy, err = strconv.ParseBool(order.Positions[indexParticipation].Answers[indexPrivacy].Answer)
if attendie.Privacy {
fmt.Println("Yey, privacy")
} else {
fmt.Println("no privacy")
}
if err != nil {
return attendies, err
}
attendies = append(attendies, attendie)
}
fmt.Printf("%+v", attendies)
return attendies, nil
}

View file

@ -9,7 +9,11 @@
<body> <body>
<main> <main>
<h1 class="textWhite">{{.Title}}</h1> <h1 class="textWhite">{{.Title}}</h1>
{{template "table" .}} {{ if eq .EventType "Suitwalk" }}
{{template "suitwalk" .}}
{{ else if eq .EventType "RegularsTable" }}
{{ template "regularstable" .}}
{{ end }}
</main> </main>
</body> </body>
</html> </html>

View file

@ -0,0 +1,32 @@
{{ define "regularstable" }}
<h1 class="textWhite">{{ .EventName }} {{ .Locals.Attendie }}</h1>
<h2 class="textWhite">{{ .Locals.Registered }}</h2>
<table>
<thead>
<tr class="tableHeading">
<th>{{ .Locals.Name }}</th>
<th>{{ .Locals.Restaurant }}</th>
<th>{{ .Locals.AfterParty }}</th>
</tr>
</thead>
<tbody>
{{range $suiter := .Attendies }}
{{if not $suiter.OnWaitingList }}
<tr>
<td>{{ $suiter.Nickname }}</td>
{{ if $suiter.AttendsRestaurant }}
<td class="tdgreen">✓ {{ $.Locals.Yes }}</td>
{{ else }}
<td class="tdred">❌ {{ $.Locals.No }}</td>
{{ end }}
{{ if $suiter.AttendsBar }}
<td class="tdgreen">✓ {{ $.Locals.Yes }}</td>
{{ else }}
<td class="tdred">❌ {{ $.Locals.No }}</td>
{{ end }}
</tr>
{{end}}
{{end}}
</tbody>
</table>
{{end}}

View file

@ -1,5 +1,5 @@
{{define "table"}} {{define "suitwalk"}}
<h1 class="textWhite">{{ index . "Event Name" }} {{ .Locals.Attendie }}</h1> <h1 class="textWhite">{{ .EventName }} {{ .Locals.Attendie }}</h1>
<h2 class="textWhite">{{ .Locals.Registered }}</h2> <h2 class="textWhite">{{ .Locals.Registered }}</h2>
<table> <table>
<thead> <thead>

View file

@ -89,4 +89,9 @@ var defaultMessages = []i18n.Message{
ID: "No", ID: "No",
Other: "No", Other: "No",
}, },
{
ID: "AfterParty",
One: "AfterParty",
Other: "AfterParties",
},
} }

View file

@ -24,11 +24,12 @@ type Db_Attendies struct {
gorm.Model gorm.Model
Nickname string `gorm:"column:nickname;not null"` Nickname string `gorm:"column:nickname;not null"`
EventID int `gorm:"not null"` EventID int `gorm:"not null"`
Event Db_Event Event *Db_Event
RoleID int `gorm:"not null"` RoleID int `gorm:""`
Role *Role Role *Role
AttendsRestaurant bool `gorm:"column:attends_restaurant;not null"` AttendsRestaurant bool `gorm:"column:attends_restaurant;not null;default:false"`
Privacy bool `gorm:"column:privacy;not null"` AttendsBar bool `gorm:"attends_restaurant;not null;default:false"`
Privacy bool `gorm:"column:privacy;not null;default:false"`
RegistrationTime time.Time `gorm:"column:registration_time;not null;default:CURRENT_TIMESTAMP"` RegistrationTime time.Time `gorm:"column:registration_time;not null;default:CURRENT_TIMESTAMP"`
OnWaitingList bool `gorm:"column:on_wating_list;not null;default:false"` OnWaitingList bool `gorm:"column:on_wating_list;not null;default:false"`
} }

View file

@ -11,6 +11,7 @@ type Db_Event struct {
Event *string `gorm:"column:event;not null" validate:"required"` Event *string `gorm:"column:event;not null" validate:"required"`
ItemIdBadge *int `gorm:"column:item_id_badge"` ItemIdBadge *int `gorm:"column:item_id_badge"`
ItemIdRestaurant *int `gorm:"column:item_id_restaurant"` ItemIdRestaurant *int `gorm:"column:item_id_restaurant"`
ItemIdBar *int `gorm:"column:item_id_bar"`
ItemIdParticipation *int `gorm:"column:item_id_participation"` ItemIdParticipation *int `gorm:"column:item_id_participation"`
ItemIdRole *int `gorm:"column:item_id_role"` ItemIdRole *int `gorm:"column:item_id_role"`
QuestionIdRole *string `gorm:"column:question_id_role"` QuestionIdRole *string `gorm:"column:question_id_role"`
@ -27,7 +28,7 @@ type Db_Event struct {
VariationIdPhotograph *int `gorm:"variation_id_photograph"` VariationIdPhotograph *int `gorm:"variation_id_photograph"`
VariationIdSpecialAnimal *int `gorm:"variation_id_special_animal"` VariationIdSpecialAnimal *int `gorm:"variation_id_special_animal"`
EventType *string `gorm:"cloumn:event_type;not null" validate:"required"` EventType *string `gorm:"cloumn:event_type;not null" validate:"required"`
SuiterPerSpotter *int `gorm:"column:suiter_per_spotter;not null;default:5" validate:"required"` SuiterPerSpotter *int `gorm:"column:suiter_per_spotter;not null;default:5"`
} }
type Db_Event_Public struct { type Db_Event_Public struct {

View file

@ -9,7 +9,9 @@ require (
github.com/golang-jwt/jwt/v5 v5.1.0 github.com/golang-jwt/jwt/v5 v5.1.0
github.com/jinzhu/copier v0.4.0 github.com/jinzhu/copier v0.4.0
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
github.com/nicksnyder/go-i18n/v2 v2.4.0
golang.org/x/crypto v0.15.0 golang.org/x/crypto v0.15.0
golang.org/x/text v0.14.0
gorm.io/driver/sqlite v1.5.3 gorm.io/driver/sqlite v1.5.3
gorm.io/gorm v1.25.4 gorm.io/gorm v1.25.4
) )
@ -20,9 +22,7 @@ require (
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/leodido/go-urn v1.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
golang.org/x/net v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect
golang.org/x/text v0.14.0 // indirect
) )
require ( require (

View file

@ -1,4 +1,9 @@
{ {
"AfterParty": {
"hash": "sha1-78064d491b346faba9074905e42300788f3b2de7",
"one": "AfterStammi",
"other": "AfterStammis"
},
"Attendie": { "Attendie": {
"hash": "sha1-4c29d6c952ccd2b114d1792c7b18fa7f7052ebed", "hash": "sha1-4c29d6c952ccd2b114d1792c7b18fa7f7052ebed",
"one": "Teilnehmer*in", "one": "Teilnehmer*in",
@ -32,9 +37,9 @@
"other": "Angemeldet" "other": "Angemeldet"
}, },
"Restaurant": { "Restaurant": {
"hash": "sha1-2b8fd2cb645ab1f1b09fbecda98978ec3518a9d9", "hash": "sha1-b19c390d03b991e33ecbb225687fcaf21da87a89",
"one": "Restaurant", "one": "Restaurant",
"other": "Restaurnts" "other": "Restaurants"
}, },
"Role": { "Role": {
"hash": "sha1-47dcc27d6e87ece8baebe7e3877a261a5467093d", "hash": "sha1-47dcc27d6e87ece8baebe7e3877a261a5467093d",

View file

@ -1,4 +1,8 @@
{ {
"AfterParty": {
"one": "AfterParty",
"other": "AfterParties"
},
"Attendie": { "Attendie": {
"one": "Attendie", "one": "Attendie",
"other": "Attendies" "other": "Attendies"
@ -20,7 +24,7 @@
"Registered": "Registered", "Registered": "Registered",
"Restaurant": { "Restaurant": {
"one": "Restaurant", "one": "Restaurant",
"other": "Restaurnts" "other": "Restaurantes"
}, },
"Role": { "Role": {
"one": "Role", "one": "Role",