diff --git a/src/pretix/base/cancellation.py b/src/pretix/base/cancellation.py index 8f525374b0..5e0827294e 100644 --- a/src/pretix/base/cancellation.py +++ b/src/pretix/base/cancellation.py @@ -109,13 +109,13 @@ class PositionCheckFn(Protocol): """ def __call__(self, order: PrefetchedOrder, keep: PositionSet, position: PrefetchedPosition, - check_ts: datetime.datetime, + check_at: datetime.datetime, /) -> Optional[CheckResult]: """ :param order: The order the position is part of. Should be the prefetched object :param keep: OrderPositions of this position that are not getting canceled :param position: OrderPosition that should be canceled and for which this check should be evaluated - :param check_ts: The time for which this check should be evaluated + :param check_at: The time for which this check should be evaluated :return: None if the check doesn't apply otherwise a CheckResult Object """ ... @@ -126,12 +126,12 @@ class ProcessCheckFn(Protocol): Check to see if a cancellation request for this Order is possible. """ - def __call__(self, order: "PrefetchedOrder", keep: PositionSet, check_ts: datetime.datetime, /) \ + def __call__(self, order: "PrefetchedOrder", keep: PositionSet, check_at: datetime.datetime, /) \ -> Optional[CheckResult]: """ :param order: The Order the cancellation is for :param keep: The OrderPositions that aren't getting canceled - :param check_ts: The time for which this check should be evaluated + :param check_at: The time for which this check should be evaluated :return: """ ... @@ -149,15 +149,15 @@ class CancellationCheck: related_selects: List[str] = field(default_factory=list) def evaluate(self, order: PrefetchedOrder, keep: PositionSet, - position: Optional["OrderPosition"], check_ts: datetime.datetime) -> Optional[CheckResult]: + position: Optional["OrderPosition"], check_at: datetime.datetime) -> Optional[CheckResult]: if position and self.type == CheckTypes.POSITION: prefetched_position = cast(PrefetchedPosition, next((p for p in order.positions.all() if p.pk == position.pk), None)) if prefetched_position is None: raise ValidationError(f"OrderPosition {position.pk} does not belong to order {order.code}") - return self.check_fn(order, keep, prefetched_position, check_ts) + return self.check_fn(order, keep, prefetched_position, check_at) elif position is None and self.type == CheckTypes.PROCESS: - return self.check_fn(order, keep, check_ts) + return self.check_fn(order, keep, check_at) else: raise ValidationError("Type of the rule doesn't match the check_fn") diff --git a/src/pretix/base/models/cancellation.py b/src/pretix/base/models/cancellation.py index 1ec59f093e..c142a503e1 100644 --- a/src/pretix/base/models/cancellation.py +++ b/src/pretix/base/models/cancellation.py @@ -330,7 +330,7 @@ class PositionCancellationRule(CancellationRule): date_field, order, resolve_subevent=lambda _reldate_type: position.subevent ) - def _evaluate_cancellation_moment(self, position: "OrderPosition", check_ts: datetime.datetime) \ + def _evaluate_cancellation_moment(self, position: "OrderPosition", check_at: datetime.datetime) \ -> List[CheckResult]: check_results = [] @@ -340,12 +340,12 @@ class PositionCancellationRule(CancellationRule): deadline: Optional[RelativeDateWrapper] = getattr(self, limit_name, None) if deadline is not None: deadline_value = self._resolve_date_field(deadline, order, self.subevent_variant) - if check_ts <= deadline_value: + if check_at <= deadline_value: check_results.append( CheckResult( id=f"position_rule_{self.id}_{limit_name}", reason=_("{evaluated_at} is earlier than {limit_name} deadline {deadline}").format( - evaluated_at=check_ts, + evaluated_at=check_at, limit_name=limit_names[limit_name], deadline=deadline_value, ), @@ -357,7 +357,7 @@ class PositionCancellationRule(CancellationRule): CheckResult( id=f"position_rule_{self.id}_{limit_name}", reason=_("{evaluated_at} is later than {limit_name} deadline {deadline}").format( - evaluated_at=check_ts, + evaluated_at=check_at, limit_name=limit_names[limit_name], deadline=deadline_value, ), @@ -376,12 +376,12 @@ class PositionCancellationRule(CancellationRule): return check_results def evaluate_position_rule(self, order: "Order", _keep: Set["OrderPosition"], position: "OrderPosition", - check_ts: datetime.datetime) -> Optional[RuleResult]: + check_at: datetime.datetime) -> Optional[RuleResult]: rule_check_results = [] match = self._position_matches_rule(position) if match: rule_check_results.append(match) - rule_check_results.extend(self._evaluate_cancellation_moment(position, check_ts)) + rule_check_results.extend(self._evaluate_cancellation_moment(position, check_at)) if self.fee_percentage_per_position and self.fee_absolute_per_position: raise NotImplementedError( @@ -459,7 +459,7 @@ class ProcessCancellationRule(CancellationRule): return CancellationRule._resolve_date_field_common(date_field, order, resolve_subevent) - def _evaluate_cancellation_moment(self, order: "Order", check_ts: datetime.datetime) -> List[CheckResult]: + def _evaluate_cancellation_moment(self, order: "Order", check_at: datetime.datetime) -> List[CheckResult]: check_results: List[CheckResult] = [] @@ -467,12 +467,12 @@ class ProcessCancellationRule(CancellationRule): deadline: Optional[RelativeDateWrapper] = getattr(self, limit_name, None) if deadline is not None: deadline_value = self._resolve_date_field(deadline, order, self.subevent_variant) - if check_ts <= deadline_value: + if check_at <= deadline_value: check_results.append( CheckResult( id=f"process_rule_{self.id}_{limit_name}", reason=_("{evaluated_at} is earlier than {limit_name} deadline {deadline}").format( - evaluated_at=check_ts, + evaluated_at=check_at, limit_name=limit_names[limit_name], deadline=deadline_value), cancellation_possible=True @@ -483,7 +483,7 @@ class ProcessCancellationRule(CancellationRule): CheckResult( id=f"process_rule_{self.id}_{limit_name}", reason=_("{evaluated_at} is later than {limit_name} deadline {deadline}").format( - evaluated_at=check_ts, + evaluated_at=check_at, limit_name=limit_names[limit_name], deadline=deadline_value), cancellation_possible=False @@ -500,12 +500,12 @@ class ProcessCancellationRule(CancellationRule): return check_results def evaluate_process_rule(self, order: "Order", _keep: Set["OrderPosition"], position_fees: Decimal, - check_ts: datetime.datetime) -> Optional[RuleResult]: + check_at: datetime.datetime) -> Optional[RuleResult]: fee_mode = self.fee_mode if fee_mode not in (FeeType.MINIMUM, FeeType.ADDITIONAL): raise ValueError(f"Unexpected fee_mode: {fee_mode!r}") - check_results: List[CheckResult] = self._evaluate_cancellation_moment(order, check_ts) + check_results: List[CheckResult] = self._evaluate_cancellation_moment(order, check_at) return RuleResult.from_process_fee( id=self.id, diff --git a/src/pretix/base/services/cancellation.py b/src/pretix/base/services/cancellation.py index e5afc7277c..8bfe9385a0 100644 --- a/src/pretix/base/services/cancellation.py +++ b/src/pretix/base/services/cancellation.py @@ -67,7 +67,7 @@ class CollectedChecks: def evaluate_cancellation(event: Event, order: Order, keep: Set[OrderPosition], - check_ts: datetime.datetime) -> "CancellationResult": + check_at: datetime.datetime) -> "CancellationResult": # validate that all keep order positions are part of the order for p in keep: if p.order_id != order.id: @@ -102,13 +102,13 @@ def evaluate_cancellation(event: Event, order: Order, keep: Set[OrderPosition], # evaluate the system/plugin checks for the position for check in collected_checks.position: - res = check.evaluate(order=order, keep=keep, position=position, check_ts=check_ts) + res = check.evaluate(order=order, keep=keep, position=position, check_at=check_at) if res is not None: position_check_results[position.id].append(res) # evaluate all customer specified rules for this position for rule in position_rules: - result = rule.evaluate_position_rule(order, keep, position, check_ts) + result = rule.evaluate_position_rule(order, keep, position, check_at) if result is not None: position_rule_results[position.id].append(result) @@ -124,13 +124,13 @@ def evaluate_cancellation(event: Event, order: Order, keep: Set[OrderPosition], # evaluate all system/plugin provided checks for the cancellation process for check in collected_checks.process: - res = check.evaluate(order=order, keep=keep, position=None, check_ts=check_ts) + res = check.evaluate(order=order, keep=keep, position=None, check_at=check_at) if res is not None: process_check_results.append(res) # evaluate all customer specified rules for the cancellation process for rule in process_rules: - result = rule.evaluate_process_rule(order, keep, temp_position_fees, check_ts) + result = rule.evaluate_process_rule(order, keep, temp_position_fees, check_at) if result is not None: process_rule_results.append(result) @@ -143,9 +143,9 @@ def evaluate_cancellation(event: Event, order: Order, keep: Set[OrderPosition], def prepare_cancellation(event: Event, order: Order, keep: Set[OrderPosition], - check_ts: datetime.datetime) -> Cancellation: - res = evaluate_cancellation(event=event, order=order, keep=set(), check_ts=check_ts) - c = Cancellation(event=event, order=order, result=res, evaluation_ts=check_ts) + check_at: datetime.datetime) -> Cancellation: + res = evaluate_cancellation(event=event, order=order, keep=set(), check_at=check_at) + c = Cancellation(event=event, order=order, result=res, evaluated_at=check_at) c.save() c.keep.add(*keep) return c @@ -201,13 +201,13 @@ def _prefetch_order(event: Event, order: Order, checks: CollectedChecks) -> "Pre def position_not_used_cancellation_check(order: "PrefetchedOrder", keep: PositionSet, position: "PrefetchedPosition", - check_ts: datetime.datetime) -> Optional[CheckResult]: + check_at: datetime.datetime) -> Optional[CheckResult]: if position in keep: return None used_checkin = next( (c for c in position.all_checkins.all() if - c.successful and c.list.consider_tickets_used and c.datetime < check_ts), + c.successful and c.list.consider_tickets_used and c.datetime < check_at), None, ) if used_checkin is not None: @@ -234,7 +234,7 @@ def signal_listener_position_not_used(sender: Event, **kwargs) -> CancellationCh def position_not_blocked_check(order: Order, keep: PositionSet, position: OrderPosition, - check_ts: datetime.datetime) -> Optional[CheckResult]: + check_at: datetime.datetime) -> Optional[CheckResult]: if position in keep: return None @@ -256,7 +256,7 @@ def signal_listener_position_not_blocked(sender: Event, **kwargs) -> Cancellatio def position_giftcard_not_used(order: PrefetchedOrder, keep: PositionSet, position: PrefetchedPosition, - check_ts: datetime.datetime) -> Optional[CheckResult]: + check_at: datetime.datetime) -> Optional[CheckResult]: if position in keep: return None @@ -287,7 +287,7 @@ def signal_listener_position_giftcard_not_used(sender: Event, **kwargs) -> Cance def position_membership_not_used(order: PrefetchedOrder, keep: PositionSet, position: PrefetchedPosition, - check_ts: datetime.datetime) -> Optional[CheckResult]: + check_at: datetime.datetime) -> Optional[CheckResult]: if position in keep: return None @@ -321,7 +321,7 @@ def signal_position_membership_not_used(sender: Event, **kwargs) -> Cancellation def position_item_allow_cancel(order: PrefetchedOrder, keep: PositionSet, position: PrefetchedPosition, - check_ts: datetime.datetime) -> Optional[CheckResult]: + check_at: datetime.datetime) -> Optional[CheckResult]: if position in keep: return None @@ -342,7 +342,7 @@ def signal_position_item_allow_cancel(sender: Event, **kwargs) -> CancellationCh ]) -def process_order_payment_state(order: PrefetchedOrder, keep: PositionSet, check_ts: datetime.datetime): +def process_order_payment_state(order: PrefetchedOrder, keep: PositionSet, check_at: datetime.datetime): if order.status == Order.STATUS_PAID: if order.total == Decimal("0.00"): return CheckResult( @@ -388,7 +388,7 @@ def signal_listener_process_order_payment_state(sender: Event, **kwargs) -> Canc ) -def process_cancel_allowed(order: PrefetchedOrder, keep: PositionSet, check_ts: datetime.datetime) -> CheckResult: +def process_cancel_allowed(order: PrefetchedOrder, keep: PositionSet, check_at: datetime.datetime) -> CheckResult: cancel_allowed = order.cancel_allowed() return CheckResult( @@ -407,7 +407,7 @@ def signal_listener_process_cancel_allowed(sender: Event, **kwargs) -> Cancellat ) -def process_cancellation_in_progress(order: PrefetchedOrder, keep: PositionSet, check_ts: datetime.datetime): +def process_cancellation_in_progress(order: PrefetchedOrder, keep: PositionSet, check_at: datetime.datetime): if any([c.state not in [Cancellation.STATE_PERFORMED, Cancellation.STATE_ABORTED] for c in order.cancellations.all()]): return CheckResult( diff --git a/src/tests/base/test_self_service_cancellation.py b/src/tests/base/test_self_service_cancellation.py index cd44d6e1d9..45de979cb4 100644 --- a/src/tests/base/test_self_service_cancellation.py +++ b/src/tests/base/test_self_service_cancellation.py @@ -108,16 +108,16 @@ def make_rule_result(fee, *, possible: bool = True, fee_type: FeeType = FeeType. def make_cancellation_check(id: str, type: CheckTypes, result: bool, prefetches=None, related_selects=None, - check_ts: datetime = datetime.now(tz=UTC)) -> CancellationCheck: + check_at: datetime = datetime.now(tz=UTC)) -> CancellationCheck: if related_selects is None: related_selects = [] if prefetches is None: prefetches = [] - def position_check_fn(_order, _keep, _position, _check_ts=check_ts): + def position_check_fn(_order, _keep, _position, _check_at=check_at): return make_check_result(result, id=id) - def check_fn(_order, _keep, _check_ts=check_ts): + def check_fn(_order, _keep, _check_at=check_at): return make_check_result(result, id=id) if type == CheckTypes.POSITION: @@ -665,7 +665,7 @@ class TestCancellationRule: ) def test_evaluate_cancellation_moment(self, event, order, order_position, rule_type_variants, attr, delta, allowed): - reference_ts = datetime(2020, 10, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=UTC) + reference = datetime(2020, 10, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=UTC) with scope(organizer=event.organizer): if rule_type_variants == 'position': @@ -677,16 +677,16 @@ class TestCancellationRule: else: raise ValueError("Unknown cancellation rule type: {}".format(rule_type_variants)) - setattr(r, attr, RelativeDateWrapper(reference_ts)) + setattr(r, attr, RelativeDateWrapper(reference)) r.save() rule = rule_object.objects.get(id=r.id) with ensure_no_queries(): if rule_type_variants == 'position': - res = rule._evaluate_cancellation_moment(position=order_position, check_ts=reference_ts + delta) + res = rule._evaluate_cancellation_moment(position=order_position, check_at=reference + delta) elif rule_type_variants == "process": res = rule._evaluate_cancellation_moment(order=order, - check_ts=reference_ts + delta) + check_at=reference + delta) else: raise ValueError("Unknown cancellation rule type: {}".format(rule_type_variants)) @@ -700,25 +700,25 @@ class TestCancellationRule: @pytest.mark.django_db def test_evaluate_simple_e2e(self, event, order, order_position): - reference_ts = datetime(2020, 10, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=UTC) + reference = datetime(2020, 10, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=UTC) - check_ts = reference_ts - timedelta(hours=1) + check_at = reference - timedelta(hours=1) PositionCancellationRule.objects.create(event=event, all_products=True, fee_absolute_per_position=Decimal("10.00"), - allowed_until=RelativeDateWrapper(reference_ts)) + allowed_until=RelativeDateWrapper(reference)) PositionCancellationRule.objects.create(event=event, all_products=True, fee_absolute_per_position=Decimal("10.00"), - allowed_until=RelativeDateWrapper(reference_ts - timedelta(days=1))) + allowed_until=RelativeDateWrapper(reference - timedelta(days=1))) ProcessCancellationRule.objects.create(event=event, fee_cancellation_process=Decimal("10.00"), fee_mode=FeeType.ADDITIONAL, - allowed_until=RelativeDateWrapper(reference_ts)) + allowed_until=RelativeDateWrapper(reference)) ProcessCancellationRule.objects.create(event=event, fee_cancellation_process=Decimal("10.00"), fee_mode=FeeType.ADDITIONAL, - allowed_until=RelativeDateWrapper(reference_ts - timedelta(days=1))) + allowed_until=RelativeDateWrapper(reference - timedelta(days=1))) with scope(organizer=event.organizer): - cancellation = evaluate_cancellation(event, order, keep=set(), check_ts=check_ts) + cancellation = evaluate_cancellation(event, order, keep=set(), check_at=check_at) assert cancellation.cancellation_possible is True