Commit be467410 authored by Etienne Allovon's avatar Etienne Allovon

Merge branch '3412-add-user-to-existing-label' into 'master'

3412 add user to existing label

See merge request !69
parents 8091b04a 88111677
xivo-dao (2020.15.00) xivo-freya; urgency=medium
* 3412 Add a user to an existing label (API)
-- Tomas Taraba <[email protected]> Mon, 24 Aug 2020 15:09:36 +0200
xivo-dao (2020.14.00) xivo-freya; urgency=medium
[Tomas Taraba]
......
......@@ -21,7 +21,7 @@ class UserModel(object):
caller_id, outgoing_caller_id, mobile_phone_number, username, password,
music_on_hold, preprocess_subroutine, userfield,
call_transfer_enabled, call_record_enabled, online_call_record_enabled, supervision_enabled,
ring_seconds, simultaneous_calls, call_permission_password, agent_number, agentid, agent_group_id, enabled):
ring_seconds, simultaneous_calls, call_permission_password, agent_number, agentid, agent_group_id, enabled, labels):
self.id = id
self.uuid = uuid
self.firstname = firstname
......@@ -49,6 +49,7 @@ class UserModel(object):
self.agentid = agentid
self.agent_group_id = agent_group_id
self.enabled = enabled
self.labels = labels
def __eq__(self, other):
return self.__dict__ == other.__dict__
......
......@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from collections import OrderedDict
from xivo_dao.alchemy.userfeatures import UserFeatures as User
from xivo_dao.alchemy.schedulepath import SchedulePath
......@@ -86,6 +87,7 @@ class UserPersistor(object):
query = view.query(self.session)
rows, total = self.user_search.search_from_query(query, parameters)
users = view.convert_list(rows)
return SearchResult(total, users)
def create(self, user):
......@@ -134,5 +136,10 @@ class UserPersistor(object):
(self.session.query(SchedulePath).filter(SchedulePath.path == 'user')
.filter(SchedulePath.pathid == user.id)
.delete())
self.disassociate_labels(user)
self.session.delete(user)
self.session.flush()
def disassociate_labels(self, user):
user.labels = []
self.session.flush()
......@@ -30,6 +30,7 @@ from hamcrest import contains
from hamcrest import not_
from hamcrest import not_none
from xivo_dao.alchemy import UserLabels
from xivo_dao.alchemy.cti_profile import CtiProfile
from xivo_dao.alchemy.entity import Entity
from xivo_dao.alchemy.userfeatures import UserFeatures as User
......@@ -338,7 +339,8 @@ class TestSimpleSearch(TestSearch):
self.assert_search_returns_result(expected)
def test_given_one_user_then_returns_one_result(self):
user = self.prepare_user(firstname='bob')
label = self.add_label()
user = self.prepare_user(firstname='bob', labels=[label])
expected_user_m = UserModel(id=user.id,
uuid=user.uuid,
......@@ -366,7 +368,46 @@ class TestSimpleSearch(TestSearch):
agent_number=None,
agent_group_id=None,
agentid=None,
enabled=True)
enabled=True,
labels=[label.id])
expected = SearchResult(1, [expected_user_m])
self.assert_search_returns_result(expected)
def test_given_one_user_has_multiple_labels_then_returns_one_result(self):
label1 = self.add_label()
label2 = self.add_label()
user = self.prepare_user(firstname='bob', labels=[label1, label2])
expected_user_m = UserModel(id=user.id,
uuid=user.uuid,
firstname='bob',
lastname=None,
email=None,
timezone=None,
language=None,
description=None,
caller_id=None,
outgoing_caller_id=None,
mobile_phone_number=None,
username=None,
password=None,
music_on_hold=None,
preprocess_subroutine=None,
userfield=None,
call_transfer_enabled=False,
call_record_enabled=False,
online_call_record_enabled=False,
supervision_enabled=True,
ring_seconds=20,
simultaneous_calls=2,
call_permission_password=None,
agent_number=None,
agent_group_id=None,
agentid=None,
enabled=True,
labels=[label1.id, label2.id])
expected = SearchResult(1, [expected_user_m])
......@@ -422,7 +463,8 @@ class TestSimpleSearch(TestSearch):
agent_number=None,
agent_group_id=None,
agentid=None,
enabled=True)
enabled=True,
labels=[])
expected = SearchResult(1, [excpected_user_m])
......@@ -434,32 +476,33 @@ class TestSimpleSearch(TestSearch):
agentid=agent_row.id)
expected_user_m = UserModel(id=user.id,
uuid=user.uuid,
firstname='bob',
lastname=None,
email=None,
timezone=None,
language=None,
description=None,
caller_id=None,
outgoing_caller_id=None,
mobile_phone_number=None,
username=None,
password=None,
music_on_hold=None,
preprocess_subroutine=None,
userfield=None,
call_transfer_enabled=False,
call_record_enabled=False,
online_call_record_enabled=False,
supervision_enabled=True,
ring_seconds=20,
simultaneous_calls=2,
call_permission_password=None,
agent_number='8000',
agent_group_id=2,
agentid=agent_row.id,
enabled=True)
uuid=user.uuid,
firstname='bob',
lastname=None,
email=None,
timezone=None,
language=None,
description=None,
caller_id=None,
outgoing_caller_id=None,
mobile_phone_number=None,
username=None,
password=None,
music_on_hold=None,
preprocess_subroutine=None,
userfield=None,
call_transfer_enabled=False,
call_record_enabled=False,
online_call_record_enabled=False,
supervision_enabled=True,
ring_seconds=20,
simultaneous_calls=2,
call_permission_password=None,
agent_number='8000',
agent_group_id=2,
agentid=agent_row.id,
enabled=True,
labels=[])
expected = SearchResult(1, [expected_user_m])
......@@ -497,7 +540,7 @@ class TestSimpleSearch(TestSearch):
context=None,
provisioning_code=None,
protocol=None,
configregistrar=None,)])
configregistrar=None, )])
self.assert_search_returns_result(expected, view='summary')
......@@ -516,7 +559,7 @@ class TestSimpleSearch(TestSearch):
context=user_line.extension.context,
provisioning_code=user_line.linefeatures.provisioning_code,
protocol=user_line.linefeatures.endpoint,
configregistrar="default",)])
configregistrar="default", )])
self.assert_search_returns_result(expected, view='summary')
......@@ -562,7 +605,6 @@ class TestSearchGivenMultipleUsers(TestSearch):
self.user3_m = self.convert_user_to_usermodel(user3)
self.user4_m = self.convert_user_to_usermodel(user4)
def test_when_searching_then_returns_one_result(self):
expected = SearchResult(1, [self.user2_m])
......@@ -807,7 +849,7 @@ class TestCreate(TestUser):
assert_that(updated_user.cti_profile, not_none())
assert_that(updated_user.cti_profile_id, equal_to(cti_profile.id))
assert_that(updated_user.enableclient, equal_to(1))
def test_that_the_user_uuid_is_unique(self):
shared_uuid = str(uuid.uuid4())
self.prepare_user(firstname='Alice', uuid=shared_uuid)
......@@ -982,7 +1024,8 @@ class TestDelete(TestUser):
assert_that(row, none())
def test_delete_references_to_other_tables(self):
user = user_dao.create(User(firstname='Delete'))
label = self.add_label()
user = user_dao.create(User(firstname='Delete', labels=[label]))
self.add_queue_member(usertype='user', userid=user.id)
self.add_right_call_member(type='user', typeval=str(user.id))
self.add_schedule_path(path='user', pathid=user.id)
......@@ -999,6 +1042,7 @@ class TestDelete(TestUser):
assert_that(self.session.query(FuncKeyDestUser).first(), none())
assert_that(self.session.query(FuncKey).first(), none())
assert_that(self.session.query(FuncKeyTemplate).first(), none())
assert_that(self.session.query(UserLabels).first(), none())
def add_right_call_member(self, **kwargs):
member = RightCallMember(**kwargs)
......
......@@ -14,9 +14,10 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from sqlalchemy.orm import aliased
from sqlalchemy.sql import func, case
from xivo_dao.alchemy import Labels
from xivo_dao.resources.utils.view import ViewSelector, View
from xivo_dao.resources.user.model import UserModel, UserDirectory, UserSummary
......@@ -32,6 +33,16 @@ from xivo_dao.alchemy.user_line import UserLine
class UserView(View):
def query(self, session):
grouped_labels = aliased(
session.query(
User.id.label('user_id'),
func.array_agg(Labels.id).label('labels')
)
.join(User.labels)
.group_by(User.id)
.subquery()
)
query = (session.query(User.id.label('id'),
User.uuid.label('uuid'),
User.firstname.label('firstname'),
......@@ -49,21 +60,24 @@ class UserView(View):
func.nullif(User.preprocess_subroutine, '').label('preprocess_subroutine'),
func.nullif(User.userfield, '').label('userfield'),
case([(User.enablexfer == 1, True)],
else_=False).label('call_transfer_enabled'),
else_=False).label('call_transfer_enabled'),
case([(User.callrecord == 1, True)],
else_=False).label('call_record_enabled'),
else_=False).label('call_record_enabled'),
case([(User.enableonlinerec == 1, True)],
else_=False).label('online_call_record_enabled'),
else_=False).label('online_call_record_enabled'),
case([(User.enablehint == 1, True)],
else_=False).label('supervision_enabled'),
else_=False).label('supervision_enabled'),
User.ringseconds.label('ring_seconds'),
User.simultcalls.label('simultaneous_calls'),
func.nullif(User.rightcallcode, '').label('call_permission_password'),
case([(User.commented == 0, True)],
else_=False).label('enabled'),
else_=False).label('enabled'),
func.nullif(AgentFeatures.number, '').label('agent_number'),
User.agentid.label('agentid'),
AgentFeatures.numgroup.label('agent_group_id')))
AgentFeatures.numgroup.label('agent_group_id'),
grouped_labels.c.labels)
.outerjoin(grouped_labels,
User.id == grouped_labels.c.user_id))
return query
def convert(self, row):
......@@ -93,7 +107,8 @@ class UserView(View):
agent_number=row.agent_number,
agentid=row.agentid,
agent_group_id=row.agent_group_id,
enabled=row.enabled)
enabled=row.enabled,
labels=[] if row.labels is None else row.labels)
class DirectoryView(View):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment