admin-dashboard-backend/routers/router/api/v1/crm/crm.go

965 lines
26 KiB
Go

package crm
import (
"jannex/admin-dashboard-backend/modules/config"
"jannex/admin-dashboard-backend/modules/database"
"jannex/admin-dashboard-backend/modules/logger"
"jannex/admin-dashboard-backend/modules/notification"
"jannex/admin-dashboard-backend/modules/structs"
"jannex/admin-dashboard-backend/modules/utils"
"jannex/admin-dashboard-backend/socketclients"
"sort"
"time"
"git.ex.umbach.dev/Alex/roese-utils/rslogger"
"github.com/go-sql-driver/mysql"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"gorm.io/gorm"
)
func GetAllCustomers(c *fiber.Ctx) error {
// swagger:operation GET /crm/customers crm crmGetAllCustomers
// ---
// summary: Get all crm customers
// produces:
// - application/json
// responses:
// '200':
// description: Crm customers
// schema:
// "$ref": "#/definitions/CrmTableCustomer"
// '401':
// description: No permissions
// '500':
// description: Failed to get crm customers
var customers []structs.CrmTableCustomer
database.DB.Find(&customers)
sort.Slice(customers, func(i, j int) bool {
return customers[i].CreatedAt.After(customers[j].CreatedAt)
})
return c.JSON(customers)
}
/*
func GetCrmTypeCustomers(c *fiber.Ctx) error {
var params structs.CrmTypeCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersView) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var query rspagination.PageQuery
if err := c.QueryParser(&query); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if params.Type == utils.CrmPipelineCustomers {
return c.JSON(structs.CrmTableCustomerResponse{
Customers: crm.GetTableCustomers(params, query),
TotalPages: rspagination.GetTotalPages(database.DB,
utils.CrmCustomersPaginationLimit,
[]structs.CrmCustomer{},
nil),
})
}
// Check if deal phase is set
if params.DealPhase == 0 {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
if params.Type == utils.CrmPipelineDmcPipeline {
return c.JSON(structs.CrmTableCustomerResponse{
Customers: crm.GetTableCustomers(params, query),
TotalPages: rspagination.GetTotalPages(database.DB,
utils.CrmCustomersPaginationLimit,
[]structs.CrmCustomer{},
structs.CrmCustomer{
Pipeline: utils.CrmPipelineDmcPipelineInt,
DealPhase: params.DealPhase}),
})
}
if params.Type == utils.CrmPipelineSetterCloser {
return c.JSON(structs.CrmTableCustomerResponse{
Customers: crm.GetTableCustomers(params, query),
TotalPages: rspagination.GetTotalPages(database.DB,
utils.CrmCustomersPaginationLimit,
[]structs.CrmCustomer{},
structs.CrmCustomer{
Pipeline: utils.CrmPipelineSetterCloserInt,
DealPhase: params.DealPhase}),
})
}
return c.SendStatus(fiber.StatusNotFound)
}
*/
// find customer by provided filters in body - used by groupTasks python scripts
func GetCrmCustomer(c *fiber.Ctx) error {
// swagger:operation POST /crm/customer crm crmGetCrmCustomer
// ---
// summary: Get crm customer by filters
// produces:
// - application/json
// parameters:
// - name: crmCustomer
// in: body
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmCustomer"
// responses:
// '200':
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmTableCustomer"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '500':
// description: Failed to get crm customer
var body structs.CrmCustomer
if err := c.BodyParser(&body); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersView) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var customers []structs.CrmTableCustomer
database.DB.Find(&customers, body)
sort.Slice(customers, func(i, j int) bool {
return customers[i].CreatedAt.After(customers[j].CreatedAt)
})
return c.JSON(customers)
}
func GetCrmCustomerById(c *fiber.Ctx) error {
// swagger:operation GET /crm/customer/view/{id} crm crmGetCrmCustomerById
// ---
// summary: Get crm customer by id
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: Customer id
// responses:
// '200':
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmCustomer"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Crm customer not found
// '500':
// description: Failed to get crm customer
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersView) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var customerResponse structs.CrmGetCustomerResponse
database.DB.First(&customerResponse.Customer, "id = ?", params.Id)
if customerResponse.Customer.Id != params.Id {
return c.SendStatus(fiber.StatusNotFound)
}
// get call protocols
database.DB.Find(&customerResponse.CallProtocols, "customer_id = ?", params.Id)
// get links
database.DB.Find(&customerResponse.Links, "customer_id = ?", params.Id)
// get links history by looping through links
for _, link := range customerResponse.Links {
var linkHistory []structs.CrmLinkHistory
database.DB.Find(&linkHistory, "link_id = ?", link.Id)
customerResponse.LinkHistory = append(customerResponse.LinkHistory, linkHistory...)
}
return c.JSON(customerResponse)
}
func UpdateCrmCustomer(c *fiber.Ctx) error {
// swagger:operation POST /crm/customer/update/{id} crm crmUpdateCrmCustomer
// ---
// summary: Update crm customer
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: Customer id
// - name: crmCustomer
// in: body
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmCustomer"
// responses:
// '200':
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmCustomer"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Crm customer not found
// '409':
// description: Crm customer with the company name already exists
// '500':
// description: Failed to update crm customer
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersEdit) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var customer structs.CrmCustomer
database.DB.First(&customer, "id = ?", params.Id)
if customer.Id != params.Id {
return c.SendStatus(fiber.StatusNotFound)
}
var crmCustomer map[string]interface{}
if err := c.BodyParser(&crmCustomer); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
crmCustomer["UpdatedAt"] = time.Now()
result := database.DB.Model(&structs.CrmCustomer{}).
Where("id = ?", params.Id).
Select("*"). // update all fields (even if they are empty)
Updates(crmCustomer)
if err := handleError(result, c); err != nil {
return err
}
crmCustomer["Id"] = params.Id
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm, structs.SendSocketMessage{
Cmd: utils.SentCmdCrmCustomerUpdated,
Body: crmCustomer,
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm customer id: %s updated with following changes: %v", params.Id, customer)
return c.JSON(crmCustomer)
}
func CreateCrmCustomer(c *fiber.Ctx) error {
// swagger:operation POST /crm/customer/create crm crmCreateCrmCustomer
// ---
// summary: Create crm customer
// produces:
// - application/json
// parameters:
// - name: crmCustomer
// in: body
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmCustomer"
// responses:
// '200':
// description: Crm customer
// schema:
// "$ref": "#/definitions/CrmCustomer"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '409':
// description: Crm customer with the company name already exists
// '500':
// description: Failed to create crm customer
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersCreate) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var crmCustomer map[string]interface{}
if err := c.BodyParser(&crmCustomer); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
crmCustomer["Id"] = uuid.New().String()
if crmCustomer["Pipeline"] == nil {
crmCustomer["Pipeline"] = 1
}
if crmCustomer["DealPhase"] == nil {
crmCustomer["DealPhase"] = 1
}
crmCustomer["CreatedBy"] = c.Locals("userId").(string)
crmCustomer["CreatedAt"] = time.Now()
// check if company name already exists
var count int64
database.DB.Model(&structs.CrmCustomer{}).Where("company = ?", crmCustomer["Company"]).Count(&count)
if count > 0 {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer as company name already exists: %v", crmCustomer)
return c.SendStatus(fiber.StatusConflict)
}
result := database.DB.Model(&structs.CrmCustomer{}).Create(&crmCustomer)
// TODO: thats not working correctly
if err := handleError(result, c); err != nil {
return err
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmCustomerCreated,
Body: crmCustomer,
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm customer id: %s created with following changes: %v", crmCustomer["Id"], crmCustomer)
return c.JSON(crmCustomer)
}
func handleError(result *gorm.DB, c *fiber.Ctx) error {
if result.Error != nil {
if mysqlErr, ok := result.Error.(*mysql.MySQLError); ok {
switch mysqlErr.Number {
case 1062:
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer as company name already exists: %v", result.Error.Error())
return c.SendStatus(fiber.StatusConflict)
default:
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
}
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
return nil
}
func DeleteCrmCustomer(c *fiber.Ctx) error {
// swagger:operation DELETE /crm/customer/delete/{id} crm crmDeleteCrmCustomer
// ---
// summary: Delete crm customer
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: Customer id
// responses:
// '200':
// description: Crm customer deleted
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Crm customer not found
// '500':
// description: Failed to delete crm customer
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersDelete) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
// check if customer exists
var customer structs.CrmCustomer
database.DB.First(&customer, "id = ?", params.Id)
if customer.Id != params.Id {
return c.SendStatus(fiber.StatusNotFound)
}
// delete customer
result := database.DB.Delete(&customer, "id = ?", params.Id)
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm customer id: %s deleted: %v by user: %s", params.Id, customer, c.Locals("userId").(string))
if result.Error != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
// delete all call protocols
result = database.DB.Delete(&structs.CrmCallProtocol{}, "customer_id = ?", params.Id)
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm call protocols for customer id: %s deleted: %v by user: %s", params.Id, customer, c.Locals("userId").(string))
if result.Error != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
// we need the crmLink Id to delete the link history
var crmLinks []structs.CrmLink
database.DB.Find(&crmLinks, "customer_id = ?", params.Id)
// delete all link history
for _, link := range crmLinks {
result = database.DB.Delete(&structs.CrmLinkHistory{}, "link_id = ?", link.Id)
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link history for link id: %s deleted: %v by user: %s", link.Id, link, c.Locals("userId").(string))
if result.Error != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
}
// delete all links
result = database.DB.Delete(&structs.CrmLink{}, "customer_id = ?", params.Id)
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm links for customer id: %s deleted: %v by user: %s", params.Id, customer, c.Locals("userId").(string))
if result.Error != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmCustomerDeleted,
Body: params.Id,
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm customer id: %s deleted: %v by user: %s", params.Id, customer, c.Locals("userId").(string))
return c.SendStatus(fiber.StatusOK)
}
func CreateCrmCallProtocol(c *fiber.Ctx) error {
// swagger:operation POST /crm/calls/create crm crmCreateCrmCallProtocol
// ---
// summary: Create crm call protocol
// produces:
// - application/json
// parameters:
// - name: crmCallProtocol
// in: body
// description: Crm call protocol
// schema:
// "$ref": "#/definitions/CrmCallProtocolRequest"
// responses:
// '200':
// description: Crm call protocol created
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Customer not found
// '500':
// description: Failed to create crm call protocol
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCallProtocolCreate) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var body structs.CrmCallProtocolRequest
if err := c.BodyParser(&body); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
// check if customer exists
var count int64
database.DB.Model(&structs.CrmCustomer{}).Where("id = ?", body.CustomerId).Count(&count)
if count == 0 {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm call protocol as customer id not found: %v", body.CustomerId)
return c.SendStatus(fiber.StatusNotFound)
}
// create crm call protocol
var crmCallProtocol structs.CrmCallProtocol
crmCallProtocol.Id = uuid.New().String()
crmCallProtocol.CustomerId = body.CustomerId
crmCallProtocol.CallType = body.CallType
crmCallProtocol.CalledAt = body.CalledAt
crmCallProtocol.Telephone = body.Telephone
crmCallProtocol.Notes = body.Notes
crmCallProtocol.ResultReached = body.ResultReached
crmCallProtocol.ResultWhoPickedUp = body.ResultWhoPickedUp
crmCallProtocol.ResultExpressedInterest = body.ResultExpressedInterest
crmCallProtocol.ResultScheduled = body.ResultScheduled
crmCallProtocol.CreatedBy = c.Locals("userId").(string)
crmCallProtocol.CreatedAt = time.Now()
result := database.DB.Model(&structs.CrmCallProtocol{}).Create(&crmCallProtocol)
if result.Error != nil {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm call protocol: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
// update last contact date
result = database.DB.Model(&structs.CrmCustomer{}).
Where("id = ?", body.CustomerId).
Update("last_contact", time.Now())
if result.Error != nil {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to update last contact date: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmCallProtocolCreated,
Body: struct {
CallProtocol structs.CrmCallProtocol
Customer struct {
Id string
LastContact time.Time
}
}{
CallProtocol: crmCallProtocol,
Customer: struct {
Id string
LastContact time.Time
}{
Id: body.CustomerId,
LastContact: time.Now(),
},
},
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm call protocol id: %s created: %v", crmCallProtocol.Id, crmCallProtocol)
return c.SendStatus(fiber.StatusOK)
}
func GetCrmCallProtocols(c *fiber.Ctx) error {
// swagger:operation GET /crm/calls/{customerId} crm crmGetCrmCallProtocols
// ---
// summary: Get crm call protocols
// produces:
// - application/json
// parameters:
// - name: customerId
// in: path
// description: Customer id
// responses:
// '200':
// description: Crm call protocols
// schema:
// "$ref": "#/definitions/CrmCallProtocol"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '500':
// description: Failed to get crm call protocols
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCallProtocolView) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var crmCallProtocols []structs.CrmCallProtocol
database.DB.Find(&crmCallProtocols, "customer_id = ?", params.Id)
return c.JSON(crmCallProtocols)
}
func DeleteCrmCallProtocol(c *fiber.Ctx) error {
// swagger:operation DELETE /crm/calls/delete/{id} crm crmDeleteCrmCallProtocol
// ---
// summary: Delete crm call protocol
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: Call protocol id
// responses:
// '200':
// description: Crm call protocol deleted
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Crm call protocol not found
// '500':
// description: Failed to delete crm call protocol
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCallProtocolDelete) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var crmCallProtocol structs.CrmCallProtocol
database.DB.First(&crmCallProtocol, "id = ?", params.Id)
if crmCallProtocol.Id != params.Id {
return c.SendStatus(fiber.StatusNotFound)
}
result := database.DB.Delete(&crmCallProtocol, "id = ?", params.Id)
if result.Error != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmCallProtocolDeleted,
Body: struct {
Id string
CustomerId string
}{
Id: crmCallProtocol.Id,
CustomerId: crmCallProtocol.CustomerId,
},
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm call protocol id: %s deleted: %v", crmCallProtocol.Id, crmCallProtocol)
return c.SendStatus(fiber.StatusOK)
}
func CreateCrmLink(c *fiber.Ctx) error {
// swagger:operation POST /crm/links crm crmCreateCrmLink
// ---
// summary: Create crm link
// produces:
// - application/json
// parameters:
// - name: crmLink
// in: body
// description: Crm link
// schema:
// "$ref": "#/definitions/CrmLink"
// responses:
// '200':
// description: Crm link created
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '500':
// description: Failed to create crm link
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmLinkCreate) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var body structs.CrmLink
if err := c.BodyParser(&body); err != nil ||
body.CustomerId == "" ||
body.Name == "" ||
body.Url == "" {
return c.SendStatus(fiber.StatusBadRequest)
}
// check if customer exists
var count int64
database.DB.Model(&structs.CrmCustomer{}).Where("id = ?", body.CustomerId).Count(&count)
if count == 0 {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm link as customer id not found: %v", body.CustomerId)
return c.SendStatus(fiber.StatusNotFound)
}
body.Id = uuid.New().String()
body.CreatedBy = c.Locals("userId").(string)
body.CreatedAt = time.Now()
result := database.DB.Model(&structs.CrmLink{}).Create(&body)
if result.Error != nil {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm link: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmLinkCreated,
Body: body,
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link id: %s created: %v", body.Id, body)
return c.SendStatus(fiber.StatusOK)
}
func GetCrmLinks(c *fiber.Ctx) error {
// swagger:operation GET /crm/links/{customerId} crm crmGetCrmLinks
// ---
// summary: Get crm links
// produces:
// - application/json
// parameters:
// - name: customerId
// in: path
// description: Customer id
// responses:
// '200':
// description: Crm links
// schema:
// "$ref": "#/definitions/CrmLink"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '500':
// description: Failed to get crm links
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmLinkView) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var crmLinks []structs.CrmLink
database.DB.Find(&crmLinks, "customer_id = ?", params.Id)
return c.JSON(crmLinks)
}
func CrmUseLink(c *fiber.Ctx) error {
// swagger:operation POST /crm/link/{id} crm crmUseLink
// ---
// summary: Use crm link
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: Link id
// responses:
// '200':
// description: Crm link used
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Crm link not found
// '500':
// description: Failed to use crm link
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var link structs.CrmLink
database.DB.First(&link, "id = ?", params.Id)
if link.Id != params.Id {
return c.SendStatus(fiber.StatusNotFound)
}
// create link history
linkHistory := structs.CrmLinkHistory{
LinkId: link.Id,
UserAgent: string(c.Context().UserAgent()),
UsedAt: time.Now(),
}
result := database.DB.Model(&structs.CrmLinkHistory{}).Create(&linkHistory)
if result.Error != nil {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to use crm link: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmLinkUsed,
Body: linkHistory,
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link id: %s used: %v", link.Id, link)
// only for debugging
var crmCustomer structs.CrmCustomer
database.DB.First(&crmCustomer, "id = ?", link.CustomerId)
notification.AddNotification(nil, structs.AddNotificationRequest{
UserIds: config.Cfg.NotificationUserIds,
Type: 1,
Title: "Crm link used: " + link.Name + " by crm customer: " + crmCustomer.FirstName + " " + crmCustomer.Email + " (" + link.CustomerId + ")",
})
return c.Redirect(link.Url)
}
func DeleteCrmLink(c *fiber.Ctx) error {
// swagger:operation DELETE /crm/links/{id} crm crmDeleteCrmLink
// ---
// summary: Delete crm link
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: Link id
// responses:
// '200':
// description: Crm link deleted
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '404':
// description: Crm link not found
// '500':
// description: Failed to delete crm link
if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmLinkDelete) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var params structs.CrmGetCustomerRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var link structs.CrmLink
database.DB.First(&link, "id = ?", params.Id)
if link.Id != params.Id {
return c.SendStatus(fiber.StatusNotFound)
}
result := database.DB.Delete(&link, "id = ?", params.Id)
if result.Error != nil {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to delete crm link: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
// delete all link history
result = database.DB.Delete(&structs.CrmLinkHistory{}, "link_id = ?", params.Id)
if result.Error != nil {
logger.AddCrmLog(rslogger.LogTypeError, "Failed to delete crm link history: %v", result.Error.Error())
return c.SendStatus(fiber.StatusInternalServerError)
}
socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
structs.SendSocketMessage{
Cmd: utils.SentCmdCrmLinkDeleted,
Body: params.Id,
})
logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link id: %s deleted: %v", link.Id, link)
return c.SendStatus(fiber.StatusOK)
}
func CrmNoLinkProvidedRedirect(c *fiber.Ctx) error {
// swagger:operation GET /crm/nolink crm crmNoLinkProvidedRedirect
// ---
// summary: Redirect to crm no link provided
// produces:
// - application/json
// responses:
// '200':
// description: Redirect to crm no link provided
// '500':
// description: Failed to redirect to crm no link provided
return c.Redirect("https://jannex.de?utm_source=web&utm_medium=web&utm_campaign=linkredirect&utm_content=redirect")
}