From dce54cd74d637b8b62a655400b6860ac60b90f8d Mon Sep 17 00:00:00 2001 From: Zeryab Khan Date: Tue, 4 Jun 2024 15:17:40 +0500 Subject: [PATCH] [ISSUE-3543] Project sync in CW deletes all projects --- djconnectwise/__init__.py | 2 +- djconnectwise/sync.py | 87 ++++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/djconnectwise/__init__.py b/djconnectwise/__init__.py index 2ac7bc4..288c9ec 100644 --- a/djconnectwise/__init__.py +++ b/djconnectwise/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -VERSION = (1, 5, 6, 'final') +VERSION = (1, 5, 7, 'final') # pragma: no cover if VERSION[-1] != "final": diff --git a/djconnectwise/sync.py b/djconnectwise/sync.py index b19d621..6a9b22f 100644 --- a/djconnectwise/sync.py +++ b/djconnectwise/sync.py @@ -2147,11 +2147,43 @@ def parent_object_ids(self): self.lookup_key).values_list(self.lookup_key, flat=True) +class ProjectSynchronizerMixin(BatchConditionMixin): + def get_batch_condition(self, conditions): + batch_condition = 'status/id in ({})'.format( + ','.join([str(i) for i in conditions]) + ) + + request_settings = DjconnectwiseSettings().get_settings() + keep_closed = request_settings.get('keep_closed_ticket_days') + if keep_closed and self.full: + batch_condition = self.format_conditions( + keep_closed, batch_condition, request_settings + ) + + return batch_condition + + def format_conditions(self, keep_closed, + batch_condition, request_settings): + closed_date = timezone.now() - timezone.timedelta(days=keep_closed) + condition = 'lastUpdated>[{}]'.format(closed_date) + + keep_closed_board_ids = \ + request_settings.get('keep_closed_status_board_ids') + if keep_closed_board_ids: + condition = '{} and board/id in ({})'.format( + condition, ','.join(map(str, keep_closed_board_ids)) + ) + + batch_condition = '{} or {}'.format(batch_condition, condition) + return batch_condition + + class ProjectSynchronizer(CreateRecordMixin, - UpdateRecordMixin, + UpdateRecordMixin, ProjectSynchronizerMixin, Synchronizer): client_class = api.ProjectAPIClient model_class = models.ProjectTracker + batch_condition_list = [] related_meta = { 'status': (models.ProjectStatus, 'status'), 'manager': (models.Member, 'manager'), @@ -2181,43 +2213,32 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.full: - # Only sync projects in non-closed statuses. We could simply use - # closedFlag=False but API versions before 2019.5 don't support the - # closedFlag field and we need to support those versions for now. - project_conditions = [ - 'status/id in ({})'.format( - ','.join( - str(status.id) - for status in models.ProjectStatus.objects.filter( - closed_flag=False - ) - ) - ) - ] - request_settings = DjconnectwiseSettings().get_settings() - keep_closed_days = request_settings.get('keep_closed_ticket_days') - if keep_closed_days: - project_conditions = self.format_conditions( - keep_closed_days, project_conditions, request_settings + self.api_conditions = ['status/id in ({})'.format( + ','.join( + str(i.id) for + i in models.ProjectStatus.objects.filter(closed_flag=False) ) + )] - self.api_conditions = project_conditions + request_settings = DjconnectwiseSettings().get_settings() + board_ids = request_settings.get('board_status_filter') - def format_conditions(self, keep_closed_days, - project_conditions, request_settings): - closed_date = \ - timezone.now() - timezone.timedelta(days=keep_closed_days) - condition = 'lastUpdated>[{}]'.format(closed_date) + filtered_statuses = models.ProjectStatus.objects.filter( + closed_flag=False + ) - keep_closed_board_ids = \ - request_settings.get('keep_closed_status_board_ids') - if keep_closed_board_ids: - condition = '{} and board/id in ({})'.format( - condition, keep_closed_board_ids - ) + if board_ids: + boards_exist = models.ConnectWiseBoard.objects.filter( + id__in=board_ids).exists() + + if boards_exist: + filtered_statuses = filtered_statuses.filter( + board__id__in=board_ids + ) - project_conditions.append(condition) - return project_conditions + if filtered_statuses: + self.batch_condition_list = \ + list(filtered_statuses.values_list('id', flat=True)) def _assign_field_data(self, instance, json_data): actual_start = json_data.get('actualStart')