From 90e50b80846b6a634570b190d5d1e30f1e8cc35c Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 27 Feb 2018 23:12:01 +0100 Subject: [PATCH] Initial commit --- .gitignore | 63 +++++++++++++++++++ LICENSE | 13 ++++ MANIFEST.in | 3 + Makefile | 8 +++ README.rst | 32 ++++++++++ pretix_servicefees/__init__.py | 20 ++++++ .../locale/de/LC_MESSAGES/django.po | 12 ++++ .../locale/de_Informal/.gitkeep | 0 .../locale/de_Informal/LC_MESSAGES/django.po | 12 ++++ pretix_servicefees/signals.py | 60 ++++++++++++++++++ .../static/pretix_servicefees/.gitkeep | 0 .../templates/pretix_servicefees/.gitkeep | 0 .../pretix_servicefees/settings.html | 18 ++++++ pretix_servicefees/urls.py | 8 +++ pretix_servicefees/views.py | 22 +++++++ pytest.ini | 2 + setup.cfg | 14 +++++ setup.py | 44 +++++++++++++ 18 files changed, 331 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 MANIFEST.in create mode 100644 Makefile create mode 100644 README.rst create mode 100644 pretix_servicefees/__init__.py create mode 100644 pretix_servicefees/locale/de/LC_MESSAGES/django.po create mode 100644 pretix_servicefees/locale/de_Informal/.gitkeep create mode 100644 pretix_servicefees/locale/de_Informal/LC_MESSAGES/django.po create mode 100644 pretix_servicefees/signals.py create mode 100644 pretix_servicefees/static/pretix_servicefees/.gitkeep create mode 100644 pretix_servicefees/templates/pretix_servicefees/.gitkeep create mode 100644 pretix_servicefees/templates/pretix_servicefees/settings.html create mode 100644 pretix_servicefees/urls.py create mode 100644 pretix_servicefees/views.py create mode 100644 pytest.ini create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d95f781 --- /dev/null +++ b/.gitignore @@ -0,0 +1,63 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg +.ropeproject/ + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3d7efad --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2018 Raphael Michel + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..8d82418 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +recursive-include pretix_servicefees/static * +recursive-include pretix_servicefees/templates * +recursive-include pretix_servicefees/locale * diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6606765 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: localecompile + +localecompile: + django-admin compilemessages + +localegen: + django-admin makemessages -l de_Informal -l de -i build -i dist -i "*egg*" + diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..c6a4a73 --- /dev/null +++ b/README.rst @@ -0,0 +1,32 @@ +pretix Service Fees +========================== + +This is a plugin for `pretix`_. + +Development setup +----------------- + +1. Make sure that you have a working `pretix development setup`_. + +2. Clone this repository, eg to ``local/pretix-servicefees``. + +3. Activate the virtual environment you use for pretix development. + +4. Execute ``python setup.py develop`` within this directory to register this application with pretix's plugin registry. + +5. Execute ``make`` within this directory to compile translations. + +6. Restart your local pretix server. You can now use the plugin from this repository for your events by enabling it in + the 'plugins' tab in the settings. + + +License +------- + +Copyright 2018 Raphael Michel + +Released under the terms of the Apache License 2.0 + + +.. _pretix: https://github.com/pretix/pretix +.. _pretix development setup: https://docs.pretix.eu/en/latest/development/setup.html diff --git a/pretix_servicefees/__init__.py b/pretix_servicefees/__init__.py new file mode 100644 index 0000000..612b781 --- /dev/null +++ b/pretix_servicefees/__init__.py @@ -0,0 +1,20 @@ +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy + + +class PluginApp(AppConfig): + name = 'pretix_servicefees' + verbose_name = 'pretix Service Fees' + + class PretixPluginMeta: + name = ugettext_lazy('pretix Service Fees') + author = 'Raphael Michel' + description = ugettext_lazy('Allows you to impose a service fee on all non-free orders.') + visible = True + version = '1.0.0' + + def ready(self): + from . import signals # NOQA + + +default_app_config = 'pretix_servicefees.PluginApp' diff --git a/pretix_servicefees/locale/de/LC_MESSAGES/django.po b/pretix_servicefees/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..b136a10 --- /dev/null +++ b/pretix_servicefees/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,12 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-07 19:01+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Raphael Michel\n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" diff --git a/pretix_servicefees/locale/de_Informal/.gitkeep b/pretix_servicefees/locale/de_Informal/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pretix_servicefees/locale/de_Informal/LC_MESSAGES/django.po b/pretix_servicefees/locale/de_Informal/LC_MESSAGES/django.po new file mode 100644 index 0000000..b136a10 --- /dev/null +++ b/pretix_servicefees/locale/de_Informal/LC_MESSAGES/django.po @@ -0,0 +1,12 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-07 19:01+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Raphael Michel\n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" diff --git a/pretix_servicefees/signals.py b/pretix_servicefees/signals.py new file mode 100644 index 0000000..dcc2c01 --- /dev/null +++ b/pretix_servicefees/signals.py @@ -0,0 +1,60 @@ +from decimal import Decimal + +from django.urls import resolve, reverse +from django.dispatch import receiver +from django.http import HttpRequest +from django.utils.translation import ugettext_lazy as _ +from pretix.base.models import Event, Order, TaxRule +from pretix.base.models.orders import OrderFee +from pretix.base.signals import order_fee_calculation +from pretix.control.signals import nav_event_settings +from pretix.presale.signals import fee_calculation_for_cart + + +@receiver(nav_event_settings, dispatch_uid='service_fee_nav_settings') +def navbar_settings(sender, request, **kwargs): + url = resolve(request.path_info) + return [{ + 'label': _('Service Fee'), + 'url': reverse('plugins:pretix_servicefees:settings', kwargs={ + 'event': request.event.slug, + 'organizer': request.organizer.slug, + }), + 'active': url.namespace == 'plugins:pretix_servicefees' and url.url_name.startswith('settings'), + }] + + +def get_fees(event, total, invoice_address): + fee = event.settings.get('service_fee_abs', as_type=Decimal) + if fee and total != Decimal('0.00'): + tax_rule = event.settings.tax_rate_default or TaxRule.zero() + if tax_rule.tax_applicable(invoice_address): + tax = tax_rule.tax(fee) + return [OrderFee( + fee_type=OrderFee.FEE_TYPE_SERVICE, + internal_type='', + value=fee, + tax_rate=tax.rate, + tax_value=tax.tax, + tax_rule=tax_rule + )] + else: + return [OrderFee( + fee_type=OrderFee.FEE_TYPE_SERVICE, + internal_type='', + value=fee, + tax_rate=Decimal('0.00'), + tax_value=Decimal('0.00'), + tax_rule=tax_rule + )] + return [] + + +@receiver(fee_calculation_for_cart, dispatch_uid="service_fee_calc_cart") +def cart_fee(sender: Event, request: HttpRequest, invoice_address, total, **kwargs): + return get_fees(sender, total, invoice_address) + + +@receiver(order_fee_calculation, dispatch_uid="service_fee_calc_order") +def order_fee(sender: Event, invoice_address, total, **kwargs): + return get_fees(sender, total, invoice_address) diff --git a/pretix_servicefees/static/pretix_servicefees/.gitkeep b/pretix_servicefees/static/pretix_servicefees/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pretix_servicefees/templates/pretix_servicefees/.gitkeep b/pretix_servicefees/templates/pretix_servicefees/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pretix_servicefees/templates/pretix_servicefees/settings.html b/pretix_servicefees/templates/pretix_servicefees/settings.html new file mode 100644 index 0000000..4424358 --- /dev/null +++ b/pretix_servicefees/templates/pretix_servicefees/settings.html @@ -0,0 +1,18 @@ +{% extends "pretixcontrol/event/settings_base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% block inside %} +
+ {% csrf_token %} + {% bootstrap_form_errors form %} +
+ {% trans "Service fees" %} + {% bootstrap_field form.service_fee_abs layout="control" %} +
+
+ +
+
+{% endblock %} diff --git a/pretix_servicefees/urls.py b/pretix_servicefees/urls.py new file mode 100644 index 0000000..7ecdff5 --- /dev/null +++ b/pretix_servicefees/urls.py @@ -0,0 +1,8 @@ +from django.conf.urls import url + +from .views import SettingsView + +urlpatterns = [ + url(r'^control/event/(?P[^/]+)/(?P[^/]+)/settings/servicefees/$', + SettingsView.as_view(), name='settings'), +] diff --git a/pretix_servicefees/views.py b/pretix_servicefees/views.py new file mode 100644 index 0000000..01b1f2c --- /dev/null +++ b/pretix_servicefees/views.py @@ -0,0 +1,22 @@ +from django import forms +from django.urls import reverse + +from pretix.base.forms import SettingsForm +from pretix.base.models import Event +from pretix.control.views.event import EventSettingsViewMixin, EventSettingsFormView + +class ServiceFeeSettingsForm(SettingsForm): + service_fee_abs = forms.DecimalField() + + +class SettingsView(EventSettingsViewMixin, EventSettingsFormView): + model = Event + form_class = ServiceFeeSettingsForm + template_name = 'pretix_servicefees/settings.html' + permission = 'can_change_event_settings' + + def get_success_url(self) -> str: + return reverse('plugins:pretix_servicefees:settings', kwargs={ + 'organizer': self.request.event.organizer.slug, + 'event': self.request.event.slug + }) diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..ccf8194 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +DJANGO_SETTINGS_MODULE=pretix.testutils.settings diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..5cd9371 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,14 @@ +[flake8] +ignore = N802,W503,E402 +max-line-length = 160 +exclude = migrations,.ropeproject,static,_static,build + +[isort] +combine_as_imports = true +default_section = THIRDPARTY +include_trailing_comma = true +known_third_party = pretix +known_standard_library = typing +multi_line_output = 5 +not_skip = __init__.py +skip = setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..09f2617 --- /dev/null +++ b/setup.py @@ -0,0 +1,44 @@ +import os +from distutils.command.build import build + +from django.core import management +from setuptools import setup, find_packages + + +try: + with open(os.path.join(os.path.dirname(__file__), 'README.rst'), encoding='utf-8') as f: + long_description = f.read() +except: + long_description = '' + + +class CustomBuild(build): + def run(self): + management.call_command('compilemessages', verbosity=1, interactive=False) + build.run(self) + + +cmdclass = { + 'build': CustomBuild +} + + +setup( + name='pretix-servicefees', + version='1.0.0', + description='Allows you to impose a service fee on all non-free orders.', + long_description=long_description, + url='https://github.com/pretix/pretix-servicefees', + author='Raphael Michel', + author_email='michel@rami.io', + license='Apache Software License', + + install_requires=[], + packages=find_packages(exclude=['tests', 'tests.*']), + include_package_data=True, + cmdclass=cmdclass, + entry_points=""" +[pretix.plugin] +pretix_servicefees=pretix_servicefees:PretixPluginMeta +""", +)