1
0
Fork 1
mirror of https://github.com/pretix/pretix-servicefees.git synced 2025-03-16 00:44:21 +01:00

Allow to exclude products from service fees (Z#23177030) ()

This commit is contained in:
Raphael Michel 2025-01-14 15:09:44 +01:00 committed by GitHub
parent 257d7e9f56
commit 6af759b615
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 131 additions and 6 deletions

View file

@ -0,0 +1,36 @@
# Generated by Django 4.2.17 on 2025-01-08 11:50
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("pretixbase", "0274_tax_codes"),
]
operations = [
migrations.CreateModel(
name="ItemServicefeesSettings",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False
),
),
("exclude", models.BooleanField()),
(
"item",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="servicefees_settings",
to="pretixbase.item",
),
),
],
),
]

View file

@ -0,0 +1,13 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class ItemServicefeesSettings(models.Model):
item = models.OneToOneField(
"pretixbase.Item", related_name="servicefees_settings", on_delete=models.CASCADE
)
exclude = models.BooleanField(
verbose_name=_(
"Exclude this product from the calculation of per-ticket service fees"
)
)

View file

@ -1,5 +1,6 @@
from collections import defaultdict from collections import defaultdict
from decimal import Decimal from decimal import Decimal
from django import forms
from django.dispatch import receiver from django.dispatch import receiver
from django.http import HttpRequest from django.http import HttpRequest
from django.urls import resolve, reverse from django.urls import resolve, reverse
@ -8,15 +9,23 @@ from pretix.base.decimal import round_decimal
from pretix.base.models import CartPosition, Event, TaxRule from pretix.base.models import CartPosition, Event, TaxRule
from pretix.base.models.orders import OrderFee from pretix.base.models.orders import OrderFee
from pretix.base.settings import settings_hierarkey from pretix.base.settings import settings_hierarkey
from pretix.base.signals import order_fee_calculation from pretix.base.signals import (
event_copy_data,
item_copy_data,
order_fee_calculation,
)
from pretix.base.templatetags.money import money_filter from pretix.base.templatetags.money import money_filter
from pretix.control.signals import nav_event_settings from pretix.control.signals import item_forms, nav_event_settings
from pretix.presale.signals import ( from pretix.presale.signals import (
fee_calculation_for_cart, front_page_top, order_meta_from_request, fee_calculation_for_cart,
front_page_top,
order_meta_from_request,
) )
from pretix.presale.views import get_cart from pretix.presale.views import get_cart
from pretix.presale.views.cart import cart_session from pretix.presale.views.cart import cart_session
from .models import ItemServicefeesSettings
@receiver(nav_event_settings, dispatch_uid="service_fee_nav_settings") @receiver(nav_event_settings, dispatch_uid="service_fee_nav_settings")
def navbar_settings(sender, request, **kwargs): def navbar_settings(sender, request, **kwargs):
@ -58,6 +67,14 @@ def get_fees(
if skip_addons: if skip_addons:
positions = [pos for pos in positions if not pos.addon_to_id] positions = [pos for pos in positions if not pos.addon_to_id]
excluded_products = set(
ItemServicefeesSettings.objects.filter(
item__event=event,
exclude=True,
).values_list("item_id", flat=True)
)
positions = [pos for pos in positions if pos.item_id not in excluded_products]
skip_non_admission = event.settings.get( skip_non_admission = event.settings.get(
"service_fee_skip_non_admission", as_type=bool "service_fee_skip_non_admission", as_type=bool
) )
@ -185,7 +202,8 @@ def cart_fee(sender: Event, request: HttpRequest, invoice_address, total, **kwar
mod = "" mod = ""
try: try:
from pretix_resellers.utils import ( from pretix_resellers.utils import (
ResellerException, get_reseller_and_user, ResellerException,
get_reseller_and_user,
) )
except ImportError: except ImportError:
pass pass
@ -269,7 +287,8 @@ def order_meta_signal(sender: Event, request: HttpRequest, **kwargs):
meta = {} meta = {}
try: try:
from pretix_resellers.utils import ( from pretix_resellers.utils import (
ResellerException, get_reseller_and_user, ResellerException,
get_reseller_and_user,
) )
except ImportError: except ImportError:
pass pass
@ -282,5 +301,61 @@ def order_meta_signal(sender: Event, request: HttpRequest, **kwargs):
return meta return meta
class ItemServicefeesSettingsForm(forms.ModelForm):
class Meta:
model = ItemServicefeesSettings
fields = ["exclude"]
exclude = []
def __init__(self, *args, **kwargs):
self.event = kwargs.pop("event")
super().__init__(*args, **kwargs)
def save(self, commit=True):
if not self.cleaned_data.get("exclude"):
if self.instance.pk:
self.instance.delete()
else:
return
else:
return super().save(commit=commit)
@receiver(item_forms, dispatch_uid="servicefees_item_forms")
def control_item_forms(sender, request, item, **kwargs):
try:
inst = ItemServicefeesSettings.objects.get(item=item)
except ItemServicefeesSettings.DoesNotExist:
inst = ItemServicefeesSettings(item=item)
return ItemServicefeesSettingsForm(
instance=inst,
event=sender,
data=(request.POST if request.method == "POST" else None),
prefix="servicefees",
)
@receiver(item_copy_data, dispatch_uid="servicefees_item_copy")
def copy_item(sender, source, target, **kwargs):
try:
inst = ItemServicefeesSettings.objects.get(item=source)
inst = copy.copy(inst)
inst.pk = None
inst.item = target
inst.save()
except ItemServicefeesSettings.DoesNotExist:
pass
@receiver(signal=event_copy_data, dispatch_uid="servicefees_copy_data")
def event_copy_data_receiver(sender, other, question_map, item_map, **kwargs):
for ip in ItemServicefeesSettings.objects.filter(item__event=other):
ip = copy.copy(ip)
ip.pk = None
ip.event = sender
ip.item = item_map[ip.item_id]
ip.save()
settings_hierarkey.add_default("service_fee_skip_addons", "True", bool) settings_hierarkey.add_default("service_fee_skip_addons", "True", bool)
settings_hierarkey.add_default("service_fee_skip_free", "True", bool) settings_hierarkey.add_default("service_fee_skip_free", "True", bool)

View file

@ -4,7 +4,8 @@ from django.utils.translation import gettext_lazy as _
from pretix.base.forms import SettingsForm from pretix.base.forms import SettingsForm
from pretix.base.models import Event from pretix.base.models import Event
from pretix.control.views.event import ( from pretix.control.views.event import (
EventSettingsFormView, EventSettingsViewMixin, EventSettingsFormView,
EventSettingsViewMixin,
) )