Untitled
unknown
python
4 years ago
5.2 kB
6
Indexable
class UserRetailerAnnouncementViewSet(BaseViewSet):
@authorized_user_required
def list(self, request, user_pk, retailer_pk=None):
"""
List retailer announcements.
---
parameters:
- name: user_pk
paramType: path
defaultValue: me
required: true
type: integer
response_serializer: serializers.AnnouncementListSerializer
"""
# This ViewSet is used in both 'user-announcement' and
# 'user-retailer-announcement' routes.
country = context.country
if not country:
raise ServiceException('HTTP_YOYO_COUNTRY header is missing', status=400)
retailer_ids_for_mobile_filtering = self.get_retailer_ids_for_mobile_filtering(
user_id=request.user.pk, path_retailer_id=retailer_pk
)
if (
context.api_client_name == APPLICATION_DEFAULT
and not self.request_retailer_id
and not retailer_pk
):
# Unfiltered request from Yoyo Wallet. Return retailer space enabled
# retailer ids that are visible to app.
retailer_ids = list(
set(
retailer_tasks_sync.get_retailer_ids_for_enabled_retailer_spaces(
user_id=user_pk
)
)
& set(
get_retailer_ids_by_api_client_name(
api_client_name=context.api_client_name
)
)
)
else:
retailer_ids = self.resolve_retailer_ids(path_retailer_id=retailer_pk)
announcements_to_m2m_ids = defaultdict(list)
announcements_to_retailer_ids = defaultdict(list)
retailer_read_replica_db = read_replica_router.db_for_read(
retailer_models.AnnouncementExcludedApiKey
)
if retailer_ids:
eligible_rule_ids = list(
loyalty_rules_tasks_sync.get_eligible_rule_ids(
user_id=user_pk,
retailer_ids=retailer_ids,
country_code=context.country,
)
)
api_key_excluded_announcements_pks = (
retailer_models.AnnouncementExcludedApiKey.objects.filter(
api_key_id=context.api_key_id
).values_list('announcement_id', flat=True)
) # yapf: disable
announcements_qs = (
retailer_models.Announcement.objects.not_dismissed_for_user(
user_id=user_pk
)
.active(country_code=context.country)
.prefetch_related_userannouncement_for_user(user_id=user_pk)
.filter(retailers__in=retailer_ids)
.filter(Q(rule_id__in=eligible_rule_ids) | Q(rule_id__isnull=True))
.exclude(pk__in=api_key_excluded_announcements_pks)
.order_by('priority_visibility', 'pk')
) # yapf: disable
announcement_retailer_values = (
retailer_models.Announcement.retailers.through.objects.filter(
announcement_id__in=announcements_qs.values_list('pk', flat=True),
retailer_id__in=retailer_ids,
)
.values_list('announcement_id', 'pk', 'retailer_id')
.using(retailer_read_replica_db)
)
for (announcement_id, m2m_id, retailer_id) in announcement_retailer_values:
announcements_to_retailer_ids[announcement_id].append(retailer_id)
announcements_to_m2m_ids[announcement_id].append(m2m_id)
else:
announcements_qs = retailer_models.Announcement.objects.none()
announcements_qs = announcements_qs.prefetch_related(
'brand_announcement_content__assets'
)
# add read replica at this point to avoid issues using read replica in
# a SQL IN statement
announcements_qs = announcements_qs.using(retailer_read_replica_db)
# Create auto dismiss entries. Materialises queryset.
announcements_qs.ensure_auto_dismiss_for_user(user_id=user_pk)
loyalty_read_replica_db = read_replica_router.db_for_read(
loyalty_rules_models.Rule
)
announcements_rules = loyalty_rules_models.Rule.objects.using(
loyalty_read_replica_db
).filter(
pk__in=list(
announcement.rule_id
for announcement in announcements_qs
if announcement.rule_id
)
) # yapf: disable
data = serializers.AnnouncementListSerializer(
{
'announcements': announcements_qs,
'retailer_ids': retailer_ids_for_mobile_filtering,
},
context={
'rule_ids_to_rules': {rule.id: rule for rule in announcements_rules},
'announcements_to_retailer_ids': announcements_to_retailer_ids,
'announcements_to_m2m_ids': announcements_to_m2m_ids,
},
).data
return render_success_response(data)Editor is loading...