package organization import ( "errors" "strings" "time" "git.ex.umbach.dev/Alex/roese-utils/rsutils" "git.ex.umbach.dev/LMS/libcore/models" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "gorm.io/gorm" "lms.de/backend/modules/database" "lms.de/backend/modules/structs" "lms.de/backend/modules/utils" "lms.de/backend/socketclients" ) func GetOrganizationSettings(c *fiber.Ctx) error { // swagger:operation GET /organization/settings organization getOrganizationSettings // --- // summary: Get settings // consumes: // - application/json // produces: // - application/json // responses: // '200': // description: Settings fetched successfully // schema: // "$ref": "#/definitions/GetOrganizationSettingsResponse" // '400': // description: Invalid request body // '500': // description: Failed to fetch settings var organizationSettings structs.GetOrganizationSettingsResponse if err := database.DB.Model(&models.Organization{}). Select("subdomain", "company_name", "primary_color", "logo_url", "banner_url"). Where("id = ?", c.Locals("organizationId").(string)). First(&organizationSettings).Error; err != nil { return c.SendStatus(fiber.StatusInternalServerError) } return c.JSON(organizationSettings) } func UpdateOrganizationSettings(c *fiber.Ctx) error { // swagger:operation PATCH /organization/settings organization updateOrganizationSettings // --- // summary: Update settings // consumes: // - application/json // produces: // - application/json // parameters: // - name: body // in: body // schema: // "$ref": "#/definitions/GetOrganizationSettingsResponse" // responses: // '200': // description: Settings updated successfully // '400': // description: Invalid request body // '500': // description: Failed to update settings var organizationSettings structs.UpdateOrganizationSettingsRequest if err := c.BodyParser(&organizationSettings); err != nil { return c.SendStatus(fiber.StatusBadRequest) } if err := database.DB.Model(&models.Organization{}).Where("id = ?", c.Locals("organizationId").(string)).Updates(organizationSettings).Error; err != nil { return c.SendStatus(fiber.StatusInternalServerError) } socketclients.BroadcastMessageExceptBrowserTabSession( c.Locals("organizationId").(string), c.Locals("browserTabSession").(string), structs.SendSocketMessage{ Cmd: utils.SendCmdSettingsUpdated, Body: organizationSettings, }, ) return c.JSON(fiber.Map{ "status": "success", }) } func UpdateOrganizationFile(c *fiber.Ctx) error { // swagger:operation POST /organization/file/{type} organization updateOrganizationFiles // --- // summary: Update files // consumes: // - multipart/form-data // produces: // - application/json // parameters: // - name: logo // in: formData // type: file // required: false // - name: banner // in: formData // type: file // required: false // responses: // '200': // description: Files updated successfully // '400': // description: Invalid request body // '500': // description: Failed to update files var params structs.UpdateOrganizationFileParam if err := c.ParamsParser(¶ms); err != nil { return c.SendStatus(fiber.StatusBadRequest) } fileHeader, err := c.FormFile("file") if err != nil { return c.SendStatus(fiber.StatusBadRequest) } if params.Type == "logo" || params.Type == "banner" { if fileHeader.Size > utils.MaxImageSize { return c.SendStatus(fiber.StatusBadRequest) } if !utils.IsFileTypeAllowed(fileHeader.Header.Get("Content-Type"), utils.AcceptedImageFileTypes) { return c.SendStatus(fiber.StatusBadRequest) } } else { return c.SendStatus(fiber.StatusBadRequest) } // get current file organization := models.Organization{} selectField := "logo_url" if params.Type == "banner" { selectField = "banner_url" } if err := database.DB.Model(&models.Organization{ Id: c.Locals("organizationId").(string), }).Select(selectField).First(&organization).Error; err != nil { return c.SendStatus(fiber.StatusInternalServerError) } // delete current file if organization.LogoUrl != "" { utils.DeleteFile(organization.LogoUrl) } if organization.BannerUrl != "" { utils.DeleteFile(organization.BannerUrl) } fileName := uuid.New().String() + "." + strings.Split(fileHeader.Header["Content-Type"][0], "/")[1] databasePath, publicPath := utils.GetFullImagePath(c.Locals("organizationId").(string), "") utils.CreateFolderStructureIfNotExists(publicPath) update := models.Organization{} if params.Type == "logo" { update.LogoUrl = databasePath + fileName } else { update.BannerUrl = databasePath + fileName } if err := database.DB.Model(&models.Organization{}).Where("id = ?", c.Locals("organizationId").(string)).Updates(update).Error; err != nil { return c.SendStatus(fiber.StatusInternalServerError) } if err := c.SaveFile(fileHeader, publicPath+fileName); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to save file", }) } cmdId := utils.SendCmdSettingsUpdatedLogo if params.Type == "banner" { cmdId = utils.SendCmdSettingsUpdatedBanner } newPath := databasePath + fileName socketclients.BroadcastMessageExceptBrowserTabSession( c.Locals("organizationId").(string), c.Locals("browserTabSession").(string), structs.SendSocketMessage{ Cmd: cmdId, Body: newPath, }, ) return c.JSON(fiber.Map{ "Data": newPath, }) } func UpdateSubdomain(c *fiber.Ctx) error { // swagger:operation PATCH /organization/subdomain/{subdomain} organization updateSubdomain // --- // summary: Update organization subdomain // consumes: // - application/json // produces: // - application/json // parameters: // - name: subdomain // in: path // required: true // type: string // responses: // '200': // description: Subdomain updated successfully // '400': // description: Invalid request body // '500': // description: Failed to update subdomain var params structs.SubdomainParam if err := rsutils.ParamsParserHelper(c, ¶ms); err != nil { return c.SendStatus(fiber.StatusBadRequest) } var organization models.Organization if err := database.DB.Select("subdomain").Model(organization).Where("id = ?", c.Locals("organizationId").(string)).First(&organization).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { return c.SendStatus(fiber.StatusNotFound) } } if organization.Subdomain == "" { return c.SendStatus(fiber.StatusBadRequest) } if err := database.DB.Model(&organization).Where("id = ?", c.Locals("organizationId")).Update("subdomain", params.Subdomain).Error; err != nil { return c.SendStatus(fiber.StatusInternalServerError) } orgId := c.Locals("organizationId").(string) // send broadcast with delay go func() { time.Sleep(1 * time.Second) socketclients.BroadcastMessage(orgId, structs.SendSocketMessage{ Cmd: utils.SendCmdSettingsUpdatedSubdomain, Body: params.Subdomain, }, ) }() return c.JSON(fiber.Map{ "status": "success", }) }