diff --git a/commons/data_access_layer/cosmos_db.py b/commons/data_access_layer/cosmos_db.py index 6c1ed54d..9cdf7f1c 100644 --- a/commons/data_access_layer/cosmos_db.py +++ b/commons/data_access_layer/cosmos_db.py @@ -173,17 +173,6 @@ def create_sql_where_conditions( else: return "" - @staticmethod - def create_custom_sql_conditions(custom_sql_conditions: List[str]) -> str: - if len(custom_sql_conditions) > 0: - return "AND {custom_sql_conditions_clause}".format( - custom_sql_conditions_clause=" AND ".join( - custom_sql_conditions - ) - ) - else: - return '' - @staticmethod def generate_params(conditions: dict) -> list: result = [] @@ -217,6 +206,16 @@ def attach_context(data: dict, event_context: EventContext): "session_id": event_context.session_id, } + @staticmethod + def create_sql_date_range_filter(date_range: dict) -> str: + if 'start_date' in date_range and 'end_date' in date_range: + return """ + AND ((c.start_date BETWEEN @start_date AND @end_date) OR + (c.end_date BETWEEN @start_date AND @end_date)) + """ + else: + return '' + def create( self, data: dict, event_context: EventContext, mapper: Callable = None ): @@ -251,19 +250,13 @@ def find_all( self, event_context: EventContext, conditions: dict = None, - custom_sql_conditions: List[str] = None, - custom_params: dict = None, + date_range: dict = None, + visible_only=True, max_count=None, offset=0, - visible_only=True, mapper: Callable = None, ): conditions = conditions if conditions else {} - custom_sql_conditions = ( - custom_sql_conditions if custom_sql_conditions else [] - ) - custom_params = custom_params if custom_params else {} - partition_key_value = self.find_partition_key_value(event_context) max_count = self.get_page_size_or(max_count) params = [ @@ -277,15 +270,20 @@ def find_all( status_value = conditions.get('status') conditions.pop('status') + date_range = date_range if date_range else {} + date_range_params = ( + self.generate_params(date_range) if date_range else [] + ) params.extend(self.generate_params(conditions)) - params.extend(custom_params) + params.extend(date_range_params) + query_str = """ SELECT * FROM c WHERE c.{partition_key_attribute}=@partition_key_value {conditions_clause} - {visibility_condition} {active_condition} - {custom_sql_conditions_clause} + {date_range_sql_condition} + {visibility_condition} {order_clause} OFFSET @offset LIMIT @max_count """.format( @@ -295,11 +293,12 @@ def find_all( ), active_condition=self.create_sql_active_condition(status_value), conditions_clause=self.create_sql_where_conditions(conditions), - custom_sql_conditions_clause=self.create_custom_sql_conditions( - custom_sql_conditions + date_range_sql_condition=self.create_sql_date_range_filter( + date_range ), order_clause=self.create_sql_order_clause(), ) + result = self.container.query_items( query=query_str, parameters=params, diff --git a/tests/time_tracker_api/activities/activities_namespace_test.py b/tests/time_tracker_api/activities/activities_namespace_test.py index d397117b..13958d8a 100644 --- a/tests/time_tracker_api/activities/activities_namespace_test.py +++ b/tests/time_tracker_api/activities/activities_namespace_test.py @@ -71,7 +71,13 @@ def test_list_all_active( json_data = json.loads(response.data) assert [] == json_data - repository_find_all_mock.assert_called_once_with(ANY, conditions={}) + repository_find_all_mock.assert_called_once_with( + event_context=ANY, + activities_id=ANY, + conditions={}, + visible_only=ANY, + max_count=ANY, + ) def test_list_all_active_activities( @@ -94,7 +100,11 @@ def test_list_all_active_activities( assert [] == json_data repository_find_all_mock.assert_called_once_with( - ANY, conditions={'status': 'active'} + event_context=ANY, + conditions={'status': 'active'}, + activities_id=ANY, + visible_only=ANY, + max_count=ANY, ) diff --git a/tests/time_tracker_api/projects/projects_model_test.py b/tests/time_tracker_api/projects/projects_model_test.py index 7338fdfe..af7c76f6 100644 --- a/tests/time_tracker_api/projects/projects_model_test.py +++ b/tests/time_tracker_api/projects/projects_model_test.py @@ -11,7 +11,7 @@ @patch( 'time_tracker_api.projects.projects_model.ProjectCosmosDBRepository.find_partition_key_value' ) -def test_find_all_v2( +def test_find_all_projects_new_version( find_partition_key_value_mock, event_context: EventContext, project_repository: ProjectCosmosDBRepository, @@ -28,13 +28,14 @@ def test_find_all_v2( project_repository.container = Mock() project_repository.container.query_items = query_items_mock - result = project_repository.find_all_v2( - event_context, - ['id'], - ['customer_id'] + result = project_repository.find_all( + event_context=event_context, + conditions={"customer_id": "1"}, + project_ids=['id'], + customer_ids=['customer_id'], ) find_partition_key_value_mock.assert_called_once() assert len(result) == 1 project = result[0] assert isinstance(project, ProjectCosmosDBModel) - assert project.__dict__ == expected_item \ No newline at end of file + assert project.__dict__ == expected_item diff --git a/tests/time_tracker_api/time_entries/time_entries_model_test.py b/tests/time_tracker_api/time_entries/time_entries_model_test.py index 0bf801b5..c4d8b354 100644 --- a/tests/time_tracker_api/time_entries/time_entries_model_test.py +++ b/tests/time_tracker_api/time_entries/time_entries_model_test.py @@ -278,23 +278,11 @@ def test_updated_item_without_deleted_key_should_call_validate_data( @patch( 'commons.data_access_layer.cosmos_db.CosmosDBRepository.generate_params' ) -@patch( - 'commons.data_access_layer.cosmos_db.CosmosDBRepository.create_sql_condition_for_visibility' -) -@patch( - 'commons.data_access_layer.cosmos_db.CosmosDBRepository.create_sql_where_conditions' -) -@patch( - 'commons.data_access_layer.cosmos_db.CosmosDBRepository.create_custom_sql_conditions' -) @patch( 'time_tracker_api.time_entries.time_entries_repository.TimeEntryCosmosDBRepository.add_complementary_info' ) -def test_find_all_v2( +def test_find_all_time_entries_new_version( add_complementary_info_mock, - create_custom_sql_conditions_mock, - create_sql_where_conditions_mock, - create_sql_condition_for_visibility_mock, generate_params_mock, get_page_size_or_mock, find_partition_key_value_mock, @@ -319,25 +307,20 @@ def test_find_all_v2( result = time_entry_repository.find_all( conditions={"user_id": "*"}, - custom_sql_conditions=[], event_context=event_context, date_range={ 'start_date': "2021-03-22T10:00:00.000Z", 'end_date': "2021-03-22T11:00:00.000Z", }, - custom_params={}, ) find_partition_key_value_mock.assert_called_once() get_page_size_or_mock.assert_called_once() + assert len(result) == 1 time_entry = result[0] assert time_entry == expected_item - create_sql_condition_for_visibility_mock.assert_called_once() - create_sql_where_conditions_mock.assert_called_once() - create_custom_sql_conditions_mock.assert_called_once() - @patch( 'time_tracker_api.time_entries.time_entries_repository.TimeEntryCosmosDBRepository.find_partition_key_value' diff --git a/tests/time_tracker_api/time_entries/time_entries_namespace_test.py b/tests/time_tracker_api/time_entries/time_entries_namespace_test.py index d01cdd6e..0954bd7c 100644 --- a/tests/time_tracker_api/time_entries/time_entries_namespace_test.py +++ b/tests/time_tracker_api/time_entries/time_entries_namespace_test.py @@ -197,7 +197,7 @@ def test_get_time_entry_should_succeed_with_valid_id( Mock(), ) @patch( - 'time_tracker_api.time_entries.time_entries_dao.TimeEntriesCosmosDBDao.build_custom_query', + 'time_tracker_api.time_entries.time_entries_dao.TimeEntriesCosmosDBDao.get_owner_ids', Mock(), ) @patch( @@ -278,7 +278,7 @@ def test_get_time_entries_by_type_of_user_when_is_user_tester( Mock(), ) @patch( - 'time_tracker_api.time_entries.time_entries_dao.TimeEntriesCosmosDBDao.build_custom_query', + 'time_tracker_api.time_entries.time_entries_dao.TimeEntriesCosmosDBDao.get_owner_ids', Mock(), ) @patch( diff --git a/tests/utils/query_builder_test.py b/tests/utils/query_builder_test.py index ab1b7204..742730db 100644 --- a/tests/utils/query_builder_test.py +++ b/tests/utils/query_builder_test.py @@ -303,6 +303,7 @@ def test__build_order_by( assert orderBy_condition == expected_order_by_condition + @pytest.mark.parametrize( "attribute,ids_list,expected_not_in_list", [ @@ -313,8 +314,11 @@ def test__build_order_by( ("id", ["id"], ["c.id NOT IN ('id')"]), ("id", ["id1", "id2"], ["c.id NOT IN ('id1', 'id2')"]), ("owner_id", ["id1", "id2"], ["c.owner_id NOT IN ('id1', 'id2')"]), - ("customer_id", ["id1", "id2"], [ - "c.customer_id NOT IN ('id1', 'id2')"]), + ( + "customer_id", + ["id1", "id2"], + ["c.customer_id NOT IN ('id1', 'id2')"], + ), ], ) def test_add_sql_not_in_condition( @@ -325,7 +329,5 @@ def test_add_sql_not_in_condition( query_builder = CosmosDBQueryBuilder().add_sql_not_in_condition( attribute, ids_list ) - assert len(query_builder.where_conditions) == len( - expected_not_in_list - ) - assert query_builder.where_conditions == expected_not_in_list \ No newline at end of file + assert len(query_builder.where_conditions) == len(expected_not_in_list) + assert query_builder.where_conditions == expected_not_in_list diff --git a/time_tracker_api/activities/activities_model.py b/time_tracker_api/activities/activities_model.py index a80bc384..47d012f7 100644 --- a/time_tracker_api/activities/activities_model.py +++ b/time_tracker_api/activities/activities_model.py @@ -14,6 +14,7 @@ convert_list_to_tuple_string, create_sql_in_condition, ) +from utils.query_builder import CosmosDBQueryBuilder, Order class ActivityDao(CRUDDao): @@ -85,6 +86,38 @@ def find_all_with_id_in_list( function_mapper = self.get_mapper_or_dict(mapper) return list(map(function_mapper, result)) + def find_all( + self, + event_context: EventContext, + conditions: dict = None, + activities_id: List = None, + visible_only=True, + max_count=None, + offset=0, + mapper: Callable = None, + ): + query_builder = ( + CosmosDBQueryBuilder() + .add_sql_in_condition('id', activities_id) + .add_sql_where_equal_condition(conditions) + .add_sql_visibility_condition(visible_only) + .add_sql_limit_condition(max_count) + .add_sql_offset_condition(offset) + .build() + ) + + query_str = query_builder.get_query() + tenant_id_value = self.find_partition_key_value(event_context) + params = query_builder.get_parameters() + + result = self.container.query_items( + query=query_str, + parameters=params, + partition_key=tenant_id_value, + ) + function_mapper = self.get_mapper_or_dict(mapper) + return list(map(function_mapper, result)) + class ActivityCosmosDBDao(APICosmosDBDao, ActivityDao): def __init__(self, repository): @@ -100,6 +133,25 @@ def get_all_with_id_in_list( activity_ids, ) + def get_all( + self, + conditions: dict = None, + activities_id: List = None, + max_count=None, + visible_only=True, + ) -> list: + event_ctx = self.create_event_context("read-many") + max_count = self.repository.get_page_size_or(max_count) + + activities = self.repository.find_all( + event_context=event_ctx, + conditions=conditions, + activities_id=activities_id, + visible_only=visible_only, + max_count=max_count, + ) + return activities + def create_dao() -> ActivityDao: repository = ActivityCosmosDBRepository() diff --git a/time_tracker_api/projects/projects_model.py b/time_tracker_api/projects/projects_model.py index f72ff09d..4b3b77ab 100644 --- a/time_tracker_api/projects/projects_model.py +++ b/time_tracker_api/projects/projects_model.py @@ -68,16 +68,18 @@ def __init__(self): mapper=ProjectCosmosDBModel, ) - def find_all_v2( + def find_all( self, event_context: EventContext, - project_ids: List[str], + conditions: dict = None, + project_ids: List[str] = None, customer_ids: List[str] = None, visible_only=True, mapper: Callable = None, ): query_builder = ( CosmosDBQueryBuilder() + .add_sql_where_equal_condition(conditions) .add_sql_in_condition("id", project_ids) .add_sql_in_condition("customer_id", customer_ids) .add_sql_visibility_condition(visible_only) @@ -85,8 +87,10 @@ def find_all_v2( ) query_str = query_builder.get_query() tenant_id_value = self.find_partition_key_value(event_context) + params = query_builder.get_parameters() result = self.container.query_items( query=query_str, + parameters=params, partition_key=tenant_id_value, ) function_mapper = self.get_mapper_or_dict(mapper) @@ -97,7 +101,9 @@ class ProjectCosmosDBDao(APICosmosDBDao, ProjectDao): def __init__(self, repository): CosmosDBDao.__init__(self, repository) - def get_all(self, conditions: dict = None, **kwargs) -> list: + def get_all( + self, conditions: dict = None, project_ids: List = None, **kwargs + ) -> list: """ Get all the projects an active client has :param (dict) conditions: Conditions for querying the database @@ -115,24 +121,19 @@ def get_all(self, conditions: dict = None, **kwargs) -> list: for customer in customers if customer.status == 'active' ] + conditions = conditions if conditions else {} - custom_condition = "c.customer_id IN {}".format( - str(tuple(customers_id)) + + projects = self.repository.find_all( + event_context=event_ctx, + conditions=conditions, + project_ids=project_ids, + customer_ids=customers_id, ) - # TODO this must be refactored to be used from the utils module ↑ - if "custom_sql_conditions" in kwargs: - kwargs["custom_sql_conditions"].append(custom_condition) - else: - kwargs["custom_sql_conditions"] = [custom_condition] - projects = self.repository.find_all(event_ctx, conditions, **kwargs) add_customer_name_to_projects(projects, customers) return projects - def get_all_with_id_in_list(self, id_list): - event_ctx = self.create_event_context("read-many") - return self.repository.find_all_v2(event_ctx, id_list) - def create_dao() -> ProjectDao: repository = ProjectCosmosDBRepository() diff --git a/time_tracker_api/time_entries/time_entries_dao.py b/time_tracker_api/time_entries/time_entries_dao.py index b46260ae..98fb64b4 100644 --- a/time_tracker_api/time_entries/time_entries_dao.py +++ b/time_tracker_api/time_entries/time_entries_dao.py @@ -8,6 +8,7 @@ add_project_info_to_time_entries, add_activity_name_to_time_entries, create_custom_query_from_str, + create_list_from_str, ) from utils.time import ( datetime_str, @@ -71,7 +72,7 @@ def check_time_entry_is_not_started(self, data): "The specified time entry is already running", ) - def build_custom_query(self, is_admin: bool, conditions: dict = None): + def get_owner_ids(self, is_admin: bool, conditions: dict = None): custom_query = [] if "user_id" in conditions: if is_admin: @@ -79,11 +80,7 @@ def build_custom_query(self, is_admin: bool, conditions: dict = None): custom_query = ( [] if conditions.get("user_id") == "*" - else [ - create_custom_query_from_str( - conditions.get("user_id"), "c.owner_id" - ) - ] + else create_list_from_str(conditions.get("user_id")) ) conditions.pop("user_id") else: @@ -96,25 +93,17 @@ def get_all(self, conditions: dict = None, **kwargs) -> list: event_ctx = self.create_event_context("read-many") conditions.update({"owner_id": event_ctx.user_id}) is_complete_query = conditions.get("user_id") == '*' - custom_query = self.build_custom_query( + owner_ids = self.get_owner_ids( is_admin=event_ctx.is_admin, conditions=conditions, ) date_range = self.handle_date_filter_args(args=conditions) - limit = conditions.get("limit", None) - conditions.pop("limit", None) + limit = conditions.pop("limit", None) azure_connection = AzureConnection() current_user_is_tester = azure_connection.is_test_user( event_ctx.user_id ) - custom_query.append( - TimeEntryCosmosDBRepository.create_sql_date_range_filter( - date_range - ) - ) - custom_params = CosmosDBRepository.generate_params(date_range) - test_user_ids = ( azure_connection.get_test_user_ids() if not current_user_is_tester and is_complete_query @@ -123,11 +112,10 @@ def get_all(self, conditions: dict = None, **kwargs) -> list: time_entries_list = self.repository.find_all( conditions=conditions, - custom_sql_conditions=custom_query, test_user_ids=test_user_ids, + owner_ids=owner_ids, date_range=date_range, max_count=limit, - custom_params=custom_params, event_context=event_ctx, ) @@ -138,10 +126,7 @@ def get_lastest_entries_by_project( ) -> list: event_ctx = self.create_event_context("read-many") conditions.update({"owner_id": event_ctx.user_id}) - custom_query = self.build_custom_query( - is_admin=event_ctx.is_admin, - conditions=conditions, - ) + date_range = self.handle_date_filter_args(args=conditions) project_dao = projects_model.create_dao() @@ -157,17 +142,15 @@ def get_lastest_entries_by_project( for id_project in projects_ids: conditions.update({"project_id": id_project}) - limit = 1 latest = self.repository.find_all_entries( event_ctx, conditions=conditions, - custom_sql_conditions=custom_query, date_range=date_range, - max_count=limit, + max_count=1, ) if len(latest) > 0: - result.append(latest[0]) + self.append = result.append(latest[0]) add_activity_name_to_time_entries(result, activities) add_project_info_to_time_entries(result, projects) @@ -180,7 +163,7 @@ def get_all_paginated(self, conditions: dict = None, **kwargs) -> list: get_all_conditions.pop("start") event_ctx = self.create_event_context("read-many") get_all_conditions.update({"owner_id": event_ctx.user_id}) - custom_query = self.build_custom_query( + owner_ids = self.get_owner_ids( is_admin=event_ctx.is_admin, conditions=get_all_conditions, ) @@ -188,11 +171,11 @@ def get_all_paginated(self, conditions: dict = None, **kwargs) -> list: records_total = self.repository.count( event_ctx, conditions=get_all_conditions, - custom_sql_conditions=custom_query, + owner_ids=owner_ids, date_range=date_range, ) conditions.update({"owner_id": event_ctx.user_id}) - custom_query = self.build_custom_query( + owner_ids = self.get_owner_ids( is_admin=event_ctx.is_admin, conditions=conditions, ) @@ -203,9 +186,9 @@ def get_all_paginated(self, conditions: dict = None, **kwargs) -> list: conditions.pop("start", None) time_entries = self.repository.find_all( - event_ctx, + event_context=event_ctx, conditions=conditions, - custom_sql_conditions=custom_query, + owner_ids=owner_ids, date_range=date_range, max_count=length, offset=start, diff --git a/time_tracker_api/time_entries/time_entries_repository.py b/time_tracker_api/time_entries/time_entries_repository.py index 7128ee8e..c4bc7f02 100644 --- a/time_tracker_api/time_entries/time_entries_repository.py +++ b/time_tracker_api/time_entries/time_entries_repository.py @@ -49,41 +49,21 @@ def create_sql_ignore_id_condition(id: str): else: return "AND c.id!=@ignore_id" - @staticmethod - def create_sql_date_range_filter(date_range: dict) -> str: - if 'start_date' and 'end_date' in date_range: - return """ - ((c.start_date BETWEEN @start_date AND @end_date) OR - (c.end_date BETWEEN @start_date AND @end_date)) - """ - else: - return '' - def find_all_entries( self, event_context: EventContext, conditions: dict = None, - custom_sql_conditions: List[str] = None, date_range: dict = None, **kwargs, ): conditions = conditions if conditions else {} - custom_sql_conditions = ( - custom_sql_conditions if custom_sql_conditions else [] - ) date_range = date_range if date_range else {} - custom_sql_conditions.append( - self.create_sql_date_range_filter(date_range) - ) - - custom_params = self.generate_params(date_range) time_entries = CosmosDBRepository.find_all( self, event_context=event_context, conditions=conditions, - custom_sql_conditions=custom_sql_conditions, - custom_params=custom_params, + date_range=date_range, max_count=kwargs.get("max_count", None), offset=kwargs.get("offset", 0), ) @@ -93,51 +73,28 @@ def count( self, event_context: EventContext, conditions: dict = None, - custom_sql_conditions: List[str] = None, + owner_ids: list = None, date_range: dict = None, visible_only=True, **kwargs, ): - conditions = conditions if conditions else {} - custom_sql_conditions = ( - custom_sql_conditions if custom_sql_conditions else [] - ) - date_range = date_range if date_range else {} - - custom_sql_conditions.append( - self.create_sql_date_range_filter(date_range) - ) - - custom_params = self.generate_params(date_range) - partition_key_value = self.find_partition_key_value(event_context) - params = [ - {"name": "@partition_key_value", "value": partition_key_value}, - ] - params.extend(self.generate_params(conditions)) - params.extend(custom_params) - - query_str = """ - SELECT VALUE COUNT(1) FROM c - WHERE c.{partition_key_attribute}=@partition_key_value - {conditions_clause} - {visibility_condition} - {custom_sql_conditions_clause} - """.format( - partition_key_attribute=self.partition_key_attribute, - visibility_condition=self.create_sql_condition_for_visibility( - visible_only - ), - conditions_clause=self.create_sql_where_conditions(conditions), - custom_sql_conditions_clause=self.create_custom_sql_conditions( - custom_sql_conditions - ), + query_builder = ( + TimeEntryQueryBuilder() + .add_select_conditions(["VALUE COUNT(1)"]) + .add_sql_in_condition('owner_id', owner_ids) + .add_sql_where_equal_condition(conditions) + .add_sql_visibility_condition(visible_only) + .add_sql_date_range_condition(date_range) + .build() ) - flask.current_app.logger.debug(query_str) + query_str = query_builder.get_query() + params = query_builder.get_parameters() + tenant_id_value = self.find_partition_key_value(event_context) result = self.container.query_items( query=query_str, parameters=params, - partition_key=partition_key_value, + partition_key=tenant_id_value, ) return result.next() @@ -146,14 +103,12 @@ def add_complementary_info( self, time_entries=None, max_count=None, exist_conditions=False ): if time_entries: - custom_conditions = create_in_condition(time_entries, "project_id") - custom_conditions_activity = create_in_condition( - time_entries, "activity_id" - ) + project_ids = list(set([x.project_id for x in time_entries])) + activity_ids = list(set([x.activity_id for x in time_entries])) project_dao = projects_model.create_dao() projects = project_dao.get_all( - custom_sql_conditions=[custom_conditions], + project_ids=project_ids, visible_only=False, max_count=max_count, ) @@ -162,10 +117,11 @@ def add_complementary_info( activity_dao = activities_model.create_dao() activities = activity_dao.get_all( - custom_sql_conditions=[custom_conditions_activity], + activities_id=activity_ids, visible_only=False, max_count=max_count, ) + add_activity_name_to_time_entries(time_entries, activities) users = AzureConnection().users() @@ -177,57 +133,38 @@ def add_complementary_info( def find_all( self, conditions, - custom_sql_conditions, event_context: EventContext, date_range: dict = None, + owner_ids: list = None, test_user_ids=None, offset=0, max_count=None, visible_only=True, - custom_params: dict = None, mapper: Callable = None, ): - partition_key_value = self.find_partition_key_value(event_context) max_count = self.get_page_size_or(max_count) + date_range = date_range if date_range else {} - params = [ - {"name": "@partition_key_value", "value": partition_key_value}, - {"name": "@offset", "value": offset}, - {"name": "@max_count", "value": max_count}, - ] - - params.extend(self.generate_params(conditions)) - params.extend(custom_params) - - query_str = """ - SELECT * FROM c - WHERE c.{partition_key_attribute}=@partition_key_value - {conditions_clause} - {visibility_condition} - {test_users_exclusion_condition} - {custom_sql_conditions_clause} - {order_clause} - OFFSET @offset LIMIT @max_count - """.format( - partition_key_attribute=self.partition_key_attribute, - visibility_condition=self.create_sql_condition_for_visibility( - visible_only - ), - conditions_clause=self.create_sql_where_conditions(conditions), - test_users_exclusion_condition=self.create_sql_test_users_exclusion_condition( - test_user_ids - ), - custom_sql_conditions_clause=self.create_custom_sql_conditions( - custom_sql_conditions - ), - order_clause=self.create_sql_order_clause(), + query_builder = ( + TimeEntryQueryBuilder() + .add_sql_in_condition('owner_id', owner_ids) + .add_sql_where_equal_condition(conditions) + .add_sql_visibility_condition(visible_only) + .add_sql_date_range_condition(date_range) + .add_sql_not_in_condition('owner_id', test_user_ids) + .add_sql_order_by_condition('start_date', Order.DESC) + .add_sql_limit_condition(max_count) + .add_sql_offset_condition(offset) + .build() ) + query_str = query_builder.get_query() + params = query_builder.get_parameters() + tenant_id_value = self.find_partition_key_value(event_context) result = self.container.query_items( query=query_str, parameters=params, - partition_key=partition_key_value, - max_item_count=max_count, + partition_key=tenant_id_value, ) function_mapper = self.get_mapper_or_dict(mapper) @@ -238,13 +175,6 @@ def find_all( time_entries, max_count, exist_conditions ) - def create_sql_test_users_exclusion_condition(self, test_user_ids): - if test_user_ids != None: - tuple_string = convert_list_to_tuple_string(test_user_ids) - return "AND c.owner_id NOT IN {list}".format(list=tuple_string) - - return "" - def get_last_entry( self, owner_id: str, diff --git a/utils/extend_model.py b/utils/extend_model.py index 6eecedcf..b13faa44 100644 --- a/utils/extend_model.py +++ b/utils/extend_model.py @@ -28,7 +28,11 @@ def add_project_info_to_time_entries(time_entries, projects): for time_entry in time_entries: for project in projects: if time_entry.project_id == project.id: - name = project.name + " (archived)" if project.is_deleted() else project.name + name = ( + project.name + " (archived)" + if project.is_deleted() + else project.name + ) setattr(time_entry, 'project_name', name) setattr(time_entry, 'customer_id', project.customer_id) setattr(time_entry, 'customer_name', project.customer_name) @@ -38,7 +42,11 @@ def add_activity_name_to_time_entries(time_entries, activities): for time_entry in time_entries: for activity in activities: if time_entry.activity_id == activity.id: - name = activity.name + " (archived)" if activity.is_deleted() else activity.name + name = ( + activity.name + " (archived)" + if activity.is_deleted() + else activity.name + ) setattr(time_entry, 'activity_name', name) @@ -89,3 +97,7 @@ def create_custom_query_from_str( else: query_str = "{} = '{}'".format(first_attr, data[0]) return query_str + + +def create_list_from_str(data: str, delimiter: str = ",") -> list: + return [id for id in data.split(delimiter)] if data else [] diff --git a/utils/query_builder.py b/utils/query_builder.py index 1fd0e5c9..2899aab4 100644 --- a/utils/query_builder.py +++ b/utils/query_builder.py @@ -53,7 +53,7 @@ def add_sql_limit_condition(self, limit): return self def add_sql_offset_condition(self, offset): - if offset: + if offset != None: self.offset = offset return self @@ -61,8 +61,9 @@ def add_sql_order_by_condition(self, attribute: str, order: Order): self.order_by = (attribute, order.name) return self - - def add_sql_not_in_condition(self, attribute: str = None, ids_list: List[str] = None): + def add_sql_not_in_condition( + self, attribute: str = None, ids_list: List[str] = None + ): if ids_list and attribute and len(ids_list) > 0: ids_values = convert_list_to_tuple_string(ids_list) self.where_conditions.append(f"c.{attribute} NOT IN {ids_values}") @@ -80,14 +81,14 @@ def __build_where(self): return "" def __build_offset(self): - if self.offset: + if self.offset != None: self.parameters.append({'name': '@offset', 'value': self.offset}) return "OFFSET @offset" else: return "" def __build_limit(self): - if self.limit: + if self.limit != None: self.parameters.append({'name': '@limit', 'value': self.limit}) return "LIMIT @limit" else: