feat(inboxes): persist chatwoot working hours
This commit is contained in:
@@ -27,7 +27,7 @@ func (r *InboxRepo) DB() *gorm.DB { return r.db }
|
||||
// FindByID retrieves an inbox by primary key.
|
||||
func (r *InboxRepo) FindByID(ctx context.Context, id uint) (*model.Inbox, error) {
|
||||
var inbox model.Inbox
|
||||
err := r.db.WithContext(ctx).First(&inbox, id).Error
|
||||
err := r.withWorkingHours(r.db.WithContext(ctx)).First(&inbox, id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (r *InboxRepo) FindByAccount(ctx context.Context, accountID uint, offset, l
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
err := r.db.WithContext(ctx).Where("account_id = ?", accountID).
|
||||
err := r.withWorkingHours(r.db.WithContext(ctx)).Where("account_id = ?", accountID).
|
||||
Offset(offset).Limit(limit).Order("id DESC").
|
||||
Find(&inboxes).Error
|
||||
return inboxes, total, err
|
||||
@@ -57,7 +57,7 @@ func (r *InboxRepo) Create(ctx context.Context, inbox *model.Inbox) error {
|
||||
|
||||
// Update modifies an existing inbox.
|
||||
func (r *InboxRepo) Update(ctx context.Context, inbox *model.Inbox) error {
|
||||
return r.db.WithContext(ctx).Save(inbox).Error
|
||||
return r.db.WithContext(ctx).Omit("WorkingHours").Save(inbox).Error
|
||||
}
|
||||
|
||||
// Delete soft-deletes an inbox.
|
||||
@@ -68,13 +68,22 @@ func (r *InboxRepo) Delete(ctx context.Context, id uint) error {
|
||||
// FindByAccountAndID retrieves an inbox scoped to an account.
|
||||
func (r *InboxRepo) FindByAccountAndID(ctx context.Context, accountID, id uint) (*model.Inbox, error) {
|
||||
var inbox model.Inbox
|
||||
err := r.db.WithContext(ctx).Where("account_id = ? AND id = ?", accountID, id).First(&inbox).Error
|
||||
err := r.withWorkingHours(r.db.WithContext(ctx)).Where("account_id = ? AND id = ?", accountID, id).First(&inbox).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &inbox, nil
|
||||
}
|
||||
|
||||
func (r *InboxRepo) withWorkingHours(db *gorm.DB) *gorm.DB {
|
||||
if r == nil || r.db == nil || !r.db.Migrator().HasTable(&model.WorkingHour{}) {
|
||||
return db
|
||||
}
|
||||
return db.Preload("WorkingHours", func(tx *gorm.DB) *gorm.DB {
|
||||
return tx.Order("day_of_week ASC")
|
||||
})
|
||||
}
|
||||
|
||||
// CountByAccount returns total number of inboxes in an account.
|
||||
func (r *InboxRepo) CountByAccount(ctx context.Context, accountID uint) (int64, error) {
|
||||
var total int64
|
||||
|
||||
@@ -2,6 +2,8 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/gochat/gochat/internal/model"
|
||||
"gorm.io/gorm"
|
||||
@@ -52,7 +54,12 @@ func (r *WorkingHourRepo) CreateDefaultWorkingHours(ctx context.Context, inboxID
|
||||
{InboxID: inboxID, AccountID: accountID, DayOfWeek: 5, OpenHour: &nine, OpenMinutes: &zero, CloseHour: &seventeen, CloseMinutes: &zero, OpenAllDay: false},
|
||||
{InboxID: inboxID, AccountID: accountID, DayOfWeek: 6, ClosedAllDay: true, OpenAllDay: false},
|
||||
}
|
||||
return r.db.WithContext(ctx).Create(&defaults).Error
|
||||
for i := range defaults {
|
||||
if err := r.db.WithContext(ctx).Create(&defaults[i]).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateWorkingHours bulk-updates the weekly schedule for an inbox.
|
||||
@@ -93,4 +100,61 @@ type WorkingHourUpdateParam struct {
|
||||
OpenMinutes *int `json:"open_minutes"`
|
||||
CloseHour *int `json:"close_hour"`
|
||||
CloseMinutes *int `json:"close_minutes"`
|
||||
}
|
||||
}
|
||||
|
||||
func (p *WorkingHourUpdateParam) UnmarshalJSON(data []byte) error {
|
||||
var raw map[string]interface{}
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
return err
|
||||
}
|
||||
p.DayOfWeek = intFromAny(raw["day_of_week"])
|
||||
p.ClosedAllDay = boolFromAny(raw["closed_all_day"])
|
||||
p.OpenAllDay = boolFromAny(raw["open_all_day"])
|
||||
p.OpenHour = intPtrFromAny(raw["open_hour"])
|
||||
p.OpenMinutes = intPtrFromAny(raw["open_minutes"])
|
||||
p.CloseHour = intPtrFromAny(raw["close_hour"])
|
||||
p.CloseMinutes = intPtrFromAny(raw["close_minutes"])
|
||||
return nil
|
||||
}
|
||||
|
||||
func intFromAny(value interface{}) int {
|
||||
if ptr := intPtrFromAny(value); ptr != nil {
|
||||
return *ptr
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func intPtrFromAny(value interface{}) *int {
|
||||
switch typed := value.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case float64:
|
||||
v := int(typed)
|
||||
return &v
|
||||
case int:
|
||||
return &typed
|
||||
case string:
|
||||
if typed == "" || typed == "null" {
|
||||
return nil
|
||||
}
|
||||
parsed, err := strconv.Atoi(typed)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &parsed
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func boolFromAny(value interface{}) bool {
|
||||
switch typed := value.(type) {
|
||||
case bool:
|
||||
return typed
|
||||
case string:
|
||||
parsed, _ := strconv.ParseBool(typed)
|
||||
return parsed
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user