end of day
This commit is contained in:
parent
3d55d4eba3
commit
e3ec65a118
3 changed files with 57 additions and 11 deletions
|
|
@ -2,9 +2,10 @@ from functools import update_wrapper
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import Promotion, Plan
|
from .models import Promotion, Plan, Event
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Plan)
|
admin.site.register(Plan)
|
||||||
admin.site.register(Promotion)
|
admin.site.register(Promotion)
|
||||||
|
admin.site.register(Event)
|
||||||
|
|
||||||
|
|
|
||||||
32
apps/promotions/migrations/0005_event_plan_event_list.py
Normal file
32
apps/promotions/migrations/0005_event_plan_event_list.py
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Generated by Django 5.2.6 on 2025-09-16 17:32
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('promotions', '0004_promotion_base_amount'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Event',
|
||||||
|
fields=[
|
||||||
|
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True, db_index=True)),
|
||||||
|
('label', models.CharField(db_index=True, max_length=255)),
|
||||||
|
('details', models.JSONField()),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='plan',
|
||||||
|
name='event_list',
|
||||||
|
field=models.JSONField(default=list),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -16,15 +16,19 @@ class EventQuerySet(models.QuerySet):
|
||||||
|
|
||||||
class Event(BaseModel):
|
class Event(BaseModel):
|
||||||
label = models.CharField(max_length=255, db_index=True)
|
label = models.CharField(max_length=255, db_index=True)
|
||||||
details = models.JSONField() # from to amount application user etc
|
data = models.JSONField() # from to amount application user etc
|
||||||
|
|
||||||
objects = EventQuerySet.as_manager()
|
objects = EventQuerySet.as_manager()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.label
|
||||||
|
|
||||||
def analyze(self):
|
def analyze(self):
|
||||||
for plan in Plan.objects.get_related_to_event(self):
|
for plan in Plan.objects.get_related_to_event(self):
|
||||||
plan.process_event(self)
|
plan.process_event(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PlanQuerySet(models.QuerySet):
|
class PlanQuerySet(models.QuerySet):
|
||||||
|
|
||||||
# this is for list of discount code for example
|
# this is for list of discount code for example
|
||||||
|
|
@ -65,20 +69,29 @@ class Plan(BaseModel):
|
||||||
def calculate_promotion(self, **kwargs):
|
def calculate_promotion(self, **kwargs):
|
||||||
handler = self.handler
|
handler = self.handler
|
||||||
self.base_amount = kwargs.get('base_amount', 0)
|
self.base_amount = kwargs.get('base_amount', 0)
|
||||||
self.promotion_amount = handler.calculate(**kwargs)
|
return handler.calculate(**kwargs)
|
||||||
return self.promotion_amount
|
|
||||||
|
|
||||||
def reserve_promotion(self, promotion):
|
def reserve_promotion_amount(self, amount):
|
||||||
updated = False
|
updated = False
|
||||||
if self.balance >= promotion.promotion_amount:
|
if amount and self.balance >= amount:
|
||||||
updated = Plan.objects.filter(pk=self.pk, balance__gte=promotion.promotion_amount).update(
|
updated = Plan.objects.filter(pk=self.pk, balance__gte=amount).update(
|
||||||
balance=F('balance') - promotion.promotion_amount
|
balance=F('balance') - amount
|
||||||
)
|
)
|
||||||
return updated
|
return updated
|
||||||
|
|
||||||
def process_event(self, event=None):
|
def process_event(self, event=None):
|
||||||
promotion, created = Promotion.objects.get_or_create()
|
referral_code = event.data.get('referral_code')
|
||||||
promotion.promote()
|
user_uuid = event.data.get('user_uuid')
|
||||||
|
promotion_amount = self.calculate_promotion()
|
||||||
|
if referral_code and promotion_amount and not self.promotions.filter(user_id=referral_code, data__user_uuid=user_uuid).exists():
|
||||||
|
with transaction.atomic():
|
||||||
|
if self.reserve_promotion_amount(promotion_amount):
|
||||||
|
promotion, created = Promotion.objects.get_or_create()
|
||||||
|
if created:
|
||||||
|
raise Exception('Promotion already reserved')
|
||||||
|
else:
|
||||||
|
raise Exception('Promotion already reserved')
|
||||||
|
promotion.promote()
|
||||||
|
|
||||||
|
|
||||||
class PromotionQuerySet(models.QuerySet):
|
class PromotionQuerySet(models.QuerySet):
|
||||||
|
|
@ -127,7 +140,7 @@ class Promotion(BaseModel):
|
||||||
|
|
||||||
def promote(self, **kwargs):
|
def promote(self, **kwargs):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
self.plan.reserve_promotion(self)
|
self.plan.reserve_promotion_amount(self)
|
||||||
self.change_state(from_states=[Promotion.StateChoices.CREATED], to_state=Promotion.StateChoices.ASSIGNED,
|
self.change_state(from_states=[Promotion.StateChoices.CREATED], to_state=Promotion.StateChoices.ASSIGNED,
|
||||||
same_ok=False, raise_exception=True)
|
same_ok=False, raise_exception=True)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue