1208 lines
27 KiB
Go
1208 lines
27 KiB
Go
package controllers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.readonly.ch/bouzoure/pop-camarades/helpers"
|
|
"git.readonly.ch/bouzoure/pop-camarades/helpers/database"
|
|
"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:"max=100"`
|
|
FirstName string `validate:"required,min=1,max=100"`
|
|
Email string `validate:"max=100"`
|
|
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 {
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allowedSections, err := helpers.PermissionsGetSections(
|
|
userid, "show_member",
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allowedSectionsArchived, err := helpers.PermissionsGetSections(
|
|
userid, "show_archived_member",
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
permShow := (len(allowedSections) > 0)
|
|
permShowArchived := (len(allowedSectionsArchived) > 0)
|
|
|
|
if !permShow && !permShowArchived {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
db, err := helpers.GetDatabase()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
/*sqlFilterSections := allowedSections
|
|
sqlFilterAppend := "IS NULL"
|
|
if filterArchive == "1" {
|
|
sqlFilterAppend = "IS NOT NULL"
|
|
sqlFilterSections = allowedSectionsArchived
|
|
}
|
|
|
|
var filterSectionUint uint
|
|
if len(filterSection) > 0 {
|
|
filterSectionUint64, err := strconv.ParseUint(filterSection, 10, 0)
|
|
if err == nil {
|
|
for _, s := range sqlFilterSections {
|
|
if s == uint(filterSectionUint64) {
|
|
filterSectionUint = uint(filterSectionUint64)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if filterSectionUint > 0 {
|
|
sqlFilterAppend = fmt.Sprintf(
|
|
"%s AND section_id = %d",
|
|
sqlFilterAppend,
|
|
filterSectionUint,
|
|
)
|
|
}
|
|
|
|
var sqlFilterSearch string
|
|
if len(filterSearch) > 0 {
|
|
sqlFilterSearch = fmt.Sprintf(
|
|
"%%%s%%", filterSearch,
|
|
)
|
|
}
|
|
|
|
var count int64
|
|
if len(filterSearch) > 0 {
|
|
db.Model(&models.Person{}).Where(
|
|
fmt.Sprintf(
|
|
"is_member = ? AND section_id IN ? AND (first_name LIKE ? OR last_name LIKE ?) AND deleted_at %s",
|
|
sqlFilterAppend,
|
|
),
|
|
true, allowedSections, sqlFilterSearch, sqlFilterSearch,
|
|
).Count(&count)
|
|
} else {
|
|
db.Model(&models.Person{}).Where(
|
|
fmt.Sprintf(
|
|
"is_member = ? AND section_id IN ? AND deleted_at %s",
|
|
sqlFilterAppend,
|
|
),
|
|
true, allowedSections,
|
|
).Count(&count)
|
|
}
|
|
|
|
var people []models.Person
|
|
if len(filterSearch) > 0 {
|
|
result := db.Unscoped().Offset(
|
|
pagination.Offset,
|
|
).Limit(
|
|
pagination.PageSize,
|
|
).Order(
|
|
"concat(last_name, first_name) collate nocase asc",
|
|
).Preload(
|
|
"Section",
|
|
).Find(
|
|
&people,
|
|
fmt.Sprintf(
|
|
"is_member = ? AND section_id IN ? AND (first_name LIKE ? OR last_name LIKE ?) AND deleted_at %s",
|
|
sqlFilterAppend,
|
|
),
|
|
true, sqlFilterSections, sqlFilterSearch, sqlFilterSearch,
|
|
)
|
|
|
|
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
} else {
|
|
result := db.Unscoped().Offset(
|
|
pagination.Offset,
|
|
).Limit(
|
|
pagination.PageSize,
|
|
).Order(
|
|
"concat(last_name, first_name) collate nocase asc",
|
|
).Preload(
|
|
"Section",
|
|
).Find(
|
|
&people,
|
|
fmt.Sprintf(
|
|
"is_member = ? AND section_id IN ? AND deleted_at %s",
|
|
sqlFilterAppend,
|
|
),
|
|
true, sqlFilterSections,
|
|
)
|
|
|
|
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
}*/
|
|
|
|
/*var sections []models.Section
|
|
db.Order(
|
|
"name collate nocase asc",
|
|
).Find(
|
|
§ions,
|
|
"contains_members = ? AND id IN ?",
|
|
true, sqlFilterSections,
|
|
)*/
|
|
|
|
searchJSON := c.Query("s")
|
|
var params database.PeopleSearchParams
|
|
|
|
if len(searchJSON) > 0 {
|
|
err = json.Unmarshal([]byte(searchJSON), ¶ms)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
page, _ := strconv.Atoi(c.Query("p"))
|
|
|
|
results, err := database.PeopleSearch(params, "members", 50, page)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var sections []models.Section
|
|
db.Order("name collate nocase asc").Find(§ions, "contains_members = ?", true)
|
|
|
|
var fields []models.Field
|
|
db.Order("position asc").Find(&fields, "person_type = ?", "member")
|
|
|
|
return c.Render("people", fiber.Map{
|
|
"PageTitle": "Membres",
|
|
"MembersPage": true,
|
|
"People": results.Results,
|
|
"Pagination": results.Pagination,
|
|
"PermShow": permShow,
|
|
"PermShowArchived": permShowArchived,
|
|
"SearchJSON": searchJSON,
|
|
"Sections": sections,
|
|
"Fields": fields,
|
|
})
|
|
}
|
|
|
|
func MembersExport(c *fiber.Ctx) error {
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allowedSections, err := helpers.PermissionsGetSections(
|
|
userid, "show_member",
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allowedSectionsArchived, err := helpers.PermissionsGetSections(
|
|
userid, "show_archived_member",
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
permShow := (len(allowedSections) > 0)
|
|
permShowArchived := (len(allowedSectionsArchived) > 0)
|
|
|
|
if !permShow && !permShowArchived {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
db, err := helpers.GetDatabase()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filterSection := c.Query("se")
|
|
filterArchive := c.Query("a")
|
|
filterSearch := c.Query("s")
|
|
|
|
sqlFilterSections := allowedSections
|
|
sqlFilterAppend := "IS NULL"
|
|
if filterArchive == "1" {
|
|
sqlFilterAppend = "IS NOT NULL"
|
|
sqlFilterSections = allowedSectionsArchived
|
|
}
|
|
|
|
var filterSectionUint uint
|
|
if len(filterSection) > 0 {
|
|
filterSectionUint64, err := strconv.ParseUint(filterSection, 10, 0)
|
|
if err == nil {
|
|
for _, s := range sqlFilterSections {
|
|
if s == uint(filterSectionUint64) {
|
|
filterSectionUint = uint(filterSectionUint64)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if filterSectionUint > 0 {
|
|
sqlFilterAppend = fmt.Sprintf(
|
|
"%s AND section_id = %d",
|
|
sqlFilterAppend,
|
|
filterSectionUint,
|
|
)
|
|
}
|
|
|
|
var sqlFilterSearch string
|
|
if len(filterSearch) > 0 {
|
|
sqlFilterSearch = fmt.Sprintf(
|
|
"%%%s%%", filterSearch,
|
|
)
|
|
}
|
|
|
|
var people []models.Person
|
|
if len(filterSearch) > 0 {
|
|
result := db.Unscoped().Order(
|
|
"last_name collate nocase asc, first_name collate nocase asc",
|
|
).Preload("Section").Find(
|
|
&people,
|
|
fmt.Sprintf(
|
|
"is_member = ? AND section_id IN ? AND (first_name LIKE ? OR last_name LIKE ?) AND deleted_at %s",
|
|
sqlFilterAppend,
|
|
),
|
|
true, sqlFilterSections, sqlFilterSearch, sqlFilterSearch,
|
|
)
|
|
|
|
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
} else {
|
|
result := db.Unscoped().Order(
|
|
"last_name collate nocase asc, first_name collate nocase asc",
|
|
).Preload("Section").Find(
|
|
&people,
|
|
fmt.Sprintf(
|
|
"is_member = ? AND section_id IN ? AND deleted_at %s",
|
|
sqlFilterAppend,
|
|
),
|
|
true, sqlFilterSections,
|
|
)
|
|
|
|
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
}
|
|
|
|
var fields []models.Field
|
|
db.Order("position asc").Preload(
|
|
"List",
|
|
).Find(
|
|
&fields, "person_type = ?", "member",
|
|
)
|
|
|
|
var fieldValues []models.FieldValue
|
|
db.Preload("ListItem").Find(&fieldValues)
|
|
|
|
c.Set("Content-Type", "text/csv")
|
|
c.Set("Content-Disposition", fmt.Sprintf(
|
|
"attachment;filename=members_%s.csv",
|
|
time.Now().Format(time.RFC3339),
|
|
))
|
|
|
|
csvFields := []string{
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"phone",
|
|
"mobile",
|
|
"address1",
|
|
"address2",
|
|
"postal_code",
|
|
"city",
|
|
"section_id",
|
|
"section_name",
|
|
}
|
|
|
|
for _, field := range fields {
|
|
csvFields = append(csvFields, field.Name)
|
|
}
|
|
|
|
for key, csvField := range csvFields {
|
|
csvField = strings.ReplaceAll(csvField, "\r", "")
|
|
csvField = strings.ReplaceAll(csvField, "\n", " ")
|
|
csvField = strings.ReplaceAll(csvField, ",", "_")
|
|
csvField = strings.ReplaceAll(csvField, ";", "_")
|
|
|
|
if key+1 == len(csvFields) {
|
|
c.Writef("\"%s\"\n", csvField)
|
|
} else {
|
|
c.Writef("\"%s\";", csvField)
|
|
}
|
|
}
|
|
|
|
for _, person := range people {
|
|
c.Writef("\"%s\";", person.FirstName)
|
|
c.Writef("\"%s\";", person.LastName)
|
|
c.Writef("\"%s\";", person.Email)
|
|
c.Writef("\"%s\";", person.Phone)
|
|
c.Writef("\"%s\";", person.Mobile)
|
|
c.Writef("\"%s\";", person.Address1)
|
|
c.Writef("\"%s\";", person.Address2)
|
|
c.Writef("\"%s\";", person.PostalCode)
|
|
c.Writef("\"%s\";", person.City)
|
|
c.Writef("\"%d\";", person.SectionID)
|
|
|
|
if len(fields) > 0 {
|
|
c.Writef("\"%s\";", person.Section.Name)
|
|
} else {
|
|
c.Writef("\"%s\"\n", person.Section.Name)
|
|
}
|
|
|
|
for key, field := range fields {
|
|
endLine := ";"
|
|
if key+1 == len(fields) {
|
|
endLine = "\n"
|
|
}
|
|
|
|
countMulti := 0
|
|
found := false
|
|
for _, value := range fieldValues {
|
|
if value.FieldID == field.ID && value.PersonID == person.ID {
|
|
found = true
|
|
|
|
if field.FieldType == "text" || field.FieldType == "longtext" {
|
|
|
|
text := value.ValueString.String
|
|
text = strings.ReplaceAll(text, "\r", "")
|
|
text = strings.ReplaceAll(text, "\n", " ")
|
|
text = strings.ReplaceAll(text, ",", "_")
|
|
text = strings.ReplaceAll(text, ";", "_")
|
|
|
|
c.Writef("\"%s\"%s", text, endLine)
|
|
|
|
} else if field.FieldType == "number" {
|
|
|
|
if value.ValueInt.Valid {
|
|
c.Writef("\"%d\"%s", value.ValueInt.Int64, endLine)
|
|
} else {
|
|
c.Writef("\"\"%s", endLine)
|
|
}
|
|
|
|
} else if field.FieldType == "date" {
|
|
|
|
if value.ValueDate.Valid {
|
|
date := value.ValueDate.Time.Format("2006-01-02")
|
|
c.Writef("\"%s\"%s", date, endLine)
|
|
} else {
|
|
c.Writef("\"\"%s", endLine)
|
|
}
|
|
|
|
} else if field.FieldType == "list" {
|
|
|
|
if field.List.Multi {
|
|
|
|
if countMulti == 0 {
|
|
c.Writef("\"")
|
|
} else {
|
|
c.Writef(",")
|
|
}
|
|
|
|
c.Writef("%s", value.ListItem.Value)
|
|
countMulti++
|
|
|
|
} else {
|
|
c.Writef("\"%s\"%s", value.ListItem.Value, endLine)
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if countMulti > 0 {
|
|
c.Writef("\"%s", endLine)
|
|
}
|
|
|
|
if !found {
|
|
c.Writef("\"\"%s", endLine)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
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.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
if result.RowsAffected < 1 {
|
|
return fiber.NewError(fiber.StatusNotFound, "Not found")
|
|
}
|
|
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
persmissionName := "show_member"
|
|
if person.DeletedAt.Valid {
|
|
persmissionName = "show_archived_member"
|
|
}
|
|
|
|
allow, err := helpers.PermissionsCheckSection(
|
|
userid, persmissionName, person.SectionID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !allow {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
title := fmt.Sprintf("%s | Membre", person.FirstName)
|
|
if person.LastName != "" {
|
|
title = fmt.Sprintf("%s %s", person.LastName, title)
|
|
}
|
|
|
|
var fields []models.Field
|
|
db.Order("position asc").Preload(
|
|
"List",
|
|
).Find(
|
|
&fields, "person_type = ?", "member",
|
|
)
|
|
|
|
var fieldValues []models.FieldValue
|
|
db.Preload("ListItem").Find(
|
|
&fieldValues,
|
|
"person_id = ?",
|
|
person.ID,
|
|
)
|
|
|
|
permEdit, _ := helpers.PermissionsGetSections(userid, "edit_member")
|
|
permConvert, _ := helpers.PermissionsGetSections(userid, "convert_member_to_contact")
|
|
permArchive, _ := helpers.PermissionsGetSections(userid, "archive_member")
|
|
permRestore, _ := helpers.PermissionsGetSections(userid, "restore_member")
|
|
permPurge, _ := helpers.PermissionsGetSections(userid, "purge_member")
|
|
|
|
return c.Render("person", fiber.Map{
|
|
"PageTitle": title,
|
|
"Person": person,
|
|
"Fields": fields,
|
|
"FieldValues": fieldValues,
|
|
"PermEdit": permEdit,
|
|
"PermConvert": permConvert,
|
|
"PermArchive": permArchive,
|
|
"PermRestore": permRestore,
|
|
"PermPurge": permPurge,
|
|
})
|
|
}
|
|
|
|
func MemberAdd(c *fiber.Ctx) error {
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allowedSections, err := helpers.PermissionsGetSections(
|
|
userid, "create_member",
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(allowedSections) < 1 {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
db, err := helpers.GetDatabase()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var sections []models.Section
|
|
db.Order("name collate nocase asc").Find(
|
|
§ions,
|
|
"contains_members = ?",
|
|
true,
|
|
)
|
|
|
|
var fields []models.Field
|
|
db.Preload("List").Preload("List.ListItems").Order(
|
|
"position asc",
|
|
).Find(
|
|
&fields, "person_type = ?", "member",
|
|
)
|
|
|
|
var person models.Person
|
|
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 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":
|
|
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
|
|
}
|
|
|
|
for _, field := range fields {
|
|
if field.List.Multi {
|
|
for _, listItem := range field.List.ListItems {
|
|
key := fmt.Sprintf("field-%d-%d", field.ID, listItem.ID)
|
|
value := c.FormValue(key)
|
|
|
|
if value == "on" {
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
fieldValue.ListItemID = listItem.ID
|
|
db.Create(&fieldValue)
|
|
}
|
|
}
|
|
} else {
|
|
key := fmt.Sprintf("field-%d", field.ID)
|
|
value := c.FormValue(key)
|
|
|
|
if (field.FieldType == "text" || field.FieldType == "longtext") && len(value) > 0 {
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
|
|
err = fieldValue.ValueString.Scan(value)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
db.Create(&fieldValue)
|
|
}
|
|
|
|
if field.FieldType == "number" && len(value) > 0 {
|
|
valueInt, err := strconv.ParseInt(value, 10, 0)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
|
|
err = fieldValue.ValueInt.Scan(valueInt)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
db.Create(&fieldValue)
|
|
}
|
|
|
|
if field.FieldType == "date" && len(value) > 0 {
|
|
valueDate, err := time.Parse("2006-01-02", value)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
|
|
err = fieldValue.ValueDate.Scan(valueDate)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
db.Create(&fieldValue)
|
|
}
|
|
|
|
if field.FieldType == "list" && len(value) > 0 {
|
|
valueInt, err := strconv.ParseUint(value, 10, 0)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
found := false
|
|
for _, listItem := range field.List.ListItems {
|
|
if listItem.ID == uint(valueInt) {
|
|
found = true
|
|
}
|
|
}
|
|
|
|
if found {
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
fieldValue.ListItemID = uint(valueInt)
|
|
db.Create(&fieldValue)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
c.Redirect(fmt.Sprintf(
|
|
"/members/%d",
|
|
person.ID,
|
|
))
|
|
}
|
|
}
|
|
|
|
return c.Render("person_form", fiber.Map{
|
|
"PageTitle": "Ajouter un membre",
|
|
"MembersPage": true,
|
|
"Person": person,
|
|
"Sections": sections,
|
|
"Fields": fields,
|
|
"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 result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
if result.RowsAffected < 1 {
|
|
return fiber.NewError(fiber.StatusNotFound, "Not found")
|
|
}
|
|
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allow, err := helpers.PermissionsCheckSection(
|
|
userid, "edit_member", person.SectionID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !allow {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
title := fmt.Sprintf("%s | Modifier membre", person.FirstName)
|
|
if person.LastName != "" {
|
|
title = fmt.Sprintf("%s %s", person.LastName, title)
|
|
}
|
|
|
|
var sections []models.Section
|
|
db.Order("name collate nocase asc").Find(
|
|
§ions,
|
|
"contains_members = ?",
|
|
true,
|
|
)
|
|
|
|
var fields []models.Field
|
|
db.Preload("List").Preload("List.ListItems").Order(
|
|
"position asc",
|
|
).Find(
|
|
&fields, "person_type = ?", "member",
|
|
)
|
|
|
|
var fieldValues []models.FieldValue
|
|
db.Preload("ListItem").Find(
|
|
&fieldValues,
|
|
"person_id = ?",
|
|
person.ID,
|
|
)
|
|
|
|
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 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":
|
|
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")
|
|
}
|
|
|
|
for _, field := range fields {
|
|
db.Unscoped().Delete(
|
|
&models.FieldValue{},
|
|
"person_id = ? AND field_id = ?",
|
|
person.ID,
|
|
field.ID,
|
|
)
|
|
|
|
if field.List.Multi {
|
|
for _, listItem := range field.List.ListItems {
|
|
key := fmt.Sprintf("field-%d-%d", field.ID, listItem.ID)
|
|
value := c.FormValue(key)
|
|
|
|
if value == "on" {
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
fieldValue.ListItemID = listItem.ID
|
|
db.Create(&fieldValue)
|
|
}
|
|
}
|
|
} else {
|
|
key := fmt.Sprintf("field-%d", field.ID)
|
|
value := c.FormValue(key)
|
|
|
|
if (field.FieldType == "text" || field.FieldType == "longtext") && len(value) > 0 {
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
|
|
err = fieldValue.ValueString.Scan(value)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
db.Create(&fieldValue)
|
|
}
|
|
|
|
if field.FieldType == "number" && len(value) > 0 {
|
|
valueInt, err := strconv.ParseInt(value, 10, 0)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
|
|
err = fieldValue.ValueInt.Scan(valueInt)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
db.Create(&fieldValue)
|
|
}
|
|
|
|
if field.FieldType == "date" && len(value) > 0 {
|
|
valueDate, err := time.Parse("2006-01-02", value)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
|
|
err = fieldValue.ValueDate.Scan(valueDate)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
db.Create(&fieldValue)
|
|
}
|
|
|
|
if field.FieldType == "list" && len(value) > 0 {
|
|
valueInt, err := strconv.ParseUint(value, 10, 0)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
found := false
|
|
for _, listItem := range field.List.ListItems {
|
|
if listItem.ID == uint(valueInt) {
|
|
found = true
|
|
}
|
|
}
|
|
|
|
if found {
|
|
var fieldValue models.FieldValue
|
|
fieldValue.FieldID = field.ID
|
|
fieldValue.PersonID = person.ID
|
|
fieldValue.ListItemID = uint(valueInt)
|
|
db.Create(&fieldValue)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(errors) == 0 {
|
|
result := db.Save(&person)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
c.Redirect(fmt.Sprintf(
|
|
"/members/%d",
|
|
person.ID,
|
|
))
|
|
}
|
|
}
|
|
|
|
return c.Render("person_form", fiber.Map{
|
|
"PageTitle": title,
|
|
"Person": person,
|
|
"Sections": sections,
|
|
"Fields": fields,
|
|
"FieldValues": fieldValues,
|
|
"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 result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
if result.RowsAffected < 1 {
|
|
return fiber.NewError(fiber.StatusNotFound, "Not found")
|
|
}
|
|
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allow, err := helpers.PermissionsCheckSection(
|
|
userid, "convert_member_to_contact", person.SectionID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !allow {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
var person models.Person
|
|
result := db.Find(&person, "id = ? AND is_member = ? AND deleted_at IS NULL", id, true)
|
|
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
if result.RowsAffected < 1 {
|
|
return fiber.NewError(fiber.StatusNotFound, "Not found")
|
|
}
|
|
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allow, err := helpers.PermissionsCheckSection(
|
|
userid, "archive_member", person.SectionID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !allow {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
result = db.Delete(&person)
|
|
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
|
|
}
|
|
|
|
var person models.Person
|
|
result := db.Unscoped().Find(
|
|
&person, "id = ? AND is_member = ? AND deleted_at IS NOT NULL", id, true,
|
|
)
|
|
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
if result.RowsAffected < 1 {
|
|
return fiber.NewError(fiber.StatusNotFound, "Not found")
|
|
}
|
|
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allow, err := helpers.PermissionsCheckSection(
|
|
userid, "restore_member", person.SectionID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !allow {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
person.DeletedAt.Valid = false
|
|
result = db.Save(&person)
|
|
|
|
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
|
|
}
|
|
|
|
var person models.Person
|
|
result := db.Unscoped().Find(
|
|
&person, "id = ? AND is_member = ?", id, true,
|
|
)
|
|
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
if result.RowsAffected < 1 {
|
|
return fiber.NewError(fiber.StatusNotFound, "Not found")
|
|
}
|
|
|
|
userid, err := helpers.GetSessionUserId(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
allow, err := helpers.PermissionsCheckSection(
|
|
userid, "purge_member", person.SectionID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !allow {
|
|
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
|
|
}
|
|
|
|
result = db.Unscoped().Delete(
|
|
&models.FieldValue{}, "person_id = ?", id,
|
|
)
|
|
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
result = db.Unscoped().Delete(
|
|
&models.Person{}, id,
|
|
)
|
|
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
|
|
return c.Redirect("/members")
|
|
}
|