From 74bd3e4ed986d19aaba2e43d459a0255b2978023 Mon Sep 17 00:00:00 2001 From: Sayyid Hamid Mahdavi Date: Sat, 6 Dec 2025 12:29:49 +0330 Subject: [PATCH] percentage promotion --- apps/promotions/models.py | 27 +++++++++---- apps/promotions/tests.py | 81 +++++++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/apps/promotions/models.py b/apps/promotions/models.py index d35ce02..52c21f3 100644 --- a/apps/promotions/models.py +++ b/apps/promotions/models.py @@ -43,8 +43,8 @@ class EventSaver(BaseModel): data = kwargs.get('data') if self.save_once: - event, created = Event.objects.get_or_create(user=user, application=application, label=label, - defaults={"data": data}) + event, created = Event.objects.get_or_create(user=user, label=label, + defaults={"data": data, "application": application}) if created: return event else: @@ -167,7 +167,6 @@ class Recipient(BaseModel): ), ] - def __str__(self): return f"{self.label} --> {self.plan}" @@ -216,6 +215,8 @@ class Recipient(BaseModel): def get_promotion_amount(self, plan=None, event=None): # TODO: get base amount from policy_choice base_amount = 0 + max_promotion_amount = int(self.data.get('max_promotion_amount', 0)) + promotion_percentage = int(self.data.get('promotion_percentage', 100)) try: model_name, key = self.base_amount_field.split(':') if model_name == 'event': @@ -230,9 +231,20 @@ class Recipient(BaseModel): try: base_amount = int(self.base_amount_field) # todo: to float except: - pass + logger.exception('can not pars base amount') + raise Exception('can not pars base amount') + + promotion_amount = int(base_amount * (promotion_percentage / 100)) + + if max_promotion_amount: + if promotion_amount > max_promotion_amount: + return max_promotion_amount + else: + return promotion_amount + + else: + return base_amount, promotion_amount - return base_amount # @property # def handler(self) -> BasePromotionHandler: @@ -240,14 +252,14 @@ class Recipient(BaseModel): def promote(self, plan=None, event=None): recipient = self.get_recipient_uuid(plan, event) - promotion_amount = self.get_promotion_amount(plan=plan, event=event) + 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), event=event, plan=plan, recipient=self, - base_amount=promotion_amount, + base_amount=base_amount, ) if recipient and promotion_amount and created: try: @@ -303,7 +315,6 @@ class Promotion(BaseModel): ), ] - def change_state(self, from_states: list | tuple, to_state, same_ok=True, raise_exception=False, error_message=None, data: None | dict = None): diff --git a/apps/promotions/tests.py b/apps/promotions/tests.py index f4534ae..caebf8c 100644 --- a/apps/promotions/tests.py +++ b/apps/promotions/tests.py @@ -11,7 +11,6 @@ from apps.promotions.tasks import analyze_event_task from apps.users.models import User from apps.promotions.models import Plan, Promotion, EventSaver, ProcessorTypeChoices, Event, Recipient - AccessToken = get_access_token_model() Application = get_application_model() @@ -23,7 +22,6 @@ def mock_submit_deposit_success(wallet_uuid, data): class Tmp(): uuid = sys_uuid.uuid4() - data = Tmp() return data @@ -39,6 +37,7 @@ def mock_verify_deposit_success(wallet_uuid, transaction_uuid): return data + def mock_submit_withdraw_success(data): import uuid as sys_uuid class Tmp(): @@ -88,7 +87,6 @@ class ApplicationApiFlowsTests(APITestCase): # self.verify_withdraw_success_patcher = patch('apps.promotions.models.withdraw_from_user_wallet_verify', # mock_verify_withdraw_success) - self.submit_deposit_success_patcher.start() self.verify_deposit_success_patcher.start() # self.submit_withdraw_success_patcher.start() @@ -97,7 +95,6 @@ class ApplicationApiFlowsTests(APITestCase): self.user_1, _ = User.objects.get_or_create(pk=self.user_1_uuid) self.user_2, _ = User.objects.get_or_create(pk=self.user_2_uuid) - expire_datetime = timezone.now() + timedelta(seconds=3600) expire_datetime.isoformat() @@ -164,7 +161,7 @@ class ApplicationApiFlowsTests(APITestCase): 'label': self.first_ad_view_reward_label, "data": { 'user': self.user_1_uuid, - 'base_amount':800 + 'base_amount': 800 } } response = self.client.get(reverse('promotions:promotion-list', kwargs={"plan": self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, @@ -172,18 +169,19 @@ class ApplicationApiFlowsTests(APITestCase): print(response.json()) print(response.status_code) # response = self.client.post(reverse('promotions:user-promote', kwargs={"pk":self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, format='json') - response = self.client.post(reverse('promotions:promotion-create', kwargs={"plan":self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, format='json') + response = self.client.post(reverse('promotions:promotion-create', kwargs={"plan": self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, + format='json') print(response.json()) self.first_ad_view_reward_plan.refresh_from_db() self.assertEqual(self.first_ad_view_reward_plan.balance, 10000 - 800) - response = self.client.get(reverse('promotions:promotion-list', kwargs={"plan":self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, format='json') + response = self.client.get(reverse('promotions:promotion-list', kwargs={"plan": self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, + format='json') print(response.json()) # response = self.client.post(reverse('promotions:promotion-create', kwargs={"plan": self.first_ad_view_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, format='json') # print(response.json()) - def test_referral_reward_success(self): self.referral_reward_event_saver, _created = EventSaver.objects.get_or_create( title=self.referral_reward_label, @@ -216,13 +214,13 @@ class ApplicationApiFlowsTests(APITestCase): 'referral': self.user_2_uuid } } - response = self.client.post(reverse('promotions:promotion-create', kwargs={"plan": self.referral_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, format='json') + response = self.client.post(reverse('promotions:promotion-create', kwargs={"plan": self.referral_reward_plan.uuid}), event_create_data, HTTP_AUTHORIZATION=auth, + format='json') print(response.json()) self.referral_reward_plan.refresh_from_db() self.assertEqual(self.referral_reward_plan.balance, 10000 - 1000) self.assertEqual(response.json()['promotions'][0]['user'], str(self.user_2_uuid)) - def test_referral_reward_submit_settlement_success(self): self.referral_reward_event_saver, _created = EventSaver.objects.get_or_create( title=self.referral_reward_label, @@ -277,12 +275,71 @@ class ApplicationApiFlowsTests(APITestCase): self.assertEqual(self.settlement_reward_plan.balance, 100000) self.assertEqual(Event.objects.count(), 1) - 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') + 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()) - 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') + 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_referral_percentage_reward_submit_settlement_success(self): + self.referral_reward_event_saver, _created = EventSaver.objects.get_or_create( + title=self.referral_reward_label, + event_label=self.referral_reward_label, + save_once=True, + ) + self.settlement_reward_event_saver, _created = EventSaver.objects.get_or_create( + title=self.settlement_reward_label, + event_label=self.settlement_reward_label, + save_once=False, + ) + self.settlement_reward_plan, _created = Plan.objects.get_or_create( + title=self.settlement_reward_label, + balance=100000, + user=self.user_1, + application=self.application, + event_list=[self.settlement_reward_label] + ) + self.settlement_referral_reward_recipient, _created = Recipient.objects.get_or_create( + label='settlement_referral_reward_label', + plan=self.settlement_reward_plan, + wallet_uuid=self.user_1_uuid, + # recipient_uuid_field=self.user_2_uuid, + recipient_uuid_field=f"QS:Event:label={self.referral_reward_label}&data__referral={self.user_2_uuid}->{self.user_2_uuid}", + base_amount_field="event:base_amount", + data={"max_promotion_amount": 0, "promotion_percentage": 50} + ) + + auth = self._create_authorization_header(self.user_access_token.token) + submit_referral_create_data = { + 'label': self.referral_reward_label, + "data": { + 'user': self.user_1_uuid, + 'referral': self.user_2_uuid + } + } + submit_settlement_create_data = { + 'label': self.settlement_reward_label, + "data": { + 'user': self.user_1_uuid, + 'settlement': self.user_2_uuid, + 'base_amount': 7000 + } + } + self.assertEqual(Event.objects.count(), 0) + response = self.client.post(reverse('promotions:event-create'), submit_referral_create_data, HTTP_AUTHORIZATION=auth, format='json') + print(response.json()) + self.settlement_reward_plan.refresh_from_db() + self.assertEqual(self.settlement_reward_plan.balance, 100000) + self.assertEqual(Event.objects.count(), 1) + + 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()) + 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())