diff --git a/apps/promotions/models.py b/apps/promotions/models.py index 52c21f3..df5f081 100644 --- a/apps/promotions/models.py +++ b/apps/promotions/models.py @@ -77,6 +77,7 @@ class Event(BaseModel): name='promotions_event_data_bc656abc' ), ] + ordering = ('-created_at',) def __str__(self): return self.label @@ -175,8 +176,29 @@ class Recipient(BaseModel): def get_recipient_uuid(self, plan=None, event=None): if ':' in self.recipient_uuid_field and not self.recipient_uuid_field.startswith('QS:'): + filters_key_values, recipient_candidate = self.recipient_uuid_field.split('->') + key_values = filters_key_values and filters_key_values.split('&') or [] + for key_value in key_values: + model_name_key, value = key_value.split('=') + model_name, key = model_name_key.split(':') + if model_name == 'event': + obj = event + elif model_name == 'plan': + obj = plan + else: + raise NotImplementedError() - model_name, key = self.recipient_uuid_field.split(':') + if key.startswith('data__'): + key = key[len('data__'):] + obj_value = obj.data.get(key) + else: + obj_value = getattr(obj, key) + + if obj_value != value: + return None + + + model_name, key = recipient_candidate.split(':') if model_name == 'event': obj = event elif model_name == 'plan': @@ -185,6 +207,7 @@ class Recipient(BaseModel): raise NotImplementedError() return obj.data.get(key) + elif ':' in self.recipient_uuid_field and self.recipient_uuid_field.startswith('QS:'): params, recipient_candidate = self.recipient_uuid_field.split('->') query_set_flag, model, filters, = params.split(':') @@ -202,8 +225,14 @@ class Recipient(BaseModel): else: raise NotImplementedError() - if model_class.objects.filter(**filter_params).exists(): - return recipient_candidate + model_object = model_class.objects.filter(**filter_params).last() + + if model_object: + try: + uuid.UUID(recipient_candidate) + return recipient_candidate + except: + return model_object.data.get(recipient_candidate) else: try: @@ -252,10 +281,14 @@ class Recipient(BaseModel): def promote(self, plan=None, event=None): recipient = self.get_recipient_uuid(plan, event) + if not recipient: + return None + + base_amount, promotion_amount = self.get_promotion_amount(plan=plan, event=event) promotion, created = Promotion.objects.get_or_create( promotion_amount=promotion_amount, - user_uuid=self.get_recipient_uuid(plan, event), + user_uuid=recipient, event=event, plan=plan, recipient=self, diff --git a/apps/promotions/tests.py b/apps/promotions/tests.py index caebf8c..911cdca 100644 --- a/apps/promotions/tests.py +++ b/apps/promotions/tests.py @@ -151,7 +151,7 @@ class ApplicationApiFlowsTests(APITestCase): label=self.first_ad_view_reward_label, plan=self.first_ad_view_reward_plan, wallet_uuid=self.user_1_uuid, - recipient_uuid_field="event:user", + recipient_uuid_field="->event:user", base_amount_field="event:base_amount", ) @@ -201,7 +201,7 @@ class ApplicationApiFlowsTests(APITestCase): label=self.referral_reward_label, plan=self.referral_reward_plan, wallet_uuid=self.user_1_uuid, - recipient_uuid_field="event:referral", + recipient_uuid_field="->event:referral", base_amount_field="1000", ) @@ -343,3 +343,113 @@ class ApplicationApiFlowsTests(APITestCase): response = self.client.post(reverse('promotions:promotion-create', kwargs={'plan': str(self.settlement_reward_plan.uuid)}), submit_settlement_create_data, HTTP_AUTHORIZATION=auth, format='json') print(response.json()) + + def test_serial_ad_view_promotion_success(self): + serial_id = 'b14e8b86-8f4a-44d9-b29d-badceb470053' + self.serial_ad_view_1_event_saver, _created = EventSaver.objects.get_or_create( + title='serial_ad_view_1', + event_label='serial_ad_view_1', + save_once=True, + ) + + self.serial_ad_view_2_event_saver, _created = EventSaver.objects.get_or_create( + title='serial_ad_view_2', + event_label='serial_ad_view_2', + save_once=True, + ) + + self.serial_ad_view_3_event_saver, _created = EventSaver.objects.get_or_create( + title='serial_ad_view_3', + event_label='serial_ad_view_3', + save_once=True, + ) + + self.serial_promotion_plan, _created = Plan.objects.get_or_create( + title=self.settlement_reward_label, + balance=100000, + user=self.user_1, + application=self.application, + event_list=['serial_ad_view_1', 'serial_ad_view_2', 'serial_ad_view_3'] + ) + + self.serial_ad_view_1_recipient, _created = Recipient.objects.get_or_create( + label='serial_ad_view_1_event_saver_label', + plan=self.serial_promotion_plan, + wallet_uuid=self.user_1_uuid, + recipient_uuid_field=f"event:label=serial_ad_view_1&event:data__serial={serial_id}->event:user", + base_amount_field=300, + # data={"max_promotion_amount": 0, "promotion_percentage": 50} + + ) + + self.serial_ad_view_2_recipient, _created = Recipient.objects.get_or_create( + label='serial_ad_view_2_event_saver_label', + plan=self.serial_promotion_plan, + wallet_uuid=self.user_1_uuid, + recipient_uuid_field=f"event:label=serial_ad_view_2&event:data__serial={serial_id}->event:user", + # recipient_uuid_field=f"QS:Event:label=serial_ad_view_2&data__user={self.user_1_uuid}&data__serial={serial_id}->user", + base_amount_field=200, + # data={"max_promotion_amount": 0, "promotion_percentage": 50} + + ) + + self.serial_ad_view_3_recipient, _created = Recipient.objects.get_or_create( + label='serial_ad_view_3_event_saver_label', + plan=self.serial_promotion_plan, + wallet_uuid=self.user_1_uuid, + recipient_uuid_field=f"event:label=serial_ad_view_3&event:data__serial={serial_id}->event:user", + # recipient_uuid_field=f"QS:Event:label=serial_ad_view_3&data__user={self.user_1_uuid}&data__serial={serial_id}->user", + base_amount_field=100, + # data={"max_promotion_amount": 0, "promotion_percentage": 50} + + ) + + auth = self._create_authorization_header(self.user_access_token.token) + + serial_ad_1_event_create_data = { + 'label': 'serial_ad_view_1', + "data": { + 'user': self.user_1_uuid, + 'serial': serial_id + } + } + serial_ad_2_event_create_data = { + 'label': 'serial_ad_view_2', + "data": { + 'user': self.user_1_uuid, + 'serial': serial_id + } + } + serial_ad_3_event_create_data = { + 'label': 'serial_ad_view_3', + "data": { + 'user': self.user_1_uuid, + 'serial': serial_id + } + } + + self.assertEqual(Event.objects.count(), 0) + + response = self.client.post(reverse('promotions:event-create'), serial_ad_2_event_create_data, HTTP_AUTHORIZATION=auth, format='json') + print(response.json()) + event_2 = Event.objects.first() + + return + + response = self.client.post(reverse('promotions:event-create'), serial_ad_1_event_create_data, HTTP_AUTHORIZATION=auth, format='json') + event_1 = Event.objects.first() + response = self.client.post(reverse('promotions:event-create'), serial_ad_2_event_create_data, HTTP_AUTHORIZATION=auth, format='json') + event_2 = Event.objects.first() + response = self.client.post(reverse('promotions:event-create'), serial_ad_3_event_create_data, HTTP_AUTHORIZATION=auth, format='json') + event_3 = Event.objects.first() + + analyze_event_task(event_1.uuid) + analyze_event_task(event_2.uuid) + analyze_event_task(event_3.uuid) + print(response.json()) + + self.serial_promotion_plan.refresh_from_db() + + self.assertEqual(self.serial_promotion_plan.balance, 100000) + self.assertEqual(Event.objects.count(), 3) +