diff --git a/website/events/admin.py b/website/events/admin.py index 62f0a02..97f3091 100644 --- a/website/events/admin.py +++ b/website/events/admin.py @@ -4,6 +4,7 @@ from events.helpers.notifications import email_notifier from events.models import ( Event, + SponsorshipDiscounts, EventOrganizer, Invoice, InvoiceAffect, @@ -20,6 +21,11 @@ from reversion_compare.admin import CompareVersionAdmin +class SponsorshipDiscountsInline(admin.TabularInline): + model = SponsorshipDiscounts + exclude = ('created_by', 'changed_by',) + + class EventOrganizerInline(admin.TabularInline): model = EventOrganizer exclude = ('created_by', 'changed_by',) @@ -28,7 +34,7 @@ class EventOrganizerInline(admin.TabularInline): class EventAdmin(CompareVersionAdmin): fields = ('name', 'commission', 'category', 'start_date', 'place', 'close') - inlines = (EventOrganizerInline,) + inlines = (SponsorshipDiscountsInline, EventOrganizerInline) list_display = ('name', 'start_date', 'place', 'category', 'close') search_fields = ('start_date', 'place', ) list_filter = ('category', 'close') @@ -43,9 +49,7 @@ def save_formset(self, request, form, formset, change): event=instance.event, organizer=instance.organizer).exists() if not exists_organizer: notify_organizers.append(instance.organizer) - super(EventAdmin, self).save_formset(request, form, formset, change) - if len(notify_organizers): current_site = get_current_site(request) context = { @@ -104,7 +108,7 @@ def sponsor(self, obj): class SponsorCategoryAdmin(CompareVersionAdmin): - fields = ('name', 'amount', 'event') + fields = ('name', 'amount', 'event', 'sponsorship_discount') list_display = ('name', 'amount', 'event', 'sponsoring_number') search_fields = ('name', 'event__name') list_select_related = ( @@ -292,6 +296,11 @@ class ProviderAdmin(CompareVersionAdmin): list_display = ('organization_name', 'document_number') +class SponsorshipDiscountsAdmin(CompareVersionAdmin): + exclude = [] + + +admin.site.register(SponsorshipDiscounts, SponsorshipDiscountsAdmin) admin.site.register(Provider, ProviderAdmin) admin.site.register(Payment, PaymentAdmin) admin.site.register(ProviderExpense, ProviderExpenseAdmin) diff --git a/website/events/forms.py b/website/events/forms.py index c634cf1..687cae5 100644 --- a/website/events/forms.py +++ b/website/events/forms.py @@ -19,7 +19,8 @@ ProviderExpense, Sponsor, SponsorCategory, - Sponsoring + Sponsoring, + SponsorshipDiscounts, ) @@ -117,6 +118,20 @@ class Meta: fields = ['name', 'amount'] +class SponsorshipDiscountForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(SponsorshipDiscountForm, self).__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.form_class = 'form-horizontal' + self.helper.form_tag = False + self.helper.label_class = "col-sm-2" + self.helper.field_class = "col-sm-10" + + class Meta: + model = SponsorshipDiscounts + fields = ['name', 'description', 'discount', 'event'] + + class BankAccountDataForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(BankAccountDataForm, self).__init__(*args, **kwargs) @@ -176,12 +191,15 @@ def __init__(self, event, *args, **kwargs): # Pre-filter sponsorcategory by event self.fields['sponsorcategory'].queryset = SponsorCategory.objects.filter(event=event) self.fields['sponsor'].queryset = Sponsor.objects.filter(enabled=True) + self.fields['sponsorship_discount'].queryset = \ + SponsorshipDiscounts.objects.filter(event=event) class Meta: model = Sponsoring fields = [ 'sponsorcategory', 'sponsor', + 'sponsorship_discount', 'comments', ] widgets = { diff --git a/website/events/helpers/notifications.py b/website/events/helpers/notifications.py index 73d43c2..0d12de2 100644 --- a/website/events/helpers/notifications.py +++ b/website/events/helpers/notifications.py @@ -9,6 +9,7 @@ class EmailNotification(): ORGANIZER_ASSOCIATED_TO_EVENT = 'organizer_associated_to_event' SPONSOR_JUST_CREATED = 'sponsor_just_created' + INVOICE_JUST_CREATED = 'invoice_just_created' INVOICE_AFFECT_JUST_CREATED = 'invoice_affect_just_created' SPONSOR_JUST_ENABLED = 'sponsor_just_enabled' diff --git a/website/events/migrations/0013_auto_20211122_1838.py b/website/events/migrations/0013_auto_20211122_1838.py new file mode 100644 index 0000000..940ba66 --- /dev/null +++ b/website/events/migrations/0013_auto_20211122_1838.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.13 on 2021-11-22 18:38 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0012_auto_20211122_1550'), + ] + + operations = [ + migrations.CreateModel( + name='SponsorshipDiscounts', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=32, verbose_name='nombre')), + ('description', models.TextField(blank=True, null=True, verbose_name='descripción')), + ('discount', models.DecimalField(decimal_places=2, max_digits=18, verbose_name='descuento (%)')), + ('event', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='discount', to='events.event')), + ], + options={ + 'verbose_name_plural': 'Sponsorship Discounts', + }, + ), + migrations.AddField( + model_name='sponsoring', + name='sponsorship_discount', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.sponsorshipdiscounts', verbose_name='Descuento'), + ), + ] diff --git a/website/events/models.py b/website/events/models.py index 3f76300..af3cf85 100644 --- a/website/events/models.py +++ b/website/events/models.py @@ -190,7 +190,6 @@ class Event(SaveReversionMixin, AuditUserTime): verbose_name=_('organizadores'), related_name='events' ) - close = models.BooleanField(_('cerrado'), default=False) def get_absolute_url(self): @@ -213,6 +212,25 @@ class Meta: ordering = ['-start_date'] +class SponsorshipDiscounts(models.Model): + """SponsorShip Discount.""" + + class Meta: + verbose_name_plural = "Sponsorship Discounts" + + name = models.CharField(_('nombre'), max_length=32) + description = models.TextField(_('descripción'), null=True, blank=True) + discount = models.DecimalField(_('descuento (%)'), max_digits=18, decimal_places=2) + event = models.ForeignKey( + Event, + related_name='discount', + on_delete=models.SET_NULL, + null=True) + + def __str__(self): + return self.name + + @reversion.register class EventOrganizer(SaveReversionMixin, AuditUserTime): """Represents the many to many relationship between events and organizers. With TimeStamped @@ -270,9 +288,24 @@ class Sponsoring(SaveReversionMixin, AuditUserTime): related_name='sponsoring', on_delete=models.CASCADE, ) + sponsorship_discount = models.ForeignKey( + 'SponsorshipDiscounts', + verbose_name=_('Descuento'), + on_delete=models.SET_NULL, + null=True, + blank=True, + ) comments = models.TextField(_('comentarios'), blank=True) close = models.BooleanField(_('cerrado'), default=False) + @property + def total_amount(self): + if self.sponsorship_discount: + amount = self.sponsorcategory.amount * (1 - self.sponsorship_discount.discount / 100) + else: + amount = self.sponsorcategory.amount + return format(amount, '.2f') + def __str__(self): return ( f"{self.sponsor.organization_name} " diff --git a/website/events/templates/events/event_create_sponsor_discount_form.html b/website/events/templates/events/event_create_sponsor_discount_form.html new file mode 100644 index 0000000..aaa4727 --- /dev/null +++ b/website/events/templates/events/event_create_sponsor_discount_form.html @@ -0,0 +1,26 @@ +{% extends "events_base.html" %} +{% load crispy_forms_tags %} +{% block content %} +