diff --git a/app/cc_member.go b/app/cc_member.go index 4a23a618..66f6429d 100644 --- a/app/cc_member.go +++ b/app/cc_member.go @@ -137,14 +137,18 @@ func (app *App) PatchMember(ctx context.Context, domainId, queueId, id int64, pa return oldMember, nil } -func (app *App) RemoveMember(ctx context.Context, domainId, queueId, id int64) (*model.Member, model.AppError) { +func (app *App) RemoveMember(ctx context.Context, domainId, queueId, id int64, force bool) (*model.Member, model.AppError) { member, err := app.GetMember(ctx, domainId, queueId, id) if err != nil { return nil, err } - err = app.Store.Member().Delete(ctx, queueId, id) + if !force && member.Reserved { + return nil, model.NewBadRequestError("member.reserved", "Member is reserved") + } + + err = app.Store.Member().Delete(ctx, queueId, id, force) if err != nil { return nil, err } diff --git a/grpc_api/cc_member.go b/grpc_api/cc_member.go index 9a023d9e..0471509e 100644 --- a/grpc_api/cc_member.go +++ b/grpc_api/cc_member.go @@ -521,8 +521,10 @@ func (api *member) DeleteMember(ctx context.Context, in *engine.DeleteMemberRequ } } + const force = false + var m *model.Member - m, err = api.app.RemoveMember(ctx, session.Domain(in.GetDomainId()), in.GetQueueId(), in.GetId()) + m, err = api.app.RemoveMember(ctx, session.Domain(in.GetDomainId()), in.GetQueueId(), in.GetId(), force) if err != nil { return nil, err } diff --git a/store/sqlstore/cc_member_store.go b/store/sqlstore/cc_member_store.go index 01a051a6..f36c4b2a 100644 --- a/store/sqlstore/cc_member_store.go +++ b/store/sqlstore/cc_member_store.go @@ -390,15 +390,18 @@ from m return member, nil } -// TODO add force -func (s SqlMemberStore) Delete(ctx context.Context, queueId, id int64) model.AppError { +func (s SqlMemberStore) Delete(ctx context.Context, queueId, id int64, force bool) model.AppError { var cnt int64 res, err := s.GetMaster().WithContext(ctx).Exec(`delete from call_center.cc_member c where c.id = :Id and c.queue_id = :QueueId - and not exists(select 1 from call_center.cc_member_attempt a where a.member_id = c.id and a.state != 'leaving' for update)`, - map[string]interface{}{"Id": id, "QueueId": queueId}) + and not exists(select 1 from call_center.cc_member_attempt a where not :Force::bool and a.member_id = c.id and a.state != 'leaving' for update)`, + map[string]interface{}{ + "Id": id, + "QueueId": queueId, + "Force": force, + }) if err != nil { return model.NewCustomCodeError("store.sql_member.delete.app_error", fmt.Sprintf("Id=%v, %s", id, err.Error()), extractCodeFromErr(err)) diff --git a/store/store.go b/store/store.go index f0c71f17..95038e12 100644 --- a/store/store.go +++ b/store/store.go @@ -312,7 +312,7 @@ type MemberStore interface { SearchMembers(ctx context.Context, domainId int64, search *model.SearchMemberRequest) ([]*model.Member, model.AppError) Get(ctx context.Context, domainId, queueId, id int64) (*model.Member, model.AppError) Update(ctx context.Context, domainId int64, member *model.Member) (*model.Member, model.AppError) - Delete(ctx context.Context, queueId, id int64) model.AppError + Delete(ctx context.Context, queueId, id int64, force bool) model.AppError MultiDelete(ctx context.Context, domainId int64, del *model.MultiDeleteMembers, withoutMembers bool) ([]*model.Member, model.AppError) ResetMembers(ctx context.Context, domainId int64, req *model.ResetMembers) (int64, model.AppError)