forked from CGM_Public/pretix_original
Check-in: Add rule for number of days with entries since (#3808)
This commit is contained in:
@@ -202,7 +202,7 @@ def _logic_explain(rules, ev, rule_data, now_dt=None):
|
||||
'var': values[0]["var"],
|
||||
'rhs': values[1:],
|
||||
}
|
||||
elif "entries_since" in values[0] or "entries_before" in values[0]:
|
||||
elif any(t in values[0] for t in ("entries_since", "entries_before", "entries_days_since", "entries_days_before")):
|
||||
_var_explanations[new_var_name] = {
|
||||
'operator': operator,
|
||||
'var': values[0],
|
||||
@@ -280,11 +280,13 @@ def _logic_explain(rules, ev, rule_data, now_dt=None):
|
||||
var_weights[vname] = (500, 0)
|
||||
var_texts[vname] = _('Wrong entrance gate')
|
||||
elif var in ('entries_number', 'entries_today', 'entries_days', 'minutes_since_last_entry', 'minutes_since_first_entry', 'now_isoweekday') \
|
||||
or (isinstance(var, dict) and ("entries_since" in var or "entries_before" in var)):
|
||||
or (isinstance(var, dict) and any(t in var for t in ("entries_since", "entries_before", "entries_days_since", "entries_days_before"))):
|
||||
w = {
|
||||
'minutes_since_first_entry': 80,
|
||||
'minutes_since_last_entry': 90,
|
||||
'entries_days': 100,
|
||||
'entries_days_since': 105,
|
||||
'entries_days_before': 105,
|
||||
'entries_since': 110,
|
||||
'entries_before': 110,
|
||||
'entries_number': 120,
|
||||
@@ -307,10 +309,12 @@ def _logic_explain(rules, ev, rule_data, now_dt=None):
|
||||
'entries_today': _('number of entries today'),
|
||||
'entries_since': _('number of entries since {datetime}'),
|
||||
'entries_before': _('number of entries before {datetime}'),
|
||||
'entries_days_since': _('number of days with an entry since {datetime}'),
|
||||
'entries_days_before': _('number of days with an entry before {datetime}'),
|
||||
'now_isoweekday': _('week day'),
|
||||
}
|
||||
|
||||
if isinstance(var, dict) and ("entries_since" in var or "entries_before" in var):
|
||||
if isinstance(var, dict) and any(t in var for t in ("entries_since", "entries_before", "entries_days_since", "entries_days_before")):
|
||||
varname = list(var.keys())[0]
|
||||
cutoff = _build_time(*var[varname][0]['buildTime'], ev=ev, now_dt=now_dt).astimezone(ev.timezone)
|
||||
if abs(now_dt - cutoff) < timedelta(hours=12):
|
||||
@@ -410,6 +414,8 @@ def _get_logic_environment(ev, rule_data, now_dt):
|
||||
logic.add_operation('isAfter', lambda t1, t2, tol=None: is_before(t2, t1, tol))
|
||||
logic.add_operation('entries_since', lambda t1: rule_data.entries_since(t1))
|
||||
logic.add_operation('entries_before', lambda t1: rule_data.entries_before(t1))
|
||||
logic.add_operation('entries_days_since', lambda t1: rule_data.entries_days_since(t1))
|
||||
logic.add_operation('entries_days_before', lambda t1: rule_data.entries_days_before(t1))
|
||||
return logic
|
||||
|
||||
|
||||
@@ -467,6 +473,32 @@ class LazyRuleVars:
|
||||
self.__cache['entries_before', cutoff] = self._position.checkins.filter(type=Checkin.TYPE_ENTRY, list=self._clist, datetime__lt=cutoff).count()
|
||||
return self.__cache['entries_before', cutoff]
|
||||
|
||||
def entries_days_since(self, cutoff):
|
||||
tz = self._clist.event.timezone
|
||||
with override(tz):
|
||||
if ('entries_days_since', cutoff) not in self.__cache:
|
||||
self.__cache['entries_days_since', cutoff] = self._position.checkins.filter(
|
||||
type=Checkin.TYPE_ENTRY,
|
||||
list=self._clist,
|
||||
datetime__gte=cutoff
|
||||
).annotate(
|
||||
day=TruncDate('datetime', tzinfo=tz)
|
||||
).values('day').distinct().count()
|
||||
return self.__cache['entries_days_since', cutoff]
|
||||
|
||||
def entries_days_before(self, cutoff):
|
||||
tz = self._clist.event.timezone
|
||||
with override(tz):
|
||||
if ('entries_days_before', cutoff) not in self.__cache:
|
||||
self.__cache['entries_days_before', cutoff] = self._position.checkins.filter(
|
||||
type=Checkin.TYPE_ENTRY,
|
||||
list=self._clist,
|
||||
datetime__lt=cutoff
|
||||
).annotate(
|
||||
day=TruncDate('datetime', tzinfo=tz)
|
||||
).values('day').distinct().count()
|
||||
return self.__cache['entries_days_before', cutoff]
|
||||
|
||||
@cached_property
|
||||
def entries_days(self):
|
||||
tz = self._clist.event.timezone
|
||||
@@ -533,7 +565,8 @@ class SQLLogic:
|
||||
"isBefore": partial(self.comparison_to_q, operator=LowerThan, modifier=partial(tolerance, sign=1)),
|
||||
"isAfter": partial(self.comparison_to_q, operator=GreaterThan, modifier=partial(tolerance, sign=-1)),
|
||||
}
|
||||
self.expression_ops = {'buildTime', 'objectList', 'lookup', 'var', 'entries_since', 'entries_before'}
|
||||
self.expression_ops = {'buildTime', 'objectList', 'lookup', 'var', 'entries_since', 'entries_before',
|
||||
'entries_days_since', 'entries_days_before'}
|
||||
|
||||
def operation_to_expression(self, rule):
|
||||
if not isinstance(rule, dict):
|
||||
@@ -611,6 +644,42 @@ class SQLLogic:
|
||||
Value(0),
|
||||
output_field=IntegerField()
|
||||
)
|
||||
elif operator == 'entries_days_since':
|
||||
tz = self.list.event.timezone
|
||||
return Coalesce(
|
||||
Subquery(
|
||||
Checkin.objects.filter(
|
||||
position_id=OuterRef('pk'),
|
||||
type=Checkin.TYPE_ENTRY,
|
||||
list_id=self.list.pk,
|
||||
datetime__gte=self.operation_to_expression(values[0]),
|
||||
).annotate(
|
||||
day=TruncDate('datetime', tzinfo=tz)
|
||||
).values('position_id').order_by().annotate(
|
||||
c=Count('day', distinct=True)
|
||||
).values('c')
|
||||
),
|
||||
Value(0),
|
||||
output_field=IntegerField()
|
||||
)
|
||||
elif operator == 'entries_days_before':
|
||||
tz = self.list.event.timezone
|
||||
return Coalesce(
|
||||
Subquery(
|
||||
Checkin.objects.filter(
|
||||
position_id=OuterRef('pk'),
|
||||
type=Checkin.TYPE_ENTRY,
|
||||
list_id=self.list.pk,
|
||||
datetime__lt=self.operation_to_expression(values[0]),
|
||||
).annotate(
|
||||
day=TruncDate('datetime', tzinfo=tz)
|
||||
).values('position_id').order_by().annotate(
|
||||
c=Count('day', distinct=True)
|
||||
).values('c')
|
||||
),
|
||||
Value(0),
|
||||
output_field=IntegerField()
|
||||
)
|
||||
elif operator == 'var':
|
||||
if values[0] == 'now':
|
||||
return Value(now().astimezone(timezone.utc))
|
||||
|
||||
Reference in New Issue
Block a user