From b3ee0429b7220b8400f7866873c0b445ea24ef10 Mon Sep 17 00:00:00 2001 From: Benjamin A Date: Sun, 27 Aug 2023 18:09:39 -0400 Subject: [PATCH] Feat: add lnl contact field --- .../migrations/0010_auto_20230827_1351.py | 25 +++++++++++++++++++ accounts/models.py | 1 + accounts/perms.py | 2 +- events/admin.py | 2 +- events/forms.py | 18 +++++++++++-- .../migrations/0009_baseevent_lnl_contact.py | 21 ++++++++++++++++ events/migrations/0010_auto_20230827_1406.py | 17 +++++++++++++ events/models.py | 2 ++ fixtures/groups.json | 5 ++++ site_tmpl/uglydetail.html | 6 +++++ 10 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 accounts/migrations/0010_auto_20230827_1351.py create mode 100644 events/migrations/0009_baseevent_lnl_contact.py create mode 100644 events/migrations/0010_auto_20230827_1406.py diff --git a/accounts/migrations/0010_auto_20230827_1351.py b/accounts/migrations/0010_auto_20230827_1351.py new file mode 100644 index 00000000..c577ff15 --- /dev/null +++ b/accounts/migrations/0010_auto_20230827_1351.py @@ -0,0 +1,25 @@ +# Generated by Django 3.1.14 on 2023-08-27 17:51 + +import django.core.validators +from django.db import migrations, models +import multiselectfield.db.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0009_officer_info'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='class_year', + field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1962), django.core.validators.MaxValueValidator(2029)]), + ), + migrations.AlterField( + model_name='userpreferences', + name='event_edited_field_subscriptions', + field=multiselectfield.db.fields.MultiSelectField(choices=[('event_name', 'Event name'), ('description', 'Description'), ('location', 'Location'), ('contact', 'Contact'), ('lnl_contact', 'LNL contact'), ('billing_org', 'Billing org'), ('datetime_setup_complete', 'Datetime setup complete'), ('datetime_start', 'Datetime start'), ('datetime_end', 'Datetime end'), ('internal_notes', 'Internal notes'), ('billed_in_bulk', 'Billed in bulk'), ('org', 'Client')], default=['location', 'datetime_setup_complete', 'datetime_start', 'datetime_end'], max_length=149), + ), + ] diff --git a/accounts/models.py b/accounts/models.py index 7dc0d31c..65123e4d 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -228,6 +228,7 @@ class PhoneVerificationCode(Model): ('description', 'Description'), ('location', 'Location'), ('contact', 'Contact'), + ('lnl_contact', 'LNL contact'), ('billing_org', 'Billing org'), ('datetime_setup_complete', 'Datetime setup complete'), ('datetime_start', 'Datetime start'), diff --git a/accounts/perms.py b/accounts/perms.py index f86ebed6..bc09415b 100644 --- a/accounts/perms.py +++ b/accounts/perms.py @@ -3,7 +3,7 @@ class EventUserPermLogic(AssocUsersCustomPermissionLogic): field_name = ['submitter__contact', 'submitter__crew_chief', 'submitter__ccinstances__crew_chief', - 'event__submitted_by', 'event__crew_chief', 'event__ccinstances__crew_chief', + 'event__submitted_by', 'event__lnl_contact', 'event__crew_chief', 'event__ccinstances__crew_chief', 'ccinstances__event__submitted_by', 'ccinstances__event__contact', 'ccinstances__event__crew_chief', 'crewchiefx__contact', 'crewchiefx__submitted_by', 'crewchiefx__ccinstances__crew_chief', 'contact__ccinstances__crew_chief', 'contact__crew_chief', 'contact__submitted_by'] diff --git a/events/admin.py b/events/admin.py index 1f475010..f547040c 100644 --- a/events/admin.py +++ b/events/admin.py @@ -91,7 +91,7 @@ class BaseEventAdmin(VersionAdmin, PolymorphicParentModelAdmin): 'fields': ('submitted_by', 'submitted_ip', 'submitted_on') }), ('Event And Contact Information', { - 'fields': ('event_name', 'description', 'internal_notes', 'contact', 'org', 'billing_org') + 'fields': ('event_name', 'lnl_contact', 'description', 'internal_notes', 'contact', 'org', 'billing_org') }), ('Scheduling & Location', { 'fields': ('datetime_setup_complete', 'datetime_start', 'datetime_end', diff --git a/events/forms.py b/events/forms.py index 9e7b8e78..2e125fc3 100644 --- a/events/forms.py +++ b/events/forms.py @@ -417,6 +417,7 @@ def __init__(self, request_user, *args, **kwargs): 'Name And Location', 'event_name', 'location', + 'lnl_contact', Field('description'), DynamicFieldContainer('internal_notes'), 'billed_in_bulk', @@ -529,9 +530,14 @@ def __init__(self): enable=('sensitive', 'test_event') ) + change_lnl_contact = FieldAccessLevel( + lambda user, instance: user.has_perm('events.edit_event_lnl_contact', instance), + enable=('lnl_contact') + ) + class Meta: model = Event - fields = ('event_name', 'location', 'description', 'internal_notes', 'billing_org', 'billed_in_bulk', 'contact', + fields = ('event_name', 'location', 'lnl_contact', 'description', 'internal_notes', 'billing_org', 'billed_in_bulk', 'contact', 'org', 'datetime_setup_complete', 'datetime_start', 'datetime_end', 'lighting', 'lighting_reqs', 'sound', 'sound_reqs', 'projection', 'proj_reqs', 'otherservices', 'otherservice_reqs', 'sensitive', 'test_event') @@ -550,6 +556,7 @@ class Meta: group_label=lambda group: group.name, ) contact = AutoCompleteSelectField('Users', required=False) + lnl_contact = AutoCompleteSelectField('Members', required=False) org = CustomAutoCompleteSelectMultipleField('Orgs', required=False, label="Client(s)") billing_org = AutoCompleteSelectField('Orgs', required=False, label="Client to bill") datetime_setup_complete = forms.SplitDateTimeField(initial=timezone.now, label="Setup Completed") @@ -566,6 +573,7 @@ def __init__(self, request_user, *args, **kwargs): 'Name And Location', 'event_name', 'location', + 'lnl_contact', 'reference_code', Field('description'), DynamicFieldContainer('internal_notes'), @@ -666,6 +674,11 @@ def __init__(self): enable=('sensitive', 'test_event') ) + change_lnl_contact = FieldAccessLevel( + lambda user, instance: user.has_perm('events.edit_event_lnl_contact', instance), + enable=('lnl_contact') + ) + change_entered_into_workday = FieldAccessLevel( lambda user, instance: user.has_perm('events.bill_event', instance), enable=('entered_into_workday',) @@ -688,7 +701,7 @@ def __init__(self): class Meta: model = Event2019 - fields = ('event_name', 'location', 'description', 'internal_notes', 'billing_org', + fields = ('event_name', 'location', 'lnl_contact', 'description', 'internal_notes', 'billing_org', 'billed_in_bulk', 'contact', 'org', 'datetime_setup_complete', 'datetime_start', 'datetime_end', 'sensitive', 'test_event', 'entered_into_workday', 'send_survey', 'max_crew','cancelled_reason', @@ -705,6 +718,7 @@ class Meta: group_label=lambda group: group.name, ) contact = AutoCompleteSelectField('Users', required=False) + lnl_contact = AutoCompleteSelectField('Members', label="LNL Contact (PM)", required=False) org = CustomAutoCompleteSelectMultipleField('Orgs', required=False, label="Client(s)") billing_org = AutoCompleteSelectField('Orgs', required=False, label="Client to bill") datetime_setup_complete = forms.SplitDateTimeField(initial=timezone.now, label="Setup Completed") diff --git a/events/migrations/0009_baseevent_lnl_contact.py b/events/migrations/0009_baseevent_lnl_contact.py new file mode 100644 index 00000000..dccc1af7 --- /dev/null +++ b/events/migrations/0009_baseevent_lnl_contact.py @@ -0,0 +1,21 @@ +# Generated by Django 3.1.14 on 2023-08-27 17:51 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('events', '0008_auto_20220210_0751'), + ] + + operations = [ + migrations.AddField( + model_name='baseevent', + name='lnl_contact', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='lnl_contact', to=settings.AUTH_USER_MODEL, verbose_name='LNL Contact'), + ), + ] diff --git a/events/migrations/0010_auto_20230827_1406.py b/events/migrations/0010_auto_20230827_1406.py new file mode 100644 index 00000000..c81a2c3e --- /dev/null +++ b/events/migrations/0010_auto_20230827_1406.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.14 on 2023-08-27 18:06 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0009_baseevent_lnl_contact'), + ] + + operations = [ + migrations.AlterModelOptions( + name='baseevent', + options={'ordering': ['-datetime_start'], 'permissions': (('view_events', "Show an event that isn't hidden"), ('add_raw_event', 'Use the editor to create an event'), ('event_images', 'Upload images to an event'), ('view_hidden_event', 'Show hidden events'), ('cancel_event', 'Declare an event to be cancelled'), ('event_attachments', 'Upload attachments to an event'), ('edit_event_times', 'Modify the dates for an event'), ('add_event_report', 'Add reports about the event'), ('edit_event_fund', 'Change where money for an event comes from'), ('view_event_billing', 'See financial info for event'), ('view_event_reports', 'See reports for event'), ('edit_event_text', 'Update any event descriptions'), ('adjust_event_owner', 'Change the event contact and organization'), ('edit_event_hours', 'Modify the time sheets'), ('edit_event_flags', 'Add flags to an event'), ('edit_event_lnl_contact', 'Change the LNL contact for an event'), ('event_view_sensitive', 'Show internal notes and other metadata marked as not public'), ('approve_event', 'Accept an event'), ('decline_event', 'Decline an event'), ('can_chief_event', 'Can crew chief an event'), ('review_event', 'Review an event for billing'), ('adjust_event_charges', 'Add charges and change event type'), ('bill_event', 'Send bills and mark event paid'), ('close_event', 'Lock an event after everything is done.'), ('view_test_event', 'Show events for testing'), ('event_view_granular', 'See debug data like ip addresses'), ('event_view_debug', 'See debug events'), ('reopen_event', 'Reopen a closed, declined, or cancelled event')), 'verbose_name': 'Event'}, + ), + ] diff --git a/events/models.py b/events/models.py index 3fca456f..b020a446 100755 --- a/events/models.py +++ b/events/models.py @@ -244,6 +244,7 @@ class BaseEvent(PolymorphicModel): description = models.TextField(null=True, blank=True) location = models.ForeignKey('Location', on_delete=models.PROTECT) contact = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True, verbose_name="Contact", related_name="contact") + lnl_contact = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True, verbose_name="LNL Contact", related_name="lnl_contact") org = models.ManyToManyField('Organization', blank=True, verbose_name="Client", related_name='events') billing_org = models.ForeignKey('Organization', on_delete=models.PROTECT, null=True, blank=True, related_name="billedevents") @@ -457,6 +458,7 @@ class Meta: ("adjust_event_owner", "Change the event contact and organization"), ("edit_event_hours", "Modify the time sheets"), ('edit_event_flags', 'Add flags to an event'), + ('edit_event_lnl_contact', 'Change the LNL contact for an event'), ("event_view_sensitive", "Show internal notes and other metadata marked as not public"), ("approve_event", "Accept an event"), ("decline_event", "Decline an event"), diff --git a/fixtures/groups.json b/fixtures/groups.json index b5a14aa1..64558073 100755 --- a/fixtures/groups.json +++ b/fixtures/groups.json @@ -125,6 +125,11 @@ "events", "baseevent" ], + [ + "edit_event_lnl_contact", + "events", + "baseevent" + ], [ "edit_event_fund", "events", diff --git a/site_tmpl/uglydetail.html b/site_tmpl/uglydetail.html index 0f366db9..d35c3a86 100644 --- a/site_tmpl/uglydetail.html +++ b/site_tmpl/uglydetail.html @@ -195,6 +195,12 @@

Confirm Reopen Event

+ + + +
LNL Contact (PM){% if event.lnl_contact %} + {{ event.lnl_contact.get_full_name }} + {% else %}{{ event.lnl_contact }} {% endif %}
Posted Description {{ event.description|markdown }}