package controllers import ( "errors" "fmt" "strconv" "git.readonly.ch/bouzoure/pop-camarades/helpers" "git.readonly.ch/bouzoure/pop-camarades/models" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) type PersonValidation struct { LastName string `validate:"required,min=1,max=100"` FirstName string `validate:"required,min=1,max=100"` Email string `validate:"max=100,email"` Phone string `validate:"max=100"` Mobile string `validate:"max=100"` Address1 string `validate:"max=100"` Address2 string `validate:"max=100"` PostalCode string `validate:"min=4,max=4,number"` City string `validate:"max=100"` Section string `validate:"required,number"` } func Members(c *fiber.Ctx) error { db, err := helpers.GetDatabase() if err != nil { return err } var people []models.Person result := db.Order( "last_name collate nocase asc, first_name collate nocase asc", ).Preload("Section").Find( &people, "is_member = ?", true, ) if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { return err } return c.Render("people", fiber.Map{ "PageTitle": "Membres", "MembersPage": true, "People": people, }) } func MemberShow(c *fiber.Ctx) error { id := c.Params("id") db, err := helpers.GetDatabase() if err != nil { return err } var person models.Person result := db.Unscoped().Preload("Section").Find( &person, "id = ? AND is_member", id, true, ) if result.RowsAffected < 1 { return fiber.NewError(fiber.StatusNotFound, "Not found") } if result.Error != nil { return result.Error } title := fmt.Sprintf( "%s %s | Membre", person.LastName, person.FirstName, ) return c.Render("person", fiber.Map{ "PageTitle": title, "Person": person, }) } func MemberAdd(c *fiber.Ctx) error { var person models.Person var errors []string db, err := helpers.GetDatabase() if err != nil { return err } var sections []models.Section db.Order("name collate nocase asc").Find( §ions, "contains_members = ?", true, ) if c.Method() == "POST" { data := PersonValidation{ LastName: c.FormValue("last_name"), FirstName: c.FormValue("first_name"), Email: c.FormValue("email"), Phone: c.FormValue("phone"), Mobile: c.FormValue("mobile"), Address1: c.FormValue("address1"), Address2: c.FormValue("address2"), PostalCode: c.FormValue("postal_code"), City: c.FormValue("city"), Section: c.FormValue("section"), } validate := validator.New() validErrs := validate.Struct(data) if validErrs != nil { for _, validErr := range validErrs.(validator.ValidationErrors) { switch validErr.Field() { case "LastName": errors = append(errors, "Le nom de famille est requis et ne peut pas contenir plus de 100 caractères") case "FirstName": errors = append(errors, "Le prénom est requis et ne peut pas contenir plus de 100 caractères") case "Email": if len(data.Email) > 0 { errors = append(errors, "L'adresse email doit être valide") } case "Phone": errors = append(errors, "Le numéro de téléphone fixe est trop long") case "Mobile": errors = append(errors, "Le numéro de téléphone mobile est trop long") case "Address1": errors = append(errors, "La ligne 1 de l'adresse est trop longue") case "Address2": errors = append(errors, "La ligne 2 de l'adresse est trop longue") case "PostalCode": if len(data.PostalCode) > 0 { errors = append(errors, "Le code postal n'est pas valide") } case "City": errors = append(errors, "Le lieu est trop long") case "Section": errors = append(errors, "La section n'est pas valide") } } } person.IsContact = false person.IsMember = true person.LastName = data.LastName person.FirstName = data.FirstName person.Email = data.Email person.Phone = data.Phone person.Mobile = data.Mobile person.Address1 = data.Address1 person.Address2 = data.Address2 person.PostalCode = data.PostalCode person.City = data.City sectionID, err := strconv.ParseUint(data.Section, 10, 0) if err == nil { for _, section := range sections { if section.ID == uint(sectionID) { person.SectionID = uint(sectionID) break } } } if person.SectionID == 0 { errors = append(errors, "La section est introuvable") } if len(errors) == 0 { result := db.Create(&person) if result.Error != nil { return result.Error } else { c.Redirect(fmt.Sprintf( "/members/%d", person.ID, )) } } } return c.Render("person_form", fiber.Map{ "PageTitle": "Ajouter un membre", "Person": person, "Sections": sections, "Errors": errors, }) } func MemberEdit(c *fiber.Ctx) error { id := c.Params("id") db, err := helpers.GetDatabase() if err != nil { return err } var person models.Person result := db.Find(&person, "id = ?", id) if errors.Is(result.Error, gorm.ErrRecordNotFound) { return fiber.NewError(fiber.StatusNotFound, "Not found") } if result.Error != nil { return result.Error } title := fmt.Sprintf( "%s %s | Modifier membre", person.LastName, person.LastName, ) var sections []models.Section db.Order("name collate nocase asc").Find( §ions, "contains_members = ?", true, ) var errors []string if c.Method() == "POST" { data := PersonValidation{ LastName: c.FormValue("last_name"), FirstName: c.FormValue("first_name"), Email: c.FormValue("email"), Phone: c.FormValue("phone"), Mobile: c.FormValue("mobile"), Address1: c.FormValue("address1"), Address2: c.FormValue("address2"), PostalCode: c.FormValue("postal_code"), City: c.FormValue("city"), Section: c.FormValue("section"), } validate := validator.New() validErrs := validate.Struct(data) if validErrs != nil { for _, validErr := range validErrs.(validator.ValidationErrors) { switch validErr.Field() { case "LastName": errors = append(errors, "Le nom de famille est requis et ne peut pas contenir plus de 100 caractères") case "FirstName": errors = append(errors, "Le prénom est requis et ne peut pas contenir plus de 100 caractères") case "Email": if len(data.Email) > 0 { errors = append(errors, "L'adresse email doit être valide") } case "Phone": errors = append(errors, "Le numéro de téléphone fixe est trop long") case "Mobile": errors = append(errors, "Le numéro de téléphone mobile est trop long") case "Address1": errors = append(errors, "La ligne 1 de l'adresse est trop longue") case "Address2": errors = append(errors, "La ligne 2 de l'adresse est trop longue") case "PostalCode": if len(data.PostalCode) > 0 { errors = append(errors, "Le code postal n'est pas valide") } case "City": errors = append(errors, "Le lieu est trop long") case "Section": errors = append(errors, "La section n'est pas valide") } } } person.IsContact = false person.IsMember = true person.LastName = data.LastName person.FirstName = data.FirstName person.Email = data.Email person.Phone = data.Phone person.Mobile = data.Mobile person.Address1 = data.Address1 person.Address2 = data.Address2 person.PostalCode = data.PostalCode person.City = data.City sectionID, err := strconv.ParseUint(data.Section, 10, 0) if err == nil { for _, section := range sections { if section.ID == uint(sectionID) { person.SectionID = uint(sectionID) break } } } if person.SectionID == 0 { errors = append(errors, "La section est introuvable") } if len(errors) == 0 { result := db.Save(&person) if result.Error != nil { return result.Error } else { c.Redirect(fmt.Sprintf( "/members/%d", person.ID, )) } } } return c.Render("person_form", fiber.Map{ "PageTitle": title, "Person": person, "Sections": sections, "Errors": errors, }) } func MemberConvert(c *fiber.Ctx) error { id := c.Params("id") db, err := helpers.GetDatabase() if err != nil { return err } var person models.Person result := db.Find(&person, "id = ?", id) if errors.Is(result.Error, gorm.ErrRecordNotFound) { return fiber.NewError(fiber.StatusNotFound, "Not found") } if result.Error != nil { return result.Error } person.IsContact = true person.IsMember = false result = db.Save(&person) if result.Error != nil { return result.Error } return c.Redirect(fmt.Sprintf( "/contacts/%d", person.ID, )) } func MemberArchive(c *fiber.Ctx) error { id := c.Params("id") db, err := helpers.GetDatabase() if err != nil { return err } result := db.Delete(&models.Person{}, id) if result.Error != nil { return result.Error } return c.Redirect(fmt.Sprintf( "/members/%s", id, )) } func MemberRestore(c *fiber.Ctx) error { id := c.Params("id") db, err := helpers.GetDatabase() if err != nil { return err } result := db.Unscoped().Model(&models.Person{}).Where( "id = ?", id, ).Update("DeletedAt", nil) if result.Error != nil { return result.Error } return c.Redirect(fmt.Sprintf( "/members/%s", id, )) } func MemberPurge(c *fiber.Ctx) error { id := c.Params("id") db, err := helpers.GetDatabase() if err != nil { return err } result := db.Unscoped().Delete( &models.Person{}, id, ) if result.Error != nil { return result.Error } return c.Redirect("/members") }