From 1bb189bcc4b24bc42588797b26237f53b3fc1d4c Mon Sep 17 00:00:00 2001 From: corsaronero Date: Tue, 1 Nov 2022 10:35:42 +0000 Subject: [PATCH 01/57] =?UTF-8?q?Datenschutzbestimmungen=20und=20F=C3=B6rd?= =?UTF-8?q?errichtlinien=20=C3=B6ffnen=20nun=20auch=20in=20neuem=20Tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- input/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/forms.py b/input/forms.py index 826898b..9fb4ed9 100644 --- a/input/forms.py +++ b/input/forms.py @@ -32,7 +32,7 @@ class ExternForm(FdbForm): label='Was möchtest Du beantragen?') check = BooleanField(required=True, - label=format_html("Ich stimme den Datenschutzbestimmungen und den Förderrichtlinen zu", + label=format_html("Ich stimme den Datenschutzbestimmungen und den Förderrichtlinen zu", DATAPROTECTION, FOERDERRICHTLINIEN)) class Meta: From ace7fde295fff5108f728d3fab113066d90e451f Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 3 Nov 2022 16:37:18 +0000 Subject: [PATCH 02/57] added search field in admin panel model Projects, added displayed fields almost like wanted --- input/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/input/admin.py b/input/admin.py index 29e35e4..544b531 100644 --- a/input/admin.py +++ b/input/admin.py @@ -29,7 +29,8 @@ admin.site.add_action(export_as_csv) @admin.register(Project) class ProjectAdmin(admin.ModelAdmin): save_as = True - readonly_fields = ('pid','finance_id','project_of_year') + search_fields = ('name', 'pid','finance_id', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') + list_display = ('name', 'pid','finance_id', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') # action = ['export_as_csv'] From a5b7d92ec2b3495ecf2a68c0a66a64b14fa23da7 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 3 Nov 2022 17:02:39 +0000 Subject: [PATCH 03/57] full search and display fields for Projects, Services also added fields --- input/admin.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/input/admin.py b/input/admin.py index 544b531..55d5cc8 100644 --- a/input/admin.py +++ b/input/admin.py @@ -29,11 +29,16 @@ admin.site.add_action(export_as_csv) @admin.register(Project) class ProjectAdmin(admin.ModelAdmin): save_as = True - search_fields = ('name', 'pid','finance_id', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') - list_display = ('name', 'pid','finance_id', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') + search_fields = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') + list_display = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') # action = ['export_as_csv'] - +@admin.register(BusinessCard) +class BusinessCardAdmin(admin.ModelAdmin): + save_as = True + search_fields = ('realname', 'service_id', 'granted', 'granted_date', 'project') + list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project') + # action = ['export_as_csv'] admin.site.register([ Account, @@ -42,7 +47,6 @@ admin.site.register([ IFG, Travel, Email, - BusinessCard, List, Literature, ]) From 792f8df58886db26077caced1c2e241f3f33846f Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 4 Nov 2022 11:18:09 +0000 Subject: [PATCH 04/57] dates in tabulatures, based on django style with almost no new code. only applied to projects change list page --- input/admin.py | 9 +++++++-- input/models.py | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/input/admin.py b/input/admin.py index 55d5cc8..536c91a 100644 --- a/input/admin.py +++ b/input/admin.py @@ -32,13 +32,18 @@ class ProjectAdmin(admin.ModelAdmin): search_fields = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') list_display = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') # action = ['export_as_csv'] + date_hierarchy = 'start' @admin.register(BusinessCard) class BusinessCardAdmin(admin.ModelAdmin): - save_as = True - search_fields = ('realname', 'service_id', 'granted', 'granted_date', 'project') + save_as = True + search_fields = (('realname', 'service_id'), 'granted', 'granted_date', 'project') list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project') + list_display_links = ('realname', 'service_id') # action = ['export_as_csv'] + classes = ['collapse'] + + admin.site.register([ Account, diff --git a/input/models.py b/input/models.py index 997a3a5..ec412d3 100644 --- a/input/models.py +++ b/input/models.py @@ -93,12 +93,14 @@ class Project(Volunteer): # we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors # but maybe there is a better solution? super().save() - self.pid = str(self.account.code) + str(self.pk).zfill(3) + self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.pk).zfill(3) + # self.pid = str(self.account.code) + str(self.pk).zfill(3) # generation of finance_id if not self.project_of_year: - #print('AAA') + print('AAA') # we need to determine if this is a new year with its first new project... year = self.start.year + print(year) projects = Project.objects.filter(start__year=year) if not projects: #print('BBB') From 29d20e040efb596f42fdc1809c3db848696d6697 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Tue, 8 Nov 2022 12:55:54 +0000 Subject: [PATCH 05/57] added NOT choice, 'nicht stattgefunden', to project status button --- input/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/models.py b/input/models.py index ec412d3..dae00e3 100644 --- a/input/models.py +++ b/input/models.py @@ -83,7 +83,7 @@ class Project(Volunteer): # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) end_mail_send = models.BooleanField(null=True) - status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet')),default='RUN') + status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet'),('NOT','nicht stattgefunden')),default='RUN') persons = models.IntegerField(default=1) finance_id = models.CharField(max_length=15, null= True, blank=True) project_of_year = models.IntegerField(default=0) From 54eca0197cd10463a550014891c45cf9013c207d Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 11 Nov 2022 08:28:46 +0000 Subject: [PATCH 06/57] notes field is now bigger, changed to Textfield analog. new entry url_of_pic, migrated, javascript to hide in businesscard if nopic is choice --- input/admin.py | 5 +- input/forms.py | 3 +- ...ard_url_of_pic_alter_ifg_notes_and_more.py | 58 +++++++++++++++++++ input/models.py | 9 ++- input/static/dropdown/js/base.js | 24 ++++++++ 5 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py create mode 100644 input/static/dropdown/js/base.js diff --git a/input/admin.py b/input/admin.py index 536c91a..dc83ea1 100644 --- a/input/admin.py +++ b/input/admin.py @@ -41,8 +41,11 @@ class BusinessCardAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project') list_display_links = ('realname', 'service_id') # action = ['export_as_csv'] - classes = ['collapse'] + class Media: + js = ('dropdown/js/base.js',) + + admin.site.register([ diff --git a/input/forms.py b/input/forms.py index 9fb4ed9..9f12c31 100644 --- a/input/forms.py +++ b/input/forms.py @@ -96,7 +96,8 @@ class EmailForm(CheckForm): class BusinessCardForm(CheckForm): class Meta: model = BusinessCard - fields = ['project', 'data', 'variant', 'sent_to'] + + fields = ['project', 'data', 'variant', 'url_of_pic', 'sent_to'] class ListForm(CheckForm): class Meta: diff --git a/input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py b/input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py new file mode 100644 index 0000000..0a2427f --- /dev/null +++ b/input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py @@ -0,0 +1,58 @@ +# Generated by Django 4.1.2 on 2022-11-11 07:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0062_auto_20211103_1155'), + ] + + operations = [ + migrations.AddField( + model_name='businesscard', + name='url_of_pic', + field=models.TextField(default='', help_text='Bitte gib die Wikimedia-Commons-URL des Bildes an.', max_length=200, verbose_name='Url des Bildes'), + ), + migrations.AlterField( + model_name='ifg', + name='notes', + field=models.TextField(blank=True, help_text='Bitte gib an wofür Du das Stipendium verwenden willst.', max_length=1000, verbose_name='Anmerkungen'), + ), + migrations.AlterField( + model_name='library', + name='notes', + field=models.TextField(blank=True, help_text='Bitte gib an wofür Du das Stipendium verwenden willst.', max_length=1000, verbose_name='Anmerkungen'), + ), + migrations.AlterField( + model_name='library', + name='type', + field=models.CharField(choices=[('BIB', 'Bibliotheksstipendium'), ('ELIT', 'eLiteraturstipendium'), ('MAIL', 'E-Mail-Adresse'), ('IFG', 'Kostenübernahme IFG-Anfrage'), ('LIT', 'Literaturstipendium'), ('LIST', 'Mailingliste'), ('SOFT', 'Softwarestipendium'), ('VIS', 'Visitenkarten')], default='BIB', max_length=4), + ), + migrations.AlterField( + model_name='literature', + name='notes', + field=models.TextField(blank=True, help_text='Bitte gib an wofür Du das Stipendium verwenden willst.', max_length=1000, verbose_name='Anmerkungen'), + ), + migrations.AlterField( + model_name='project', + name='notes', + field=models.TextField(blank=True, max_length=1000, null=True, verbose_name='Anmerkungen'), + ), + migrations.AlterField( + model_name='project', + name='start', + field=models.DateField(null=True, verbose_name='Startdatum'), + ), + migrations.AlterField( + model_name='project', + name='status', + field=models.CharField(choices=[('RUN', 'läuft'), ('END', 'beendet'), ('NOT', 'nicht stattgefunden')], default='RUN', max_length=3), + ), + migrations.AlterField( + model_name='travel', + name='notes', + field=models.TextField(blank=True, max_length=1000), + ), + ] diff --git a/input/models.py b/input/models.py index dae00e3..a016742 100644 --- a/input/models.py +++ b/input/models.py @@ -78,7 +78,7 @@ class Project(Volunteer): cost = models.IntegerField(blank=True, null=True) account = models.ForeignKey('Account', on_delete=models.CASCADE, null=True, to_field='code', db_constraint = False) granted_from = models.CharField(max_length=100,null=True,verbose_name='Bewilligt von') - notes = models.CharField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') + notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) @@ -152,14 +152,14 @@ class Travel(Intern): checkout = models.DateField(blank=True, null=True, verbose_name='Check Out') payed_for_hotel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Hotel durch') payed_for_travel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Fahrt durch') - notes = models.CharField(max_length=500, blank=True) + notes = models.TextField(max_length=1000, blank=True) #abstract base class for Library and IFG class Grant(Extern): cost = models.CharField(max_length=10, verbose_name='Kosten', help_text="Bitte gib die ungefähr zu erwartenden Kosten in Euro an.") - notes = models.TextField(max_length=500, blank=True, verbose_name='Anmerkungen', + notes = models.TextField(max_length=1000, blank=True, verbose_name='Anmerkungen', help_text="Bitte gib an wofür Du das Stipendium verwenden willst.") class Meta: @@ -265,5 +265,8 @@ class BusinessCard(Extern): default='NOPIC', verbose_name='Variante', help_text=format_html('so sehen die Varianten aus: \ mit Bild ohne Bild' )) + + url_of_pic = models.CharField(max_length=200, verbose_name='Url des Bildes', default='', help_text="Bitte gib die Wikimedia-Commons-URL des Bildes an.") + sent_to = models.TextField(max_length=1000, verbose_name='Versandadresse', default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.") diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js new file mode 100644 index 0000000..d469bb5 --- /dev/null +++ b/input/static/dropdown/js/base.js @@ -0,0 +1,24 @@ +window.addEventListener("load", function() { +(function($) { + $(function() { + var selectField = $('#id_variant'), + verified = $('.field-url_of_pic'); + + function toggleVerified(value) { + if (value === 'PIC') { + verified.show(); + } else { + verified.hide(); + } + } + + // show/hide on load based on existing value of selectField + toggleVerified(selectField.val()); + + // show/hide on change + selectField.change(function() { + toggleVerified($(this).val()); + }); + }); +})(django.jQuery); +}); From 9167adeab51f2b37f0f017b0bbfe3d1192c44087 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 11 Nov 2022 08:44:38 +0000 Subject: [PATCH 07/57] added boolean field send_data_to_print with html formatted link to businesscard --- input/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/input/models.py b/input/models.py index a016742..341561c 100644 --- a/input/models.py +++ b/input/models.py @@ -270,3 +270,4 @@ class BusinessCard(Extern): sent_to = models.TextField(max_length=1000, verbose_name='Versandadresse', default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.") + send_data_to_print = models.BooleanField(null=False, verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten Versands der Druckerzeugnisse an mich.')) From 0d51dae1747afd0dd0944d0cf69d243586154427 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 11 Nov 2022 09:34:09 +0000 Subject: [PATCH 08/57] pic_of_url hidden in all views --- input/static/dropdown/js/base.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js index d469bb5..5769caa 100644 --- a/input/static/dropdown/js/base.js +++ b/input/static/dropdown/js/base.js @@ -2,7 +2,7 @@ window.addEventListener("load", function() { (function($) { $(function() { var selectField = $('#id_variant'), - verified = $('.field-url_of_pic'); + verified = $('#id_url_of_pic').parent().parent(); function toggleVerified(value) { if (value === 'PIC') { From 4c016a4a5aec54bc103b62c0d345e4be79a3cd51 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 11 Nov 2022 11:54:26 +0000 Subject: [PATCH 09/57] added dropdown agreement to send my data for buying literature for me --- input/static/dropdown/js/base.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js index 5769caa..0d8d5c4 100644 --- a/input/static/dropdown/js/base.js +++ b/input/static/dropdown/js/base.js @@ -1,9 +1,33 @@ window.addEventListener("load", function() { (function($) { $(function() { + var selectField_selfbuy = $('#id_selfbuy'), + verified_selfbuy_div = $('#id_selfbuy_give_data').parent().parent(), + verified_selfbuy = $('#id_selfbuy_give_data'); + + function toggleVerified_selfbuy(value) { + if (value === "FALSE") { + verified_selfbuy_div.show(); + verified_selfbuy.prop("checked", false); + } else { + verified_selfbuy_div.hide(); + verified_selfbuy.prop("checked", true); + } + } + + // show/hide on load based on existing value of selectField + toggleVerified_selfbuy(selectField_selfbuy.val()); + + // show/hide on change + selectField_selfbuy.change(function() { + toggleVerified_selfbuy($(this).val()); + }); + + + var selectField = $('#id_variant'), verified = $('#id_url_of_pic').parent().parent(); - + function toggleVerified(value) { if (value === 'PIC') { verified.show(); From fba8178d48eba13c4318748a8092237aba1c47d7 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Tue, 15 Nov 2022 16:57:01 +0000 Subject: [PATCH 10/57] Anfang code der Funktion end of proj approved in sendmails.py --- input/admin.py | 7 +++- input/forms.py | 20 +++++++++-- input/management/commands/sendmails.py | 30 ++++++++++++++++- ...ta_to_print_literature_selfbuy_and_more.py | 33 +++++++++++++++++++ .../0065_alter_literature_selfbuy_and_more.py | 23 +++++++++++++ input/models.py | 12 ++++++- input/settings.py | 6 ++-- 7 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py create mode 100644 input/migrations/0065_alter_literature_selfbuy_and_more.py diff --git a/input/admin.py b/input/admin.py index dc83ea1..f617d8e 100644 --- a/input/admin.py +++ b/input/admin.py @@ -34,6 +34,7 @@ class ProjectAdmin(admin.ModelAdmin): # action = ['export_as_csv'] date_hierarchy = 'start' + @admin.register(BusinessCard) class BusinessCardAdmin(admin.ModelAdmin): save_as = True @@ -45,6 +46,11 @@ class BusinessCardAdmin(admin.ModelAdmin): class Media: js = ('dropdown/js/base.js',) +@admin.register(Literature) +class LiteratureAdmin(admin.ModelAdmin): + + class Media: + js = ('dropdown/js/base.js',) @@ -56,5 +62,4 @@ admin.site.register([ Travel, Email, List, - Literature, ]) diff --git a/input/forms.py b/input/forms.py index 9f12c31..20b0746 100644 --- a/input/forms.py +++ b/input/forms.py @@ -83,21 +83,37 @@ class CheckForm(FdbForm): NUTZUNGSBEDINGUNGEN)) class LiteratureForm(CheckForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['selfbuy_give_data'].required = True class Meta: model = Literature - fields = ['cost', 'info', 'source', 'notes'] + fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_give_data'] + class Media: + js = ('dropdown/js/base.js',) class EmailForm(CheckForm): # TODO: add some javascript to show/hide other-field class Meta: model = Email fields = ['domain', 'address', 'other'] + class Media: + js = ('dropdown/js/base.js',) + + class BusinessCardForm(CheckForm): - class Meta: + # this is the code, to change required to false if needed + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['url_of_pic'].required = True + + class Meta: model = BusinessCard fields = ['project', 'data', 'variant', 'url_of_pic', 'sent_to'] + class Media: + js = ('dropdown/js/base.js',) class ListForm(CheckForm): class Meta: diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 4e3e2ae..917fc74 100644 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -50,9 +50,11 @@ class Command(BaseCommand): def end_of_projects_reached(self): ''' end of project reached ''' # get all projects which ended + + print(Project.objects.filter(end__lt = date.today())) old = Project.objects.filter(end__lt = date.today())\ .exclude(end_mail_send = True) - + mail_template = get_template('input/if_end_of_project.txt') for project in old: context = {'project': project} @@ -70,6 +72,31 @@ class Command(BaseCommand): self.stdout.write(self.style.SUCCESS('end_of_projects_reached() executed.')) + def end_of_projects_approved(self): + ''' end of project approved ''' + # get all projects where end was reached already, and send mails for the ones already set to status "ended" by the admins + + approved_end = Project.objects.filter(status = 'END')\ + .exclude(end_mail_send = False) + print(approved_end) + mail_template = get_template('input/if_end_of_project.txt') + for project in approved_end: + context = {'project': project} + context['URLPREFIX'] = settings.URLPREFIX + try: + send_mail('Projektende erreicht', + mail_template.render(context), + IF_EMAIL, + [IF_EMAIL], + fail_silently=False) + project.end_mail_send = True + project.save() + except BadHeaderError: + self.stdout.write(self.style.ERROR('Invalid header found.')) + + self.stdout.write(self.style.SUCCESS('end_of_projects_reached() executed.')) + + def surveymails_to_object(self, supported, name='', type='LIB'): mytype=type myname = name @@ -158,6 +185,7 @@ class Command(BaseCommand): '''the main function which is called by the custom command''' self.end_of_projects_reached() + self.end_of_projects_approved() self.surveymails_to_lib() self.surveymails_to_hon() self.surveymails_to_ifg() diff --git a/input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py b/input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py new file mode 100644 index 0000000..2875fec --- /dev/null +++ b/input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.1.2 on 2022-11-11 10:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0063_businesscard_url_of_pic_alter_ifg_notes_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='businesscard', + name='send_data_to_print', + field=models.BooleanField(default=False, help_text='Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten Versands der Druckerzeugnisse an mich.', verbose_name='Datenweitergabe erlauben'), + ), + migrations.AddField( + model_name='literature', + name='selfbuy', + field=models.CharField(choices=[('TRUE', 'Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), ('FALSE', 'Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft')], default='TRUE', max_length=10, verbose_name='Selbstkauf?'), + ), + migrations.AddField( + model_name='literature', + name='selfbuy_give_data', + field=models.BooleanField(default=False, help_text='Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.', verbose_name='Datenweitergabe erlauben'), + ), + migrations.AlterField( + model_name='businesscard', + name='url_of_pic', + field=models.CharField(default='', help_text='Bitte gib die Wikimedia-Commons-URL des Bildes an.', max_length=200, verbose_name='Url des Bildes'), + ), + ] diff --git a/input/migrations/0065_alter_literature_selfbuy_and_more.py b/input/migrations/0065_alter_literature_selfbuy_and_more.py new file mode 100644 index 0000000..d081397 --- /dev/null +++ b/input/migrations/0065_alter_literature_selfbuy_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.2 on 2022-11-11 11:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0064_businesscard_send_data_to_print_literature_selfbuy_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='literature', + name='selfbuy', + field=models.CharField(choices=[('TRUE', 'Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), ('FALSE', 'Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'), ('NONE', 'Nichts ausgewählt')], default='TRUE', max_length=10, verbose_name='Selbstkauf?'), + ), + migrations.AlterField( + model_name='literature', + name='selfbuy_give_data', + field=models.BooleanField(default='NONE', help_text='Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.', verbose_name='Datenweitergabe erlauben'), + ), + ] diff --git a/input/models.py b/input/models.py index 341561c..d1f6589 100644 --- a/input/models.py +++ b/input/models.py @@ -190,17 +190,27 @@ class Library(Grant): def __str__(self): return self.library + +SELFBUY_CHOICES = {'TRUE': format_html('Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), + 'FALSE': format_html('Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'), + 'NONE': format_html('Nichts ausgewählt') + } + + class Literature(Grant): info = models.CharField(max_length=500, verbose_name='Informationen zum Werk', help_text=format_html("Bitte gib alle Informationen zum benötigten Werk an,
\ die eine eindeutige Identifizierung ermöglichen (Autor, Titel, Verlag, ISBN, ...)")) source = models.CharField(max_length=200, verbose_name='Bezugsquelle', help_text="Bitte gib an, wo du das Werk kaufen möchtest.") + selfbuy = models.CharField( max_length=10, verbose_name='Selbstkauf?', choices=SELFBUY_CHOICES.items(), default='TRUE') + selfbuy_give_data = models.BooleanField(default='NONE', verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.')) class IFG(Grant): url = models.URLField(max_length=2000, verbose_name="URL", help_text="Bitte gib den Link zu deiner Anfrage bei Frag den Staat an.") + def __str__(self): return "IFG-Anfrage von " + self.realname @@ -270,4 +280,4 @@ class BusinessCard(Extern): sent_to = models.TextField(max_length=1000, verbose_name='Versandadresse', default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.") - send_data_to_print = models.BooleanField(null=False, verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten Versands der Druckerzeugnisse an mich.')) + send_data_to_print = models.BooleanField(default=False, verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten Versands der Druckerzeugnisse an mich.')) diff --git a/input/settings.py b/input/settings.py index eacac3f..8b01de1 100644 --- a/input/settings.py +++ b/input/settings.py @@ -1,6 +1,8 @@ # mail for IF-OTRS -IF_EMAIL = 'community@wikimedia.de' -SURVEY_EMAIL = 'christof.pins@wikimedia.de' +#IF_EMAIL = 'community@wikimedia.de' +IF_EMAIL = 'luca@cannabinieri.de' +#SURVEY_EMAIL = 'christof.pins@wikimedia.de' +SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' # prefix for urls SURVEYPREFIX = 'https://wikimedia.sslsurvey.de/Foerderbarometer/?' From 835646024200023de078e87954b22a5362bf8949 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Tue, 15 Nov 2022 17:01:58 +0000 Subject: [PATCH 11/57] added templates for changed sendmail.txt --- .../input/if_end_of_project_approved.txt | 35 +++++++++++++++++++ .../input/if_not_of_project_approved.txt | 29 +++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 input/templates/input/if_end_of_project_approved.txt create mode 100644 input/templates/input/if_not_of_project_approved.txt diff --git a/input/templates/input/if_end_of_project_approved.txt b/input/templates/input/if_end_of_project_approved.txt new file mode 100644 index 0000000..6d7f941 --- /dev/null +++ b/input/templates/input/if_end_of_project_approved.txt @@ -0,0 +1,35 @@ +Hallo, + +dein Projekt/die Veranstaltung {{project.name}} ist nun beendet und wir hoffen, dass alles gut geklappt hat! + +Bitte beachte nun, dass im Vorfeld besprochene Kostenerstattungen innerhalb eines Monats nach Entstehen der Kosten über unser Online-Formular Antrag auf Kostenerstattung eingereicht werden müssen. Spätere Einsendungen können ggf. nicht mehr erstattet werden. + +Da wir verpflichtet sind, über unsere geförderten Maßnahmen zu berichten, möchten wir dich gerne bitten uns kurz folgende Infos zu deinem Projekt zukommen zu lassen: +* Wie viele Personen haben an dem Projekt teilgenommen? +* Wo können die Ergebnisse des Projektes eingesehen werden? (Projektseite, Commons-Link, Bericht o. ä.) + +Sollten bei dem Projekt Fotos oder andere Mediendateien entstanden sein, findest du hier eine Anleitung, wie diese bei Commons hochgeladen werden sollen. + +Solltest du einen öffentlichen Förderantrag in der Wikipedia erstellt haben, kannst du diesen nun archivieren, indem du den Projektstatus oben im Quellcode entsprechend anpasst und die Liste der geförderten Aktivitäten entsprechend aktualisierst. + +Falls nicht bereits geschehen, wirst du demnächst eine weitere E-Mail erhalten, mit der du die Möglichkeit hast uns Feedback zu der Unterstützung zu geben. Danke, dass du dir Zeit dafür nimmst! + +Insbesondere möchten wir uns an dieser Stelle ganz herzlich bei dir für die Zusammenarbeit und dein Engagement für Freies Wissen bedanken! + +Viele Grüße +Dein Team Communitys und Engagement + +----- +Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden. + +Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin +Tel. (030) 219 158 26-0 +https://wikimedia.de + +Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei! +https://spenden.wikimedia.de + +Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207. + +Datenschutzerklärung: +Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. diff --git a/input/templates/input/if_not_of_project_approved.txt b/input/templates/input/if_not_of_project_approved.txt new file mode 100644 index 0000000..af3a719 --- /dev/null +++ b/input/templates/input/if_not_of_project_approved.txt @@ -0,0 +1,29 @@ +Hallo, + +dein Projekt/die Veranstaltung {{project.name}} konnte leider nicht wie geplant stattfinden. Gib uns gerne Bescheid, falls es bereits einen Nachholtermin geben sollte. Ansonsten freuen wir uns auf dein nächstes Vorhaben! + +Solltest du für dieses Projekt bereits Ausgaben gehabt haben, müssen im Vorfeld besprochene Kostenerstattungen innerhalb eines Monats nach Entstehen der Kosten über unser Online-Formular Antrag auf Kostenerstattung eingereicht werden. Spätere Einsendungen können ggf. nicht mehr erstattet werden. + +Solltest du einen öffentlichen Förderantrag in der Wikipedia erstellt haben, kannst du den Projektstatus oben im Quellcode entsprechend anpassen (z. B. „ausgesetztes Förderprojekt”). + +Auch wenn ein Projekt mal nicht wie geplant stattfindet: Wir möchten jeden Schritt unserer Arbeit bestmöglich gestalten und freuen uns über dein Feedback dazu. Falls nicht bereits geschehen, wirst du daher demnächst eine weitere E-Mail erhalten, mit der du die Möglichkeit hast uns Rückmeldung zu unserer Unterstützung zu geben. Danke, dass du dir Zeit dafür nimmst! + +Insbesondere möchten wir uns an dieser Stelle ganz herzlich bei dir für die Zusammenarbeit und dein Engagement für Freies Wissen bedanken! + +Viele Grüße +Dein Team Communitys und Engagement + +----- +Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden. + +Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin +Tel. (030) 219 158 26-0 +https://wikimedia.de + +Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei! +https://spenden.wikimedia.de + +Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207. + +Datenschutzerklärung: +Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. From 8d6be910f34085e8d60547777d0d6e5fceee426e Mon Sep 17 00:00:00 2001 From: corsaronero Date: Wed, 16 Nov 2022 21:19:49 +0000 Subject: [PATCH 12/57] added two sendmails functions, that are executed when admins change status of ended project --- foerderbarometer/settings.py_old | 151 ++++++++++++++++++ foerderbarometer/settings_development.py | 9 +- foerderbarometer/settings_production.py | 7 +- input/management/commands/sendmails.py | 50 +++++- input/settings.py | 2 +- .../input/if_end_of_project_orginformed.txt | 13 ++ 6 files changed, 225 insertions(+), 7 deletions(-) create mode 100644 foerderbarometer/settings.py_old create mode 100644 input/templates/input/if_end_of_project_orginformed.txt diff --git a/foerderbarometer/settings.py_old b/foerderbarometer/settings.py_old new file mode 100644 index 0000000..3b3ff79 --- /dev/null +++ b/foerderbarometer/settings.py_old @@ -0,0 +1,151 @@ +""" +Django settings for foerderbarometer project. + +Generated by 'django-admin startproject' using Django 3.1.1. + +For more information on this file, see +https://docs.djangoproject.com/en/3.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.1/ref/settings/ +""" + +import json +import os +from pathlib import Path + +from django.core.exceptions import ImproperlyConfigured + +# prefix for urls in mails +URLPREFIX = 'http://localhost:8000' + +# mails in development go to stdout +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# get secrets +with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file: + secrets = json.load(secrets_file) + +def get_secret(setting, secrets=secrets): + """Get secret setting or fail with ImproperlyConfigured""" + try: + return secrets[setting] + except KeyError: + raise ImproperlyConfigured("Set the {} setting".format(setting)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '*&7p9#_n$@^%0z49s+7jpy@+j1rw_hqh05knyd6y2*!0)r&b6h' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +STATIC_ROOT = BASE_DIR / 'staticfiles' + +ALLOWED_HOSTS = ['*'] + + +# Application definition + +INSTALLED_APPS = [ + 'input.apps.InputConfig', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'formtools', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'foerderbarometer.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'foerderbarometer.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/3.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + 'PASSWORD': get_secret('DATABASE_PASSWORD') + } +} + + +# Password validation +# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.1/howto/static-files/ + +STATIC_URL = '/static/' + +# needed since django 3.2 +DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' diff --git a/foerderbarometer/settings_development.py b/foerderbarometer/settings_development.py index 3b3ff79..15c0f3d 100644 --- a/foerderbarometer/settings_development.py +++ b/foerderbarometer/settings_development.py @@ -20,7 +20,14 @@ from django.core.exceptions import ImproperlyConfigured URLPREFIX = 'http://localhost:8000' # mails in development go to stdout -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' + +EMAIL_HOST = 'email.wikimedia.de' +EMAIL_PORT = '587' +EMAIL_USE_TLS = True +EMAIL_HOST_USER = '636ea784dd6ec43' +EMAIL_HOST_PASSWORD = 'wsgqp4ZaVRZZEpRJ' + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent diff --git a/foerderbarometer/settings_production.py b/foerderbarometer/settings_production.py index 2e40922..720e689 100644 --- a/foerderbarometer/settings_production.py +++ b/foerderbarometer/settings_production.py @@ -19,8 +19,11 @@ from django.core.exceptions import ImproperlyConfigured # mails in development go to stdout EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = '10.0.6.25' -EMAIL_PORT = '25' +EMAIL_HOST = 'email.wikimedia.de' +EMAIL_PORT = '587' +EMAIL_USE_TLS = True +EMAIL_HOST_USER = '636ea784dd6ec43' +EMAIL_HOST_PASSWORD = 'wsgqp4ZaVRZZEpRJ' # prefix for urls in mails URLPREFIX = 'http://foerderung.wikimedia.de' diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 917fc74..8471f43 100644 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -63,7 +63,7 @@ class Command(BaseCommand): send_mail('Projektende erreicht', mail_template.render(context), IF_EMAIL, - [IF_EMAIL], + ['luca@cannabinieri.de'], fail_silently=False) project.end_mail_send = True project.save() @@ -79,7 +79,10 @@ class Command(BaseCommand): approved_end = Project.objects.filter(status = 'END')\ .exclude(end_mail_send = False) print(approved_end) - mail_template = get_template('input/if_end_of_project.txt') + mail_template = get_template('input/if_end_of_project_approved.txt') + informMail_template = get_template('input/if_end_of_project_orginformed.txt') + # send the mail to project.email, which would be the mail of the volunteer filling out the form + for project in approved_end: context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX @@ -87,14 +90,54 @@ class Command(BaseCommand): send_mail('Projektende erreicht', mail_template.render(context), IF_EMAIL, + [project.email], + fail_silently=False) + send_mail('Projektorganisator*in wurde informiert', + informMail_template.render(context), + IF_EMAIL, [IF_EMAIL], fail_silently=False) + project.end_mail_send = True project.save() except BadHeaderError: self.stdout.write(self.style.ERROR('Invalid header found.')) - self.stdout.write(self.style.SUCCESS('end_of_projects_reached() executed.')) + self.stdout.write(self.style.SUCCESS('end_of_projects_approved() executed.')) + + def notHappened_of_projects_approved(self): + ''' notHappened of project approved ''' + # get all projects where end was reached already, and send mails for the ones where status was put to NOT by admins + + approved_notHappened = Project.objects.filter(status = 'NOT')\ + .exclude(end_mail_send = False) + + mail_template = get_template('input/if_not_of_project_approved.txt') + informMail_template = get_template('input/if_end_of_project_orginformed.txt') + + # send the mail to project.email, which would be the mail of the volunteer that filled out the form + + for project in approved_notHappened: + context = {'project': project} + context['URLPREFIX'] = settings.URLPREFIX + try: + send_mail('Projektende erreicht', + mail_template.render(context), + IF_EMAIL, + [project.email], + fail_silently=False) + send_mail('Projektorganisator*in wurde informiert', + informMail_template.render(context), + IF_EMAIL, + [IF_EMAIL], + fail_silently=False) + + project.end_mail_send = True + project.save() + except BadHeaderError: + self.stdout.write(self.style.ERROR('Invalid header found.')) + + self.stdout.write(self.style.SUCCESS('notHappened_of_projects_approved() executed.')) def surveymails_to_object(self, supported, name='', type='LIB'): @@ -186,6 +229,7 @@ class Command(BaseCommand): self.end_of_projects_reached() self.end_of_projects_approved() + self.notHappened_of_projects_approved() self.surveymails_to_lib() self.surveymails_to_hon() self.surveymails_to_ifg() diff --git a/input/settings.py b/input/settings.py index 8b01de1..5ee83b0 100644 --- a/input/settings.py +++ b/input/settings.py @@ -1,6 +1,6 @@ # mail for IF-OTRS #IF_EMAIL = 'community@wikimedia.de' -IF_EMAIL = 'luca@cannabinieri.de' +IF_EMAIL = 'test-luca-ext@wikimedia.de' #SURVEY_EMAIL = 'christof.pins@wikimedia.de' SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' diff --git a/input/templates/input/if_end_of_project_orginformed.txt b/input/templates/input/if_end_of_project_orginformed.txt new file mode 100644 index 0000000..05b12a3 --- /dev/null +++ b/input/templates/input/if_end_of_project_orginformed.txt @@ -0,0 +1,13 @@ +Hallo Team Communitys und Engagement! + +Das Project {{project.name}} hat am {{project.end}} sein vorraussichtliches +Ende erreicht. + +Hier könnt ihr es in der Datenbank editieren: + +{{URLPREFIX}}/admin/input/project/{{project.pk}}/change + + +Projektorganisator*in wurde über den Projektabschluss informiert. + +mit freundlichen Grüßen, Eure Lieblingsdatenbank From 372bd3239551eb497faddd9b2176b3f39d6be1cb Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 11:04:23 +0000 Subject: [PATCH 13/57] buttons in input form displaying 'Weiter', if last step then displaying 'Absenden' --- input/templates/input/extern.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/input/templates/input/extern.html b/input/templates/input/extern.html index 7efd013..f4386a4 100644 --- a/input/templates/input/extern.html +++ b/input/templates/input/extern.html @@ -52,7 +52,11 @@ Du hast {{choice}} ausgewählt. {% if wizard.steps.prev %} {% endif %} + {% if wizard.steps.current == wizard.steps.last %} + + {% else %} + {% endif %}

From 08406d97d1758a43c709cf4e061318cca1c22daa Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 11:40:30 +0000 Subject: [PATCH 14/57] if not happened mail is now in html format, if not html then txt --- .../input/if_not_of_project_approved.html | 41 +++++++++++++++++++ .../input/if_not_of_project_approved.txt | 1 + 2 files changed, 42 insertions(+) create mode 100644 input/templates/input/if_not_of_project_approved.html diff --git a/input/templates/input/if_not_of_project_approved.html b/input/templates/input/if_not_of_project_approved.html new file mode 100644 index 0000000..fa5f4df --- /dev/null +++ b/input/templates/input/if_not_of_project_approved.html @@ -0,0 +1,41 @@ + + + + +

+Hallo, +
+dein Projekt/die Veranstaltung {{project.name}} konnte leider nicht wie geplant stattfinden. Gib uns gerne Bescheid, falls es bereits einen Nachholtermin geben sollte. Ansonsten freuen wir uns auf dein nächstes Vorhaben! +
+Solltest du für dieses Projekt bereits Ausgaben gehabt haben, müssen im Vorfeld besprochene Kostenerstattungen innerhalb eines Monats nach Entstehen der Kosten über unser Online-Formular Antrag auf Kostenerstattung eingereicht werden. Spätere Einsendungen können ggf. nicht mehr erstattet werden. +
+Solltest du einen öffentlichen Förderantrag in der Wikipedia erstellt haben, kannst du den Projektstatus oben im Quellcode entsprechend anpassen (z. B. „ausgesetztes Förderprojekt”). +
+Auch wenn ein Projekt mal nicht wie geplant stattfindet: Wir möchten jeden Schritt unserer Arbeit bestmöglich gestalten und freuen uns über dein Feedback dazu. Falls nicht bereits geschehen, wirst du daher demnächst eine weitere E-Mail erhalten, mit der du die Möglichkeit hast uns Rückmeldung zu unserer Unterstützung zu geben. Danke, dass du dir Zeit dafür nimmst! +
+Insbesondere möchten wir uns an dieser Stelle ganz herzlich bei dir für die Zusammenarbeit und dein Engagement für Freies Wissen bedanken! +
+Ein Link zum Probieren +
+Viele Grüße +Dein Team Communitys und Engagement +

+----- +Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden. +

+Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin
+Tel. (030) 219 158 26-0
+https://wikimedia.de
+

+Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei!
+https://spenden.wikimedia.de +

+Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207. +

+Datenschutzerklärung:
+Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. +

+

+ + + diff --git a/input/templates/input/if_not_of_project_approved.txt b/input/templates/input/if_not_of_project_approved.txt index af3a719..3fe07fa 100644 --- a/input/templates/input/if_not_of_project_approved.txt +++ b/input/templates/input/if_not_of_project_approved.txt @@ -27,3 +27,4 @@ Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Einge Datenschutzerklärung: Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. + From 4603dddb69dc68554bfee494ea779d378b1add79 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 16:22:18 +0000 Subject: [PATCH 15/57] added the automated mail with the possibility to grant travel costs by link in email --- input/forms.py | 8 ++++++- input/management/commands/sendmails.py | 23 ++++++++++++++----- input/migrations/0066_email_adult.py | 18 +++++++++++++++ ..._travel_project_name_alter_library_type.py | 23 +++++++++++++++++++ input/migrations/0068_travel_hotel.py | 18 +++++++++++++++ .../migrations/0069_alter_travel_transport.py | 18 +++++++++++++++ input/migrations/0070_alter_travel_project.py | 19 +++++++++++++++ input/models.py | 14 +++++++++-- input/views.py | 7 +++++- 9 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 input/migrations/0066_email_adult.py create mode 100644 input/migrations/0067_travel_project_name_alter_library_type.py create mode 100644 input/migrations/0068_travel_hotel.py create mode 100644 input/migrations/0069_alter_travel_transport.py create mode 100644 input/migrations/0070_alter_travel_project.py diff --git a/input/forms.py b/input/forms.py index 20b0746..de6fc83 100644 --- a/input/forms.py +++ b/input/forms.py @@ -26,6 +26,7 @@ class ProjectForm(FdbForm): widgets = {'start': AdminDateWidget(), 'end': AdminDateWidget(),} + class ExternForm(FdbForm): choice = ChoiceField(choices=TYPE_CHOICES.items(), widget=RadioSelect, @@ -39,6 +40,7 @@ class ExternForm(FdbForm): model = ConcreteExtern exclude = ('granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date') + INTERN_CHOICES = {'PRO': 'Projektsteckbrief', 'HON': 'Ehrenamtsbescheinigung, Akkreditierung oder Redaktionsbestätigung', 'TRAV': 'Reisekostenerstattung'} @@ -51,11 +53,12 @@ class InternForm(FdbForm): model = ConcreteVolunteer exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date') + class TravelForm(FdbForm): # TODO: add some javascript to show/hide other-field class Meta: model = Travel - exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date') + exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by' ) widgets = {'checkin': AdminDateWidget(), 'checkout': AdminDateWidget(),} @@ -82,6 +85,7 @@ class CheckForm(FdbForm): label=format_html("Ich stimme den Nutzungsbedingungen zu", NUTZUNGSBEDINGUNGEN)) + class LiteratureForm(CheckForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -115,7 +119,9 @@ class BusinessCardForm(CheckForm): class Media: js = ('dropdown/js/base.js',) + class ListForm(CheckForm): class Meta: model = List fields = ['domain', 'address'] + diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 8471f43..243c396 100644 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -4,6 +4,7 @@ import sys from django.core.management.base import BaseCommand, CommandError from django.template.loader import get_template from django.core.mail import send_mail, BadHeaderError, EmailMessage +from django.core.mail import EmailMultiAlternatives from django.conf import settings from input.models import Project, Library, HonoraryCertificate, Travel, Email,\ @@ -112,7 +113,8 @@ class Command(BaseCommand): approved_notHappened = Project.objects.filter(status = 'NOT')\ .exclude(end_mail_send = False) - mail_template = get_template('input/if_not_of_project_approved.txt') + html_mail_template = get_template('input/if_not_of_project_approved.html') + txt_mail_template = get_template('input/if_not_of_project_approved.txt') informMail_template = get_template('input/if_end_of_project_orginformed.txt') # send the mail to project.email, which would be the mail of the volunteer that filled out the form @@ -121,11 +123,20 @@ class Command(BaseCommand): context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX try: - send_mail('Projektende erreicht', - mail_template.render(context), - IF_EMAIL, - [project.email], - fail_silently=False) + subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + + + #send_mail('Projektende erreicht', + # mail_template.render(context), + # IF_EMAIL, + # [project.email], + # fail_silently=False) send_mail('Projektorganisator*in wurde informiert', informMail_template.render(context), IF_EMAIL, diff --git a/input/migrations/0066_email_adult.py b/input/migrations/0066_email_adult.py new file mode 100644 index 0000000..419a9b4 --- /dev/null +++ b/input/migrations/0066_email_adult.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-17 11:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0065_alter_literature_selfbuy_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='email', + name='adult', + field=models.CharField(choices=[('TRUE', 'Ich bin volljährig.'), ('FALSE', 'Ich bin noch nicht volljährig.'), ('NONE', 'Nichts ausgewählt')], default='NONE', max_length=10, verbose_name='Volljährigkeit'), + ), + ] diff --git a/input/migrations/0067_travel_project_name_alter_library_type.py b/input/migrations/0067_travel_project_name_alter_library_type.py new file mode 100644 index 0000000..5cbcb7a --- /dev/null +++ b/input/migrations/0067_travel_project_name_alter_library_type.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.2 on 2022-11-17 15:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0066_email_adult'), + ] + + operations = [ + migrations.AddField( + model_name='travel', + name='project_name', + field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Projektname:'), + ), + migrations.AlterField( + model_name='library', + name='type', + field=models.CharField(choices=[('BIB', 'Bibliotheksstipendium'), ('ELIT', 'eLiteraturstipendium'), ('MAIL', 'E-Mail-Adresse'), ('IFG', 'Kostenübernahme IFG-Anfrage'), ('LIT', 'Literaturstipendium'), ('LIST', 'Mailingliste'), ('SOFT', 'Softwarestipendium'), ('VIS', 'Visitenkarten'), ('TRAV', 'Reisekosten')], default='BIB', max_length=4), + ), + ] diff --git a/input/migrations/0068_travel_hotel.py b/input/migrations/0068_travel_hotel.py new file mode 100644 index 0000000..82fd575 --- /dev/null +++ b/input/migrations/0068_travel_hotel.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-17 15:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0067_travel_project_name_alter_library_type'), + ] + + operations = [ + migrations.AddField( + model_name='travel', + name='hotel', + field=models.BooleanField(default=False, verbose_name='Hotelzimmer benötigt:'), + ), + ] diff --git a/input/migrations/0069_alter_travel_transport.py b/input/migrations/0069_alter_travel_transport.py new file mode 100644 index 0000000..77538db --- /dev/null +++ b/input/migrations/0069_alter_travel_transport.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-17 15:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0068_travel_hotel'), + ] + + operations = [ + migrations.AlterField( + model_name='travel', + name='transport', + field=models.CharField(choices=[('BAHN', 'Bahn'), ('NONE', 'Keine Fahrtkosten'), ('OTHER', 'Sonstiges (mit Begründung)')], default='BAHN', max_length=5, verbose_name='Transportmittel:'), + ), + ] diff --git a/input/migrations/0070_alter_travel_project.py b/input/migrations/0070_alter_travel_project.py new file mode 100644 index 0000000..fe82970 --- /dev/null +++ b/input/migrations/0070_alter_travel_project.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.2 on 2022-11-17 16:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0069_alter_travel_transport'), + ] + + operations = [ + migrations.AlterField( + model_name='travel', + name='project', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='input.project'), + ), + ] diff --git a/input/models.py b/input/models.py index d1f6589..a92ff61 100644 --- a/input/models.py +++ b/input/models.py @@ -144,14 +144,17 @@ PAYEDBY_CHOICES = {'WMDE': 'WMDE', 'REQU': 'Antragstellender Mensch'} class Travel(Intern): - project = models.ForeignKey(Project, on_delete=models.CASCADE) - transport = models.CharField(max_length=5, choices=TRANSPORT_CHOICES.items(), default='BAHN') + # project variable is now null true and blank true, which means it can be saved without project id to be later on filled out by admins + project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True) + project_name = models.CharField(max_length=50, null=True, blank=True, verbose_name='Projektname:') + transport = models.CharField(max_length=5, choices=TRANSPORT_CHOICES.items(), default='BAHN', verbose_name='Transportmittel:') other_transport = models.CharField(max_length=200, null=True, blank=True, verbose_name='Sonstige Transportmittel (mit Begründung)') travelcost = models.CharField(max_length=10, default="0", verbose_name="Fahrtkosten") checkin = models.DateField(blank=True, null=True, verbose_name='Check In') checkout = models.DateField(blank=True, null=True, verbose_name='Check Out') payed_for_hotel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Hotel durch') payed_for_travel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Fahrt durch') + hotel = models.BooleanField(default=False, verbose_name='Hotelzimmer benötigt:') notes = models.TextField(max_length=1000, blank=True) @@ -174,6 +177,7 @@ TYPE_CHOICES = {'BIB': format_html('Mailingliste'), 'SOFT': format_html('Softwarestipendium'), 'VIS': format_html('Visitenkarten'), + 'TRAV': format_html('Reisekosten'), } # same model is used for Library, ELitStip and Software! @@ -232,6 +236,11 @@ MAIL_CHOICES = {'REALNAME': 'Vorname.Nachname', 'USERNAME': 'Username', 'OTHER': 'Sonstiges:'} +ADULT_CHOICES = {'TRUE': format_html('Ich bin volljährig.'), + 'FALSE': format_html('Ich bin noch nicht volljährig.'), + 'NONE': format_html('Nichts ausgewählt') + } + class Email(Domain): address = models.CharField(max_length=50, choices=MAIL_CHOICES.items(), @@ -239,6 +248,7 @@ class Email(Domain): help_text=format_html("Bitte gib hier den gewünschten Adressbestandteil an,
der sich vor der Domain befinden soll.")) other = models.CharField(max_length=50,blank=True,null=True, verbose_name="Sonstiges") + adult = models.CharField( max_length=10, verbose_name='Volljährigkeit', choices=ADULT_CHOICES.items(), default='NONE') class List(Domain): address = models.CharField(max_length=50, default='NO_ADDRESS', diff --git a/input/views.py b/input/views.py index cadf55a..e86ebbf 100644 --- a/input/views.py +++ b/input/views.py @@ -16,7 +16,7 @@ from django.utils.html import format_html from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\ HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ ListForm, BusinessCardForm, INTERN_CHOICES -from .models import Project, TYPE_CHOICES, Library, Literature +from .models import Project, TYPE_CHOICES, Library, Literature, Travel from .settings import IF_EMAIL def auth_deny(choice,pk,auth): @@ -26,6 +26,8 @@ def auth_deny(choice,pk,auth): Literature.set_granted(pk,auth) elif choice == 'IFG': IFG.set_granted(pk,auth) + elif choice == 'TRAV': + Travel.set_granted(pk,auth) else: return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}') return False @@ -134,6 +136,7 @@ LABEL_CHOICES = {'BIB': format_html('Bibliothek'), 'LIST': format_html('Mailingliste'), 'SOFT': format_html('Software'), 'VIS': format_html('Visitenkarten'), + 'TRAV': format_html('Reisekosten'), } HELP_CHOICES = {'BIB': format_html("In welchem Zeitraum möchtest du recherchieren oder
wie lange ist der Bibliotheksausweis gültig?"), @@ -178,6 +181,8 @@ class ExternView(CookieWizardView): elif choice == 'LIST': form = ListForm(data) form.fields['domain'].help_text = format_html("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,
möchtest du eine Mailingliste beantragen?") + elif choice == 'TRAV': + form = TravelForm(data) else: raise RuntimeError(f'ERROR! UNKNOWN FORMTYPE {choice} in ExternView') self.choice = choice From ca7fbf6af7972b2b933631069f9b6ae987333965 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 16:27:42 +0000 Subject: [PATCH 16/57] intern url commented out in urls.py --- input/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/urls.py b/input/urls.py index 4854f11..ba4c2b4 100644 --- a/input/urls.py +++ b/input/urls.py @@ -4,7 +4,7 @@ from .views import ExternView, done, authorize, deny, InternView, export urlpatterns = [ path('', ExternView.as_view(), name='extern'), - path('intern', InternView.as_view(), name='intern'), +# path('intern', InternView.as_view(), name='intern'), path('saved', done, name='done'), path('export', export, name='export'), path('authorize//', authorize, name='authorize'), From 687fdddb8e4a1667faa553e1d676296da9ad86b9 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 16:46:58 +0000 Subject: [PATCH 17/57] made mail.adult a required field --- input/forms.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/input/forms.py b/input/forms.py index de6fc83..3a7bae9 100644 --- a/input/forms.py +++ b/input/forms.py @@ -97,10 +97,17 @@ class LiteratureForm(CheckForm): js = ('dropdown/js/base.js',) class EmailForm(CheckForm): + + # this is the code, to change required to false if needed + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['adult'].required = True + + # TODO: add some javascript to show/hide other-field class Meta: model = Email - fields = ['domain', 'address', 'other'] + fields = ['domain', 'address', 'other', 'adult'] class Media: js = ('dropdown/js/base.js',) From c3c5a44be58df625af2d98bc2f9110283dffe514 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 17:39:43 +0000 Subject: [PATCH 18/57] added date hierarchy and overview in admin panel to all other forms in admin.py, also created variable intern_notes --- input/admin.py | 81 ++++++++++++++++--- ...ficate_intern_notes_travel_intern_notes.py | 23 ++++++ input/models.py | 2 +- 3 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py diff --git a/input/admin.py b/input/admin.py index f617d8e..eff2e5e 100644 --- a/input/admin.py +++ b/input/admin.py @@ -42,24 +42,83 @@ class BusinessCardAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project') list_display_links = ('realname', 'service_id') # action = ['export_as_csv'] - + date_hierarchy = 'granted_date' class Media: js = ('dropdown/js/base.js',) @admin.register(Literature) class LiteratureAdmin(admin.ModelAdmin): - + save_as = True + search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + list_display = ('realname', 'service_id', 'granted', 'granted_date') + list_display_links = ('realname', 'service_id') + date_hierarchy = 'granted_date' class Media: js = ('dropdown/js/base.js',) +@admin.register(Account) +class AccountAdmin(admin.ModelAdmin): + save_as = True -admin.site.register([ - Account, - HonoraryCertificate, - Library, - IFG, - Travel, - Email, - List, - ]) + +@admin.register(HonoraryCertificate) +class HonoraryCertificateAdmin(admin.ModelAdmin): + save_as = True + search_fields = ('realname', 'granted', 'granted_date', 'project') + list_display = ('realname', 'granted', 'granted_date', 'project') + list_display_links = ('realname', 'project') + date_hierarchy = 'granted_date' + +@admin.register(Library) +class LibraryAdmin(admin.ModelAdmin): + save_as = True + search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + list_display = ('realname', 'service_id', 'granted', 'granted_date') + list_display_links = ('realname', 'service_id') + date_hierarchy = 'granted_date' + +@admin.register(IFG) +class IFGAdmin(admin.ModelAdmin): + save_as = True + search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + list_display = ('realname', 'service_id', 'granted', 'granted_date') + list_display_links = ('realname', 'service_id') + date_hierarchy = 'granted_date' + +@admin.register(Travel) +class TravelAdmin(admin.ModelAdmin): + save_as = True + search_fields = ('realname', 'granted', 'granted_date', 'project') + list_display = ('realname', 'granted', 'granted_date', 'project') + list_display_links = ('realname', 'project') + date_hierarchy = 'granted_date' + +@admin.register(Email) +class EmailAdmin(admin.ModelAdmin): + save_as = True + search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + list_display = ('realname', 'service_id', 'granted', 'granted_date') + list_display_links = ('realname', 'service_id') + date_hierarchy = 'granted_date' + + +@admin.register(List) +class ListAdmin(admin.ModelAdmin): + save_as = True + search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + list_display = ('realname', 'service_id', 'granted', 'granted_date') + list_display_links = ('realname', 'service_id') + date_hierarchy = 'granted_date' + +# commented out because of the individual registering to control displays in admin panel + +#admin.site.register([ +# Account, +# HonoraryCertificate, +# Library, +# IFG, +# Travel, +# Email, +# List, +# ]) diff --git a/input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py b/input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py new file mode 100644 index 0000000..ed4f2df --- /dev/null +++ b/input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.2 on 2022-11-17 17:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0070_alter_travel_project'), + ] + + operations = [ + migrations.AddField( + model_name='honorarycertificate', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + migrations.AddField( + model_name='travel', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + ] diff --git a/input/models.py b/input/models.py index a92ff61..703c43d 100644 --- a/input/models.py +++ b/input/models.py @@ -119,7 +119,7 @@ class Project(Volunteer): class Intern(Volunteer): '''abstrat base class for data entry from /intern (except Project)''' request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') - + intern_notes = models.TextField(max_length=1000, blank=True) class Meta: abstract = True From 5d436f9294a5dc16b05683fe44778037d0347f2d Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 18:19:18 +0000 Subject: [PATCH 19/57] added intern_notes variable to all dbs, not excluded in extern view for all --- input/forms.py | 10 ++++- ...ntern_notes_email_intern_notes_and_more.py | 43 +++++++++++++++++++ input/migrations/0073_account_intern_notes.py | 18 ++++++++ input/migrations/0074_project_intern_notes.py | 18 ++++++++ input/models.py | 13 ++++-- 5 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py create mode 100644 input/migrations/0073_account_intern_notes.py create mode 100644 input/migrations/0074_project_intern_notes.py diff --git a/input/forms.py b/input/forms.py index 3a7bae9..c3e8127 100644 --- a/input/forms.py +++ b/input/forms.py @@ -58,7 +58,7 @@ class TravelForm(FdbForm): # TODO: add some javascript to show/hide other-field class Meta: model = Travel - exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by' ) + exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes' ) widgets = {'checkin': AdminDateWidget(), 'checkout': AdminDateWidget(),} @@ -67,16 +67,19 @@ class LibraryForm(FdbForm): class Meta: model = Library fields = ['cost', 'library', 'duration', 'notes'] + exclude = ['intern_notes'] class HonoraryCertificateForm(FdbForm): class Meta: model = HonoraryCertificate fields = ['request_url', 'project'] + exclude = ['intern_notes'] class IFGForm(FdbForm): class Meta: model = IFG fields = ['cost', 'url', 'notes'] + exclude = ['intern_notes'] class CheckForm(FdbForm): @@ -93,6 +96,7 @@ class LiteratureForm(CheckForm): class Meta: model = Literature fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_give_data'] + exclude = ['intern_notes'] class Media: js = ('dropdown/js/base.js',) @@ -108,6 +112,7 @@ class EmailForm(CheckForm): class Meta: model = Email fields = ['domain', 'address', 'other', 'adult'] + exclude = ['intern_notes'] class Media: js = ('dropdown/js/base.js',) @@ -121,7 +126,7 @@ class BusinessCardForm(CheckForm): class Meta: model = BusinessCard - + exclude = ['intern_notes'] fields = ['project', 'data', 'variant', 'url_of_pic', 'sent_to'] class Media: js = ('dropdown/js/base.js',) @@ -131,4 +136,5 @@ class ListForm(CheckForm): class Meta: model = List fields = ['domain', 'address'] + exclude = ['intern_notes'] diff --git a/input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py b/input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py new file mode 100644 index 0000000..d837869 --- /dev/null +++ b/input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 4.1.2 on 2022-11-17 18:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0071_honorarycertificate_intern_notes_travel_intern_notes'), + ] + + operations = [ + migrations.AddField( + model_name='businesscard', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + migrations.AddField( + model_name='email', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + migrations.AddField( + model_name='ifg', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + migrations.AddField( + model_name='library', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + migrations.AddField( + model_name='list', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + migrations.AddField( + model_name='literature', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + ] diff --git a/input/migrations/0073_account_intern_notes.py b/input/migrations/0073_account_intern_notes.py new file mode 100644 index 0000000..1048bc7 --- /dev/null +++ b/input/migrations/0073_account_intern_notes.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-17 18:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0072_businesscard_intern_notes_email_intern_notes_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='account', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + ] diff --git a/input/migrations/0074_project_intern_notes.py b/input/migrations/0074_project_intern_notes.py new file mode 100644 index 0000000..ef6dce2 --- /dev/null +++ b/input/migrations/0074_project_intern_notes.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-17 18:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0073_account_intern_notes'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000), + ), + ] diff --git a/input/models.py b/input/models.py index 703c43d..e42cd43 100644 --- a/input/models.py +++ b/input/models.py @@ -55,7 +55,7 @@ class Account(models.Model): code = models.CharField('Kostenstelle', max_length=5, default="DEF", null=False, primary_key = True) description = models.CharField('Beschreibung', max_length=60, default='NO DESCRIPTION') - + intern_notes = models.TextField(max_length=1000, blank=True) def __str__(self): return f"{self.code} {self.description}" @@ -79,7 +79,8 @@ class Project(Volunteer): account = models.ForeignKey('Account', on_delete=models.CASCADE, null=True, to_field='code', db_constraint = False) granted_from = models.CharField(max_length=100,null=True,verbose_name='Bewilligt von') notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') - + intern_notes = models.TextField(max_length=1000, blank=True) + # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) end_mail_send = models.BooleanField(null=True) @@ -190,7 +191,7 @@ class Library(Grant): ) library = models.CharField(max_length=200) duration = models.CharField(max_length=100, verbose_name="Dauer") - + intern_notes = models.TextField(max_length=1000, blank=True) def __str__(self): return self.library @@ -209,11 +210,12 @@ class Literature(Grant): help_text="Bitte gib an, wo du das Werk kaufen möchtest.") selfbuy = models.CharField( max_length=10, verbose_name='Selbstkauf?', choices=SELFBUY_CHOICES.items(), default='TRUE') selfbuy_give_data = models.BooleanField(default='NONE', verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.')) + intern_notes = models.TextField(max_length=1000, blank=True) class IFG(Grant): url = models.URLField(max_length=2000, verbose_name="URL", help_text="Bitte gib den Link zu deiner Anfrage bei Frag den Staat an.") - + intern_notes = models.TextField(max_length=1000, blank=True) def __str__(self): return "IFG-Anfrage von " + self.realname @@ -249,11 +251,13 @@ class Email(Domain): other = models.CharField(max_length=50,blank=True,null=True, verbose_name="Sonstiges") adult = models.CharField( max_length=10, verbose_name='Volljährigkeit', choices=ADULT_CHOICES.items(), default='NONE') + intern_notes = models.TextField(max_length=1000, blank=True) class List(Domain): address = models.CharField(max_length=50, default='NO_ADDRESS', verbose_name="Adressbestandteil für Projektmailingliste", help_text=format_html("Bitte gib hier den gewünschten Adressbestandteil an,
der sich vor der Domain befinden soll.")) + intern_notes = models.TextField(max_length=1000, blank=True) PROJECT_CHOICE = {'PEDIA': 'Wikipedia', 'SOURCE': 'Wikisource', @@ -291,3 +295,4 @@ class BusinessCard(Extern): sent_to = models.TextField(max_length=1000, verbose_name='Versandadresse', default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.") send_data_to_print = models.BooleanField(default=False, verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten Versands der Druckerzeugnisse an mich.')) + intern_notes = models.TextField(max_length=1000, blank=True) From 43df9bd3539058ba4c64dc5fe9a188b69eebcbf0 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 18:37:38 +0000 Subject: [PATCH 20/57] created html versions of all mail templates --- input/templates/input/if_end_of_project.html | 16 +++++++ .../input/if_end_of_project_approved.html | 41 ++++++++++++++++++ .../input/if_end_of_project_orginformed.html | 19 +++++++++ input/templates/input/if_mail.html | 35 ++++++++++++++++ input/templates/input/ifg_volunteer_mail.html | 34 +++++++++++++++ input/templates/input/survey_mail.html | 42 +++++++++++++++++++ 6 files changed, 187 insertions(+) create mode 100644 input/templates/input/if_end_of_project.html create mode 100644 input/templates/input/if_end_of_project_approved.html create mode 100644 input/templates/input/if_end_of_project_orginformed.html create mode 100644 input/templates/input/if_mail.html create mode 100644 input/templates/input/ifg_volunteer_mail.html create mode 100644 input/templates/input/survey_mail.html diff --git a/input/templates/input/if_end_of_project.html b/input/templates/input/if_end_of_project.html new file mode 100644 index 0000000..fefd007 --- /dev/null +++ b/input/templates/input/if_end_of_project.html @@ -0,0 +1,16 @@ + + + +Hallo Team Communitys und Engagement! +

+Das Project {{project.name}} hat am {{project.end}} sein vorraussichtliches +Ende erreicht.

+ +Hier könnt ihr es in der Datenbank editieren: +

+{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +

+mit freundlichen Grüßen, Eure Lieblingsdatenbank + + + diff --git a/input/templates/input/if_end_of_project_approved.html b/input/templates/input/if_end_of_project_approved.html new file mode 100644 index 0000000..5ab0b79 --- /dev/null +++ b/input/templates/input/if_end_of_project_approved.html @@ -0,0 +1,41 @@ + + +Hallo, +

+dein Projekt/die Veranstaltung {{project.name}} ist nun beendet und wir hoffen, dass alles gut geklappt hat! +

+Bitte beachte nun, dass im Vorfeld besprochene Kostenerstattungen innerhalb eines Monats nach Entstehen der Kosten über unser Online-Formular Antrag auf Kostenerstattung eingereicht werden müssen. Spätere Einsendungen können ggf. nicht mehr erstattet werden. +

+Da wir verpflichtet sind, über unsere geförderten Maßnahmen zu berichten, möchten wir dich gerne bitten uns kurz folgende Infos zu deinem Projekt zukommen zu lassen:
+* Wie viele Personen haben an dem Projekt teilgenommen?
+* Wo können die Ergebnisse des Projektes eingesehen werden? (Projektseite, Commons-Link, Bericht o. ä.) +

+Sollten bei dem Projekt Fotos oder andere Mediendateien entstanden sein, findest du hier eine Anleitung, wie diese bei Commons hochgeladen werden sollen. +

+Solltest du einen öffentlichen Förderantrag in der Wikipedia erstellt haben, kannst du diesen nun archivieren, indem du den Projektstatus oben im Quellcode entsprechend anpasst und die Liste der geförderten Aktivitäten entsprechend aktualisierst. +

+Falls nicht bereits geschehen, wirst du demnächst eine weitere E-Mail erhalten, mit der du die Möglichkeit hast uns Feedback zu der Unterstützung zu geben. Danke, dass du dir Zeit dafür nimmst! +

+Insbesondere möchten wir uns an dieser Stelle ganz herzlich bei dir für die Zusammenarbeit und dein Engagement für Freies Wissen bedanken! +

+Viele Grüße
+Dein Team Communitys und Engagement +

+-----
+Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden. +

+Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin
+Tel. (030) 219 158 26-0
+https://wikimedia.de
+

+Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei!
+https://spenden.wikimedia.de
+

+Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207. +

+Datenschutzerklärung:
+Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. +

+ + + diff --git a/input/templates/input/if_end_of_project_orginformed.html b/input/templates/input/if_end_of_project_orginformed.html new file mode 100644 index 0000000..2d83129 --- /dev/null +++ b/input/templates/input/if_end_of_project_orginformed.html @@ -0,0 +1,19 @@ + + + +Hallo Team Communitys und Engagement! +

+Das Project {{project.name}} hat am {{project.end}} sein vorraussichtliches +Ende erreicht. +

+Hier könnt ihr es in der Datenbank editieren: +

+{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +

+ +Projektorganisator*in wurde über den Projektabschluss informiert. +


+mit freundlichen Grüßen, Eure Lieblingsdatenbank + + + diff --git a/input/templates/input/if_mail.html b/input/templates/input/if_mail.html new file mode 100644 index 0000000..b7ec91f --- /dev/null +++ b/input/templates/input/if_mail.html @@ -0,0 +1,35 @@ + + +Hallo Team Communitys und Engagement, +

+es gab einen neuen Antrag von {{data.realname}}. +

+Der Nutzer mit dem Username {{data.username}} ({{data.email}}) fragt ein_e {{data.typestring|striptags}} an.
+{% if data.choice in data.grant %}
+Vorraussichtliche Kosten: {{data.cost}}
+Anmerkungen: {{data.notes}} {% endif %} {% if data.choice in data.domain %}
+Domain: {{data.domain}}
+Adressenbestandteil: {{data.address}}
{% endif %} {% if data.choice == 'BIB' %} +Bibliothek: {{data.library}}
+Dauer: {{data.duration}}
{% elif data.choice == 'ELIT' %} +Datenbank: {{data.library}}
+Dauer: {{data.duration}}
{% elif data.choice == 'SOFT' %} +Software: {{data.library}}
+Dauer: {{data.duration}}
{% elif data.choice == 'IFG'%} +Anfrage-URL: {{data.url}}
{% elif data.choice == 'LIT'%} +Info zum Werk: {{data.info}}
+Bezugsquelle: {{data.source}}
{% elif data.choice == 'MAIL'%} +Adressenbestandteil frei gewählt: {{data.other}}
{% elif data.choice == 'VIS'%} +Wikimedia-Projekt: {{data.project}}
+Persönliche Daten: {{data.data}}
+Variante: {{data.variant}}
+Sendungsadrese: {{data.send_to}}
{% endif %} +

+Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %} +

+Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %} +

+Stets zu Diensten, Deine Förderdatenbank + + + diff --git a/input/templates/input/ifg_volunteer_mail.html b/input/templates/input/ifg_volunteer_mail.html new file mode 100644 index 0000000..e8da031 --- /dev/null +++ b/input/templates/input/ifg_volunteer_mail.html @@ -0,0 +1,34 @@ + + +Hallo {{data.realname}}, +

+wir haben Deine Anfrage ({{data.typestring|striptags}}) erhalten.
+{% if data.choice in data.grant %}
+Vorraussichtliche Kosten: {{data.cost}}
+Anmerkungen: {{data.notes}} {% endif %} {% if data.choice in data.domain %}
+Domain: {{data.domain}}
+Adressenbestandteil: {{data.address}} {% endif %} {% if data.choice == 'BIB' %}
+Bibliothek: {{data.library}}
+Dauer: {{data.duration}} {% elif data.choice == 'ELIT' %}
+Datenbank: {{data.library}}
+Dauer: {{data.duration}} {% elif data.choice == 'SOFT' %}
+Software: {{data.library}}
+Dauer: {{data.duration}} {% elif data.choice == 'IFG'%}
+Anfrage-URL: {{data.url}} {% elif data.choice == 'LIT'%}
+Info zum Werk: {{data.info}}
+Bezugsquelle: {{data.source}} {% elif data.choice == 'MAIL'%}
+Adressenbestandteil frei gewählt: {{data.other}} {% elif data.choice == 'VIS'%}
+Wikimedia-Projekt: {{data.project}}
+Persönliche Daten: {{data.data}}
+Variante: {{data.variant}}
+Sendungsadrese: {{data.send_to}} {% endif %}
+

+Das Team Comunitys und Engagement wird sich um die Bearbeitung deiner Anfrage kümmern
+und sich in den nächsten Tagen bei dir melden. Solltest du Rückfragen haben,
+wende dich gern an community@wikimedia.de.
+

+Viele Grüße, dein freundliches aber komplett unmenschliches automatisches +Formularbeantwortungssystem. + + + diff --git a/input/templates/input/survey_mail.html b/input/templates/input/survey_mail.html new file mode 100644 index 0000000..f62c146 --- /dev/null +++ b/input/templates/input/survey_mail.html @@ -0,0 +1,42 @@ + + +Hallo, +

+Vor einiger Zeit durfte Wikimedia Deutschland Deine Aktivität für Freies Wissen +unterstützen.
+{% if type == 'PRO' %} +Deine Aktivitäten werden von uns unter dem Projekttitel "{{name}}" geführt.

+{% elif type == 'HON' %} +Du hast von uns eine Bescheinigung ({{name}}) erhalten.

+{% elif type == 'BIB' %} +Du hast von uns ein Bibliotheksstipendium für {{name}} erhalten.

+{% elif type == 'ELIT' %} +Du hast von uns ein eLiteraturstipendium für {{name}} erhalten.

+{% elif type == 'IFG' %} +Wir haben Dich bei einer IFG-Anfrage unterstützt: {{name}}

+{% elif type == 'LIT' %} +Du hast von uns ein Literaturstipendium für {{name}} erhalten.

+{% elif type == 'TRAV' %} +Wir haben Dich mit Reisekostenübernahme für {{name}} unterstützt.

+{% elif type == 'SOFT' %} +Du hast von uns ein Softwarestipendium für {{name}} erhalten.

+{% elif type == 'MAIL' %} +Du hast von uns eine E-Mail-Adresse erhalten.

+{% elif type == 'LIST' %} +Wir haben Dir eine Mailingliste bereit gestellt.

+{% elif type == 'VIS' %} +Du hast von uns Visitenkarten erhalten.

+{% endif %} + +Zu dieser Unterstützung kannst du uns ein Feedback über einen kurzen Fragebogen +geben. Deine Teilnahme ist freiwillig und hilft uns dabei, die verschiedenen +Förderprogramme im Sinne der Communitys weiter zu verbessern. Wir freuen uns, +wenn du dir kurz die Zeit dafür nehmen würdest. Die Umfrage mit weiteren +Informationen findest du unter dem folgenden Link:
+ +{{SURVEYPREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1

+ +Da dies eine automatisch erzeugte Nachricht ist, wende dich bei Rückfragen zur Umfrage bitte an community@wikimedia.de + + + From 21cfd509721cb46c0a68238a1355e4d3b8998138 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Thu, 17 Nov 2022 18:45:45 +0000 Subject: [PATCH 21/57] sendmails is sending html regarding the informing of the organisator when not happened --- input/management/commands/sendmails.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 243c396..fe4b471 100644 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -115,8 +115,9 @@ class Command(BaseCommand): html_mail_template = get_template('input/if_not_of_project_approved.html') txt_mail_template = get_template('input/if_not_of_project_approved.txt') - informMail_template = get_template('input/if_end_of_project_orginformed.txt') - + + txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt') + html_informMail_template = get_template('input/if_end_of_project_orginformed.html') # send the mail to project.email, which would be the mail of the volunteer that filled out the form for project in approved_notHappened: @@ -137,11 +138,19 @@ class Command(BaseCommand): # IF_EMAIL, # [project.email], # fail_silently=False) - send_mail('Projektorganisator*in wurde informiert', - informMail_template.render(context), - IF_EMAIL, - [IF_EMAIL], - fail_silently=False) + + inform_subject, inform_from_email, inform_to = Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL + inform_text_content = txt_informMail_template.render(context) + inform_html_content = html_informMail_template.render(context) + inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to]) + inform_msg.attach_alternative(html_content, "text/html") + inform_msg.send() + + #send_mail('Projektorganisator*in wurde informiert', + # informMail_template.render(context), + # IF_EMAIL, + # [IF_EMAIL], + # fail_silently=False) project.end_mail_send = True project.save() From 7a99176b23a715d31a65bf91ca6edb501c68f8ef Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 18 Nov 2022 12:42:29 +0000 Subject: [PATCH 22/57] changed sending of last mails in sendmails.py and in views.py --- input/management/commands/sendmails.py | 86 ++++++++++++++++++-------- input/views.py | 54 +++++++++++----- 2 files changed, 97 insertions(+), 43 deletions(-) diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index fe4b471..e08c877 100644 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -35,14 +35,22 @@ class Command(BaseCommand): 'name': name, 'pid': pid, 'SURVEYPREFIX': SURVEYPREFIX, } - mail_template = get_template('input/survey_mail.txt') + txt_mail_template = get_template('input/survey_mail.txt') + html_mail_template = get_template('input/survey_mail.html') try: - survey_mail = EmailMessage('Dein Feedback zur Förderung durch Wikimedia Deutschland', - mail_template.render(context), - IF_EMAIL, - [email], - bcc=[SURVEY_EMAIL]) - survey_mail.send(fail_silently=False) + subject, from_email, to = 'Dein Feedback zur Förderung durch Wikimedia Deutschland', IF_EMAIL, email + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[SURVEY_EMAIL]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + #survey_mail = EmailMessage('Dein Feedback zur Förderung durch Wikimedia Deutschland', + # mail_template.render(context), + # IF_EMAIL, + # [email], + # bcc=[SURVEY_EMAIL]) + #survey_mail.send(fail_silently=False) except BadHeaderError: return HttpResponse('Invalid header found.') @@ -52,20 +60,28 @@ class Command(BaseCommand): ''' end of project reached ''' # get all projects which ended - print(Project.objects.filter(end__lt = date.today())) old = Project.objects.filter(end__lt = date.today())\ .exclude(end_mail_send = True) - mail_template = get_template('input/if_end_of_project.txt') + txt_mail_template = get_template('input/if_end_of_project.txt') + html_mail_template = get_template('input/if_end_of_project.html') + for project in old: context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX try: - send_mail('Projektende erreicht', - mail_template.render(context), - IF_EMAIL, - ['luca@cannabinieri.de'], - fail_silently=False) + subject, from_email, to = 'Projektende erreicht', IF_EMAIL, IF_EMAIL + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + #send_mail('Projektende erreicht', + # mail_template.render(context), + # IF_EMAIL, + # [IF_EMAIL], + # fail_silently=False) project.end_mail_send = True project.save() except BadHeaderError: @@ -80,24 +96,42 @@ class Command(BaseCommand): approved_end = Project.objects.filter(status = 'END')\ .exclude(end_mail_send = False) print(approved_end) - mail_template = get_template('input/if_end_of_project_approved.txt') - informMail_template = get_template('input/if_end_of_project_orginformed.txt') + txt_mail_template = get_template('input/if_end_of_project_approved.txt') + html_mail_template = get_template('input/if_end_of_project_approved.html') + + txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt') + html_informMail_template = get_template('input/if_end_of_project_orginformed.html') # send the mail to project.email, which would be the mail of the volunteer filling out the form for project in approved_end: context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX try: - send_mail('Projektende erreicht', - mail_template.render(context), - IF_EMAIL, - [project.email], - fail_silently=False) - send_mail('Projektorganisator*in wurde informiert', - informMail_template.render(context), - IF_EMAIL, - [IF_EMAIL], - fail_silently=False) + subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + inform_subject, inform_from_email, inform_to = Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL + inform_text_content = txt_informMail_template.render(context) + inform_html_content = html_informMail_template.render(context) + inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to]) + inform_msg.attach_alternative(html_content, "text/html") + inform_msg.send() + + + #send_mail('Projektende erreicht', + # mail_template.render(context), + # IF_EMAIL, + # [project.email], + # fail_silently=False) + #send_mail('Projektorganisator*in wurde informiert', + # informMail_template.render(context), + # IF_EMAIL, + # [IF_EMAIL], + # fail_silently=False) project.end_mail_send = True project.save() diff --git a/input/views.py b/input/views.py index e86ebbf..dd9fb4f 100644 --- a/input/views.py +++ b/input/views.py @@ -5,7 +5,7 @@ from django.shortcuts import render from django.forms import modelformset_factory from django.http import HttpResponse from formtools.wizard.views import CookieWizardView -from django.core.mail import send_mail, BadHeaderError +from django.core.mail import send_mail, BadHeaderError, EmailMultiAlternatives from django.conf import settings from django.template.loader import get_template from django.template import Context @@ -227,22 +227,42 @@ class ExternView(CookieWizardView): context = { 'data': data } try: # - mail with entered data to the Volunteer - mail_template = get_template('input/ifg_volunteer_mail.txt') - send_mail( - 'Formular ausgefüllt', - mail_template.render(context), - IF_EMAIL, - [data['email']], - fail_silently=False) - # - mail to IF with link to accept/decline - mail_template = get_template('input/if_mail.txt') - send_mail( - 'Formular ausgefüllt', - mail_template.render(context), - IF_EMAIL, - [IF_EMAIL], - fail_silently=False) - # raise SMTPException("testing pupose only") + + txt_mail_template = get_template('input/ifg_volunteer_mail.txt') + html_mail_template = get_template('input/ifg_volunteer_mail.html') + + subject, from_email, to = 'Formular ausgefüllt', IF_EMAIL, data['email'] + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + #send_mail( + # 'Formular ausgefüllt', + # mail_template.render(context), + # IF_EMAIL, + # [data['email']], + # fail_silently=False) + ## - mail to IF with link to accept/decline + + txt_mail_template = get_template('input/if_mail.txt') + html_mail_template = get_template('input/if_mail.html') + + subject, from_email, to = 'Formular ausgefüllt', IF_EMAIL, IF_EMAIL + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + #send_mail( + # 'Formular ausgefüllt', + # mail_template.render(context), + # IF_EMAIL, + # [IF_EMAIL], + # fail_silently=False) + ## raise SMTPException("testing pupose only") except BadHeaderError: modell.delete() From 2501bb08668d3954e719e58ceab3a2cf97b3db96 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Mon, 21 Nov 2022 13:09:12 +0000 Subject: [PATCH 23/57] changed fields in Travel to required, changed saving of value of selfbuy_give_data when person wants to selfbuy to false --- input/forms.py | 12 ++++++++++++ input/static/dropdown/js/base.js | 8 ++++++-- input/views.py | 6 +++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/input/forms.py b/input/forms.py index c3e8127..da386f8 100644 --- a/input/forms.py +++ b/input/forms.py @@ -56,11 +56,23 @@ class InternForm(FdbForm): class TravelForm(FdbForm): # TODO: add some javascript to show/hide other-field + + # this is the code, to change required to false if needed + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['project_name'].required = True + self.fields['transport'].required = True + self.fields['travelcost'].required = True + self.fields['checkin'].required = True + self.fields['checkout'].required = True + self.fields['hotel'].required = True + class Meta: model = Travel exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes' ) widgets = {'checkin': AdminDateWidget(), 'checkout': AdminDateWidget(),} + fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes'] class LibraryForm(FdbForm): diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js index 0d8d5c4..df0ae5f 100644 --- a/input/static/dropdown/js/base.js +++ b/input/static/dropdown/js/base.js @@ -1,10 +1,16 @@ window.addEventListener("load", function() { (function($) { $(function() { + + + // selfbuy section + var selectField_selfbuy = $('#id_selfbuy'), verified_selfbuy_div = $('#id_selfbuy_give_data').parent().parent(), verified_selfbuy = $('#id_selfbuy_give_data'); + + // make checked to get through the required function toggleVerified_selfbuy(value) { if (value === "FALSE") { verified_selfbuy_div.show(); @@ -23,8 +29,6 @@ window.addEventListener("load", function() { toggleVerified_selfbuy($(this).val()); }); - - var selectField = $('#id_variant'), verified = $('#id_url_of_pic').parent().parent(); diff --git a/input/views.py b/input/views.py index dd9fb4f..3ca0f33 100644 --- a/input/views.py +++ b/input/views.py @@ -202,8 +202,11 @@ class ExternView(CookieWizardView): data = {} for form in form_list: data = {**data, **form.cleaned_data} + + if data['selfbuy'] == 'TRUE': + data['selfbuy_give_data'] = 'False' print(data) - + # write data to database modell = form.save(commit=False) # we have to copy the data from the first form here @@ -214,6 +217,7 @@ class ExternView(CookieWizardView): # write type of form in some cases if data['choice'] in ('BIB', 'ELIT', 'SOFT'): modell.type = data['choice'] + form.save() # add some data to context for mail templates From b28c145454cefed7609bdc4a7c5589e666a4da51 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Mon, 21 Nov 2022 13:11:49 +0000 Subject: [PATCH 24/57] changing saved value in database selfbuy_give_data to false when selfbuy true also in internview done() --- input/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/input/views.py b/input/views.py index 3ca0f33..2b28773 100644 --- a/input/views.py +++ b/input/views.py @@ -110,6 +110,8 @@ class InternView(LoginRequiredMixin, CookieWizardView): data = {} for form in form_list: data = {**data, **form.cleaned_data} + if data['selfbuy'] == 'TRUE': + data['selfbuy_give_data'] = 'False' print(data) # write data to database From 9b9209f2b575a819313bb5cda737591ddc9c6838 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Mon, 21 Nov 2022 15:30:01 +0000 Subject: [PATCH 25/57] conditional hiding of address textfield in literature form added --- input/forms.py | 2 +- .../migrations/0075_literature_selfbuy_data.py | 18 ++++++++++++++++++ input/models.py | 9 ++++++++- input/static/dropdown/js/base.js | 11 +++++++++-- input/views.py | 9 ++++++++- 5 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 input/migrations/0075_literature_selfbuy_data.py diff --git a/input/forms.py b/input/forms.py index da386f8..e2e6d07 100644 --- a/input/forms.py +++ b/input/forms.py @@ -107,7 +107,7 @@ class LiteratureForm(CheckForm): self.fields['selfbuy_give_data'].required = True class Meta: model = Literature - fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_give_data'] + fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_data', 'selfbuy_give_data'] exclude = ['intern_notes'] class Media: js = ('dropdown/js/base.js',) diff --git a/input/migrations/0075_literature_selfbuy_data.py b/input/migrations/0075_literature_selfbuy_data.py new file mode 100644 index 0000000..2565a73 --- /dev/null +++ b/input/migrations/0075_literature_selfbuy_data.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2022-11-21 13:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0074_project_intern_notes'), + ] + + operations = [ + migrations.AddField( + model_name='literature', + name='selfbuy_data', + field=models.TextField(default='', help_text='Bitte gib hier alle persönlichen Daten an, und zwar genau so,
wie sie (auch in der entsprechenden Reihenfolge) auf den Visitenkarten stehen sollen
(z.B. Vorname Nachname, Benutzer:/Benutzerin:, Benutzer-/-innenname, Anschrift,
Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.
Hinweis: Telefonnummern bilden wir üblicherweise im internationalen Format gemäß
DIN 5008 ab. Als anzugebende E-Mail-Adresse empfehlen wir dir eine Wikimedia-Projekt-
Adresse, die du ebenfalls beantragen kannst, sofern du nicht bereits eine besitzt.', max_length=1000, verbose_name='Persönliche Daten für die Visitenkarten'), + ), + ] diff --git a/input/models.py b/input/models.py index e42cd43..b1b4f83 100644 --- a/input/models.py +++ b/input/models.py @@ -209,7 +209,14 @@ class Literature(Grant): source = models.CharField(max_length=200, verbose_name='Bezugsquelle', help_text="Bitte gib an, wo du das Werk kaufen möchtest.") selfbuy = models.CharField( max_length=10, verbose_name='Selbstkauf?', choices=SELFBUY_CHOICES.items(), default='TRUE') - selfbuy_give_data = models.BooleanField(default='NONE', verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.')) + selfbuy_give_data = models.BooleanField(verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.')) + selfbuy_data = models.TextField(max_length=1000, verbose_name='Persönliche Daten sowie Adresse', default='', + help_text=format_html("Bitte gib hier alle persönlichen Daten an, die wir benötigen, um das Werk
\ + für dich zu kaufen und es dir anschließend zu schicken (z.B. Vorname Nachname, Anschrift,
\ + Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.
\ + Hinweis: Telefonnummern bilden wir üblicherweise im internationalen Format gemäß
\ + DIN 5008 ab. Als anzugebende E-Mail-Adresse empfehlen wir dir eine Wikimedia-Projekt-
\ + Adresse, die du ebenfalls beantragen kannst, sofern du nicht bereits eine besitzt.")) intern_notes = models.TextField(max_length=1000, blank=True) class IFG(Grant): diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js index df0ae5f..b93cf52 100644 --- a/input/static/dropdown/js/base.js +++ b/input/static/dropdown/js/base.js @@ -7,16 +7,23 @@ window.addEventListener("load", function() { var selectField_selfbuy = $('#id_selfbuy'), verified_selfbuy_div = $('#id_selfbuy_give_data').parent().parent(), - verified_selfbuy = $('#id_selfbuy_give_data'); - + verified_selfbuy = $('#id_selfbuy_give_data'), + data_selfbuy_div = $('#id_selfbuy_data').parent().parent(), + data_selfbuy = $('#id_selfbuy_data'); + + // make checked to get through the required function toggleVerified_selfbuy(value) { if (value === "FALSE") { verified_selfbuy_div.show(); + data_selfbuy_div.show(); + data_selfbuy.val(""); verified_selfbuy.prop("checked", false); } else { verified_selfbuy_div.hide(); + data_selfbuy_div.hide(); + data_selfbuy.val("NONE"); verified_selfbuy.prop("checked", true); } } diff --git a/input/views.py b/input/views.py index 2b28773..4a257dd 100644 --- a/input/views.py +++ b/input/views.py @@ -124,6 +124,10 @@ class InternView(LoginRequiredMixin, CookieWizardView): form.email = data['email'] form.granted = True form.granted_date = date.today() + + if data['choice'] == 'LIT': + form.selfbuy_give_data = data['selfbuy_give_data'] + form.save() return done(self.request) @@ -204,7 +208,6 @@ class ExternView(CookieWizardView): data = {} for form in form_list: data = {**data, **form.cleaned_data} - if data['selfbuy'] == 'TRUE': data['selfbuy_give_data'] = 'False' print(data) @@ -213,6 +216,10 @@ class ExternView(CookieWizardView): modell = form.save(commit=False) # we have to copy the data from the first form here # this is a bit ugly code. can we copy this without explicit writing? + + if data['choice'] == 'LIT': + modell.selfbuy_give_data = data['selfbuy_give_data'] + modell.realname = data['realname'] modell.username = data['username'] modell.email = data['email'] From d2d48c1a823fb442655e7a8e097d88616b6a836e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Wed, 30 Nov 2022 00:09:10 +0000 Subject: [PATCH 26/57] added mail_state to all objects, added filters regarding sendmail.py --- .gitignore | 3 +- LICENSE | 0 README.md | 0 TODO | 0 foerderbarometer/__init__.py | 0 foerderbarometer/asgi.py | 0 foerderbarometer/settings.py_old | 0 foerderbarometer/settings_development.py | 0 .../settings_mariadb_development.py | 0 foerderbarometer/settings_production.py | 4 +- foerderbarometer/urls.py | 0 foerderbarometer/wsgi.py | 0 input/__init__.py | 0 input/admin.py | 0 input/apps.py | 0 input/fixtures/accounts.json | 0 input/forms.py | 6 +- input/management/commands/sendmails.py | 75 +++++++---- input/migrations/0001_initial.py | 0 input/migrations/0002_auto_20200922_1340.py | 0 input/migrations/0003_volonteer.py | 0 input/migrations/0004_project_contact.py | 0 input/migrations/0005_auto_20200930_1015.py | 0 input/migrations/0006_honorarycertificate.py | 0 input/migrations/0007_library.py | 0 input/migrations/0008_ifg.py | 0 input/migrations/0009_project_pid.py | 0 input/migrations/0010_auto_20201007_0732.py | 0 input/migrations/0011_auto_20201007_0743.py | 0 input/migrations/0012_auto_20201007_0754.py | 0 input/migrations/0013_library_type.py | 0 input/migrations/0014_auto_20201020_0714.py | 0 input/migrations/0015_auto_20201021_0721.py | 0 input/migrations/0016_project_account.py | 0 input/migrations/0017_auto_20201021_1145.py | 0 input/migrations/0018_auto_20201021_1147.py | 0 input/migrations/0019_auto_20201021_1148.py | 0 .../0020_project_project_end_mail.py | 0 input/migrations/0021_auto_20201022_0934.py | 0 input/migrations/0022_auto_20201022_1233.py | 0 input/migrations/0023_auto_20201022_1400.py | 0 input/migrations/0024_travel.py | 0 input/migrations/0025_auto_20201026_1048.py | 0 input/migrations/0026_auto_20201026_1214.py | 0 .../0027_businesscard_email_list.py | 0 input/migrations/0028_auto_20201027_1131.py | 0 input/migrations/0029_auto_20201027_1247.py | 0 input/migrations/0030_auto_20201027_1337.py | 0 input/migrations/0031_auto_20201028_1402.py | 0 input/migrations/0032_auto_20201029_1213.py | 0 input/migrations/0033_auto_20201029_1338.py | 0 input/migrations/0034_auto_20201102_0913.py | 0 input/migrations/0035_auto_20201102_0944.py | 0 input/migrations/0036_auto_20201102_1049.py | 0 input/migrations/0037_auto_20201102_1054.py | 0 input/migrations/0038_auto_20201102_1055.py | 0 input/migrations/0039_auto_20201102_1212.py | 0 input/migrations/0040_auto_20201102_1302.py | 0 input/migrations/0041_auto_20201102_1318.py | 0 input/migrations/0042_auto_20201102_1319.py | 0 input/migrations/0043_auto_20201102_1320.py | 0 input/migrations/0044_auto_20201103_1545.py | 0 input/migrations/0044_auto_20201116_1531.py | 0 input/migrations/0045_auto_20201116_1557.py | 0 input/migrations/0046_auto_20201117_1542.py | 0 input/migrations/0047_auto_20201117_1546.py | 0 input/migrations/0048_auto_20201118_1503.py | 0 input/migrations/0049_auto_20201118_1509.py | 0 input/migrations/0050_auto_20201118_1512.py | 0 input/migrations/0051_auto_20201118_1521.py | 0 input/migrations/0052_auto_20201118_1524.py | 0 input/migrations/0053_auto_20201118_1531.py | 0 input/migrations/0054_auto_20201118_1702.py | 0 input/migrations/0055_merge_20201118_1734.py | 0 input/migrations/0056_auto_20201217_1215.py | 0 input/migrations/0057_auto_20210104_0937.py | 0 input/migrations/0058_auto_20210412_0946.py | 0 input/migrations/0059_auto_20210412_1142.py | 0 input/migrations/0060_concreteextern.py | 0 input/migrations/0061_concretevolunteer.py | 0 input/migrations/0062_auto_20211103_1155.py | 0 ...ard_url_of_pic_alter_ifg_notes_and_more.py | 0 ...ta_to_print_literature_selfbuy_and_more.py | 0 .../0065_alter_literature_selfbuy_and_more.py | 0 input/migrations/0066_email_adult.py | 0 ..._travel_project_name_alter_library_type.py | 0 input/migrations/0068_travel_hotel.py | 0 .../migrations/0069_alter_travel_transport.py | 0 input/migrations/0070_alter_travel_project.py | 0 ...ficate_intern_notes_travel_intern_notes.py | 0 ...ntern_notes_email_intern_notes_and_more.py | 0 input/migrations/0073_account_intern_notes.py | 0 input/migrations/0074_project_intern_notes.py | 0 .../0075_literature_selfbuy_data.py | 0 input/migrations/0076_auto_20221129_1601.py | 78 +++++++++++ input/migrations/0077_auto_20221129_1706.py | 123 ++++++++++++++++++ input/migrations/0078_auto_20221129_1712.py | 68 ++++++++++ input/migrations/0079_auto_20221129_2310.py | 68 ++++++++++ input/migrations/0080_auto_20221129_2323.py | 68 ++++++++++ input/migrations/__init__.py | 0 input/models.py | 6 + input/settings.py | 0 input/static/dropdown/js/base.js | 0 input/static/input/logo.png | Bin input/static/input/nutzungsbedingungen.html | 0 input/templates/input/extern.html | 0 input/templates/input/if_end_of_project.html | 0 input/templates/input/if_end_of_project.txt | 0 .../input/if_end_of_project_approved.html | 0 .../input/if_end_of_project_approved.txt | 0 .../input/if_end_of_project_orginformed.html | 0 .../input/if_end_of_project_orginformed.txt | 0 input/templates/input/if_mail.html | 0 input/templates/input/if_mail.txt | 0 .../input/if_not_of_project_approved.html | 0 .../input/if_not_of_project_approved.txt | 0 input/templates/input/ifg_volunteer_mail.html | 0 input/templates/input/ifg_volunteer_mail.txt | 0 input/templates/input/survey_mail.html | 0 input/templates/input/survey_mail.txt | 0 input/templates/registration/login.html | 0 input/tests.py | 0 input/urls.py | 0 input/views.py | 8 +- requirements.txt | 7 + 125 files changed, 482 insertions(+), 32 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md mode change 100644 => 100755 TODO mode change 100644 => 100755 foerderbarometer/__init__.py mode change 100644 => 100755 foerderbarometer/asgi.py mode change 100644 => 100755 foerderbarometer/settings.py_old mode change 100644 => 100755 foerderbarometer/settings_development.py mode change 100644 => 100755 foerderbarometer/settings_mariadb_development.py mode change 100644 => 100755 foerderbarometer/settings_production.py mode change 100644 => 100755 foerderbarometer/urls.py mode change 100644 => 100755 foerderbarometer/wsgi.py mode change 100644 => 100755 input/__init__.py mode change 100644 => 100755 input/admin.py mode change 100644 => 100755 input/apps.py mode change 100644 => 100755 input/fixtures/accounts.json mode change 100644 => 100755 input/forms.py mode change 100644 => 100755 input/management/commands/sendmails.py mode change 100644 => 100755 input/migrations/0001_initial.py mode change 100644 => 100755 input/migrations/0002_auto_20200922_1340.py mode change 100644 => 100755 input/migrations/0003_volonteer.py mode change 100644 => 100755 input/migrations/0004_project_contact.py mode change 100644 => 100755 input/migrations/0005_auto_20200930_1015.py mode change 100644 => 100755 input/migrations/0006_honorarycertificate.py mode change 100644 => 100755 input/migrations/0007_library.py mode change 100644 => 100755 input/migrations/0008_ifg.py mode change 100644 => 100755 input/migrations/0009_project_pid.py mode change 100644 => 100755 input/migrations/0010_auto_20201007_0732.py mode change 100644 => 100755 input/migrations/0011_auto_20201007_0743.py mode change 100644 => 100755 input/migrations/0012_auto_20201007_0754.py mode change 100644 => 100755 input/migrations/0013_library_type.py mode change 100644 => 100755 input/migrations/0014_auto_20201020_0714.py mode change 100644 => 100755 input/migrations/0015_auto_20201021_0721.py mode change 100644 => 100755 input/migrations/0016_project_account.py mode change 100644 => 100755 input/migrations/0017_auto_20201021_1145.py mode change 100644 => 100755 input/migrations/0018_auto_20201021_1147.py mode change 100644 => 100755 input/migrations/0019_auto_20201021_1148.py mode change 100644 => 100755 input/migrations/0020_project_project_end_mail.py mode change 100644 => 100755 input/migrations/0021_auto_20201022_0934.py mode change 100644 => 100755 input/migrations/0022_auto_20201022_1233.py mode change 100644 => 100755 input/migrations/0023_auto_20201022_1400.py mode change 100644 => 100755 input/migrations/0024_travel.py mode change 100644 => 100755 input/migrations/0025_auto_20201026_1048.py mode change 100644 => 100755 input/migrations/0026_auto_20201026_1214.py mode change 100644 => 100755 input/migrations/0027_businesscard_email_list.py mode change 100644 => 100755 input/migrations/0028_auto_20201027_1131.py mode change 100644 => 100755 input/migrations/0029_auto_20201027_1247.py mode change 100644 => 100755 input/migrations/0030_auto_20201027_1337.py mode change 100644 => 100755 input/migrations/0031_auto_20201028_1402.py mode change 100644 => 100755 input/migrations/0032_auto_20201029_1213.py mode change 100644 => 100755 input/migrations/0033_auto_20201029_1338.py mode change 100644 => 100755 input/migrations/0034_auto_20201102_0913.py mode change 100644 => 100755 input/migrations/0035_auto_20201102_0944.py mode change 100644 => 100755 input/migrations/0036_auto_20201102_1049.py mode change 100644 => 100755 input/migrations/0037_auto_20201102_1054.py mode change 100644 => 100755 input/migrations/0038_auto_20201102_1055.py mode change 100644 => 100755 input/migrations/0039_auto_20201102_1212.py mode change 100644 => 100755 input/migrations/0040_auto_20201102_1302.py mode change 100644 => 100755 input/migrations/0041_auto_20201102_1318.py mode change 100644 => 100755 input/migrations/0042_auto_20201102_1319.py mode change 100644 => 100755 input/migrations/0043_auto_20201102_1320.py mode change 100644 => 100755 input/migrations/0044_auto_20201103_1545.py mode change 100644 => 100755 input/migrations/0044_auto_20201116_1531.py mode change 100644 => 100755 input/migrations/0045_auto_20201116_1557.py mode change 100644 => 100755 input/migrations/0046_auto_20201117_1542.py mode change 100644 => 100755 input/migrations/0047_auto_20201117_1546.py mode change 100644 => 100755 input/migrations/0048_auto_20201118_1503.py mode change 100644 => 100755 input/migrations/0049_auto_20201118_1509.py mode change 100644 => 100755 input/migrations/0050_auto_20201118_1512.py mode change 100644 => 100755 input/migrations/0051_auto_20201118_1521.py mode change 100644 => 100755 input/migrations/0052_auto_20201118_1524.py mode change 100644 => 100755 input/migrations/0053_auto_20201118_1531.py mode change 100644 => 100755 input/migrations/0054_auto_20201118_1702.py mode change 100644 => 100755 input/migrations/0055_merge_20201118_1734.py mode change 100644 => 100755 input/migrations/0056_auto_20201217_1215.py mode change 100644 => 100755 input/migrations/0057_auto_20210104_0937.py mode change 100644 => 100755 input/migrations/0058_auto_20210412_0946.py mode change 100644 => 100755 input/migrations/0059_auto_20210412_1142.py mode change 100644 => 100755 input/migrations/0060_concreteextern.py mode change 100644 => 100755 input/migrations/0061_concretevolunteer.py mode change 100644 => 100755 input/migrations/0062_auto_20211103_1155.py mode change 100644 => 100755 input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py mode change 100644 => 100755 input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py mode change 100644 => 100755 input/migrations/0065_alter_literature_selfbuy_and_more.py mode change 100644 => 100755 input/migrations/0066_email_adult.py mode change 100644 => 100755 input/migrations/0067_travel_project_name_alter_library_type.py mode change 100644 => 100755 input/migrations/0068_travel_hotel.py mode change 100644 => 100755 input/migrations/0069_alter_travel_transport.py mode change 100644 => 100755 input/migrations/0070_alter_travel_project.py mode change 100644 => 100755 input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py mode change 100644 => 100755 input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py mode change 100644 => 100755 input/migrations/0073_account_intern_notes.py mode change 100644 => 100755 input/migrations/0074_project_intern_notes.py mode change 100644 => 100755 input/migrations/0075_literature_selfbuy_data.py create mode 100644 input/migrations/0076_auto_20221129_1601.py create mode 100644 input/migrations/0077_auto_20221129_1706.py create mode 100644 input/migrations/0078_auto_20221129_1712.py create mode 100644 input/migrations/0079_auto_20221129_2310.py create mode 100644 input/migrations/0080_auto_20221129_2323.py mode change 100644 => 100755 input/migrations/__init__.py mode change 100644 => 100755 input/models.py mode change 100644 => 100755 input/settings.py mode change 100644 => 100755 input/static/dropdown/js/base.js mode change 100644 => 100755 input/static/input/logo.png mode change 100644 => 100755 input/static/input/nutzungsbedingungen.html mode change 100644 => 100755 input/templates/input/extern.html mode change 100644 => 100755 input/templates/input/if_end_of_project.html mode change 100644 => 100755 input/templates/input/if_end_of_project.txt mode change 100644 => 100755 input/templates/input/if_end_of_project_approved.html mode change 100644 => 100755 input/templates/input/if_end_of_project_approved.txt mode change 100644 => 100755 input/templates/input/if_end_of_project_orginformed.html mode change 100644 => 100755 input/templates/input/if_end_of_project_orginformed.txt mode change 100644 => 100755 input/templates/input/if_mail.html mode change 100644 => 100755 input/templates/input/if_mail.txt mode change 100644 => 100755 input/templates/input/if_not_of_project_approved.html mode change 100644 => 100755 input/templates/input/if_not_of_project_approved.txt mode change 100644 => 100755 input/templates/input/ifg_volunteer_mail.html mode change 100644 => 100755 input/templates/input/ifg_volunteer_mail.txt mode change 100644 => 100755 input/templates/input/survey_mail.html mode change 100644 => 100755 input/templates/input/survey_mail.txt mode change 100644 => 100755 input/templates/registration/login.html mode change 100644 => 100755 input/tests.py mode change 100644 => 100755 input/urls.py mode change 100644 => 100755 input/views.py create mode 100755 requirements.txt diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index bc0ab41..1139068 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ # secret passwords and so /secrets.json /staticfiles -/foerderbarometer/settings.py +# /foerderbarometer/settings.py +/foerderbarometer/*settings* /nohup.out /logfile *~ diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/TODO b/TODO old mode 100644 new mode 100755 diff --git a/foerderbarometer/__init__.py b/foerderbarometer/__init__.py old mode 100644 new mode 100755 diff --git a/foerderbarometer/asgi.py b/foerderbarometer/asgi.py old mode 100644 new mode 100755 diff --git a/foerderbarometer/settings.py_old b/foerderbarometer/settings.py_old old mode 100644 new mode 100755 diff --git a/foerderbarometer/settings_development.py b/foerderbarometer/settings_development.py old mode 100644 new mode 100755 diff --git a/foerderbarometer/settings_mariadb_development.py b/foerderbarometer/settings_mariadb_development.py old mode 100644 new mode 100755 diff --git a/foerderbarometer/settings_production.py b/foerderbarometer/settings_production.py old mode 100644 new mode 100755 index 720e689..7a77496 --- a/foerderbarometer/settings_production.py +++ b/foerderbarometer/settings_production.py @@ -111,8 +111,8 @@ WSGI_APPLICATION = 'foerderbarometer.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'fdb', - 'USER': 'fdb', + 'NAME': 'fdbdevel', + 'USER': 'fdbdevel', 'PASSWORD': get_secret('DATABASE_PASSWORD'), 'HOST': '10.0.6.7', # Or an IP Address that your database is hosted on # 'PORT': '3306', diff --git a/foerderbarometer/urls.py b/foerderbarometer/urls.py old mode 100644 new mode 100755 diff --git a/foerderbarometer/wsgi.py b/foerderbarometer/wsgi.py old mode 100644 new mode 100755 diff --git a/input/__init__.py b/input/__init__.py old mode 100644 new mode 100755 diff --git a/input/admin.py b/input/admin.py old mode 100644 new mode 100755 diff --git a/input/apps.py b/input/apps.py old mode 100644 new mode 100755 diff --git a/input/fixtures/accounts.json b/input/fixtures/accounts.json old mode 100644 new mode 100755 diff --git a/input/forms.py b/input/forms.py old mode 100644 new mode 100755 index e2e6d07..c8e6897 --- a/input/forms.py +++ b/input/forms.py @@ -72,13 +72,13 @@ class TravelForm(FdbForm): exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes' ) widgets = {'checkin': AdminDateWidget(), 'checkout': AdminDateWidget(),} - fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes'] + fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes', 'mail_state'] class LibraryForm(FdbForm): class Meta: model = Library - fields = ['cost', 'library', 'duration', 'notes'] + fields = ['cost', 'library', 'duration', 'notes', 'survey_mail_send'] exclude = ['intern_notes'] class HonoraryCertificateForm(FdbForm): @@ -139,7 +139,7 @@ class BusinessCardForm(CheckForm): class Meta: model = BusinessCard exclude = ['intern_notes'] - fields = ['project', 'data', 'variant', 'url_of_pic', 'sent_to'] + fields = ['project', 'data', 'variant', 'url_of_pic', 'sent_to', 'mail_state'] class Media: js = ('dropdown/js/base.js',) diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py old mode 100644 new mode 100755 index e08c877..9451cac --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -39,11 +39,12 @@ class Command(BaseCommand): html_mail_template = get_template('input/survey_mail.html') try: subject, from_email, to = 'Dein Feedback zur Förderung durch Wikimedia Deutschland', IF_EMAIL, email - text_content = txt_mail_template.render(context) - html_content = html_mail_template.render(context) - msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[SURVEY_EMAIL]) - msg.attach_alternative(html_content, "text/html") - msg.send() + text_content = txt_mail_template.render(context) + html_content = html_mail_template.render(context) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[SURVEY_EMAIL]) + msg.attach_alternative(html_content, "text/html") + msg.send() + #print('survey mail would have been send') #survey_mail = EmailMessage('Dein Feedback zur Förderung durch Wikimedia Deutschland', # mail_template.render(context), @@ -56,12 +57,19 @@ class Command(BaseCommand): print(f'send surveylinkemail to {email}...') + ''' the db entry mail_state was added. Useful when migrating databases. first delete the entry, then makemigrations + then migrate.. after that, recreate the entry with default END, after that makemigrations and migrate. + now all entries have the value END. after that rewrite the default to NONE in models.py, then makemigrations + and migrate again, to have NONE as default for all new queries. ''' + + def end_of_projects_reached(self): ''' end of project reached ''' # get all projects which ended old = Project.objects.filter(end__lt = date.today())\ - .exclude(end_mail_send = True) + .exclude(end_mail_send = True)\ + .filter(mail_state = 'NONE') txt_mail_template = get_template('input/if_end_of_project.txt') html_mail_template = get_template('input/if_end_of_project.html') @@ -69,6 +77,7 @@ class Command(BaseCommand): for project in old: context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX + try: subject, from_email, to = 'Projektende erreicht', IF_EMAIL, IF_EMAIL text_content = txt_mail_template.render(context) @@ -76,6 +85,7 @@ class Command(BaseCommand): msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") msg.send() + #print('end of project mail would have been sent') #send_mail('Projektende erreicht', # mail_template.render(context), @@ -83,7 +93,11 @@ class Command(BaseCommand): # [IF_EMAIL], # fail_silently=False) project.end_mail_send = True - project.save() + project.mail_state = 'INF' + try: + project.save() + except: + print( 'For project', project, 'there is possibly no project.start (', project.start, ') class') except BadHeaderError: self.stdout.write(self.style.ERROR('Invalid header found.')) @@ -94,8 +108,8 @@ class Command(BaseCommand): # get all projects where end was reached already, and send mails for the ones already set to status "ended" by the admins approved_end = Project.objects.filter(status = 'END')\ - .exclude(end_mail_send = False) - print(approved_end) + .exclude(end_mail_send = False)\ + .filter(mail_state = 'INF') txt_mail_template = get_template('input/if_end_of_project_approved.txt') html_mail_template = get_template('input/if_end_of_project_approved.html') @@ -106,6 +120,8 @@ class Command(BaseCommand): for project in approved_end: context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX + + try: subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email text_content = txt_mail_template.render(context) @@ -113,14 +129,15 @@ class Command(BaseCommand): msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") msg.send() + #print('if and of project approved mail would have been sent') - inform_subject, inform_from_email, inform_to = Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL + inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL inform_text_content = txt_informMail_template.render(context) inform_html_content = html_informMail_template.render(context) inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to]) inform_msg.attach_alternative(html_content, "text/html") inform_msg.send() - + #print('if end of project orginformed mail would have been sent') #send_mail('Projektende erreicht', # mail_template.render(context), @@ -134,7 +151,11 @@ class Command(BaseCommand): # fail_silently=False) project.end_mail_send = True - project.save() + project.mail_state = 'END' + try: + project.save() + except: + print( 'For project', project, 'there is possibly no project.start (', project.start, ') class') except BadHeaderError: self.stdout.write(self.style.ERROR('Invalid header found.')) @@ -145,7 +166,8 @@ class Command(BaseCommand): # get all projects where end was reached already, and send mails for the ones where status was put to NOT by admins approved_notHappened = Project.objects.filter(status = 'NOT')\ - .exclude(end_mail_send = False) + .exclude(end_mail_send = False)\ + .filter(mail_state = 'INF') html_mail_template = get_template('input/if_not_of_project_approved.html') txt_mail_template = get_template('input/if_not_of_project_approved.txt') @@ -164,7 +186,7 @@ class Command(BaseCommand): msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") msg.send() - + #print('if not of project approved end mail would have been sent') #send_mail('Projektende erreicht', @@ -173,12 +195,13 @@ class Command(BaseCommand): # [project.email], # fail_silently=False) - inform_subject, inform_from_email, inform_to = Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL + inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL inform_text_content = txt_informMail_template.render(context) inform_html_content = html_informMail_template.render(context) inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to]) inform_msg.attach_alternative(html_content, "text/html") inform_msg.send() + #print('if not of project approved end mail orginformed would have been sent') #send_mail('Projektorganisator*in wurde informiert', # informMail_template.render(context), @@ -187,6 +210,7 @@ class Command(BaseCommand): # fail_silently=False) project.end_mail_send = True + project.mail_state = 'END' project.save() except BadHeaderError: self.stdout.write(self.style.ERROR('Invalid header found.')) @@ -221,7 +245,8 @@ class Command(BaseCommand): supported = Library.objects.filter(granted=True)\ .filter(granted_date__lt = date.today() - timedelta(days=14))\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported,name='library') def surveymails_to_hon(self): @@ -229,7 +254,8 @@ class Command(BaseCommand): supported = HonoraryCertificate.objects.filter(granted=True)\ .filter(granted_date__lt = date.today() - timedelta(days=14))\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported, type='HON', name='project') def surveymails_to_ifg(self): @@ -237,7 +263,8 @@ class Command(BaseCommand): supported = IFG.objects.filter(granted=True)\ .filter(granted_date__lt = date.today() - timedelta(days=14))\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported, type='IFG', name='url') def surveymails_to_lit(self): @@ -245,14 +272,16 @@ class Command(BaseCommand): supported = Literature.objects.filter(granted=True)\ .filter(granted_date__lt = date.today() - timedelta(days=14))\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported, type='LIT', name='info') def surveymails_to_project(self): '''send survey link 4 weeks after end of project reached''' supported = Project.objects.filter(granted=True)\ .filter(end__lt = date.today() - timedelta(days=28))\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported, type='PRO', name='name') def surveymails_to_travel(self): @@ -260,7 +289,8 @@ class Command(BaseCommand): supported = Travel.objects.filter(project__granted=True)\ .filter(project__end__lt = date.today() - timedelta(days=21))\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported, type='TRAV', name='project') def surveymails_to_mail_vis_lis(self): @@ -273,7 +303,8 @@ class Command(BaseCommand): # get class via string supported = getattr(sys.modules[__name__], c).objects.filter(granted=True)\ .filter(granted_date__lt = lastdate)\ - .exclude(survey_mail_send=True) + .exclude(survey_mail_send=True)\ + .exclude(mail_state = 'END') self.surveymails_to_object(supported, type=typefield[count]) count += 1 diff --git a/input/migrations/0001_initial.py b/input/migrations/0001_initial.py old mode 100644 new mode 100755 diff --git a/input/migrations/0002_auto_20200922_1340.py b/input/migrations/0002_auto_20200922_1340.py old mode 100644 new mode 100755 diff --git a/input/migrations/0003_volonteer.py b/input/migrations/0003_volonteer.py old mode 100644 new mode 100755 diff --git a/input/migrations/0004_project_contact.py b/input/migrations/0004_project_contact.py old mode 100644 new mode 100755 diff --git a/input/migrations/0005_auto_20200930_1015.py b/input/migrations/0005_auto_20200930_1015.py old mode 100644 new mode 100755 diff --git a/input/migrations/0006_honorarycertificate.py b/input/migrations/0006_honorarycertificate.py old mode 100644 new mode 100755 diff --git a/input/migrations/0007_library.py b/input/migrations/0007_library.py old mode 100644 new mode 100755 diff --git a/input/migrations/0008_ifg.py b/input/migrations/0008_ifg.py old mode 100644 new mode 100755 diff --git a/input/migrations/0009_project_pid.py b/input/migrations/0009_project_pid.py old mode 100644 new mode 100755 diff --git a/input/migrations/0010_auto_20201007_0732.py b/input/migrations/0010_auto_20201007_0732.py old mode 100644 new mode 100755 diff --git a/input/migrations/0011_auto_20201007_0743.py b/input/migrations/0011_auto_20201007_0743.py old mode 100644 new mode 100755 diff --git a/input/migrations/0012_auto_20201007_0754.py b/input/migrations/0012_auto_20201007_0754.py old mode 100644 new mode 100755 diff --git a/input/migrations/0013_library_type.py b/input/migrations/0013_library_type.py old mode 100644 new mode 100755 diff --git a/input/migrations/0014_auto_20201020_0714.py b/input/migrations/0014_auto_20201020_0714.py old mode 100644 new mode 100755 diff --git a/input/migrations/0015_auto_20201021_0721.py b/input/migrations/0015_auto_20201021_0721.py old mode 100644 new mode 100755 diff --git a/input/migrations/0016_project_account.py b/input/migrations/0016_project_account.py old mode 100644 new mode 100755 diff --git a/input/migrations/0017_auto_20201021_1145.py b/input/migrations/0017_auto_20201021_1145.py old mode 100644 new mode 100755 diff --git a/input/migrations/0018_auto_20201021_1147.py b/input/migrations/0018_auto_20201021_1147.py old mode 100644 new mode 100755 diff --git a/input/migrations/0019_auto_20201021_1148.py b/input/migrations/0019_auto_20201021_1148.py old mode 100644 new mode 100755 diff --git a/input/migrations/0020_project_project_end_mail.py b/input/migrations/0020_project_project_end_mail.py old mode 100644 new mode 100755 diff --git a/input/migrations/0021_auto_20201022_0934.py b/input/migrations/0021_auto_20201022_0934.py old mode 100644 new mode 100755 diff --git a/input/migrations/0022_auto_20201022_1233.py b/input/migrations/0022_auto_20201022_1233.py old mode 100644 new mode 100755 diff --git a/input/migrations/0023_auto_20201022_1400.py b/input/migrations/0023_auto_20201022_1400.py old mode 100644 new mode 100755 diff --git a/input/migrations/0024_travel.py b/input/migrations/0024_travel.py old mode 100644 new mode 100755 diff --git a/input/migrations/0025_auto_20201026_1048.py b/input/migrations/0025_auto_20201026_1048.py old mode 100644 new mode 100755 diff --git a/input/migrations/0026_auto_20201026_1214.py b/input/migrations/0026_auto_20201026_1214.py old mode 100644 new mode 100755 diff --git a/input/migrations/0027_businesscard_email_list.py b/input/migrations/0027_businesscard_email_list.py old mode 100644 new mode 100755 diff --git a/input/migrations/0028_auto_20201027_1131.py b/input/migrations/0028_auto_20201027_1131.py old mode 100644 new mode 100755 diff --git a/input/migrations/0029_auto_20201027_1247.py b/input/migrations/0029_auto_20201027_1247.py old mode 100644 new mode 100755 diff --git a/input/migrations/0030_auto_20201027_1337.py b/input/migrations/0030_auto_20201027_1337.py old mode 100644 new mode 100755 diff --git a/input/migrations/0031_auto_20201028_1402.py b/input/migrations/0031_auto_20201028_1402.py old mode 100644 new mode 100755 diff --git a/input/migrations/0032_auto_20201029_1213.py b/input/migrations/0032_auto_20201029_1213.py old mode 100644 new mode 100755 diff --git a/input/migrations/0033_auto_20201029_1338.py b/input/migrations/0033_auto_20201029_1338.py old mode 100644 new mode 100755 diff --git a/input/migrations/0034_auto_20201102_0913.py b/input/migrations/0034_auto_20201102_0913.py old mode 100644 new mode 100755 diff --git a/input/migrations/0035_auto_20201102_0944.py b/input/migrations/0035_auto_20201102_0944.py old mode 100644 new mode 100755 diff --git a/input/migrations/0036_auto_20201102_1049.py b/input/migrations/0036_auto_20201102_1049.py old mode 100644 new mode 100755 diff --git a/input/migrations/0037_auto_20201102_1054.py b/input/migrations/0037_auto_20201102_1054.py old mode 100644 new mode 100755 diff --git a/input/migrations/0038_auto_20201102_1055.py b/input/migrations/0038_auto_20201102_1055.py old mode 100644 new mode 100755 diff --git a/input/migrations/0039_auto_20201102_1212.py b/input/migrations/0039_auto_20201102_1212.py old mode 100644 new mode 100755 diff --git a/input/migrations/0040_auto_20201102_1302.py b/input/migrations/0040_auto_20201102_1302.py old mode 100644 new mode 100755 diff --git a/input/migrations/0041_auto_20201102_1318.py b/input/migrations/0041_auto_20201102_1318.py old mode 100644 new mode 100755 diff --git a/input/migrations/0042_auto_20201102_1319.py b/input/migrations/0042_auto_20201102_1319.py old mode 100644 new mode 100755 diff --git a/input/migrations/0043_auto_20201102_1320.py b/input/migrations/0043_auto_20201102_1320.py old mode 100644 new mode 100755 diff --git a/input/migrations/0044_auto_20201103_1545.py b/input/migrations/0044_auto_20201103_1545.py old mode 100644 new mode 100755 diff --git a/input/migrations/0044_auto_20201116_1531.py b/input/migrations/0044_auto_20201116_1531.py old mode 100644 new mode 100755 diff --git a/input/migrations/0045_auto_20201116_1557.py b/input/migrations/0045_auto_20201116_1557.py old mode 100644 new mode 100755 diff --git a/input/migrations/0046_auto_20201117_1542.py b/input/migrations/0046_auto_20201117_1542.py old mode 100644 new mode 100755 diff --git a/input/migrations/0047_auto_20201117_1546.py b/input/migrations/0047_auto_20201117_1546.py old mode 100644 new mode 100755 diff --git a/input/migrations/0048_auto_20201118_1503.py b/input/migrations/0048_auto_20201118_1503.py old mode 100644 new mode 100755 diff --git a/input/migrations/0049_auto_20201118_1509.py b/input/migrations/0049_auto_20201118_1509.py old mode 100644 new mode 100755 diff --git a/input/migrations/0050_auto_20201118_1512.py b/input/migrations/0050_auto_20201118_1512.py old mode 100644 new mode 100755 diff --git a/input/migrations/0051_auto_20201118_1521.py b/input/migrations/0051_auto_20201118_1521.py old mode 100644 new mode 100755 diff --git a/input/migrations/0052_auto_20201118_1524.py b/input/migrations/0052_auto_20201118_1524.py old mode 100644 new mode 100755 diff --git a/input/migrations/0053_auto_20201118_1531.py b/input/migrations/0053_auto_20201118_1531.py old mode 100644 new mode 100755 diff --git a/input/migrations/0054_auto_20201118_1702.py b/input/migrations/0054_auto_20201118_1702.py old mode 100644 new mode 100755 diff --git a/input/migrations/0055_merge_20201118_1734.py b/input/migrations/0055_merge_20201118_1734.py old mode 100644 new mode 100755 diff --git a/input/migrations/0056_auto_20201217_1215.py b/input/migrations/0056_auto_20201217_1215.py old mode 100644 new mode 100755 diff --git a/input/migrations/0057_auto_20210104_0937.py b/input/migrations/0057_auto_20210104_0937.py old mode 100644 new mode 100755 diff --git a/input/migrations/0058_auto_20210412_0946.py b/input/migrations/0058_auto_20210412_0946.py old mode 100644 new mode 100755 diff --git a/input/migrations/0059_auto_20210412_1142.py b/input/migrations/0059_auto_20210412_1142.py old mode 100644 new mode 100755 diff --git a/input/migrations/0060_concreteextern.py b/input/migrations/0060_concreteextern.py old mode 100644 new mode 100755 diff --git a/input/migrations/0061_concretevolunteer.py b/input/migrations/0061_concretevolunteer.py old mode 100644 new mode 100755 diff --git a/input/migrations/0062_auto_20211103_1155.py b/input/migrations/0062_auto_20211103_1155.py old mode 100644 new mode 100755 diff --git a/input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py b/input/migrations/0063_businesscard_url_of_pic_alter_ifg_notes_and_more.py old mode 100644 new mode 100755 diff --git a/input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py b/input/migrations/0064_businesscard_send_data_to_print_literature_selfbuy_and_more.py old mode 100644 new mode 100755 diff --git a/input/migrations/0065_alter_literature_selfbuy_and_more.py b/input/migrations/0065_alter_literature_selfbuy_and_more.py old mode 100644 new mode 100755 diff --git a/input/migrations/0066_email_adult.py b/input/migrations/0066_email_adult.py old mode 100644 new mode 100755 diff --git a/input/migrations/0067_travel_project_name_alter_library_type.py b/input/migrations/0067_travel_project_name_alter_library_type.py old mode 100644 new mode 100755 diff --git a/input/migrations/0068_travel_hotel.py b/input/migrations/0068_travel_hotel.py old mode 100644 new mode 100755 diff --git a/input/migrations/0069_alter_travel_transport.py b/input/migrations/0069_alter_travel_transport.py old mode 100644 new mode 100755 diff --git a/input/migrations/0070_alter_travel_project.py b/input/migrations/0070_alter_travel_project.py old mode 100644 new mode 100755 diff --git a/input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py b/input/migrations/0071_honorarycertificate_intern_notes_travel_intern_notes.py old mode 100644 new mode 100755 diff --git a/input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py b/input/migrations/0072_businesscard_intern_notes_email_intern_notes_and_more.py old mode 100644 new mode 100755 diff --git a/input/migrations/0073_account_intern_notes.py b/input/migrations/0073_account_intern_notes.py old mode 100644 new mode 100755 diff --git a/input/migrations/0074_project_intern_notes.py b/input/migrations/0074_project_intern_notes.py old mode 100644 new mode 100755 diff --git a/input/migrations/0075_literature_selfbuy_data.py b/input/migrations/0075_literature_selfbuy_data.py old mode 100644 new mode 100755 diff --git a/input/migrations/0076_auto_20221129_1601.py b/input/migrations/0076_auto_20221129_1601.py new file mode 100644 index 0000000..988c42e --- /dev/null +++ b/input/migrations/0076_auto_20221129_1601.py @@ -0,0 +1,78 @@ +# Generated by Django 3.1.2 on 2022-11-29 16:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0075_literature_selfbuy_data'), + ] + + operations = [ + migrations.AlterField( + model_name='businesscard', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='concreteextern', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='email', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='ifg', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='library', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='list', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='literature', + name='selfbuy_data', + field=models.TextField(default='', help_text='Bitte gib hier alle persönlichen Daten an, die wir benötigen, um das Werk
für dich zu kaufen und es dir anschließend zu schicken (z.B. Vorname Nachname, Anschrift,
Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.
Hinweis: Telefonnummern bilden wir üblicherweise im internationalen Format gemäß
DIN 5008 ab. Als anzugebende E-Mail-Adresse empfehlen wir dir eine Wikimedia-Projekt-
Adresse, die du ebenfalls beantragen kannst, sofern du nicht bereits eine besitzt.', max_length=1000, verbose_name='Persönliche Daten sowie Adresse'), + ), + migrations.AlterField( + model_name='literature', + name='selfbuy_give_data', + field=models.BooleanField(help_text='Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.', verbose_name='Datenweitergabe erlauben'), + ), + migrations.AlterField( + model_name='literature', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='project', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='travel', + name='survey_mail_send', + field=models.BooleanField(default=True, verbose_name='Keine Umfragemail schicken'), + ), + ] diff --git a/input/migrations/0077_auto_20221129_1706.py b/input/migrations/0077_auto_20221129_1706.py new file mode 100644 index 0000000..e59dba8 --- /dev/null +++ b/input/migrations/0077_auto_20221129_1706.py @@ -0,0 +1,123 @@ +# Generated by Django 3.1.2 on 2022-11-29 17:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0076_auto_20221129_1601'), + ] + + operations = [ + migrations.AddField( + model_name='businesscard', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='concreteextern', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='concretevolunteer', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='email', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='honorarycertificate', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='ifg', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='library', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='list', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='literature', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='project', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AddField( + model_name='travel', + name='mailState', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('SURVEY', 'die Survey Mail wurde bereits versendet'), ('END', 'alle automatischen Mails wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='businesscard', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='concreteextern', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='email', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='ifg', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='library', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='list', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='literature', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='project', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + migrations.AlterField( + model_name='travel', + name='survey_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken'), + ), + ] diff --git a/input/migrations/0078_auto_20221129_1712.py b/input/migrations/0078_auto_20221129_1712.py new file mode 100644 index 0000000..f4520f4 --- /dev/null +++ b/input/migrations/0078_auto_20221129_1712.py @@ -0,0 +1,68 @@ +# Generated by Django 3.1.2 on 2022-11-29 17:12 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0077_auto_20221129_1706'), + ] + + operations = [ + migrations.RenameField( + model_name='businesscard', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='concreteextern', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='concretevolunteer', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='email', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='honorarycertificate', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='ifg', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='library', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='list', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='literature', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='project', + old_name='mailState', + new_name='mail_state', + ), + migrations.RenameField( + model_name='travel', + old_name='mailState', + new_name='mail_state', + ), + ] diff --git a/input/migrations/0079_auto_20221129_2310.py b/input/migrations/0079_auto_20221129_2310.py new file mode 100644 index 0000000..9e7967b --- /dev/null +++ b/input/migrations/0079_auto_20221129_2310.py @@ -0,0 +1,68 @@ +# Generated by Django 3.1.2 on 2022-11-29 23:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0078_auto_20221129_1712'), + ] + + operations = [ + migrations.AlterField( + model_name='businesscard', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='concreteextern', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='email', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='ifg', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='library', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='list', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='literature', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='project', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + migrations.AlterField( + model_name='travel', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('END', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('APPR', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='APPR', max_length=6), + ), + ] diff --git a/input/migrations/0080_auto_20221129_2323.py b/input/migrations/0080_auto_20221129_2323.py new file mode 100644 index 0000000..2ed8741 --- /dev/null +++ b/input/migrations/0080_auto_20221129_2323.py @@ -0,0 +1,68 @@ +# Generated by Django 3.1.2 on 2022-11-29 23:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0079_auto_20221129_2310'), + ] + + operations = [ + migrations.AlterField( + model_name='businesscard', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='concreteextern', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='email', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='ifg', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='library', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='list', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='literature', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='project', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='travel', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + ] diff --git a/input/migrations/__init__.py b/input/migrations/__init__.py old mode 100644 new mode 100755 diff --git a/input/models.py b/input/models.py old mode 100644 new mode 100755 index b1b4f83..f5ced02 --- a/input/models.py +++ b/input/models.py @@ -6,6 +6,10 @@ from django.utils.html import format_html from .settings import ACCOUNTS +EMAIL_STATES = {'NONE': 'noch keine Mail versendet', + 'INF': 'die Benachrichtigung End-Mail wurde bereits versendet', + 'END': 'alle automatischen Mails, auch surveyMail, wurden bereits versendet'} + class Volunteer(models.Model): realname = models.CharField(max_length=200, null=True, verbose_name="Realname", help_text="Bitte gib deinen Vornamen und deinen Nachnamen ein.") @@ -17,6 +21,8 @@ class Volunteer(models.Model): granted_date = models.DateField(null=True) survey_mail_send = models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken') survey_mail_date = models.DateField(verbose_name='Umfragemail wurde verschickt am', null=True, blank=True) + mail_state = models.CharField(max_length=6, choices=EMAIL_STATES.items(), default='NONE') + @classmethod def set_granted(cl, key, b): diff --git a/input/settings.py b/input/settings.py old mode 100644 new mode 100755 diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js old mode 100644 new mode 100755 diff --git a/input/static/input/logo.png b/input/static/input/logo.png old mode 100644 new mode 100755 diff --git a/input/static/input/nutzungsbedingungen.html b/input/static/input/nutzungsbedingungen.html old mode 100644 new mode 100755 diff --git a/input/templates/input/extern.html b/input/templates/input/extern.html old mode 100644 new mode 100755 diff --git a/input/templates/input/if_end_of_project.html b/input/templates/input/if_end_of_project.html old mode 100644 new mode 100755 diff --git a/input/templates/input/if_end_of_project.txt b/input/templates/input/if_end_of_project.txt old mode 100644 new mode 100755 diff --git a/input/templates/input/if_end_of_project_approved.html b/input/templates/input/if_end_of_project_approved.html old mode 100644 new mode 100755 diff --git a/input/templates/input/if_end_of_project_approved.txt b/input/templates/input/if_end_of_project_approved.txt old mode 100644 new mode 100755 diff --git a/input/templates/input/if_end_of_project_orginformed.html b/input/templates/input/if_end_of_project_orginformed.html old mode 100644 new mode 100755 diff --git a/input/templates/input/if_end_of_project_orginformed.txt b/input/templates/input/if_end_of_project_orginformed.txt old mode 100644 new mode 100755 diff --git a/input/templates/input/if_mail.html b/input/templates/input/if_mail.html old mode 100644 new mode 100755 diff --git a/input/templates/input/if_mail.txt b/input/templates/input/if_mail.txt old mode 100644 new mode 100755 diff --git a/input/templates/input/if_not_of_project_approved.html b/input/templates/input/if_not_of_project_approved.html old mode 100644 new mode 100755 diff --git a/input/templates/input/if_not_of_project_approved.txt b/input/templates/input/if_not_of_project_approved.txt old mode 100644 new mode 100755 diff --git a/input/templates/input/ifg_volunteer_mail.html b/input/templates/input/ifg_volunteer_mail.html old mode 100644 new mode 100755 diff --git a/input/templates/input/ifg_volunteer_mail.txt b/input/templates/input/ifg_volunteer_mail.txt old mode 100644 new mode 100755 diff --git a/input/templates/input/survey_mail.html b/input/templates/input/survey_mail.html old mode 100644 new mode 100755 diff --git a/input/templates/input/survey_mail.txt b/input/templates/input/survey_mail.txt old mode 100644 new mode 100755 diff --git a/input/templates/registration/login.html b/input/templates/registration/login.html old mode 100644 new mode 100755 diff --git a/input/tests.py b/input/tests.py old mode 100644 new mode 100755 diff --git a/input/urls.py b/input/urls.py old mode 100644 new mode 100755 diff --git a/input/views.py b/input/views.py old mode 100644 new mode 100755 index 4a257dd..9f48e10 --- a/input/views.py +++ b/input/views.py @@ -249,8 +249,8 @@ class ExternView(CookieWizardView): html_content = html_mail_template.render(context) msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") - msg.send() - + #msg.send() + print('ifg volunteer mail would have been sent') #send_mail( # 'Formular ausgefüllt', # mail_template.render(context), @@ -267,8 +267,8 @@ class ExternView(CookieWizardView): html_content = html_mail_template.render(context) msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") - msg.send() - + #msg.send() + print('if mail would have been sent') #send_mail( # 'Formular ausgefüllt', # mail_template.render(context), diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000..59966ae --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +asgiref==3.2.10 +Django==3.1.2 +django-formtools==2.4 +gunicorn==20.0.4 +mysqlclient==2.1.1 +sqlparse==0.4.3 +whitenoise==6.2.0 From 4aa8d15f747b9425404df6cdb698bc6c0985f776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Thu, 1 Dec 2022 15:49:30 +0000 Subject: [PATCH 27/57] =?UTF-8?q?html=20format=20ge=C3=A4ndert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- input/settings.py | 8 ++++---- input/templates/input/if_end_of_project.html | 2 +- .../templates/input/if_end_of_project_approved.html | 10 +++++----- .../input/if_end_of_project_orginformed.html | 2 +- input/templates/input/if_mail.html | 8 ++++---- .../templates/input/if_not_of_project_approved.html | 12 ++++++------ input/templates/input/ifg_volunteer_mail.html | 6 +++--- input/templates/input/survey_mail.html | 4 ++-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/input/settings.py b/input/settings.py index 5ee83b0..bda472e 100755 --- a/input/settings.py +++ b/input/settings.py @@ -1,9 +1,9 @@ # mail for IF-OTRS -#IF_EMAIL = 'community@wikimedia.de' -IF_EMAIL = 'test-luca-ext@wikimedia.de' +IF_EMAIL = 'community@wikimedia.de' +#IF_EMAIL = 'test-luca-ext@wikimedia.de' #SURVEY_EMAIL = 'christof.pins@wikimedia.de' -SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' - +#SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' +SURVEY_EMAIL = 'sandro.halank@wikimedia.de' # prefix for urls SURVEYPREFIX = 'https://wikimedia.sslsurvey.de/Foerderbarometer/?' diff --git a/input/templates/input/if_end_of_project.html b/input/templates/input/if_end_of_project.html index fefd007..e52b86c 100755 --- a/input/templates/input/if_end_of_project.html +++ b/input/templates/input/if_end_of_project.html @@ -8,7 +8,7 @@ Ende erreicht.

Hier könnt ihr es in der Datenbank editieren:

-{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +{{URLPREFIX}}/admin/input/project/{{project.pk}}/change

mit freundlichen Grüßen, Eure Lieblingsdatenbank diff --git a/input/templates/input/if_end_of_project_approved.html b/input/templates/input/if_end_of_project_approved.html index 5ab0b79..317e412 100755 --- a/input/templates/input/if_end_of_project_approved.html +++ b/input/templates/input/if_end_of_project_approved.html @@ -24,17 +24,17 @@ Dein Team Communitys und Engagement -----
Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden.

-Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin
+Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin
Tel. (030) 219 158 26-0
-https://wikimedia.de
+https://wikimedia.de


-Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei!
-https://spenden.wikimedia.de
+Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei!
+https://spenden.wikimedia.de


Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207.

Datenschutzerklärung:
-Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. +Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung.

diff --git a/input/templates/input/if_end_of_project_orginformed.html b/input/templates/input/if_end_of_project_orginformed.html index 2d83129..83ad2d3 100755 --- a/input/templates/input/if_end_of_project_orginformed.html +++ b/input/templates/input/if_end_of_project_orginformed.html @@ -8,7 +8,7 @@ Ende erreicht.

Hier könnt ihr es in der Datenbank editieren:

-{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +{{URLPREFIX}}/admin/input/project/{{project.pk}}/change

Projektorganisator*in wurde über den Projektabschluss informiert. diff --git a/input/templates/input/if_mail.html b/input/templates/input/if_mail.html index b7ec91f..d130016 100755 --- a/input/templates/input/if_mail.html +++ b/input/templates/input/if_mail.html @@ -8,7 +8,7 @@ Der Nutzer mit dem Username {{data.username}} ({{data.email}}) fragt ein_e {{dat {% if data.choice in data.grant %}
Vorraussichtliche Kosten: {{data.cost}}
Anmerkungen: {{data.notes}} {% endif %} {% if data.choice in data.domain %}
-Domain: {{data.domain}}
+Domain: {{data.domain}}
Adressenbestandteil: {{data.address}}
{% endif %} {% if data.choice == 'BIB' %} Bibliothek: {{data.library}}
Dauer: {{data.duration}}
{% elif data.choice == 'ELIT' %} @@ -16,7 +16,7 @@ Datenbank: {{data.library}}
Dauer: {{data.duration}}
{% elif data.choice == 'SOFT' %} Software: {{data.library}}
Dauer: {{data.duration}}
{% elif data.choice == 'IFG'%} -Anfrage-URL: {{data.url}}
{% elif data.choice == 'LIT'%} +Anfrage-URL: {{data.url}}
{% elif data.choice == 'LIT'%} Info zum Werk: {{data.info}}
Bezugsquelle: {{data.source}}
{% elif data.choice == 'MAIL'%} Adressenbestandteil frei gewählt: {{data.other}}
{% elif data.choice == 'VIS'%} @@ -25,9 +25,9 @@ Persönliche Daten: {{data.data}}
Variante: {{data.variant}}
Sendungsadrese: {{data.send_to}}
{% endif %}

-Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %} +Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %}

-Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %} +Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %}

Stets zu Diensten, Deine Förderdatenbank diff --git a/input/templates/input/if_not_of_project_approved.html b/input/templates/input/if_not_of_project_approved.html index fa5f4df..0ab585b 100755 --- a/input/templates/input/if_not_of_project_approved.html +++ b/input/templates/input/if_not_of_project_approved.html @@ -15,25 +15,25 @@ Auch wenn ein Projekt mal nicht wie geplant stattfindet: Wir möchten jeden Schr
Insbesondere möchten wir uns an dieser Stelle ganz herzlich bei dir für die Zusammenarbeit und dein Engagement für Freies Wissen bedanken!
-Ein Link zum Probieren +
Viele Grüße Dein Team Communitys und Engagement

----- -Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden. +Diese E-Mail wurde automatisch verschickt, bei Rückfragen kannst du dich jederzeit an community@wikimedia.de wenden.

Wikimedia Deutschland e. V. | Tempelhofer Ufer 23–24 | 10963 Berlin
Tel. (030) 219 158 26-0
-https://wikimedia.de
+https://wikimedia.de


-Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei!
-https://spenden.wikimedia.de +Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilhaben, es nutzen und mehren können. Helfen Sie uns dabei!
+https://spenden.wikimedia.de

Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207.

Datenschutzerklärung:
-Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. +Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung.

diff --git a/input/templates/input/ifg_volunteer_mail.html b/input/templates/input/ifg_volunteer_mail.html index e8da031..646a653 100755 --- a/input/templates/input/ifg_volunteer_mail.html +++ b/input/templates/input/ifg_volunteer_mail.html @@ -6,7 +6,7 @@ wir haben Deine Anfrage ({{data.typestring|striptags}}) erhalten.
{% if data.choice in data.grant %}
Vorraussichtliche Kosten: {{data.cost}}
Anmerkungen: {{data.notes}} {% endif %} {% if data.choice in data.domain %}
-Domain: {{data.domain}}
+Domain: {{data.domain}}
Adressenbestandteil: {{data.address}} {% endif %} {% if data.choice == 'BIB' %}
Bibliothek: {{data.library}}
Dauer: {{data.duration}} {% elif data.choice == 'ELIT' %}
@@ -14,7 +14,7 @@ Datenbank: {{data.library}}
Dauer: {{data.duration}} {% elif data.choice == 'SOFT' %}
Software: {{data.library}}
Dauer: {{data.duration}} {% elif data.choice == 'IFG'%}
-Anfrage-URL: {{data.url}} {% elif data.choice == 'LIT'%}
+Anfrage-URL: {{data.url}} {% elif data.choice == 'LIT'%}
Info zum Werk: {{data.info}}
Bezugsquelle: {{data.source}} {% elif data.choice == 'MAIL'%}
Adressenbestandteil frei gewählt: {{data.other}} {% elif data.choice == 'VIS'%}
@@ -25,7 +25,7 @@ Sendungsadrese: {{data.send_to}} {% endif %}


Das Team Comunitys und Engagement wird sich um die Bearbeitung deiner Anfrage kümmern
und sich in den nächsten Tagen bei dir melden. Solltest du Rückfragen haben,
-wende dich gern an community@wikimedia.de.
+wende dich gern an community@wikimedia.de.


Viele Grüße, dein freundliches aber komplett unmenschliches automatisches Formularbeantwortungssystem. diff --git a/input/templates/input/survey_mail.html b/input/templates/input/survey_mail.html index f62c146..bc381ae 100755 --- a/input/templates/input/survey_mail.html +++ b/input/templates/input/survey_mail.html @@ -34,9 +34,9 @@ Förderprogramme im Sinne der Communitys weiter zu verbessern. Wir freuen uns, wenn du dir kurz die Zeit dafür nehmen würdest. Die Umfrage mit weiteren Informationen findest du unter dem folgenden Link:
-{{SURVEYPREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1

+{{SURVEYPREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1

-Da dies eine automatisch erzeugte Nachricht ist, wende dich bei Rückfragen zur Umfrage bitte an community@wikimedia.de +Da dies eine automatisch erzeugte Nachricht ist, wende dich bei Rückfragen zur Umfrage bitte an community@wikimedia.de From 4d7b48f8b865f7e4dcfe2b790d2723f48d6b6530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 2 Dec 2022 16:04:11 +0000 Subject: [PATCH 28/57] admin search bar working now for all models, gave a 500 error because of wrong syntax in admin.py - searchfields --- input/admin.py | 12 ++++++------ input/models.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/input/admin.py b/input/admin.py index eff2e5e..20db719 100755 --- a/input/admin.py +++ b/input/admin.py @@ -38,7 +38,7 @@ class ProjectAdmin(admin.ModelAdmin): @admin.register(BusinessCard) class BusinessCardAdmin(admin.ModelAdmin): save_as = True - search_fields = (('realname', 'service_id'), 'granted', 'granted_date', 'project') + search_fields = ('realname', 'service_id', 'granted', 'granted_date', 'project') list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project') list_display_links = ('realname', 'service_id') # action = ['export_as_csv'] @@ -49,7 +49,7 @@ class BusinessCardAdmin(admin.ModelAdmin): @admin.register(Literature) class LiteratureAdmin(admin.ModelAdmin): save_as = True - search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + search_fields = ('realname', 'service_id', 'granted', 'granted_date') list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' @@ -73,7 +73,7 @@ class HonoraryCertificateAdmin(admin.ModelAdmin): @admin.register(Library) class LibraryAdmin(admin.ModelAdmin): save_as = True - search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + search_fields = ('realname', 'service_id', 'granted', 'granted_date') list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' @@ -81,7 +81,7 @@ class LibraryAdmin(admin.ModelAdmin): @admin.register(IFG) class IFGAdmin(admin.ModelAdmin): save_as = True - search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + search_fields = ('realname', 'service_id', 'granted', 'granted_date') list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' @@ -97,7 +97,7 @@ class TravelAdmin(admin.ModelAdmin): @admin.register(Email) class EmailAdmin(admin.ModelAdmin): save_as = True - search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + search_fields = ('realname', 'service_id', 'granted', 'granted_date') list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' @@ -106,7 +106,7 @@ class EmailAdmin(admin.ModelAdmin): @admin.register(List) class ListAdmin(admin.ModelAdmin): save_as = True - search_fields = (('realname', 'service_id'), 'granted', 'granted_date') + search_fields = ('realname', 'service_id', 'granted', 'granted_date') list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' diff --git a/input/models.py b/input/models.py index f5ced02..a302bd3 100755 --- a/input/models.py +++ b/input/models.py @@ -124,7 +124,7 @@ class Project(Volunteer): class Intern(Volunteer): - '''abstrat base class for data entry from /intern (except Project)''' + '''abstract base class for data entry from /intern (except Project)''' request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') intern_notes = models.TextField(max_length=1000, blank=True) class Meta: From 0085c5ff026d04ebfddf7e9a982c174adf63b325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 2 Dec 2022 16:20:55 +0000 Subject: [PATCH 29/57] changed the data protection link in html mails --- input/templates/input/if_end_of_project_approved.html | 2 +- input/templates/input/if_not_of_project_approved.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/input/templates/input/if_end_of_project_approved.html b/input/templates/input/if_end_of_project_approved.html index 317e412..75a5893 100755 --- a/input/templates/input/if_end_of_project_approved.html +++ b/input/templates/input/if_end_of_project_approved.html @@ -34,7 +34,7 @@ Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilh Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207.

Datenschutzerklärung:
-Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. +Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung.

diff --git a/input/templates/input/if_not_of_project_approved.html b/input/templates/input/if_not_of_project_approved.html index 0ab585b..0e70e34 100755 --- a/input/templates/input/if_not_of_project_approved.html +++ b/input/templates/input/if_not_of_project_approved.html @@ -33,7 +33,7 @@ Unsere Vision ist eine Welt, in der alle Menschen am Wissen der Menschheit teilh Wikimedia Deutschland — Gesellschaft zur Förderung Freien Wissens e. V. Eingetragen im Vereinsregister des Amtsgerichts Berlin-Charlottenburg unter der Nummer 23855 B. Als gemeinnützig anerkannt durch das Finanzamt für Körperschaften I Berlin, Steuernummer 27/029/42207.

Datenschutzerklärung:
-Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung. +Soweit Sie uns personenbezogene Daten mitteilen, verarbeiten wir diese Daten gemäß unserer Datenschutzerklärung.

From a50c8efd6011bc09b9dd7fab260434ae84a068fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 2 Dec 2022 17:10:09 +0000 Subject: [PATCH 30/57] sort of label choices on extern.html view alphabetically, change of text when form was sent to communitys und engagement instead of Ideenfoerderung --- input/models.py | 2 +- input/views.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/input/models.py b/input/models.py index a302bd3..dcc81b1 100755 --- a/input/models.py +++ b/input/models.py @@ -182,9 +182,9 @@ TYPE_CHOICES = {'BIB': format_html('Kostenübernahme IFG-Anfrage'), 'LIT': format_html('Literaturstipendium'), 'LIST': format_html('Mailingliste'), + 'TRAV': format_html('Reisekosten'), 'SOFT': format_html('Softwarestipendium'), 'VIS': format_html('Visitenkarten'), - 'TRAV': format_html('Reisekosten'), } # same model is used for Library, ELitStip and Software! diff --git a/input/views.py b/input/views.py index 9f48e10..d875537 100755 --- a/input/views.py +++ b/input/views.py @@ -61,7 +61,7 @@ def deny(request, choice, pk): def done(request): - return HttpResponse("Deine Anfrage wurde gesendet. Du erhältst in Kürze eine E-Mail-Benachrichtigung mit deinen Angaben. Für alle Fragen kontaktiere bitte das Team Ideenförderung unter community@wikimedia.de.") + return HttpResponse("Deine Anfrage wurde gesendet. Du erhältst in Kürze eine E-Mail-Benachrichtigung mit deinen Angaben. Für alle Fragen kontaktiere bitte das Team Communitys und Engagement unter community@wikimedia.de.") class InternView(LoginRequiredMixin, CookieWizardView): @@ -140,9 +140,9 @@ LABEL_CHOICES = {'BIB': format_html('Bibliothek'), 'IFG': format_html('Kostenübernahme IFG-Anfrage'), 'LIT': format_html('Literaturstipendium'), 'LIST': format_html('Mailingliste'), + 'TRAV': format_html('Reisekosten'), 'SOFT': format_html('Software'), 'VIS': format_html('Visitenkarten'), - 'TRAV': format_html('Reisekosten'), } HELP_CHOICES = {'BIB': format_html("In welchem Zeitraum möchtest du recherchieren oder
wie lange ist der Bibliotheksausweis gültig?"), From 97525ad5640ef4e0873561d61c18ee56351a9acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 2 Dec 2022 17:14:03 +0000 Subject: [PATCH 31/57] added link to Reisekosten in label choices in extern.html view --- input/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/models.py b/input/models.py index dcc81b1..09bf011 100755 --- a/input/models.py +++ b/input/models.py @@ -182,7 +182,7 @@ TYPE_CHOICES = {'BIB': format_html('Kostenübernahme IFG-Anfrage'), 'LIT': format_html('Literaturstipendium'), 'LIST': format_html('Mailingliste'), - 'TRAV': format_html('Reisekosten'), + 'TRAV': format_html('Reisekosten'), 'SOFT': format_html('Softwarestipendium'), 'VIS': format_html('Visitenkarten'), } From b662011618a550e7098af28f348d480e7ed17d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Sun, 4 Dec 2022 16:40:23 +0000 Subject: [PATCH 32/57] changed languages default to german, translated last labels (verbosename) for variables --- foerderbarometer/urls.py | 8 ++++++++ input/admin.py | 2 +- input/management/commands/sendmails.py | 2 -- input/models.py | 10 +++++----- input/settings.py | 6 ++++++ input/urls.py | 4 ++-- input/views.py | 1 + 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/foerderbarometer/urls.py b/foerderbarometer/urls.py index 7f1b85a..3fdfb85 100755 --- a/foerderbarometer/urls.py +++ b/foerderbarometer/urls.py @@ -15,9 +15,17 @@ Including another URLconf """ from django.contrib import admin from django.urls import path, include +from django.conf.urls.i18n import i18n_patterns urlpatterns = [ path('', include("input.urls")), path('admin/', admin.site.urls), path('accounts/', include('django.contrib.auth.urls')), ] + +#urlpatterns = i18n_patterns('', +# path('', include("input.urls")), +# path('admin/', admin.site.urls), +# path('accounts/', include('django.contrib.auth.urls')), +# #your urls +#) diff --git a/input/admin.py b/input/admin.py index 20db719..469bcf8 100755 --- a/input/admin.py +++ b/input/admin.py @@ -22,7 +22,7 @@ def export_as_csv(self, request, queryset): return response -export_as_csv.short_description = "Export Selected" +export_as_csv.short_description = "Ausgewähltes zu CSV exportieren" admin.site.add_action(export_as_csv) diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 9451cac..43abad3 100755 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -150,7 +150,6 @@ class Command(BaseCommand): # [IF_EMAIL], # fail_silently=False) - project.end_mail_send = True project.mail_state = 'END' try: project.save() @@ -209,7 +208,6 @@ class Command(BaseCommand): # [IF_EMAIL], # fail_silently=False) - project.end_mail_send = True project.mail_state = 'END' project.save() except BadHeaderError: diff --git a/input/models.py b/input/models.py index 09bf011..fc7ad5b 100755 --- a/input/models.py +++ b/input/models.py @@ -17,8 +17,8 @@ class Volunteer(models.Model): help_text=format_html('Bitte gib deine E-Mail-Adresse ein, damit dich
Wikimedia Deutschland bei Rückfragen oder für
die Zusage kontaktieren kann.')) # the following Fields are not supposed to be edited by users - granted = models.BooleanField(null=True) - granted_date = models.DateField(null=True) + granted = models.BooleanField(null=True, verbose_name='bewilligt') + granted_date = models.DateField(null=True, verbose_name='bewilligt am') survey_mail_send = models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken') survey_mail_date = models.DateField(verbose_name='Umfragemail wurde verschickt am', null=True, blank=True) mail_state = models.CharField(max_length=6, choices=EMAIL_STATES.items(), default='NONE') @@ -61,7 +61,7 @@ class Account(models.Model): code = models.CharField('Kostenstelle', max_length=5, default="DEF", null=False, primary_key = True) description = models.CharField('Beschreibung', max_length=60, default='NO DESCRIPTION') - intern_notes = models.TextField(max_length=1000, blank=True) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") def __str__(self): return f"{self.code} {self.description}" @@ -81,7 +81,7 @@ class Project(Volunteer): insurance = models.BooleanField(default=False, verbose_name='Haftpflichtversicherung') insurance_technic = models.BooleanField(default=False, verbose_name='Technikversicherung Ausland') support = models.CharField(max_length=300, blank=True, null=True, verbose_name='Betreuungsperson und Vertretung') - cost = models.IntegerField(blank=True, null=True) + cost = models.IntegerField(blank=True, null=True, verbose_name='Kosten') account = models.ForeignKey('Account', on_delete=models.CASCADE, null=True, to_field='code', db_constraint = False) granted_from = models.CharField(max_length=100,null=True,verbose_name='Bewilligt von') notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') @@ -89,7 +89,7 @@ class Project(Volunteer): # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) - end_mail_send = models.BooleanField(null=True) + end_mail_send = models.BooleanField(null=True, verbose_name='Endmail versenden') status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet'),('NOT','nicht stattgefunden')),default='RUN') persons = models.IntegerField(default=1) finance_id = models.CharField(max_length=15, null= True, blank=True) diff --git a/input/settings.py b/input/settings.py index bda472e..3b43e9a 100755 --- a/input/settings.py +++ b/input/settings.py @@ -12,6 +12,12 @@ DATAPROTECTION = "https://www.wikimedia.de/datenschutz/#datenerfassung" FOERDERRICHTLINIEN = "https://de.wikipedia.org/wiki/Wikipedia:Wikimedia_Deutschland/F%C3%B6rderrichtlinien" NUTZUNGSBEDINGUNGEN = 'static/input/nutzungsbedingungen.html' +LANGUAGE_CODE = 'de' +TIME_ZONE = 'UTC' +USE_I18N = True +USE_L10N = True +USE_TZ = True + ACCOUNTS ={ # "21103": '21103 Willkommen', "DEF": 'DEFAULT VALUE, you hould not see this!', diff --git a/input/urls.py b/input/urls.py index ba4c2b4..e5fd5a9 100755 --- a/input/urls.py +++ b/input/urls.py @@ -1,12 +1,12 @@ from django.urls import path - from .views import ExternView, done, authorize, deny, InternView, export + urlpatterns = [ path('', ExternView.as_view(), name='extern'), # path('intern', InternView.as_view(), name='intern'), path('saved', done, name='done'), path('export', export, name='export'), path('authorize//', authorize, name='authorize'), - path('deny//', deny, name='deny') + path('deny//', deny, name='deny'), ] diff --git a/input/views.py b/input/views.py index d875537..919c9e5 100755 --- a/input/views.py +++ b/input/views.py @@ -12,6 +12,7 @@ from django.template import Context from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.html import format_html +from django.utils.translation import gettext as _ from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\ HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ From 5335865fcda1a608977b53c803b3bd9d2ad7de37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Mon, 5 Dec 2022 10:19:03 +0000 Subject: [PATCH 33/57] rewrote the javascript part --- input/admin.py | 9 +- input/forms.py | 34 ++-- input/logfile | 120 +++++++++++ input/migrations/0081_auto_20221204_1733.py | 213 ++++++++++++++++++++ input/migrations/0082_auto_20221204_1822.py | 23 +++ input/migrations/0083_auto_20221205_0946.py | 18 ++ input/models.py | 45 ++--- input/static/dropdown/js/base.js | 1 + input/static/dropdown/js/businessCard.js | 28 +++ input/static/dropdown/js/literature.js | 42 ++++ input/static/dropdown/js/mail.js | 35 ++++ input/views.py | 13 +- 12 files changed, 530 insertions(+), 51 deletions(-) create mode 100644 input/logfile create mode 100644 input/migrations/0081_auto_20221204_1733.py create mode 100644 input/migrations/0082_auto_20221204_1822.py create mode 100644 input/migrations/0083_auto_20221205_0946.py create mode 100644 input/static/dropdown/js/businessCard.js create mode 100644 input/static/dropdown/js/literature.js create mode 100644 input/static/dropdown/js/mail.js diff --git a/input/admin.py b/input/admin.py index 469bcf8..cce44e1 100755 --- a/input/admin.py +++ b/input/admin.py @@ -65,9 +65,8 @@ class AccountAdmin(admin.ModelAdmin): @admin.register(HonoraryCertificate) class HonoraryCertificateAdmin(admin.ModelAdmin): save_as = True - search_fields = ('realname', 'granted', 'granted_date', 'project') - list_display = ('realname', 'granted', 'granted_date', 'project') - list_display_links = ('realname', 'project') + search_fields = ['realname', 'granted'] + list_display = ('realname', 'granted','project') date_hierarchy = 'granted_date' @admin.register(Library) @@ -89,7 +88,7 @@ class IFGAdmin(admin.ModelAdmin): @admin.register(Travel) class TravelAdmin(admin.ModelAdmin): save_as = True - search_fields = ('realname', 'granted', 'granted_date', 'project') + search_fields = ['realname', 'granted_date'] list_display = ('realname', 'granted', 'granted_date', 'project') list_display_links = ('realname', 'project') date_hierarchy = 'granted_date' @@ -101,6 +100,8 @@ class EmailAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' + class Media: + js = ('dropdown/js/base.js',) @admin.register(List) diff --git a/input/forms.py b/input/forms.py index c8e6897..261da35 100755 --- a/input/forms.py +++ b/input/forms.py @@ -22,7 +22,7 @@ class ProjectForm(FdbForm): class Meta: model = Project exclude = ('pid', 'project_of_year', 'finance_id','granted', 'granted_date', 'realname', 'email',\ - 'end_mail_send', 'status', 'persons', 'survey_mail_date') + 'end_mail_send', 'status', 'persons', 'survey_mail_date', 'mail_state') widgets = {'start': AdminDateWidget(), 'end': AdminDateWidget(),} @@ -38,7 +38,7 @@ class ExternForm(FdbForm): class Meta: model = ConcreteExtern - exclude = ('granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date') + exclude = ('granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date', 'mail_state') INTERN_CHOICES = {'PRO': 'Projektsteckbrief', @@ -51,7 +51,7 @@ class InternForm(FdbForm): class Meta: model = ConcreteVolunteer - exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date') + exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date', 'mail_state') class TravelForm(FdbForm): @@ -69,19 +69,20 @@ class TravelForm(FdbForm): class Meta: model = Travel - exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes' ) + exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes', 'mail_state' ) widgets = {'checkin': AdminDateWidget(), 'checkout': AdminDateWidget(),} - fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes', 'mail_state'] + fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes'] class LibraryForm(FdbForm): class Meta: model = Library fields = ['cost', 'library', 'duration', 'notes', 'survey_mail_send'] - exclude = ['intern_notes'] + exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] class HonoraryCertificateForm(FdbForm): + class Meta: model = HonoraryCertificate fields = ['request_url', 'project'] @@ -91,7 +92,7 @@ class IFGForm(FdbForm): class Meta: model = IFG fields = ['cost', 'url', 'notes'] - exclude = ['intern_notes'] + exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] class CheckForm(FdbForm): @@ -108,9 +109,9 @@ class LiteratureForm(CheckForm): class Meta: model = Literature fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_data', 'selfbuy_give_data'] - exclude = ['intern_notes'] + exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] class Media: - js = ('dropdown/js/base.js',) + js = ('dropdown/js/literature.js',) class EmailForm(CheckForm): @@ -118,15 +119,15 @@ class EmailForm(CheckForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['adult'].required = True - + self.fields['other'].required = True # TODO: add some javascript to show/hide other-field class Meta: model = Email fields = ['domain', 'address', 'other', 'adult'] - exclude = ['intern_notes'] + exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] class Media: - js = ('dropdown/js/base.js',) + js = ('dropdown/js/mail.js',) @@ -135,18 +136,19 @@ class BusinessCardForm(CheckForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['url_of_pic'].required = True + self.fields['send_data_to_print'].required = True class Meta: model = BusinessCard - exclude = ['intern_notes'] - fields = ['project', 'data', 'variant', 'url_of_pic', 'sent_to', 'mail_state'] + exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] + fields = ['project', 'data', 'variant', 'url_of_pic', 'send_data_to_print', 'sent_to'] class Media: - js = ('dropdown/js/base.js',) + js = ('dropdown/js/businessCard.js',) class ListForm(CheckForm): class Meta: model = List fields = ['domain', 'address'] - exclude = ['intern_notes'] + exclude = ['intern_notes', 'survey_mail_send','mail_state'] diff --git a/input/logfile b/input/logfile new file mode 100644 index 0000000..861f27e --- /dev/null +++ b/input/logfile @@ -0,0 +1,120 @@ +nohup: ignoring input +[2022-12-05 10:02:21 +0000] [12084] [DEBUG] Current configuration: + config: None + bind: ['0:8000'] + backlog: 2048 + workers: 1 + worker_class: sync + threads: 1 + worker_connections: 1000 + max_requests: 0 + max_requests_jitter: 0 + timeout: 30 + graceful_timeout: 30 + keepalive: 2 + limit_request_line: 4094 + limit_request_fields: 100 + limit_request_field_size: 8190 + reload: False + reload_engine: auto + reload_extra_files: [] + spew: False + check_config: False + preload_app: False + sendfile: None + reuse_port: False + chdir: /home/fdb/foerderbaro/foerderbarometer/input + daemon: False + raw_env: [] + pidfile: None + worker_tmp_dir: None + user: 1001 + group: 1001 + umask: 0 + initgroups: False + tmp_upload_dir: None + secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'} + forwarded_allow_ips: ['*'] + accesslog: None + disable_redirect_access_to_syslog: False + access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" + errorlog: - + loglevel: debug + capture_output: False + logger_class: gunicorn.glogging.Logger + logconfig: None + logconfig_dict: {} + syslog_addr: udp://localhost:514 + syslog: False + syslog_prefix: None + syslog_facility: user + enable_stdio_inheritance: False + statsd_host: None + dogstatsd_tags: + statsd_prefix: + proc_name: None + default_proc_name: foerderbarometer.wsgi + pythonpath: None + paste: None + on_starting: + on_reload: + when_ready: + pre_fork: + post_fork: + post_worker_init: + worker_int: + worker_abort: + pre_exec: + pre_request: + post_request: + child_exit: + worker_exit: + nworkers_changed: + on_exit: + proxy_protocol: False + proxy_allow_ips: ['127.0.0.1'] + keyfile: None + certfile: None + ssl_version: 2 + cert_reqs: 0 + ca_certs: None + suppress_ragged_eofs: True + do_handshake_on_connect: False + ciphers: None + raw_paste_global_conf: [] + strip_header_spaces: False +[2022-12-05 10:02:21 +0000] [12084] [INFO] Starting gunicorn 20.0.4 +[2022-12-05 10:02:21 +0000] [12084] [DEBUG] Arbiter booted +[2022-12-05 10:02:21 +0000] [12084] [INFO] Listening at: http://0.0.0.0:8000 (12084) +[2022-12-05 10:02:21 +0000] [12084] [INFO] Using worker: sync +[2022-12-05 10:02:21 +0000] [12086] [INFO] Booting worker with pid: 12086 +[2022-12-05 10:02:21 +0000] [12084] [DEBUG] 1 workers +[2022-12-05 10:02:21 +0000] [12086] [ERROR] Exception in worker process +Traceback (most recent call last): + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker + worker.init_process() + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process + self.load_wsgi() + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi + self.wsgi = self.app.wsgi() + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi + self.callable = self.load() + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load + return self.load_wsgiapp() + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp + return util.import_app(self.app_uri) + File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app + mod = importlib.import_module(module) + File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + File "", line 1014, in _gcd_import + File "", line 991, in _find_and_load + File "", line 961, in _find_and_load_unlocked + File "", line 219, in _call_with_frames_removed + File "", line 1014, in _gcd_import + File "", line 991, in _find_and_load + File "", line 973, in _find_and_load_unlocked +ModuleNotFoundError: No module named 'foerderbarometer' +[2022-12-05 10:02:21 +0000] [12086] [INFO] Worker exiting (pid: 12086) +[2022-12-05 10:02:21 +0000] [12084] [INFO] Shutting down: Master +[2022-12-05 10:02:21 +0000] [12084] [INFO] Reason: Worker failed to boot. diff --git a/input/migrations/0081_auto_20221204_1733.py b/input/migrations/0081_auto_20221204_1733.py new file mode 100644 index 0000000..9be8454 --- /dev/null +++ b/input/migrations/0081_auto_20221204_1733.py @@ -0,0 +1,213 @@ +# Generated by Django 3.1.2 on 2022-12-04 17:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0080_auto_20221129_2323'), + ] + + operations = [ + migrations.AlterField( + model_name='account', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='businesscard', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='businesscard', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='businesscard', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='businesscard', + name='send_data_to_print', + field=models.BooleanField(default=False, help_text='Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia
Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten
Versands der Druckerzeugnisse an mich.', verbose_name='Datenweitergabe erlauben'), + ), + migrations.AlterField( + model_name='concreteextern', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='concreteextern', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='email', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='email', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='email', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='ifg', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='ifg', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='ifg', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='library', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='library', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='library', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='library', + name='type', + field=models.CharField(choices=[('BIB', 'Bibliotheksstipendium'), ('ELIT', 'eLiteraturstipendium'), ('MAIL', 'E-Mail-Adresse'), ('IFG', 'Kostenübernahme IFG-Anfrage'), ('LIT', 'Literaturstipendium'), ('LIST', 'Mailingliste'), ('TRAV', 'Reisekosten'), ('SOFT', 'Softwarestipendium'), ('VIS', 'Visitenkarten')], default='BIB', max_length=4), + ), + migrations.AlterField( + model_name='list', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='list', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='list', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='literature', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='literature', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='literature', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='literature', + name='selfbuy', + field=models.CharField(choices=[('TRUE', 'Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), ('FALSE', 'Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft')], default='TRUE', max_length=10, verbose_name='Selbstkauf?'), + ), + migrations.AlterField( + model_name='project', + name='cost', + field=models.IntegerField(blank=True, null=True, verbose_name='Kosten'), + ), + migrations.AlterField( + model_name='project', + name='end_mail_send', + field=models.BooleanField(null=True, verbose_name='Endmail versenden'), + ), + migrations.AlterField( + model_name='project', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='project', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='project', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='travel', + name='checkin', + field=models.DateTimeField(blank=True, null=True, verbose_name='Anreise'), + ), + migrations.AlterField( + model_name='travel', + name='checkout', + field=models.DateTimeField(blank=True, null=True, verbose_name='Abreise'), + ), + migrations.AlterField( + model_name='travel', + name='granted', + field=models.BooleanField(null=True, verbose_name='bewilligt'), + ), + migrations.AlterField( + model_name='travel', + name='granted_date', + field=models.DateField(null=True, verbose_name='bewilligt am'), + ), + migrations.AlterField( + model_name='travel', + name='intern_notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='interne Anmerkungen'), + ), + migrations.AlterField( + model_name='travel', + name='notes', + field=models.TextField(blank=True, max_length=1000, verbose_name='Anmerkungen'), + ), + ] diff --git a/input/migrations/0082_auto_20221204_1822.py b/input/migrations/0082_auto_20221204_1822.py new file mode 100644 index 0000000..ae5b196 --- /dev/null +++ b/input/migrations/0082_auto_20221204_1822.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.2 on 2022-12-04 18:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0081_auto_20221204_1733'), + ] + + operations = [ + migrations.AlterField( + model_name='literature', + name='selfbuy_data', + field=models.TextField(default='', help_text='Bitte gib hier alle persönlichen Daten an, die wir benötigen, um das Werk
für dich zu kaufen und es dir anschließend zu schicken (z.B. Vorname Nachname, Anschrift,
Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.', max_length=1000, verbose_name='Persönliche Daten sowie Adresse'), + ), + migrations.AlterField( + model_name='literature', + name='selfbuy_give_data', + field=models.BooleanField(help_text='Ich stimme der Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister zu.', verbose_name='Datenweitergabe erlauben'), + ), + ] diff --git a/input/migrations/0083_auto_20221205_0946.py b/input/migrations/0083_auto_20221205_0946.py new file mode 100644 index 0000000..81f6d5f --- /dev/null +++ b/input/migrations/0083_auto_20221205_0946.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-05 09:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0082_auto_20221204_1822'), + ] + + operations = [ + migrations.AlterField( + model_name='email', + name='adult', + field=models.CharField(choices=[('TRUE', 'Ich bin volljährig.'), ('FALSE', 'Ich bin noch nicht volljährig.')], default='FALSE', max_length=10, verbose_name='Volljährigkeit'), + ), + ] diff --git a/input/models.py b/input/models.py index fc7ad5b..78d44c4 100755 --- a/input/models.py +++ b/input/models.py @@ -85,7 +85,7 @@ class Project(Volunteer): account = models.ForeignKey('Account', on_delete=models.CASCADE, null=True, to_field='code', db_constraint = False) granted_from = models.CharField(max_length=100,null=True,verbose_name='Bewilligt von') notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') - intern_notes = models.TextField(max_length=1000, blank=True) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) @@ -126,7 +126,7 @@ class Project(Volunteer): class Intern(Volunteer): '''abstract base class for data entry from /intern (except Project)''' request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') - intern_notes = models.TextField(max_length=1000, blank=True) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') class Meta: abstract = True @@ -138,7 +138,6 @@ class HonoraryCertificate(Intern): ''' this class is also used for accreditations ''' project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.SET_NULL) - def __str__(self): return "Certificate for " + self.realname @@ -150,20 +149,21 @@ TRANSPORT_CHOICES = {'BAHN': 'Bahn', PAYEDBY_CHOICES = {'WMDE': 'WMDE', 'REQU': 'Antragstellender Mensch'} -class Travel(Intern): +class Travel(Volunteer): # project variable is now null true and blank true, which means it can be saved without project id to be later on filled out by admins project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True) project_name = models.CharField(max_length=50, null=True, blank=True, verbose_name='Projektname:') transport = models.CharField(max_length=5, choices=TRANSPORT_CHOICES.items(), default='BAHN', verbose_name='Transportmittel:') other_transport = models.CharField(max_length=200, null=True, blank=True, verbose_name='Sonstige Transportmittel (mit Begründung)') - travelcost = models.CharField(max_length=10, default="0", verbose_name="Fahrtkosten") - checkin = models.DateField(blank=True, null=True, verbose_name='Check In') - checkout = models.DateField(blank=True, null=True, verbose_name='Check Out') + travelcost = models.CharField(max_length=10, default="0", verbose_name='Fahrtkosten') + checkin = models.DateTimeField(blank=True, null=True, verbose_name='Anreise') + checkout = models.DateTimeField(blank=True, null=True, verbose_name='Abreise') payed_for_hotel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Hotel durch') payed_for_travel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Fahrt durch') hotel = models.BooleanField(default=False, verbose_name='Hotelzimmer benötigt:') - notes = models.TextField(max_length=1000, blank=True) - + notes = models.TextField(max_length=1000, blank=True, verbose_name='Anmerkungen') + request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') #abstract base class for Library and IFG class Grant(Extern): @@ -197,14 +197,13 @@ class Library(Grant): ) library = models.CharField(max_length=200) duration = models.CharField(max_length=100, verbose_name="Dauer") - intern_notes = models.TextField(max_length=1000, blank=True) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") def __str__(self): return self.library SELFBUY_CHOICES = {'TRUE': format_html('Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), 'FALSE': format_html('Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'), - 'NONE': format_html('Nichts ausgewählt') } @@ -215,20 +214,17 @@ class Literature(Grant): source = models.CharField(max_length=200, verbose_name='Bezugsquelle', help_text="Bitte gib an, wo du das Werk kaufen möchtest.") selfbuy = models.CharField( max_length=10, verbose_name='Selbstkauf?', choices=SELFBUY_CHOICES.items(), default='TRUE') - selfbuy_give_data = models.BooleanField(verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister.')) + selfbuy_give_data = models.BooleanField(verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Ich stimme der Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister zu.')) selfbuy_data = models.TextField(max_length=1000, verbose_name='Persönliche Daten sowie Adresse', default='', help_text=format_html("Bitte gib hier alle persönlichen Daten an, die wir benötigen, um das Werk
\ für dich zu kaufen und es dir anschließend zu schicken (z.B. Vorname Nachname, Anschrift,
\ - Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.
\ - Hinweis: Telefonnummern bilden wir üblicherweise im internationalen Format gemäß
\ - DIN 5008 ab. Als anzugebende E-Mail-Adresse empfehlen wir dir eine Wikimedia-Projekt-
\ - Adresse, die du ebenfalls beantragen kannst, sofern du nicht bereits eine besitzt.")) - intern_notes = models.TextField(max_length=1000, blank=True) + Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.")) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") class IFG(Grant): url = models.URLField(max_length=2000, verbose_name="URL", help_text="Bitte gib den Link zu deiner Anfrage bei Frag den Staat an.") - intern_notes = models.TextField(max_length=1000, blank=True) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") def __str__(self): return "IFG-Anfrage von " + self.realname @@ -252,8 +248,7 @@ MAIL_CHOICES = {'REALNAME': 'Vorname.Nachname', 'OTHER': 'Sonstiges:'} ADULT_CHOICES = {'TRUE': format_html('Ich bin volljährig.'), - 'FALSE': format_html('Ich bin noch nicht volljährig.'), - 'NONE': format_html('Nichts ausgewählt') + 'FALSE': format_html('Ich bin noch nicht volljährig.') } class Email(Domain): @@ -263,14 +258,14 @@ class Email(Domain): help_text=format_html("Bitte gib hier den gewünschten Adressbestandteil an,
der sich vor der Domain befinden soll.")) other = models.CharField(max_length=50,blank=True,null=True, verbose_name="Sonstiges") - adult = models.CharField( max_length=10, verbose_name='Volljährigkeit', choices=ADULT_CHOICES.items(), default='NONE') - intern_notes = models.TextField(max_length=1000, blank=True) + adult = models.CharField( max_length=10, verbose_name='Volljährigkeit', choices=ADULT_CHOICES.items(), default='FALSE') + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") class List(Domain): address = models.CharField(max_length=50, default='NO_ADDRESS', verbose_name="Adressbestandteil für Projektmailingliste", help_text=format_html("Bitte gib hier den gewünschten Adressbestandteil an,
der sich vor der Domain befinden soll.")) - intern_notes = models.TextField(max_length=1000, blank=True) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") PROJECT_CHOICE = {'PEDIA': 'Wikipedia', 'SOURCE': 'Wikisource', @@ -307,5 +302,5 @@ class BusinessCard(Extern): sent_to = models.TextField(max_length=1000, verbose_name='Versandadresse', default='', help_text="Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen.") - send_data_to_print = models.BooleanField(default=False, verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten Versands der Druckerzeugnisse an mich.')) - intern_notes = models.TextField(max_length=1000, blank=True) + send_data_to_print = models.BooleanField(default=False, verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Hiermit erlaube ich die Weitergabe meiner Daten (Name, Postadresse) an den von Wikimedia
Deutschland ausgewählten Dienstleister (z. B. wir-machen-druck.de) zum Zwecke des direkten
Versands der Druckerzeugnisse an mich.')) + intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") diff --git a/input/static/dropdown/js/base.js b/input/static/dropdown/js/base.js index b93cf52..842bb7d 100755 --- a/input/static/dropdown/js/base.js +++ b/input/static/dropdown/js/base.js @@ -54,6 +54,7 @@ window.addEventListener("load", function() { selectField.change(function() { toggleVerified($(this).val()); }); + }); })(django.jQuery); }); diff --git a/input/static/dropdown/js/businessCard.js b/input/static/dropdown/js/businessCard.js new file mode 100644 index 0000000..cec9f9f --- /dev/null +++ b/input/static/dropdown/js/businessCard.js @@ -0,0 +1,28 @@ +window.addEventListener("load", function() { +(function($) { + $(function() { + + var selectField = $('#id_variant'), + verified_div = $('#id_url_of_pic').parent().parent(), + verified_data = $('#id_url_of_pic'); + function toggleVerified(value) { + if (value === 'PIC') { + verified_div.show(); + verified_data.val(""); + } else { + verified_div.hide(); + verified_data.val("NONE"); + } + } + + // show/hide on load based on existing value of selectField + toggleVerified(selectField.val()); + + // show/hide on change + selectField.change(function() { + toggleVerified($(this).val()); + }); + + }); +})(django.jQuery); +}); diff --git a/input/static/dropdown/js/literature.js b/input/static/dropdown/js/literature.js new file mode 100644 index 0000000..893b4a9 --- /dev/null +++ b/input/static/dropdown/js/literature.js @@ -0,0 +1,42 @@ +window.addEventListener("load", function() { +(function($) { + $(function() { + + + // selfbuy section + + var selectField_selfbuy = $('#id_selfbuy'), + verified_selfbuy_div = $('#id_selfbuy_give_data').parent().parent(), + verified_selfbuy = $('#id_selfbuy_give_data'), + data_selfbuy_div = $('#id_selfbuy_data').parent().parent(), + data_selfbuy = $('#id_selfbuy_data'); + + + + // make checked to get through the required + function toggleVerified_selfbuy(value) { + if (value === "FALSE") { + verified_selfbuy_div.show(); + data_selfbuy_div.show(); + data_selfbuy.val(""); + verified_selfbuy.prop("checked", false); + } else { + verified_selfbuy_div.hide(); + data_selfbuy_div.hide(); + data_selfbuy.val("NONE"); + verified_selfbuy.prop("checked", true); + } + } + + // show/hide on load based on existing value of selectField + toggleVerified_selfbuy(selectField_selfbuy.val()); + + // show/hide on change + selectField_selfbuy.change(function() { + toggleVerified_selfbuy($(this).val()); + }); + + }); +})(django.jQuery); +}); + diff --git a/input/static/dropdown/js/mail.js b/input/static/dropdown/js/mail.js new file mode 100644 index 0000000..c5626b8 --- /dev/null +++ b/input/static/dropdown/js/mail.js @@ -0,0 +1,35 @@ +window.addEventListener("load", function() { +(function($) { + $(function() { + + // mail section + + var selectField_addrOther = $('#id_address'), + data_addrOther_div = $('#id_other').parent().parent(), + data_addrOther = $('#id_other'); + console.log(data_addrOther, data_addrOther_div ); + // make checked to get through the required + function toggleVerified_addrOther(value) { + if (value === "OTHER") { + data_addrOther_div.show(); + data_addrOther.val(""); + } else { + data_addrOther_div.hide(); + data_addrOther.val("NONE"); + } + } + + // show/hide on load based on existing value of selectField + toggleVerified_addrOther(selectField_addrOther.val()); + + // show/hide on change + selectField_addrOther.change(function() { + toggleVerified_addrOther($(this).val()); + }); + + + + + }); +})(django.jQuery); +}); diff --git a/input/views.py b/input/views.py index 919c9e5..4dbff38 100755 --- a/input/views.py +++ b/input/views.py @@ -111,9 +111,10 @@ class InternView(LoginRequiredMixin, CookieWizardView): data = {} for form in form_list: data = {**data, **form.cleaned_data} - if data['selfbuy'] == 'TRUE': - data['selfbuy_give_data'] = 'False' - print(data) + + if data['choice'] == 'LIT': + if data['selfbuy'] == 'TRUE': + data['selfbuy_give_data'] = 'False' # write data to database form = form.save(commit=False) @@ -209,9 +210,9 @@ class ExternView(CookieWizardView): data = {} for form in form_list: data = {**data, **form.cleaned_data} - if data['selfbuy'] == 'TRUE': - data['selfbuy_give_data'] = 'False' - print(data) + if data['choice'] == 'LIT': + if data['selfbuy'] == 'TRUE': + data['selfbuy_give_data'] = 'False' # write data to database modell = form.save(commit=False) From 76f8df70ee391ca402864eb9fac267e1fd486840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Tue, 6 Dec 2022 16:19:02 +0000 Subject: [PATCH 34/57] added a presave signal for travel model to update own field with foreign key project field --- input/admin.py | 2 +- input/forms.py | 1 + input/migrations/0084_travel_project_end.py | 18 +++++++++++++++ input/migrations/0085_auto_20221205_1820.py | 18 +++++++++++++++ input/models.py | 25 ++++++++++++++++++++- 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 input/migrations/0084_travel_project_end.py create mode 100644 input/migrations/0085_auto_20221205_1820.py diff --git a/input/admin.py b/input/admin.py index cce44e1..9c5f954 100755 --- a/input/admin.py +++ b/input/admin.py @@ -32,7 +32,7 @@ class ProjectAdmin(admin.ModelAdmin): search_fields = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') list_display = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') # action = ['export_as_csv'] - date_hierarchy = 'start' + date_hierarchy = 'end' @admin.register(BusinessCard) diff --git a/input/forms.py b/input/forms.py index 261da35..076b099 100755 --- a/input/forms.py +++ b/input/forms.py @@ -66,6 +66,7 @@ class TravelForm(FdbForm): self.fields['checkin'].required = True self.fields['checkout'].required = True self.fields['hotel'].required = True + self.fields['project_end'].required = False class Meta: model = Travel diff --git a/input/migrations/0084_travel_project_end.py b/input/migrations/0084_travel_project_end.py new file mode 100644 index 0000000..6098047 --- /dev/null +++ b/input/migrations/0084_travel_project_end.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-05 18:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0083_auto_20221205_0946'), + ] + + operations = [ + migrations.AddField( + model_name='travel', + name='project_end', + field=models.DateField(null=True, verbose_name='Projektende'), + ), + ] diff --git a/input/migrations/0085_auto_20221205_1820.py b/input/migrations/0085_auto_20221205_1820.py new file mode 100644 index 0000000..2cc3038 --- /dev/null +++ b/input/migrations/0085_auto_20221205_1820.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-05 18:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0084_travel_project_end'), + ] + + operations = [ + migrations.AlterField( + model_name='travel', + name='project_end', + field=models.DateField(blank=True, null=True, verbose_name='Projektende'), + ), + ] diff --git a/input/models.py b/input/models.py index 78d44c4..30d1c02 100755 --- a/input/models.py +++ b/input/models.py @@ -87,9 +87,10 @@ class Project(Volunteer): notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") + end_mail_send = models.BooleanField(null=True, verbose_name='Endmail versenden') + # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) - end_mail_send = models.BooleanField(null=True, verbose_name='Endmail versenden') status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet'),('NOT','nicht stattgefunden')),default='RUN') persons = models.IntegerField(default=1) finance_id = models.CharField(max_length=15, null= True, blank=True) @@ -149,6 +150,8 @@ TRANSPORT_CHOICES = {'BAHN': 'Bahn', PAYEDBY_CHOICES = {'WMDE': 'WMDE', 'REQU': 'Antragstellender Mensch'} +from django.contrib.contenttypes.models import ContentType + class Travel(Volunteer): # project variable is now null true and blank true, which means it can be saved without project id to be later on filled out by admins project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True) @@ -164,6 +167,26 @@ class Travel(Volunteer): notes = models.TextField(max_length=1000, blank=True, verbose_name='Anmerkungen') request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') + project_end = models.DateField(blank=True, null=True, verbose_name='Projektende') + # use content type model to get the end date for the project foreign key + + +from django.db.models.signals import pre_save +from django.dispatch import receiver + +@receiver(pre_save, sender=Travel, dispatch_uid="get_project_end") +def getProjectEnd(sender, instance, **kwargs): + #instance.project_end = instance.project.end + instance.project_end = instance.project.end + + +# def save(self,*args,**kwargs): +# '''we generate the autogenerated fields here''' +# # we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors +# # but maybe there is a better solution? +# intern_notes +# project_end = self.checkout +# super(Travel, self).save(*args,**kwargs) #abstract base class for Library and IFG class Grant(Extern): From 40ec56481590e1fa2eb98020360735cf247ec6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Tue, 6 Dec 2022 16:48:02 +0000 Subject: [PATCH 35/57] travel und project models now have date hierarchy based on project end --- input/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/input/admin.py b/input/admin.py index 9c5f954..ce8fe34 100755 --- a/input/admin.py +++ b/input/admin.py @@ -89,9 +89,9 @@ class IFGAdmin(admin.ModelAdmin): class TravelAdmin(admin.ModelAdmin): save_as = True search_fields = ['realname', 'granted_date'] - list_display = ('realname', 'granted', 'granted_date', 'project') + list_display = ('realname', 'granted', 'granted_date', 'project_end', 'project') list_display_links = ('realname', 'project') - date_hierarchy = 'granted_date' + date_hierarchy = 'project_end' @admin.register(Email) class EmailAdmin(admin.ModelAdmin): From b153b78048274f127712fe5063cf3058a69163e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Tue, 6 Dec 2022 17:39:25 +0000 Subject: [PATCH 36/57] added adult multiple choice radio button by changing admin.py and forms.py --- input/admin.py | 1 + input/forms.py | 9 +++++++++ input/models.py | 1 + 3 files changed, 11 insertions(+) diff --git a/input/admin.py b/input/admin.py index ce8fe34..547fc8f 100755 --- a/input/admin.py +++ b/input/admin.py @@ -100,6 +100,7 @@ class EmailAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' + radio_fields = {'adult': admin.VERTICAL} class Media: js = ('dropdown/js/base.js',) diff --git a/input/forms.py b/input/forms.py index 076b099..8b0b898 100755 --- a/input/forms.py +++ b/input/forms.py @@ -114,6 +114,11 @@ class LiteratureForm(CheckForm): class Media: js = ('dropdown/js/literature.js',) +ADULT_CHOICES = {'TRUE': format_html('Ich bin volljährig.'), + 'FALSE': format_html('Ich bin noch nicht volljährig.') + } + + class EmailForm(CheckForm): # this is the code, to change required to false if needed @@ -122,6 +127,10 @@ class EmailForm(CheckForm): self.fields['adult'].required = True self.fields['other'].required = True + adult = ChoiceField(label='Volljährigkeit', choices=ADULT_CHOICES.items(), widget=RadioSelect()) + + + # TODO: add some javascript to show/hide other-field class Meta: model = Email diff --git a/input/models.py b/input/models.py index 30d1c02..8ae7958 100755 --- a/input/models.py +++ b/input/models.py @@ -180,6 +180,7 @@ def getProjectEnd(sender, instance, **kwargs): instance.project_end = instance.project.end +# using pre save instead # def save(self,*args,**kwargs): # '''we generate the autogenerated fields here''' # # we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors From 35f0dd84ab3ddec10e6db2e02566a43bf54530e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Tue, 6 Dec 2022 19:22:56 +0000 Subject: [PATCH 37/57] hidden for all 'today' shortcuts in datetimefields via css --- input/templates/input/extern.html | 1 + 1 file changed, 1 insertion(+) diff --git a/input/templates/input/extern.html b/input/templates/input/extern.html index f4386a4..13dcb6a 100755 --- a/input/templates/input/extern.html +++ b/input/templates/input/extern.html @@ -9,6 +9,7 @@ + {% load i18n %} {% block content %} From 2fe292fda0c91ec4f35307060956a0eac94bc2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Wed, 7 Dec 2022 13:56:22 +0000 Subject: [PATCH 38/57] changed logic of generation of finId and pId, solved Travelform error, hotel variable travelmodel is not required anymore --- input/admin.py | 9 +++-- input/forms.py | 3 +- input/migrations/0086_project_end_quartal.py | 18 +++++++++ .../0087_travel_project_end_quartal.py | 18 +++++++++ input/models.py | 39 +++++++++++++++---- .../css/dateFieldNoNowShortcutInTravels.css | 5 +++ 6 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 input/migrations/0086_project_end_quartal.py create mode 100644 input/migrations/0087_travel_project_end_quartal.py create mode 100644 input/static/css/dateFieldNoNowShortcutInTravels.css diff --git a/input/admin.py b/input/admin.py index 547fc8f..59746a0 100755 --- a/input/admin.py +++ b/input/admin.py @@ -29,11 +29,11 @@ admin.site.add_action(export_as_csv) @admin.register(Project) class ProjectAdmin(admin.ModelAdmin): save_as = True - search_fields = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') - list_display = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status') + search_fields = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status', 'end_quartal') + list_display = ('name', 'pid','finance_id', 'realname', 'start', 'end', 'participants_estimated', 'participants_real', 'cost', 'status', 'end_quartal') # action = ['export_as_csv'] date_hierarchy = 'end' - + readonly_fields = ('end_quartal', 'project_of_year', 'pid', 'finance_id') @admin.register(BusinessCard) class BusinessCardAdmin(admin.ModelAdmin): @@ -89,9 +89,10 @@ class IFGAdmin(admin.ModelAdmin): class TravelAdmin(admin.ModelAdmin): save_as = True search_fields = ['realname', 'granted_date'] - list_display = ('realname', 'granted', 'granted_date', 'project_end', 'project') + list_display = ('realname', 'granted', 'granted_date', 'project_end', 'project', 'project_end_quartal') list_display_links = ('realname', 'project') date_hierarchy = 'project_end' + readonly_fields = ('project_end_quartal', 'project_end') @admin.register(Email) class EmailAdmin(admin.ModelAdmin): diff --git a/input/forms.py b/input/forms.py index 8b0b898..f4bf805 100755 --- a/input/forms.py +++ b/input/forms.py @@ -65,8 +65,7 @@ class TravelForm(FdbForm): self.fields['travelcost'].required = True self.fields['checkin'].required = True self.fields['checkout'].required = True - self.fields['hotel'].required = True - self.fields['project_end'].required = False + self.fields['hotel'].required = False class Meta: model = Travel diff --git a/input/migrations/0086_project_end_quartal.py b/input/migrations/0086_project_end_quartal.py new file mode 100644 index 0000000..6eb6ed7 --- /dev/null +++ b/input/migrations/0086_project_end_quartal.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-07 09:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0085_auto_20221205_1820'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='end_quartal', + field=models.CharField(blank=True, max_length=15, null=True, verbose_name='Quartal Projekt Ende'), + ), + ] diff --git a/input/migrations/0087_travel_project_end_quartal.py b/input/migrations/0087_travel_project_end_quartal.py new file mode 100644 index 0000000..c1d8ea8 --- /dev/null +++ b/input/migrations/0087_travel_project_end_quartal.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-07 09:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0086_project_end_quartal'), + ] + + operations = [ + migrations.AddField( + model_name='travel', + name='project_end_quartal', + field=models.CharField(blank=True, max_length=15, null=True, verbose_name='Quartal Projekt Ende'), + ), + ] diff --git a/input/models.py b/input/models.py index 8ae7958..96ce900 100755 --- a/input/models.py +++ b/input/models.py @@ -95,6 +95,7 @@ class Project(Volunteer): persons = models.IntegerField(default=1) finance_id = models.CharField(max_length=15, null= True, blank=True) project_of_year = models.IntegerField(default=0) + end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name="Quartal Projekt Ende") def save(self,*args,**kwargs): '''we generate the autogenerated fields here''' @@ -103,21 +104,43 @@ class Project(Volunteer): super().save() self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.pk).zfill(3) # self.pid = str(self.account.code) + str(self.pk).zfill(3) - # generation of finance_id + + # generation of field quartals + if self.end.month in [1, 2, 3]: + self.end_quartal = 'Q1' + if self.end.month in [4, 5, 6]: + self.end_quartal = 'Q2' + if self.end.month in [7, 8, 9]: + self.end_quartal = 'Q3' + if self.end.month in [10, 11, 12]: + self.end_quartal = 'Q4' + + # generation of pid and financeID + if not self.project_of_year: - print('AAA') + #print('AAA') # we need to determine if this is a new year with its first new project... year = self.start.year - print(year) + #print(year) projects = Project.objects.filter(start__year=year) if not projects: #print('BBB') self.project_of_year = 1 + self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.project_of_year).zfill(3) else: #print('CCC') + # get the project of year number of latest entry projects = projects.order_by("-project_of_year")[0] + # add one to value of latest entry self.project_of_year = int(projects.project_of_year) + 1 - self.finance_id = str(self.account.code) + str(self.project_of_year).zfill(3) + self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.project_of_year).zfill(3) + + if str(self.account.code) == '21111': + self.finance_id = str(self.account.code) + str(self.project_of_year).zfill(3) + else: + self.finance_id = str(self.account.code) + + super().save() def __str__(self): @@ -169,7 +192,7 @@ class Travel(Volunteer): intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') project_end = models.DateField(blank=True, null=True, verbose_name='Projektende') # use content type model to get the end date for the project foreign key - + project_end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name="Quartal Projekt Ende") from django.db.models.signals import pre_save from django.dispatch import receiver @@ -177,8 +200,10 @@ from django.dispatch import receiver @receiver(pre_save, sender=Travel, dispatch_uid="get_project_end") def getProjectEnd(sender, instance, **kwargs): #instance.project_end = instance.project.end - instance.project_end = instance.project.end - + + if instance.project: + instance.project_end = instance.project.end + instance.project_end_quartal = instance.project.end_quartal # using pre save instead # def save(self,*args,**kwargs): diff --git a/input/static/css/dateFieldNoNowShortcutInTravels.css b/input/static/css/dateFieldNoNowShortcutInTravels.css new file mode 100644 index 0000000..0c0c7f2 --- /dev/null +++ b/input/static/css/dateFieldNoNowShortcutInTravels.css @@ -0,0 +1,5 @@ + +span.datetimeshortcuts > a:first-child { + visibility: hidden; +} + From b5062dcc28eb3a6a66f83d852214e902a20bbc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Wed, 7 Dec 2022 14:08:23 +0000 Subject: [PATCH 39/57] custom css is now only applied to travel form, not to all forms --- input/forms.py | 6 ++++++ input/templates/input/extern.html | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/input/forms.py b/input/forms.py index f4bf805..262f376 100755 --- a/input/forms.py +++ b/input/forms.py @@ -74,6 +74,12 @@ class TravelForm(FdbForm): 'checkout': AdminDateWidget(),} fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes'] + class Media: + css = { + 'all': ('admin/css/dateFieldNoNowShortcutInTravels.css',) + } + + class LibraryForm(FdbForm): class Meta: diff --git a/input/templates/input/extern.html b/input/templates/input/extern.html index 13dcb6a..d0721bf 100755 --- a/input/templates/input/extern.html +++ b/input/templates/input/extern.html @@ -9,7 +9,7 @@ - + {% load i18n %} {% block content %} From 2cd2d9f110d09c8877ecffe13a2953b129d44835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Thu, 8 Dec 2022 20:21:36 +0000 Subject: [PATCH 40/57] fixed literature selfbuy variables in admin view --- input/admin.py | 2 -- input/forms.py | 2 +- input/models.py | 2 +- input/views.py | 3 ++- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/input/admin.py b/input/admin.py index 59746a0..82d1bfc 100755 --- a/input/admin.py +++ b/input/admin.py @@ -53,8 +53,6 @@ class LiteratureAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' - class Media: - js = ('dropdown/js/base.js',) @admin.register(Account) diff --git a/input/forms.py b/input/forms.py index 262f376..152cc97 100755 --- a/input/forms.py +++ b/input/forms.py @@ -111,7 +111,7 @@ class CheckForm(FdbForm): class LiteratureForm(CheckForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['selfbuy_give_data'].required = True + self.fields['selfbuy_give_data'].required = False class Meta: model = Literature fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_data', 'selfbuy_give_data'] diff --git a/input/models.py b/input/models.py index 96ce900..4b45457 100755 --- a/input/models.py +++ b/input/models.py @@ -264,7 +264,7 @@ class Literature(Grant): help_text="Bitte gib an, wo du das Werk kaufen möchtest.") selfbuy = models.CharField( max_length=10, verbose_name='Selbstkauf?', choices=SELFBUY_CHOICES.items(), default='TRUE') selfbuy_give_data = models.BooleanField(verbose_name=format_html('Datenweitergabe erlauben'), help_text=format_html('Ich stimme der Weitergabe meiner Daten (Name, Postadresse) an den von mir angegebenen Anbieter/Dienstleister zu.')) - selfbuy_data = models.TextField(max_length=1000, verbose_name='Persönliche Daten sowie Adresse', default='', + selfbuy_data = models.TextField(max_length=1000, verbose_name='Persönliche Daten sowie Adresse', default='',\ help_text=format_html("Bitte gib hier alle persönlichen Daten an, die wir benötigen, um das Werk
\ für dich zu kaufen und es dir anschließend zu schicken (z.B. Vorname Nachname, Anschrift,
\ Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.")) diff --git a/input/views.py b/input/views.py index 4dbff38..281fd52 100755 --- a/input/views.py +++ b/input/views.py @@ -210,10 +210,11 @@ class ExternView(CookieWizardView): data = {} for form in form_list: data = {**data, **form.cleaned_data} + if data['choice'] == 'LIT': if data['selfbuy'] == 'TRUE': data['selfbuy_give_data'] = 'False' - + # write data to database modell = form.save(commit=False) # we have to copy the data from the first form here From f35a788fd05756663d9c4d88d945a00d18268161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Thu, 8 Dec 2022 21:32:17 +0000 Subject: [PATCH 41/57] hotel in forms.py is now radioselect choicefield and required --- input/forms.py | 8 +++++++- input/migrations/0088_auto_20221208_2128.py | 18 ++++++++++++++++++ input/models.py | 6 +++++- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 input/migrations/0088_auto_20221208_2128.py diff --git a/input/forms.py b/input/forms.py index 152cc97..48600af 100755 --- a/input/forms.py +++ b/input/forms.py @@ -54,6 +54,11 @@ class InternForm(FdbForm): exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date', 'mail_state') +HOTEL_CHOICES = {'TRUE': format_html('Hotelzimmer benötigt'), + 'FALSE': format_html('Kein Hotelzimmer benötigt') + } + + class TravelForm(FdbForm): # TODO: add some javascript to show/hide other-field @@ -65,7 +70,7 @@ class TravelForm(FdbForm): self.fields['travelcost'].required = True self.fields['checkin'].required = True self.fields['checkout'].required = True - self.fields['hotel'].required = False + self.fields['hotel'].required = True class Meta: model = Travel @@ -73,6 +78,7 @@ class TravelForm(FdbForm): widgets = {'checkin': AdminDateWidget(), 'checkout': AdminDateWidget(),} fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes'] + hotel = ChoiceField(label='Hotelzimmer benötigt:', choices=HOTEL_CHOICES.items(), widget=RadioSelect()) class Media: css = { diff --git a/input/migrations/0088_auto_20221208_2128.py b/input/migrations/0088_auto_20221208_2128.py new file mode 100644 index 0000000..9291efe --- /dev/null +++ b/input/migrations/0088_auto_20221208_2128.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-08 21:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0087_travel_project_end_quartal'), + ] + + operations = [ + migrations.AlterField( + model_name='travel', + name='hotel', + field=models.CharField(choices=[('TRUE', 'Hotelzimmer benötigt'), ('FALSE', 'Kein Hotelzimmer benötigt')], max_length=10, verbose_name='Hotelzimmer benötigt:'), + ), + ] diff --git a/input/models.py b/input/models.py index 4b45457..d1d00e0 100755 --- a/input/models.py +++ b/input/models.py @@ -173,6 +173,10 @@ TRANSPORT_CHOICES = {'BAHN': 'Bahn', PAYEDBY_CHOICES = {'WMDE': 'WMDE', 'REQU': 'Antragstellender Mensch'} +HOTEL_CHOICES = {'TRUE': format_html('Hotelzimmer benötigt'), + 'FALSE': format_html('Kein Hotelzimmer benötigt') + } + from django.contrib.contenttypes.models import ContentType class Travel(Volunteer): @@ -186,7 +190,7 @@ class Travel(Volunteer): checkout = models.DateTimeField(blank=True, null=True, verbose_name='Abreise') payed_for_hotel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Hotel durch') payed_for_travel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Fahrt durch') - hotel = models.BooleanField(default=False, verbose_name='Hotelzimmer benötigt:') + hotel = models.CharField(max_length=10, choices=HOTEL_CHOICES.items(), verbose_name='Hotelzimmer benötigt:') notes = models.TextField(max_length=1000, blank=True, verbose_name='Anmerkungen') request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') From e814b7fa411d602c875490cc3cce52b0b0fd55fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Thu, 8 Dec 2022 21:36:48 +0000 Subject: [PATCH 42/57] added search bar to foreign key choice field project in model travel --- input/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/input/admin.py b/input/admin.py index 82d1bfc..2c406ec 100755 --- a/input/admin.py +++ b/input/admin.py @@ -91,6 +91,7 @@ class TravelAdmin(admin.ModelAdmin): list_display_links = ('realname', 'project') date_hierarchy = 'project_end' readonly_fields = ('project_end_quartal', 'project_end') + autocomplete_fields = ['project'] @admin.register(Email) class EmailAdmin(admin.ModelAdmin): From fbad8873baa680773d6960c5a8719abda0e2bca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 16:33:52 +0000 Subject: [PATCH 43/57] all service ids are readonly fields now --- input/.models.py.swp | Bin 0 -> 1024 bytes input/admin.py | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 input/.models.py.swp diff --git a/input/.models.py.swp b/input/.models.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..b7ad36d7725791f9570a22e76a5936683e1ae43c GIT binary patch literal 1024 zcmYc?$V<%2S1{4DU_b#H0SpXjDM=_|xHxI~sYNM3lvt9Qmz0>7os*cGl#+<4IyXNh WHK$mwpb}GRRAe*+Mnhl#LI407F%c*L literal 0 HcmV?d00001 diff --git a/input/admin.py b/input/admin.py index 2c406ec..08df4ec 100755 --- a/input/admin.py +++ b/input/admin.py @@ -43,6 +43,7 @@ class BusinessCardAdmin(admin.ModelAdmin): list_display_links = ('realname', 'service_id') # action = ['export_as_csv'] date_hierarchy = 'granted_date' + readonly_fields = ['service_id'] class Media: js = ('dropdown/js/base.js',) @@ -53,6 +54,7 @@ class LiteratureAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' + readonly_fields = ['service_id'] @admin.register(Account) @@ -74,6 +76,7 @@ class LibraryAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' + readonly_fields = ['service_id'] @admin.register(IFG) class IFGAdmin(admin.ModelAdmin): @@ -82,6 +85,7 @@ class IFGAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' + readonly_fields = ['service_id'] @admin.register(Travel) class TravelAdmin(admin.ModelAdmin): @@ -101,6 +105,7 @@ class EmailAdmin(admin.ModelAdmin): list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' radio_fields = {'adult': admin.VERTICAL} + readonly_fields = ['service_id'] class Media: js = ('dropdown/js/base.js',) @@ -112,6 +117,7 @@ class ListAdmin(admin.ModelAdmin): list_display = ('realname', 'service_id', 'granted', 'granted_date') list_display_links = ('realname', 'service_id') date_hierarchy = 'granted_date' + readonly_fields = ['service_id'] # commented out because of the individual registering to control displays in admin panel From d09b97f72fc9bcba7ddba5eaad141405221de273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 16:52:52 +0000 Subject: [PATCH 44/57] model travel is now based on extern instead of intern, service id is displayed and a readonly field --- input/.models.py.swp | Bin 1024 -> 0 bytes input/admin.py | 5 +++-- input/migrations/0089_auto_20221209_1648.py | 23 ++++++++++++++++++++ input/models.py | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) delete mode 100644 input/.models.py.swp create mode 100644 input/migrations/0089_auto_20221209_1648.py diff --git a/input/.models.py.swp b/input/.models.py.swp deleted file mode 100644 index b7ad36d7725791f9570a22e76a5936683e1ae43c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 zcmYc?$V<%2S1{4DU_b#H0SpXjDM=_|xHxI~sYNM3lvt9Qmz0>7os*cGl#+<4IyXNh WHK$mwpb}GRRAe*+Mnhl#LI407F%c*L diff --git a/input/admin.py b/input/admin.py index 08df4ec..5537d38 100755 --- a/input/admin.py +++ b/input/admin.py @@ -90,12 +90,13 @@ class IFGAdmin(admin.ModelAdmin): @admin.register(Travel) class TravelAdmin(admin.ModelAdmin): save_as = True - search_fields = ['realname', 'granted_date'] - list_display = ('realname', 'granted', 'granted_date', 'project_end', 'project', 'project_end_quartal') + search_fields = ['realname', 'service_id', 'granted_date'] + list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project_end', 'project', 'project_end_quartal') list_display_links = ('realname', 'project') date_hierarchy = 'project_end' readonly_fields = ('project_end_quartal', 'project_end') autocomplete_fields = ['project'] + readonly_fields = ['service_id'] @admin.register(Email) class EmailAdmin(admin.ModelAdmin): diff --git a/input/migrations/0089_auto_20221209_1648.py b/input/migrations/0089_auto_20221209_1648.py new file mode 100644 index 0000000..55f394d --- /dev/null +++ b/input/migrations/0089_auto_20221209_1648.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.2 on 2022-12-09 16:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0088_auto_20221208_2128'), + ] + + operations = [ + migrations.AddField( + model_name='travel', + name='service_id', + field=models.CharField(blank=True, max_length=15, null=True), + ), + migrations.AddField( + model_name='travel', + name='username', + field=models.CharField(help_text='Bitte gib den Namen ein, mit dem du dich
in den Wikimedia-Projekten registriert hast.', max_length=200, null=True, verbose_name='Benutzer_innenname'), + ), + ] diff --git a/input/models.py b/input/models.py index d1d00e0..d57d599 100755 --- a/input/models.py +++ b/input/models.py @@ -179,7 +179,7 @@ HOTEL_CHOICES = {'TRUE': format_html('Hotelzimmer benötigt'), from django.contrib.contenttypes.models import ContentType -class Travel(Volunteer): +class Travel(Extern): # project variable is now null true and blank true, which means it can be saved without project id to be later on filled out by admins project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True) project_name = models.CharField(max_length=50, null=True, blank=True, verbose_name='Projektname:') From 0b044692d68a32d58763b7c5c75d1eb44ca4a8d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 16:55:26 +0000 Subject: [PATCH 45/57] literature self_buy_giveData variable is now required in extern view --- input/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/forms.py b/input/forms.py index 48600af..3951955 100755 --- a/input/forms.py +++ b/input/forms.py @@ -117,7 +117,7 @@ class CheckForm(FdbForm): class LiteratureForm(CheckForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['selfbuy_give_data'].required = False + self.fields['selfbuy_give_data'].required = True class Meta: model = Literature fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_data', 'selfbuy_give_data'] From 3d591a39f77403b266366e70dda2bd5f79d1044a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 17:20:03 +0000 Subject: [PATCH 46/57] now the | in datefield is also hidden via css --- input/forms.py | 2 +- input/static/css/dateFieldNoNowShortcutInTravels.css | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/input/forms.py b/input/forms.py index 3951955..79fa58c 100755 --- a/input/forms.py +++ b/input/forms.py @@ -82,7 +82,7 @@ class TravelForm(FdbForm): class Media: css = { - 'all': ('admin/css/dateFieldNoNowShortcutInTravels.css',) + 'all': ('css/dateFieldNoNowShortcutInTravels.css',) } diff --git a/input/static/css/dateFieldNoNowShortcutInTravels.css b/input/static/css/dateFieldNoNowShortcutInTravels.css index 0c0c7f2..08c9cd0 100644 --- a/input/static/css/dateFieldNoNowShortcutInTravels.css +++ b/input/static/css/dateFieldNoNowShortcutInTravels.css @@ -1,5 +1,14 @@ +/* span.datetimeshortcuts > a:first-child { visibility: hidden; } +*/ +span.datetimeshortcuts { + visibility: hidden; +} + +span.datetimeshortcuts > a:nth-child(2) { + visibility: visible; +} From a6defcb627becc8e7858360dba91a19e5ba46a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 17:25:41 +0000 Subject: [PATCH 47/57] admin model travel has now datefields instead of datetimefields for checkin and checkout --- input/migrations/0090_auto_20221209_1720.py | 23 +++++++++++++++++++++ input/models.py | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 input/migrations/0090_auto_20221209_1720.py diff --git a/input/migrations/0090_auto_20221209_1720.py b/input/migrations/0090_auto_20221209_1720.py new file mode 100644 index 0000000..440811b --- /dev/null +++ b/input/migrations/0090_auto_20221209_1720.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.2 on 2022-12-09 17:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0089_auto_20221209_1648'), + ] + + operations = [ + migrations.AlterField( + model_name='travel', + name='checkin', + field=models.DateField(blank=True, null=True, verbose_name='Anreise'), + ), + migrations.AlterField( + model_name='travel', + name='checkout', + field=models.DateField(blank=True, null=True, verbose_name='Abreise'), + ), + ] diff --git a/input/models.py b/input/models.py index d57d599..fa336a4 100755 --- a/input/models.py +++ b/input/models.py @@ -186,8 +186,8 @@ class Travel(Extern): transport = models.CharField(max_length=5, choices=TRANSPORT_CHOICES.items(), default='BAHN', verbose_name='Transportmittel:') other_transport = models.CharField(max_length=200, null=True, blank=True, verbose_name='Sonstige Transportmittel (mit Begründung)') travelcost = models.CharField(max_length=10, default="0", verbose_name='Fahrtkosten') - checkin = models.DateTimeField(blank=True, null=True, verbose_name='Anreise') - checkout = models.DateTimeField(blank=True, null=True, verbose_name='Abreise') + checkin = models.DateField(blank=True, null=True, verbose_name='Anreise') + checkout = models.DateField(blank=True, null=True, verbose_name='Abreise') payed_for_hotel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Hotel durch') payed_for_travel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Fahrt durch') hotel = models.CharField(max_length=10, choices=HOTEL_CHOICES.items(), verbose_name='Hotelzimmer benötigt:') From d2d9149a627d3f270e03e90434402824833a2971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 17:58:37 +0000 Subject: [PATCH 48/57] send end mails var in admin.model.project changed to boolean check field, also true is false now, so changed logic in sendmails.py --- input/management/commands/sendmails.py | 8 ++++---- input/migrations/0091_auto_20221209_1752.py | 18 ++++++++++++++++++ input/migrations/0092_auto_20221209_1754.py | 18 ++++++++++++++++++ input/models.py | 4 ++-- 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 input/migrations/0091_auto_20221209_1752.py create mode 100644 input/migrations/0092_auto_20221209_1754.py diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 43abad3..4e1ad64 100755 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -68,7 +68,7 @@ class Command(BaseCommand): # get all projects which ended old = Project.objects.filter(end__lt = date.today())\ - .exclude(end_mail_send = True)\ + .exclude(end_mail_send = False)\ .filter(mail_state = 'NONE') txt_mail_template = get_template('input/if_end_of_project.txt') @@ -92,7 +92,7 @@ class Command(BaseCommand): # IF_EMAIL, # [IF_EMAIL], # fail_silently=False) - project.end_mail_send = True + project.end_mail_send = False project.mail_state = 'INF' try: project.save() @@ -108,7 +108,7 @@ class Command(BaseCommand): # get all projects where end was reached already, and send mails for the ones already set to status "ended" by the admins approved_end = Project.objects.filter(status = 'END')\ - .exclude(end_mail_send = False)\ + .exclude(end_mail_send = True)\ .filter(mail_state = 'INF') txt_mail_template = get_template('input/if_end_of_project_approved.txt') html_mail_template = get_template('input/if_end_of_project_approved.html') @@ -165,7 +165,7 @@ class Command(BaseCommand): # get all projects where end was reached already, and send mails for the ones where status was put to NOT by admins approved_notHappened = Project.objects.filter(status = 'NOT')\ - .exclude(end_mail_send = False)\ + .exclude(end_mail_send = True)\ .filter(mail_state = 'INF') html_mail_template = get_template('input/if_not_of_project_approved.html') diff --git a/input/migrations/0091_auto_20221209_1752.py b/input/migrations/0091_auto_20221209_1752.py new file mode 100644 index 0000000..63905de --- /dev/null +++ b/input/migrations/0091_auto_20221209_1752.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-09 17:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0090_auto_20221209_1720'), + ] + + operations = [ + migrations.AlterField( + model_name='project', + name='end_mail_send', + field=models.BooleanField(null=True, verbose_name='Keine Projektabschlussmail schicken'), + ), + ] diff --git a/input/migrations/0092_auto_20221209_1754.py b/input/migrations/0092_auto_20221209_1754.py new file mode 100644 index 0000000..ac5a873 --- /dev/null +++ b/input/migrations/0092_auto_20221209_1754.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.2 on 2022-12-09 17:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0091_auto_20221209_1752'), + ] + + operations = [ + migrations.AlterField( + model_name='project', + name='end_mail_send', + field=models.BooleanField(default=False, verbose_name='Keine Projektabschlussmail schicken'), + ), + ] diff --git a/input/models.py b/input/models.py index fa336a4..cce427a 100755 --- a/input/models.py +++ b/input/models.py @@ -19,9 +19,9 @@ class Volunteer(models.Model): # the following Fields are not supposed to be edited by users granted = models.BooleanField(null=True, verbose_name='bewilligt') granted_date = models.DateField(null=True, verbose_name='bewilligt am') - survey_mail_send = models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken') survey_mail_date = models.DateField(verbose_name='Umfragemail wurde verschickt am', null=True, blank=True) mail_state = models.CharField(max_length=6, choices=EMAIL_STATES.items(), default='NONE') + survey_mail_send = models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken') @classmethod @@ -66,6 +66,7 @@ class Account(models.Model): return f"{self.code} {self.description}" class Project(Volunteer): + end_mail_send = models.BooleanField(default=False, verbose_name='Keine Projektabschlussmail schicken') name = models.CharField(max_length=200, verbose_name='Name des Projekts') description = models.CharField(max_length=500, verbose_name="Kurzbeschreibung", null=True) start = models.DateField('Startdatum', null=True) @@ -87,7 +88,6 @@ class Project(Volunteer): notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name="interne Anmerkungen") - end_mail_send = models.BooleanField(null=True, verbose_name='Endmail versenden') # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) From cb930ecedaea84681805f8e9fd55fb8605be74fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 18:31:38 +0000 Subject: [PATCH 49/57] deleted variable persons in admin model project --- input/migrations/0093_remove_project_persons.py | 17 +++++++++++++++++ input/models.py | 1 - 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 input/migrations/0093_remove_project_persons.py diff --git a/input/migrations/0093_remove_project_persons.py b/input/migrations/0093_remove_project_persons.py new file mode 100644 index 0000000..b467960 --- /dev/null +++ b/input/migrations/0093_remove_project_persons.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.2 on 2022-12-09 18:28 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0092_auto_20221209_1754'), + ] + + operations = [ + migrations.RemoveField( + model_name='project', + name='persons', + ), + ] diff --git a/input/models.py b/input/models.py index cce427a..2e70b41 100755 --- a/input/models.py +++ b/input/models.py @@ -92,7 +92,6 @@ class Project(Volunteer): # the following Fields are not supposed to be edited by users pid = models.CharField(max_length=15, null=True, blank=True) status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet'),('NOT','nicht stattgefunden')),default='RUN') - persons = models.IntegerField(default=1) finance_id = models.CharField(max_length=15, null= True, blank=True) project_of_year = models.IntegerField(default=0) end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name="Quartal Projekt Ende") From fcb906c193685c442cbb43c86095394e363e3c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Fri, 9 Dec 2022 18:54:58 +0000 Subject: [PATCH 50/57] changed order of fields in admin panel of model project --- input/.models.py.swp | Bin 0 -> 1024 bytes input/admin.py | 1 + 2 files changed, 1 insertion(+) create mode 100644 input/.models.py.swp diff --git a/input/.models.py.swp b/input/.models.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..19391f2caab1944a1ce039476b6c9045810e9889 GIT binary patch literal 1024 zcmYc?$V<%2S1{4DU_b%$0~r|7Qj$=_aB Date: Mon, 12 Dec 2022 10:13:46 +0000 Subject: [PATCH 51/57] honorary certificate model now has autocomplete field foreign key project too --- input/.models.py.swp | Bin 1024 -> 0 bytes input/admin.py | 1 + 2 files changed, 1 insertion(+) delete mode 100644 input/.models.py.swp diff --git a/input/.models.py.swp b/input/.models.py.swp deleted file mode 100644 index 19391f2caab1944a1ce039476b6c9045810e9889..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 zcmYc?$V<%2S1{4DU_b%$0~r|7Qj$=_aB Date: Mon, 12 Dec 2022 10:26:19 +0000 Subject: [PATCH 52/57] search fields for travel and honorary are using foreign keys now, with the notation of double underscores --- input/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/input/admin.py b/input/admin.py index 01902fd..209e578 100755 --- a/input/admin.py +++ b/input/admin.py @@ -66,7 +66,7 @@ class AccountAdmin(admin.ModelAdmin): @admin.register(HonoraryCertificate) class HonoraryCertificateAdmin(admin.ModelAdmin): save_as = True - search_fields = ['realname', 'granted'] + search_fields = ['realname', 'granted', 'project__name', 'project__pid'] list_display = ('realname', 'granted','project') date_hierarchy = 'granted_date' autocomplete_fields = ['project'] @@ -92,7 +92,7 @@ class IFGAdmin(admin.ModelAdmin): @admin.register(Travel) class TravelAdmin(admin.ModelAdmin): save_as = True - search_fields = ['realname', 'service_id', 'granted_date'] + search_fields = ['realname', 'service_id', 'granted_date', 'project__name', 'project__pid'] list_display = ('realname', 'service_id', 'granted', 'granted_date', 'project_end', 'project', 'project_end_quartal') list_display_links = ('realname', 'project') date_hierarchy = 'project_end' From e41ba42e1e613eff762e56cf820b3df9bbde6f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benni=20B=C3=A4rmann?= Date: Wed, 14 Dec 2022 16:28:09 +0000 Subject: [PATCH 53/57] changed mail_state, implemented live, changed mail sender --- input/logfile | 52 ++++++++-------- input/migrations/0094_auto_20221212_1146.py | 68 +++++++++++++++++++++ input/migrations/0095_auto_20221214_1207.py | 68 +++++++++++++++++++++ input/views.py | 34 +++++------ 4 files changed, 179 insertions(+), 43 deletions(-) create mode 100644 input/migrations/0094_auto_20221212_1146.py create mode 100644 input/migrations/0095_auto_20221214_1207.py diff --git a/input/logfile b/input/logfile index 861f27e..9fc7c01 100644 --- a/input/logfile +++ b/input/logfile @@ -1,5 +1,5 @@ nohup: ignoring input -[2022-12-05 10:02:21 +0000] [12084] [DEBUG] Current configuration: +[2022-12-14 11:22:16 +0000] [29484] [DEBUG] Current configuration: config: None bind: ['0:8000'] backlog: 2048 @@ -56,21 +56,21 @@ nohup: ignoring input default_proc_name: foerderbarometer.wsgi pythonpath: None paste: None - on_starting: - on_reload: - when_ready: - pre_fork: - post_fork: - post_worker_init: - worker_int: - worker_abort: - pre_exec: - pre_request: - post_request: - child_exit: - worker_exit: - nworkers_changed: - on_exit: + on_starting: + on_reload: + when_ready: + pre_fork: + post_fork: + post_worker_init: + worker_int: + worker_abort: + pre_exec: + pre_request: + post_request: + child_exit: + worker_exit: + nworkers_changed: + on_exit: proxy_protocol: False proxy_allow_ips: ['127.0.0.1'] keyfile: None @@ -83,13 +83,13 @@ nohup: ignoring input ciphers: None raw_paste_global_conf: [] strip_header_spaces: False -[2022-12-05 10:02:21 +0000] [12084] [INFO] Starting gunicorn 20.0.4 -[2022-12-05 10:02:21 +0000] [12084] [DEBUG] Arbiter booted -[2022-12-05 10:02:21 +0000] [12084] [INFO] Listening at: http://0.0.0.0:8000 (12084) -[2022-12-05 10:02:21 +0000] [12084] [INFO] Using worker: sync -[2022-12-05 10:02:21 +0000] [12086] [INFO] Booting worker with pid: 12086 -[2022-12-05 10:02:21 +0000] [12084] [DEBUG] 1 workers -[2022-12-05 10:02:21 +0000] [12086] [ERROR] Exception in worker process +[2022-12-14 11:22:16 +0000] [29484] [INFO] Starting gunicorn 20.0.4 +[2022-12-14 11:22:16 +0000] [29484] [DEBUG] Arbiter booted +[2022-12-14 11:22:16 +0000] [29484] [INFO] Listening at: http://0.0.0.0:8000 (29484) +[2022-12-14 11:22:16 +0000] [29484] [INFO] Using worker: sync +[2022-12-14 11:22:16 +0000] [29486] [INFO] Booting worker with pid: 29486 +[2022-12-14 11:22:16 +0000] [29484] [DEBUG] 1 workers +[2022-12-14 11:22:16 +0000] [29486] [ERROR] Exception in worker process Traceback (most recent call last): File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker worker.init_process() @@ -115,6 +115,6 @@ Traceback (most recent call last): File "", line 991, in _find_and_load File "", line 973, in _find_and_load_unlocked ModuleNotFoundError: No module named 'foerderbarometer' -[2022-12-05 10:02:21 +0000] [12086] [INFO] Worker exiting (pid: 12086) -[2022-12-05 10:02:21 +0000] [12084] [INFO] Shutting down: Master -[2022-12-05 10:02:21 +0000] [12084] [INFO] Reason: Worker failed to boot. +[2022-12-14 11:22:16 +0000] [29486] [INFO] Worker exiting (pid: 29486) +[2022-12-14 11:22:16 +0000] [29484] [INFO] Shutting down: Master +[2022-12-14 11:22:16 +0000] [29484] [INFO] Reason: Worker failed to boot. diff --git a/input/migrations/0094_auto_20221212_1146.py b/input/migrations/0094_auto_20221212_1146.py new file mode 100644 index 0000000..f4b804f --- /dev/null +++ b/input/migrations/0094_auto_20221212_1146.py @@ -0,0 +1,68 @@ +# Generated by Django 3.1.2 on 2022-12-12 11:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0093_remove_project_persons'), + ] + + operations = [ + migrations.AlterField( + model_name='businesscard', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='concreteextern', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='email', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='ifg', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='library', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='list', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='literature', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='project', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + migrations.AlterField( + model_name='travel', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='END', max_length=6), + ), + ] diff --git a/input/migrations/0095_auto_20221214_1207.py b/input/migrations/0095_auto_20221214_1207.py new file mode 100644 index 0000000..57a9331 --- /dev/null +++ b/input/migrations/0095_auto_20221214_1207.py @@ -0,0 +1,68 @@ +# Generated by Django 3.1.2 on 2022-12-14 12:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0094_auto_20221212_1146'), + ] + + operations = [ + migrations.AlterField( + model_name='businesscard', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='concreteextern', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='email', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='ifg', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='library', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='list', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='literature', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='project', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='travel', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung End-Mail wurde bereits versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden bereits versendet')], default='NONE', max_length=6), + ), + ] diff --git a/input/views.py b/input/views.py index 281fd52..203de7a 100755 --- a/input/views.py +++ b/input/views.py @@ -244,19 +244,19 @@ class ExternView(CookieWizardView): try: # - mail with entered data to the Volunteer - txt_mail_template = get_template('input/ifg_volunteer_mail.txt') - html_mail_template = get_template('input/ifg_volunteer_mail.html') + txt_mail_template1 = get_template('input/ifg_volunteer_mail.txt') + html_mail_template1 = get_template('input/ifg_volunteer_mail.html') - subject, from_email, to = 'Formular ausgefüllt', IF_EMAIL, data['email'] - text_content = txt_mail_template.render(context) - html_content = html_mail_template.render(context) - msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) - msg.attach_alternative(html_content, "text/html") - #msg.send() - print('ifg volunteer mail would have been sent') + subject1, from_email1, to1 = 'Formular ausgefüllt', IF_EMAIL, data['email'] + text_content1 = txt_mail_template1.render(context) + html_content1 = html_mail_template1.render(context) + msg1 = EmailMultiAlternatives(subject1, text_content1, from_email1, [to1]) + msg1.attach_alternative(html_content1, "text/html") + msg1.send() + #print('ifg volunteer mail would have been sent') #send_mail( # 'Formular ausgefüllt', - # mail_template.render(context), + # txt_mail_template1.render(context), # IF_EMAIL, # [data['email']], # fail_silently=False) @@ -268,24 +268,24 @@ class ExternView(CookieWizardView): subject, from_email, to = 'Formular ausgefüllt', IF_EMAIL, IF_EMAIL text_content = txt_mail_template.render(context) html_content = html_mail_template.render(context) - msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) - msg.attach_alternative(html_content, "text/html") - #msg.send() - print('if mail would have been sent') + msg2 = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg2.attach_alternative(html_content, "text/html") + msg2.send() + #print('if mail would have been sent') #send_mail( # 'Formular ausgefüllt', - # mail_template.render(context), + # txt_mail_template.render(context), # IF_EMAIL, # [IF_EMAIL], # fail_silently=False) ## raise SMTPException("testing pupose only") - + except BadHeaderError: modell.delete() return HttpResponse('Invalid header found. Data not saved!') except SMTPException: modell.delete() - return HttpResponse('Error in sending mails (propably wrong adress?). Data not saved!') + return HttpResponse('Error in sending mails (probably wrong adress?). Data not saved!') return done(self.request) From c06b7f39b19030448db43069ad693347d98ab750 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Tue, 20 Dec 2022 09:14:45 +0000 Subject: [PATCH 54/57] trying with different username --- input/logfile | 120 -------------------------------------------------- 1 file changed, 120 deletions(-) delete mode 100644 input/logfile diff --git a/input/logfile b/input/logfile deleted file mode 100644 index 9fc7c01..0000000 --- a/input/logfile +++ /dev/null @@ -1,120 +0,0 @@ -nohup: ignoring input -[2022-12-14 11:22:16 +0000] [29484] [DEBUG] Current configuration: - config: None - bind: ['0:8000'] - backlog: 2048 - workers: 1 - worker_class: sync - threads: 1 - worker_connections: 1000 - max_requests: 0 - max_requests_jitter: 0 - timeout: 30 - graceful_timeout: 30 - keepalive: 2 - limit_request_line: 4094 - limit_request_fields: 100 - limit_request_field_size: 8190 - reload: False - reload_engine: auto - reload_extra_files: [] - spew: False - check_config: False - preload_app: False - sendfile: None - reuse_port: False - chdir: /home/fdb/foerderbaro/foerderbarometer/input - daemon: False - raw_env: [] - pidfile: None - worker_tmp_dir: None - user: 1001 - group: 1001 - umask: 0 - initgroups: False - tmp_upload_dir: None - secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'} - forwarded_allow_ips: ['*'] - accesslog: None - disable_redirect_access_to_syslog: False - access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" - errorlog: - - loglevel: debug - capture_output: False - logger_class: gunicorn.glogging.Logger - logconfig: None - logconfig_dict: {} - syslog_addr: udp://localhost:514 - syslog: False - syslog_prefix: None - syslog_facility: user - enable_stdio_inheritance: False - statsd_host: None - dogstatsd_tags: - statsd_prefix: - proc_name: None - default_proc_name: foerderbarometer.wsgi - pythonpath: None - paste: None - on_starting: - on_reload: - when_ready: - pre_fork: - post_fork: - post_worker_init: - worker_int: - worker_abort: - pre_exec: - pre_request: - post_request: - child_exit: - worker_exit: - nworkers_changed: - on_exit: - proxy_protocol: False - proxy_allow_ips: ['127.0.0.1'] - keyfile: None - certfile: None - ssl_version: 2 - cert_reqs: 0 - ca_certs: None - suppress_ragged_eofs: True - do_handshake_on_connect: False - ciphers: None - raw_paste_global_conf: [] - strip_header_spaces: False -[2022-12-14 11:22:16 +0000] [29484] [INFO] Starting gunicorn 20.0.4 -[2022-12-14 11:22:16 +0000] [29484] [DEBUG] Arbiter booted -[2022-12-14 11:22:16 +0000] [29484] [INFO] Listening at: http://0.0.0.0:8000 (29484) -[2022-12-14 11:22:16 +0000] [29484] [INFO] Using worker: sync -[2022-12-14 11:22:16 +0000] [29486] [INFO] Booting worker with pid: 29486 -[2022-12-14 11:22:16 +0000] [29484] [DEBUG] 1 workers -[2022-12-14 11:22:16 +0000] [29486] [ERROR] Exception in worker process -Traceback (most recent call last): - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker - worker.init_process() - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process - self.load_wsgi() - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi - self.wsgi = self.app.wsgi() - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi - self.callable = self.load() - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load - return self.load_wsgiapp() - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp - return util.import_app(self.app_uri) - File "/home/fdb/foerderbaro/foerderbarometer/venv/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app - mod = importlib.import_module(module) - File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module - return _bootstrap._gcd_import(name[level:], package, level) - File "", line 1014, in _gcd_import - File "", line 991, in _find_and_load - File "", line 961, in _find_and_load_unlocked - File "", line 219, in _call_with_frames_removed - File "", line 1014, in _gcd_import - File "", line 991, in _find_and_load - File "", line 973, in _find_and_load_unlocked -ModuleNotFoundError: No module named 'foerderbarometer' -[2022-12-14 11:22:16 +0000] [29486] [INFO] Worker exiting (pid: 29486) -[2022-12-14 11:22:16 +0000] [29484] [INFO] Shutting down: Master -[2022-12-14 11:22:16 +0000] [29484] [INFO] Reason: Worker failed to boot. From 689da900830fe836c33d6bca65e14bbc5a2683df Mon Sep 17 00:00:00 2001 From: corsaronero Date: Fri, 13 Jan 2023 18:18:29 +0000 Subject: [PATCH 55/57] last version, talked to admin today --- input/management/commands/sendmails.py | 14 +++-- input/migrations/0096_auto_20230106_1338.py | 68 +++++++++++++++++++++ input/models.py | 5 +- 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 input/migrations/0096_auto_20230106_1338.py diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index 4e1ad64..f22fa8f 100755 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -68,12 +68,13 @@ class Command(BaseCommand): # get all projects which ended old = Project.objects.filter(end__lt = date.today())\ - .exclude(end_mail_send = False)\ + .exclude(end_mail_send = True)\ .filter(mail_state = 'NONE') txt_mail_template = get_template('input/if_end_of_project.txt') html_mail_template = get_template('input/if_end_of_project.html') + for project in old: context = {'project': project} context['URLPREFIX'] = settings.URLPREFIX @@ -92,7 +93,7 @@ class Command(BaseCommand): # IF_EMAIL, # [IF_EMAIL], # fail_silently=False) - project.end_mail_send = False + project.end_mail_send = True project.mail_state = 'INF' try: project.save() @@ -149,8 +150,8 @@ class Command(BaseCommand): # IF_EMAIL, # [IF_EMAIL], # fail_silently=False) - - project.mail_state = 'END' + project.end_mail_send = True + project.mail_state = 'CLOSE' try: project.save() except: @@ -207,8 +208,8 @@ class Command(BaseCommand): # IF_EMAIL, # [IF_EMAIL], # fail_silently=False) - - project.mail_state = 'END' + project.end_mail_send = True + project.mail_state = 'CLOSE' project.save() except BadHeaderError: self.stdout.write(self.style.ERROR('Invalid header found.')) @@ -231,6 +232,7 @@ class Command(BaseCommand): name=myname, realname=item.realname) item.survey_mail_send = True + item.mail_state = 'END' item.survey_mail_date = date.today() item.save() self.stdout.write(self.style.SUCCESS(f'surveymails for object type {type} sent')) diff --git a/input/migrations/0096_auto_20230106_1338.py b/input/migrations/0096_auto_20230106_1338.py new file mode 100644 index 0000000..ecca5e3 --- /dev/null +++ b/input/migrations/0096_auto_20230106_1338.py @@ -0,0 +1,68 @@ +# Generated by Django 3.1.2 on 2023-01-06 13:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('input', '0095_auto_20221214_1207'), + ] + + operations = [ + migrations.AlterField( + model_name='businesscard', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='concreteextern', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='concretevolunteer', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='email', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='honorarycertificate', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='ifg', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='library', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='list', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='literature', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='project', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + migrations.AlterField( + model_name='travel', + name='mail_state', + field=models.CharField(choices=[('NONE', 'noch keine Mail versendet'), ('INF', 'die Benachrichtigung zur Projektabschlussmail wurde versendet'), ('CLOSE', 'die Projektabschlussmail wurde versendet'), ('END', 'alle automatischen Mails, auch surveyMail, wurden versendet')], default='NONE', max_length=6), + ), + ] diff --git a/input/models.py b/input/models.py index 2e70b41..6e0e58a 100755 --- a/input/models.py +++ b/input/models.py @@ -7,8 +7,9 @@ from .settings import ACCOUNTS EMAIL_STATES = {'NONE': 'noch keine Mail versendet', - 'INF': 'die Benachrichtigung End-Mail wurde bereits versendet', - 'END': 'alle automatischen Mails, auch surveyMail, wurden bereits versendet'} + 'INF': 'die Benachrichtigung zur Projektabschlussmail wurde versendet', + 'CLOSE': 'die Projektabschlussmail wurde versendet', + 'END': 'alle automatischen Mails, auch surveyMail, wurden versendet'} class Volunteer(models.Model): realname = models.CharField(max_length=200, null=True, verbose_name="Realname", From a72d9de3dd4610acbee8816d0b04895065835a8a Mon Sep 17 00:00:00 2001 From: corsaronero Date: Tue, 7 Feb 2023 14:02:58 +0000 Subject: [PATCH 56/57] bugfixFDB completed --- .gitignore | 1 + input/logfile | 34 ++++++++++++++++++++++++++++++ input/settings.py | 8 +++---- input/templates/input/if_mail.html | 23 ++++++++++++++++++++ input/templates/input/if_mail.txt | 22 +++++++++++++++++++ input/views.py | 8 ++++++- 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 input/logfile diff --git a/.gitignore b/.gitignore index 1139068..f041b72 100755 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /staticfiles # /foerderbarometer/settings.py /foerderbarometer/*settings* +/foerderbarometer/input/settings.py /nohup.out /logfile *~ diff --git a/input/logfile b/input/logfile new file mode 100644 index 0000000..5f53927 --- /dev/null +++ b/input/logfile @@ -0,0 +1,34 @@ +nohup: ignoring input +[2023-02-07 12:36:29 +0000] [2449] [INFO] Starting gunicorn 20.1.0 +[2023-02-07 12:36:29 +0000] [2449] [INFO] Listening at: http://0.0.0.0:8000 (2449) +[2023-02-07 12:36:29 +0000] [2449] [INFO] Using worker: sync +[2023-02-07 12:36:29 +0000] [2450] [INFO] Booting worker with pid: 2450 +[2023-02-07 12:36:29 +0000] [2450] [ERROR] Exception in worker process +Traceback (most recent call last): + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker + worker.init_process() + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 134, in init_process + self.load_wsgi() + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi + self.wsgi = self.app.wsgi() + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 67, in wsgi + self.callable = self.load() + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 58, in load + return self.load_wsgiapp() + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp + return util.import_app(self.app_uri) + File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/util.py", line 359, in import_app + mod = importlib.import_module(module) + File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + File "", line 1050, in _gcd_import + File "", line 1027, in _find_and_load + File "", line 992, in _find_and_load_unlocked + File "", line 241, in _call_with_frames_removed + File "", line 1050, in _gcd_import + File "", line 1027, in _find_and_load + File "", line 1004, in _find_and_load_unlocked +ModuleNotFoundError: No module named 'foerderbarometer' +[2023-02-07 12:36:29 +0000] [2450] [INFO] Worker exiting (pid: 2450) +[2023-02-07 12:36:29 +0000] [2449] [INFO] Shutting down: Master +[2023-02-07 12:36:29 +0000] [2449] [INFO] Reason: Worker failed to boot. diff --git a/input/settings.py b/input/settings.py index 3b43e9a..e1ba53e 100755 --- a/input/settings.py +++ b/input/settings.py @@ -1,9 +1,9 @@ # mail for IF-OTRS -IF_EMAIL = 'community@wikimedia.de' -#IF_EMAIL = 'test-luca-ext@wikimedia.de' +#IF_EMAIL = 'community@wikimedia.de' +IF_EMAIL = 'test-luca-ext@wikimedia.de' #SURVEY_EMAIL = 'christof.pins@wikimedia.de' -#SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' -SURVEY_EMAIL = 'sandro.halank@wikimedia.de' +SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' +#SURVEY_EMAIL = 'sandro.halank@wikimedia.de' # prefix for urls SURVEYPREFIX = 'https://wikimedia.sslsurvey.de/Foerderbarometer/?' diff --git a/input/templates/input/if_mail.html b/input/templates/input/if_mail.html index d130016..efd2941 100755 --- a/input/templates/input/if_mail.html +++ b/input/templates/input/if_mail.html @@ -25,6 +25,29 @@ Persönliche Daten: {{data.data}}
Variante: {{data.variant}}
Sendungsadrese: {{data.send_to}}
{% endif %}

+ +Zum Eintrag in der Förderdatenbank: +{% if data.choice == 'BIB' %} +{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{% elif data.choice == 'ELIT'%} +{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{% elif data.choice == 'LIT'%} +{{data.urlprefix}}/admin/input/literature/{{data.pk}}/change +{% elif data.choice == 'MAIL'%} +{{data.urlprefix}}/admin/input/email/{{data.pk}}/change +{% elif data.choice == 'IFG'%} +{{data.urlprefix}}/admin/input/ifg/{{data.pk}}/change +{% elif data.choice == 'LIST'%} +{{data.urlprefix}}/admin/input/list/{{data.pk}}/change +{% elif data.choice == 'TRAV'%} +{{data.urlprefix}}/admin/input/travel/{{data.pk}}/change +{% elif data.choice == 'SOFT'%} +{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{% elif data.choice == 'VIS'%} +{{data.urlprefix}}/admin/input/businesscard/{{data.pk}}/change +{% endif %} +

+ Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %}

Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %} diff --git a/input/templates/input/if_mail.txt b/input/templates/input/if_mail.txt index d3cfd04..4cb0375 100755 --- a/input/templates/input/if_mail.txt +++ b/input/templates/input/if_mail.txt @@ -23,6 +23,28 @@ Persönliche Daten: {{data.data}} Variante: {{data.variant}} Sendungsadrese: {{data.send_to}} {% endif %} +Zum Eintrag in der Förderdatenbank: +{% if data.choice == 'BIB' %} +{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{% elif data.choice == 'ELIT'%} +{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{% elif data.choice == 'LIT'%} +{{data.urlprefix}}/admin/input/literature/{{data.pk}}/change +{% elif data.choice == 'MAIL'%} +{{data.urlprefix}}/admin/input/email/{{data.pk}}/change +{% elif data.choice == 'IFG'%} +{{data.urlprefix}}/admin/input/ifg/{{data.pk}}/change +{% elif data.choice == 'LIST'%} +{{data.urlprefix}}/admin/input/list/{{data.pk}}/change +{% elif data.choice == 'TRAV'%} +{{data.urlprefix}}/admin/input/travel/{{data.pk}}/change +{% elif data.choice == 'SOFT'%} +{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{% elif data.choice == 'VIS'%} +{{data.urlprefix}}/admin/input/businesscard/{{data.pk}}/change +{% endif %} + + Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %} Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %} diff --git a/input/views.py b/input/views.py index 203de7a..8a3df6f 100755 --- a/input/views.py +++ b/input/views.py @@ -17,7 +17,7 @@ from django.utils.translation import gettext as _ from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\ HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ ListForm, BusinessCardForm, INTERN_CHOICES -from .models import Project, TYPE_CHOICES, Library, Literature, Travel +from .models import Project, TYPE_CHOICES, Library, Literature, Travel, IFG, BusinessCard, Email, List from .settings import IF_EMAIL def auth_deny(choice,pk,auth): @@ -29,6 +29,12 @@ def auth_deny(choice,pk,auth): IFG.set_granted(pk,auth) elif choice == 'TRAV': Travel.set_granted(pk,auth) + elif choice == 'VIS': + BusinessCard.set_granted(pk,auth) + elif choice == 'MAIL': + Email.set_granted(pk,auth) + elif choice == 'LIST': + List.set_granted(pk,auth) else: return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}') return False From 6ecc5e985fdc244b7945e445b34579d66106c834 Mon Sep 17 00:00:00 2001 From: corsaronero Date: Mon, 13 Feb 2023 14:59:44 +0000 Subject: [PATCH 57/57] removed wrongly generated logfile within input folder --- input/logfile | 34 ---------------------------------- input/settings.py | 8 ++++---- 2 files changed, 4 insertions(+), 38 deletions(-) delete mode 100644 input/logfile diff --git a/input/logfile b/input/logfile deleted file mode 100644 index 5f53927..0000000 --- a/input/logfile +++ /dev/null @@ -1,34 +0,0 @@ -nohup: ignoring input -[2023-02-07 12:36:29 +0000] [2449] [INFO] Starting gunicorn 20.1.0 -[2023-02-07 12:36:29 +0000] [2449] [INFO] Listening at: http://0.0.0.0:8000 (2449) -[2023-02-07 12:36:29 +0000] [2449] [INFO] Using worker: sync -[2023-02-07 12:36:29 +0000] [2450] [INFO] Booting worker with pid: 2450 -[2023-02-07 12:36:29 +0000] [2450] [ERROR] Exception in worker process -Traceback (most recent call last): - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker - worker.init_process() - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 134, in init_process - self.load_wsgi() - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi - self.wsgi = self.app.wsgi() - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/app/base.py", line 67, in wsgi - self.callable = self.load() - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 58, in load - return self.load_wsgiapp() - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp - return util.import_app(self.app_uri) - File "/home/alpcentaur/ProjektA/wikimedia/wmdeit_foerderbarometer/foerderbarometer/venv/lib/python3.10/site-packages/gunicorn/util.py", line 359, in import_app - mod = importlib.import_module(module) - File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module - return _bootstrap._gcd_import(name[level:], package, level) - File "", line 1050, in _gcd_import - File "", line 1027, in _find_and_load - File "", line 992, in _find_and_load_unlocked - File "", line 241, in _call_with_frames_removed - File "", line 1050, in _gcd_import - File "", line 1027, in _find_and_load - File "", line 1004, in _find_and_load_unlocked -ModuleNotFoundError: No module named 'foerderbarometer' -[2023-02-07 12:36:29 +0000] [2450] [INFO] Worker exiting (pid: 2450) -[2023-02-07 12:36:29 +0000] [2449] [INFO] Shutting down: Master -[2023-02-07 12:36:29 +0000] [2449] [INFO] Reason: Worker failed to boot. diff --git a/input/settings.py b/input/settings.py index e1ba53e..3b43e9a 100755 --- a/input/settings.py +++ b/input/settings.py @@ -1,9 +1,9 @@ # mail for IF-OTRS -#IF_EMAIL = 'community@wikimedia.de' -IF_EMAIL = 'test-luca-ext@wikimedia.de' +IF_EMAIL = 'community@wikimedia.de' +#IF_EMAIL = 'test-luca-ext@wikimedia.de' #SURVEY_EMAIL = 'christof.pins@wikimedia.de' -SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' -#SURVEY_EMAIL = 'sandro.halank@wikimedia.de' +#SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' +SURVEY_EMAIL = 'sandro.halank@wikimedia.de' # prefix for urls SURVEYPREFIX = 'https://wikimedia.sslsurvey.de/Foerderbarometer/?'