diff --git a/lingo/pricing/forms.py b/lingo/pricing/forms.py index 371d9b3..5ac9760 100644 --- a/lingo/pricing/forms.py +++ b/lingo/pricing/forms.py @@ -292,6 +292,9 @@ class PricingMatrixForm(forms.Form): class PricingTestToolForm(forms.Form): agenda = forms.ModelChoiceField(label=_('Agenda'), empty_label=None, queryset=Agenda.objects.none()) event_slug = forms.CharField(label=_('Event identifier')) + billing_date = forms.ModelChoiceField( + label=_('Billing date'), empty_label=None, queryset=BillingDate.objects.none() + ) user_external_id = forms.CharField(label=_('User external identifier')) adult_external_id = forms.CharField(label=_('Adult external identifier')) booking_status = forms.ChoiceField(label=_('Booking status'), choices=[]) @@ -307,7 +310,25 @@ class PricingTestToolForm(forms.Form): self.check_type_slug = None self.booking_status = None super().__init__(*args, **kwargs) - self.fields['agenda'].queryset = self.agenda_pricing.agendas.all() + if self.agenda_pricing.subscription_required: + self.fields['agenda'].queryset = self.agenda_pricing.agendas.all() + else: + del self.fields['agenda'] + if self.agenda_pricing.flat_fee_schedule: + del self.fields['event_slug'] + del self.fields['booking_status'] + self.init_billing_date() + else: + del self.fields['billing_date'] + self.init_booking_status() + + def init_agenda(self, agenda_id): + try: + self.agenda = self.agenda_pricing.agendas.get(pk=agenda_id) + except Agenda.DoesNotExist: + pass + + def init_booking_status(self): presence_check_types = ( self.agenda.check_type_group.check_types.presences() if self.agenda and self.agenda.check_type_group @@ -330,11 +351,12 @@ class PricingTestToolForm(forms.Form): ] self.fields['booking_status'].choices = status_choices - def init_agenda(self, agenda_id): - try: - self.agenda = self.agenda_pricing.agendas.get(pk=agenda_id) - except Agenda.DoesNotExist: - pass + def init_billing_date(self): + billing_dates = self.agenda_pricing.billingdates.order_by('date_start') + if not billing_dates: + del self.fields['billing_date'] + return + self.fields['billing_date'].queryset = billing_dates def clean_event_slug(self): event_slug = self.cleaned_data['event_slug'] @@ -359,9 +381,7 @@ class PricingTestToolForm(forms.Form): self.booking_status, self.check_type_slug = original_booking_status.split('::') return original_booking_status - def get_subscription(self, user_external_id): - start_date = datetime.datetime.fromisoformat(self.serialized_event['start_datetime']).date() - end_date = start_date + datetime.timedelta(days=1) + def get_subscription(self, user_external_id, start_date, end_date): try: subscriptions = get_subscriptions(self.agenda.slug, user_external_id) except ChronoError as e: @@ -375,33 +395,70 @@ class PricingTestToolForm(forms.Form): if sub_end_date <= start_date: continue return subscription - self.add_error('user_external_id', _('No subscription found for this event')) + error_message = _('No subscription found for this event') + if self.agenda_pricing.flat_fee_schedule: + error_message = _('No subscription found for this period') + self.add_error('user_external_id', error_message) def clean(self): super().clean() - if self.cleaned_data.get('user_external_id') and self.serialized_event: - user_external_id = self.cleaned_data['user_external_id'] - self.serialized_subscription = self.get_subscription(user_external_id) + + user_external_id = self.cleaned_data.get('user_external_id') + start_date = None + end_date = None + if self.agenda_pricing.flat_fee_schedule and self.agenda_pricing.subscription_required: + if self.cleaned_data.get('billing_date'): + start_date = self.cleaned_data['billing_date'].date_start + next_billing_date = ( + self.fields['billing_date'].queryset.filter(date_start__gt=start_date).first() + ) + end_date = next_billing_date.date_start if next_billing_date else self.agenda_pricing.date_end + else: + start_date = self.agenda_pricing.date_start + end_date = self.agenda_pricing.date_end + elif self.serialized_event: + start_date = datetime.datetime.fromisoformat(self.serialized_event['start_datetime']).date() + end_date = start_date + datetime.timedelta(days=1) + if user_external_id and start_date and end_date: + self.serialized_subscription = self.get_subscription(user_external_id, start_date, end_date) def compute(self): + try: + if self.agenda_pricing.flat_fee_schedule: + return self.compute_for_flat_fee_schedule() + return self.compute_for_event() + except PricingError as e: + return { + 'error': type(e), + 'error_details': e.details, + } + + def compute_for_flat_fee_schedule(self): + if self.agenda_pricing.subscription_required and not self.serialized_subscription: + return + return self.agenda_pricing.get_pricing_data( + request=self.request, + subscription=self.serialized_subscription, + user_external_id=self.cleaned_data['user_external_id'], + adult_external_id=self.cleaned_data['adult_external_id'], + ) + + def compute_for_event(self): if not self.serialized_event or not self.serialized_subscription: return - try: - return self.agenda_pricing.get_pricing_data_for_event( - request=self.request, - agenda=self.agenda, - event=self.serialized_event, - subscription=self.serialized_subscription, - check_status={ - 'status': self.booking_status, - 'check_type': self.check_type_slug, - }, - booking={}, - user_external_id=self.cleaned_data['user_external_id'], - adult_external_id=self.cleaned_data['adult_external_id'], - ) - except PricingError as e: - return {'error': e.details} + return self.agenda_pricing.get_pricing_data_for_event( + request=self.request, + agenda=self.agenda, + event=self.serialized_event, + subscription=self.serialized_subscription, + check_status={ + 'status': self.booking_status, + 'check_type': self.check_type_slug, + }, + booking={}, + user_external_id=self.cleaned_data['user_external_id'], + adult_external_id=self.cleaned_data['adult_external_id'], + ) class NewCheckTypeForm(forms.ModelForm): diff --git a/lingo/pricing/models.py b/lingo/pricing/models.py index 3ef41e3..cb273fe 100644 --- a/lingo/pricing/models.py +++ b/lingo/pricing/models.py @@ -694,6 +694,9 @@ class BillingDate(models.Model): date_start = models.DateField(_('Billing start date')) label = models.CharField(_('Label'), max_length=150) + def __str__(self): + return '%s (%s)' % (self.date_start.strftime('%d/%m/%Y'), self.label) + def export_json(self): return { 'date_start': self.date_start.strftime('%Y-%m-%d'), diff --git a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html index 8cdd647..15af0a2 100644 --- a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html +++ b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html @@ -74,6 +74,7 @@