feat(inboxes): persist chatwoot working hours
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gochat/gochat/internal/repository"
|
||||
"github.com/gochat/gochat/internal/service"
|
||||
"github.com/gochat/gochat/pkg/response"
|
||||
)
|
||||
@@ -317,6 +318,8 @@ func applyCreateInboxForm(req *service.CreateInboxRequest, values map[string][]s
|
||||
req.BusinessName = inboxStringPtr(value)
|
||||
case "csat_config":
|
||||
req.CsatConfig = inboxJSONObject(value)
|
||||
case "working_hours":
|
||||
req.WorkingHours = inboxWorkingHours(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,6 +372,8 @@ func applyUpdateInboxForm(req *service.UpdateInboxRequest, values map[string][]s
|
||||
req.BusinessName = inboxStringPtr(value)
|
||||
case "csat_config":
|
||||
req.CsatConfig = inboxJSONObject(value)
|
||||
case "working_hours":
|
||||
req.WorkingHours = inboxWorkingHours(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -443,6 +448,17 @@ func inboxJSONObject(value string) map[string]any {
|
||||
return data
|
||||
}
|
||||
|
||||
func inboxWorkingHours(value string) []repository.WorkingHourUpdateParam {
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
var data []repository.WorkingHourUpdateParam
|
||||
if err := json.Unmarshal([]byte(value), &data); err != nil {
|
||||
return nil
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Member-action handlers (Chatwoot InboxesController member routes)
|
||||
// ========================================
|
||||
|
||||
@@ -33,7 +33,7 @@ func TestInboxHandler_ChatwootSerializerParity(t *testing.T) {
|
||||
_ = sqlDB.Close()
|
||||
}
|
||||
})
|
||||
require.NoError(t, db.AutoMigrate(&model.Account{}, &model.Inbox{}))
|
||||
require.NoError(t, db.AutoMigrate(&model.Account{}, &model.Inbox{}, &model.WorkingHour{}))
|
||||
|
||||
account := &model.Account{Name: "Inbox Parity", Locale: "en", Active: true}
|
||||
require.NoError(t, db.Create(account).Error)
|
||||
@@ -123,7 +123,7 @@ func TestInboxHandler_ChatwootCreateUpdateRequestBinding(t *testing.T) {
|
||||
_ = sqlDB.Close()
|
||||
}
|
||||
})
|
||||
require.NoError(t, db.AutoMigrate(&model.Account{}, &model.Inbox{}))
|
||||
require.NoError(t, db.AutoMigrate(&model.Account{}, &model.Inbox{}, &model.WorkingHour{}))
|
||||
|
||||
account := &model.Account{Name: "Inbox Binding", Locale: "en", Active: true}
|
||||
require.NoError(t, db.Create(account).Error)
|
||||
@@ -206,6 +206,41 @@ func TestInboxHandler_ChatwootCreateUpdateRequestBinding(t *testing.T) {
|
||||
require.Equal(t, "Rate this conversation", csatConfig["message"])
|
||||
require.Equal(t, "Please rate us", csatConfig["button_text"])
|
||||
require.ElementsMatch(t, []any{"vip", "priority"}, csatConfig["survey_rules"].(map[string]any)["values"].([]any))
|
||||
|
||||
workingHoursUpdate := inboxParityRequest(t, router, http.MethodPut, fmt.Sprintf("/api/v1/accounts/%d/inboxes/%d", account.ID, websiteID), map[string]any{
|
||||
"working_hours_enabled": true,
|
||||
"out_of_office_message": "We are away",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"working_hours": []map[string]any{
|
||||
{"day_of_week": 0, "closed_all_day": true, "open_hour": "", "open_minutes": "", "close_hour": "", "close_minutes": "", "open_all_day": false},
|
||||
{"day_of_week": 1, "closed_all_day": false, "open_hour": "9", "open_minutes": "30", "close_hour": "18", "close_minutes": "0", "open_all_day": false},
|
||||
{"day_of_week": 2, "closed_all_day": false, "open_hour": "", "open_minutes": "", "close_hour": "", "close_minutes": "", "open_all_day": true},
|
||||
{"day_of_week": 3, "closed_all_day": true, "open_hour": "", "open_minutes": "", "close_hour": "", "close_minutes": "", "open_all_day": false},
|
||||
{"day_of_week": 4, "closed_all_day": true, "open_hour": "", "open_minutes": "", "close_hour": "", "close_minutes": "", "open_all_day": false},
|
||||
{"day_of_week": 5, "closed_all_day": true, "open_hour": "", "open_minutes": "", "close_hour": "", "close_minutes": "", "open_all_day": false},
|
||||
{"day_of_week": 6, "closed_all_day": true, "open_hour": "", "open_minutes": "", "close_hour": "", "close_minutes": "", "open_all_day": false},
|
||||
},
|
||||
"channel": map[string]any{},
|
||||
})
|
||||
require.Equal(t, http.StatusOK, workingHoursUpdate.Code, workingHoursUpdate.Body.String())
|
||||
workingHoursData := inboxParityObject(t, workingHoursUpdate)
|
||||
require.Equal(t, true, workingHoursData["working_hours_enabled"])
|
||||
require.Equal(t, "We are away", workingHoursData["out_of_office_message"])
|
||||
require.Equal(t, "Asia/Shanghai", workingHoursData["timezone"])
|
||||
workingHours := workingHoursData["working_hours"].([]any)
|
||||
require.Len(t, workingHours, 7)
|
||||
monday := workingHours[1].(map[string]any)
|
||||
require.Equal(t, float64(1), monday["day_of_week"])
|
||||
require.Equal(t, float64(9), monday["open_hour"])
|
||||
require.Equal(t, float64(30), monday["open_minutes"])
|
||||
tuesday := workingHours[2].(map[string]any)
|
||||
require.Equal(t, true, tuesday["open_all_day"])
|
||||
require.Equal(t, float64(0), tuesday["open_hour"])
|
||||
require.Equal(t, float64(23), tuesday["close_hour"])
|
||||
|
||||
showUpdated := inboxParityRequest(t, router, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%d/inboxes/%d", account.ID, websiteID), nil)
|
||||
require.Equal(t, http.StatusOK, showUpdated.Code, showUpdated.Body.String())
|
||||
require.Len(t, inboxParityObject(t, showUpdated)["working_hours"].([]any), 7)
|
||||
}
|
||||
|
||||
func setupInboxParityRouter(db *gorm.DB) *gin.Engine {
|
||||
|
||||
@@ -32,7 +32,7 @@ func serializeInbox(inbox *model.Inbox) map[string]any {
|
||||
"enable_auto_assignment": inbox.EnableAutoAssignment,
|
||||
"auto_assignment_config": configValue(config, "auto_assignment_config"),
|
||||
"out_of_office_message": inbox.OutOfOfficeMessage,
|
||||
"working_hours": configArray(config, "working_hours"),
|
||||
"working_hours": serializeInboxWorkingHours(inbox, config),
|
||||
"timezone": inbox.Timezone,
|
||||
"callback_webhook_url": configValue(config, "callback_webhook_url"),
|
||||
"allow_messages_after_resolved": inbox.AllowMessagesAfterResolved,
|
||||
@@ -96,6 +96,25 @@ func serializeInbox(inbox *model.Inbox) map[string]any {
|
||||
return payload
|
||||
}
|
||||
|
||||
func serializeInboxWorkingHours(inbox *model.Inbox, config map[string]any) any {
|
||||
if len(inbox.WorkingHours) == 0 {
|
||||
return configArray(config, "working_hours")
|
||||
}
|
||||
payload := make([]any, 0, len(inbox.WorkingHours))
|
||||
for _, wh := range inbox.WorkingHours {
|
||||
payload = append(payload, map[string]any{
|
||||
"day_of_week": wh.DayOfWeek,
|
||||
"closed_all_day": wh.ClosedAllDay,
|
||||
"open_hour": wh.OpenHour,
|
||||
"open_minutes": wh.OpenMinutes,
|
||||
"close_hour": wh.CloseHour,
|
||||
"close_minutes": wh.CloseMinutes,
|
||||
"open_all_day": wh.OpenAllDay,
|
||||
})
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
func chatwootChannelType(channelType string) string {
|
||||
if strings.HasPrefix(channelType, "Channel::") {
|
||||
return channelType
|
||||
|
||||
Reference in New Issue
Block a user