diff --git a/cypress/e2e/verification_request.cy.js b/cypress/e2e/verification_request.cy.js new file mode 100644 index 0000000..38e3255 --- /dev/null +++ b/cypress/e2e/verification_request.cy.js @@ -0,0 +1,33 @@ +describe("Verification request", () => { + it("lists", () => { + cy.login(); + cy.createAdminUnit().then(function (adminUnitId) { + cy.createIncomingVerificationRequest(adminUnitId).then(function ( + requestId + ) { + cy.visit( + "/manage/admin_unit/" + adminUnitId + "/verification_requests/incoming" + ); + cy.screenshot("incoming"); + }); + }); + }); + + it("creates", () => { + cy.login(); + cy.createAdminUnit().then(function (adminUnitId) { + cy.createAdminUnit("test@test.de", "Other Crew", false).then(function (otherAdminUnitId) { + cy.visit("/manage/admin_unit/" + otherAdminUnitId + "/verification_requests/outgoing/create/select"); + cy.screenshot("create-select"); + cy.get(".btn-primary:first").click(); + + cy.url().should("include", "/verification_requests/outgoing/create/target"); + cy.screenshot("create"); + cy.get("#submit").click(); + + cy.url().should("include", "/verification_requests/outgoing"); + cy.screenshot("outgoing"); + }); + }); + }); +}); diff --git a/cypress/e2e/verification_request_review.cy.js b/cypress/e2e/verification_request_review.cy.js new file mode 100644 index 0000000..354e2aa --- /dev/null +++ b/cypress/e2e/verification_request_review.cy.js @@ -0,0 +1,42 @@ +describe("Verification request review", () => { + it("reviews", () => { + cy.login(); + cy.createAdminUnit().then(function (adminUnitId) { + cy.createIncomingVerificationRequest(adminUnitId).then(function ( + requestId + ) { + // Status + cy.visit("/verification_request/" + requestId + "/review_status"); + cy.screenshot("status"); + + // Reject + cy.visit("/verification_request/" + requestId + "/review"); + cy.screenshot("review"); + cy.get(".decision-container .btn-danger").click(); + cy.get("#rejectFormModal select[name=rejection_reason]") + .select("Nicht relevant") + .should("have.value", "6"); + cy.get("#rejectFormModal").screenshot("reject"); + cy.get("#rejectFormModal .btn-danger").click(); + cy.url().should("include", "/verification_requests/incoming"); + cy.get("div.alert").should( + "contain", + "Verifizierungsanfrage erfolgreich aktualisiert" + ); + cy.get("main .badge-pill").should("contain", "Abgelehnt"); + + // Accept + cy.visit("/verification_request/" + requestId + "/review"); + cy.get(".decision-container .btn-success").click(); + cy.get("#auto_verify").parent().click(); + cy.get("#acceptFormModal").screenshot("accept"); + cy.get("#acceptFormModal .btn-success").click(); + cy.url().should("include", "/verification_requests/incoming"); + cy.get("div.alert").should( + "contain", + "Organisation erfolgreich verifiziert" + ); + }); + }); + }); +}); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 5079958..3ee85b1 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -32,9 +32,11 @@ Cypress.Commands.add( Cypress.Commands.add( "createAdminUnit", - (userEmail = "test@test.de", name = "Meine Crew") => { + (userEmail = "test@test.de", name = "Meine Crew", verified = true) => { + let cmd = "flask test admin-unit-create " + userEmail + ' "' + name + '"'; + cmd += (verified) ? " --verified" : " --no-verified"; return cy - .logexec("flask test admin-unit-create " + userEmail + ' "' + name + '"') + .logexec(cmd) .then(function (result) { let json = JSON.parse(result.stdout); return json.admin_unit_id; @@ -114,6 +116,15 @@ Cypress.Commands.add("createOauth2Client", (userId) => { }); }); +Cypress.Commands.add("createIncomingVerificationRequest", (adminUnitId) => { + return cy + .logexec("flask test verification-request-create-incoming " + adminUnitId) + .then(function (result) { + let json = JSON.parse(result.stdout); + return json.verification_request_id; + }); +}); + Cypress.Commands.add("createIncomingReferenceRequest", (adminUnitId) => { return cy .logexec("flask test reference-request-create-incoming " + adminUnitId) diff --git a/messages.pot b/messages.pot index 869d8c6..090e51f 100644 --- a/messages.pot +++ b/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-05-30 14:22+0200\n" +"POT-Creation-Date: 2023-06-02 12:16+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -202,24 +202,24 @@ msgstr "" msgid "You have received an invitation" msgstr "" -#: project/forms/admin.py:11 project/templates/layout.html:315 +#: project/forms/admin.py:11 project/templates/layout.html:334 #: project/views/root.py:55 msgid "Terms of service" msgstr "" -#: project/forms/admin.py:12 project/templates/layout.html:320 +#: project/forms/admin.py:12 project/templates/layout.html:339 #: project/views/root.py:67 msgid "Legal notice" msgstr "" -#: project/forms/admin.py:13 project/templates/_macros.html:1441 -#: project/templates/layout.html:324 +#: project/forms/admin.py:13 project/templates/_macros.html:1461 +#: project/templates/layout.html:343 #: project/templates/widget/event_suggestion/create.html:204 #: project/views/admin_unit.py:83 project/views/root.py:75 msgid "Contact" msgstr "" -#: project/forms/admin.py:14 project/templates/layout.html:328 +#: project/forms/admin.py:14 project/templates/layout.html:347 #: project/views/root.py:83 msgid "Privacy" msgstr "" @@ -255,12 +255,12 @@ msgstr "" msgid "Delete user" msgstr "" -#: project/forms/admin.py:34 project/forms/admin_unit.py:53 +#: project/forms/admin.py:34 project/forms/admin_unit.py:60 #: project/forms/admin_unit_member.py:12 project/forms/admin_unit_member.py:25 #: project/forms/admin_unit_member.py:30 project/forms/event.py:107 #: project/forms/event_suggestion.py:38 project/forms/organizer.py:33 #: project/forms/user.py:18 project/forms/user.py:23 -#: project/templates/_macros.html:237 project/templates/_macros.html:1537 +#: project/templates/_macros.html:246 project/templates/_macros.html:1557 #: project/templates/admin/admin.html:27 project/templates/admin/email.html:4 #: project/templates/admin/email.html:66 project/templates/admin/users.html:19 #: project/templates/manage/organizers.html:21 @@ -316,17 +316,18 @@ msgstr "" #: project/forms/admin.py:75 project/templates/admin/delete_admin_unit.html:6 #: project/templates/admin_unit/request_deletion.html:6 -#: project/templates/admin_unit/update.html:93 +#: project/templates/admin_unit/update.html:94 msgid "Delete organization" msgstr "" -#: project/forms/admin.py:76 project/forms/admin_unit.py:34 -#: project/forms/admin_unit.py:142 project/forms/admin_unit.py:147 -#: project/forms/admin_unit.py:152 project/forms/event.py:85 -#: project/forms/event.py:114 project/forms/event_place.py:30 -#: project/forms/event_place.py:56 project/forms/event_suggestion.py:26 -#: project/forms/oauth2_client.py:66 project/forms/organizer.py:30 -#: project/forms/organizer.py:58 project/forms/reference_request.py:23 +#: project/forms/admin.py:76 project/forms/admin_unit.py:149 +#: project/forms/admin_unit.py:154 project/forms/admin_unit.py:159 +#: project/forms/event.py:85 project/forms/event.py:114 +#: project/forms/event_place.py:30 project/forms/event_place.py:56 +#: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 +#: project/forms/organizer.py:30 project/forms/organizer.py:58 +#: project/forms/reference_request.py:23 +#: project/forms/verification_request.py:19 #: project/templates/admin/admin_units.html:19 #: project/templates/event_place/list.html:19 #: project/templates/manage/organizers.html:18 @@ -365,7 +366,7 @@ msgid "Street" msgstr "" #: project/forms/admin_unit.py:18 project/forms/event.py:453 -#: project/forms/event_date.py:56 project/forms/event_place.py:16 +#: project/forms/event_date.py:52 project/forms/event_place.py:16 #: project/forms/organizer.py:16 msgid "Postal code" msgstr "" @@ -390,109 +391,127 @@ msgstr "" msgid "Longitude" msgstr "" -#: project/forms/admin_unit.py:37 -msgid "Short name" +#: project/forms/admin_unit.py:34 +msgid "Name of organization" msgstr "" -#: project/forms/admin_unit.py:38 +#: project/forms/admin_unit.py:35 +msgid "The full name of the organization" +msgstr "" + +#: project/forms/admin_unit.py:39 +msgid "Short name for organization" +msgstr "" + +#: project/forms/admin_unit.py:40 msgid "The short name is used to create a unique identifier for your events" msgstr "" -#: project/forms/admin_unit.py:46 project/templates/_macros.html:1579 +#: project/forms/admin_unit.py:48 project/templates/_macros.html:1599 msgid "Short name must contain only letters numbers or underscore" msgstr "" -#: project/forms/admin_unit.py:52 project/forms/event.py:106 +#: project/forms/admin_unit.py:55 project/forms/event.py:119 +#: project/forms/event_place.py:34 +msgid "Description" +msgstr "" + +#: project/forms/admin_unit.py:56 +msgid "Describe the organization in a few words" +msgstr "" + +#: project/forms/admin_unit.py:59 project/forms/event.py:106 #: project/forms/event.py:124 project/forms/event_place.py:32 #: project/forms/organizer.py:32 project/templates/manage/organizers.html:21 msgid "Link URL" msgstr "" -#: project/forms/admin_unit.py:54 project/forms/event.py:108 +#: project/forms/admin_unit.py:61 project/forms/event.py:108 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:34 -#: project/templates/_macros.html:290 +#: project/templates/_macros.html:305 #: project/templates/manage/organizers.html:20 msgid "Phone" msgstr "" -#: project/forms/admin_unit.py:55 project/forms/event.py:109 -#: project/forms/organizer.py:35 project/templates/_macros.html:298 +#: project/forms/admin_unit.py:62 project/forms/event.py:109 +#: project/forms/organizer.py:35 project/templates/_macros.html:313 msgid "Fax" msgstr "" -#: project/forms/admin_unit.py:56 project/forms/organizer.py:36 +#: project/forms/admin_unit.py:63 project/forms/organizer.py:36 #: project/templates/manage/organizers.html:22 #: project/templates/manage/organizers.html:47 msgid "Logo" msgstr "" -#: project/forms/admin_unit.py:60 +#: project/forms/admin_unit.py:67 msgid "Allow verification requests" msgstr "" -#: project/forms/admin_unit.py:61 +#: project/forms/admin_unit.py:68 msgid "If set, unverified organizations may ask you for verification." msgstr "" -#: project/forms/admin_unit.py:67 +#: project/forms/admin_unit.py:74 msgid "Verification requests information" msgstr "" -#: project/forms/admin_unit.py:69 +#: project/forms/admin_unit.py:76 msgid "" "This text is shown to unverified organizations to help them decide " "whether they ask you for verification." msgstr "" -#: project/forms/admin_unit.py:85 +#: project/forms/admin_unit.py:92 msgid "Verify new organization" msgstr "" -#: project/forms/admin_unit.py:86 +#: project/forms/admin_unit.py:93 msgid "If set, events of the new organization are publicly visible." msgstr "" -#: project/forms/admin_unit.py:92 project/forms/reference_request.py:86 +#: project/forms/admin_unit.py:99 project/forms/reference_request.py:86 +#: project/forms/verification_request.py:86 msgid "Verify reference requests automatically" msgstr "" -#: project/forms/admin_unit.py:93 +#: project/forms/admin_unit.py:100 msgid "" "If set, all upcoming reference requests of the new organization are " "verified automatically." msgstr "" -#: project/forms/admin_unit.py:104 project/templates/admin_unit/create.html:5 +#: project/forms/admin_unit.py:111 project/templates/admin_unit/create.html:5 #: project/templates/admin_unit/create.html:22 #: project/templates/manage/admin_units.html:32 msgid "Create organization" msgstr "" -#: project/forms/admin_unit.py:112 project/forms/admin_unit.py:137 +#: project/forms/admin_unit.py:119 project/forms/admin_unit.py:144 msgid "Update settings" msgstr "" -#: project/forms/admin_unit.py:117 +#: project/forms/admin_unit.py:124 msgid "Font" msgstr "" -#: project/forms/admin_unit.py:120 +#: project/forms/admin_unit.py:127 msgid "Background Color" msgstr "" -#: project/forms/admin_unit.py:126 +#: project/forms/admin_unit.py:133 msgid "Primary Color" msgstr "" -#: project/forms/admin_unit.py:132 +#: project/forms/admin_unit.py:139 msgid "Link Color" msgstr "" -#: project/forms/admin_unit.py:141 project/forms/user.py:17 +#: project/forms/admin_unit.py:148 project/forms/user.py:17 msgid "Request deletion" msgstr "" -#: project/forms/admin_unit.py:146 project/forms/user.py:22 +#: project/forms/admin_unit.py:153 project/forms/user.py:22 #: project/templates/admin_unit/cancel_deletion.html:6 #: project/templates/admin_unit/update.html:26 #: project/templates/manage/events.html:49 project/templates/profile.html:13 @@ -500,7 +519,7 @@ msgstr "" msgid "Cancel deletion" msgstr "" -#: project/forms/admin_unit.py:151 project/templates/layout.html:286 +#: project/forms/admin_unit.py:158 project/templates/layout.html:305 #: project/templates/manage/delete_membership.html:6 msgid "Leave organization" msgstr "" @@ -638,16 +657,16 @@ msgstr "" msgid "All-day" msgstr "" -#: project/forms/event.py:54 project/templates/_macros.html:1749 +#: project/forms/event.py:54 project/templates/_macros.html:1769 #: project/templates/widget/event_suggestion/create.html:240 msgid "Recurring event" msgstr "" -#: project/forms/event.py:61 project/templates/_macros.html:1298 +#: project/forms/event.py:61 project/templates/_macros.html:1318 msgid "The start must be before the end." msgstr "" -#: project/forms/event.py:67 project/templates/_macros.html:1315 +#: project/forms/event.py:67 project/templates/_macros.html:1335 msgid "An event can last a maximum of 14 days." msgstr "" @@ -659,10 +678,6 @@ msgstr "" msgid "Enter a short, meaningful name for the event." msgstr "" -#: project/forms/event.py:119 project/forms/event_place.py:34 -msgid "Description" -msgstr "" - #: project/forms/event.py:121 msgid "Add an description of the event." msgstr "" @@ -681,7 +696,7 @@ msgstr "" msgid "Enter a link where tickets can be purchased." msgstr "" -#: project/forms/event.py:136 project/templates/_macros.html:219 +#: project/forms/event.py:136 project/templates/_macros.html:228 msgid "Tags" msgstr "" @@ -731,7 +746,7 @@ msgstr "" msgid "If the participants needs to register for the event." msgstr "" -#: project/forms/event.py:170 project/templates/_macros.html:251 +#: project/forms/event.py:170 project/templates/_macros.html:260 #: project/templates/layout.html:115 msgid "Booked up" msgstr "" @@ -815,8 +830,8 @@ msgid "" " course it works without it." msgstr "" -#: project/forms/event.py:242 project/templates/_macros.html:398 -#: project/templates/_macros.html:561 +#: project/forms/event.py:242 project/templates/_macros.html:418 +#: project/templates/_macros.html:581 msgid "Previous start date" msgstr "" @@ -862,8 +877,8 @@ msgstr "" #: project/forms/event.py:286 project/forms/event.py:295 #: project/forms/event.py:368 project/forms/event.py:442 -#: project/forms/event_suggestion.py:50 project/templates/_macros.html:438 -#: project/templates/_macros.html:604 project/templates/event/create.html:288 +#: project/forms/event_suggestion.py:50 project/templates/_macros.html:458 +#: project/templates/_macros.html:624 project/templates/event/create.html:288 #: project/templates/event/update.html:170 #: project/templates/event_place/create.html:31 #: project/templates/event_place/delete.html:13 @@ -882,8 +897,8 @@ msgstr "" #: project/forms/event.py:302 project/forms/event.py:311 #: project/forms/event.py:376 project/forms/event.py:439 -#: project/forms/event_date.py:44 project/forms/event_suggestion.py:60 -#: project/templates/_macros.html:475 project/templates/_macros.html:647 +#: project/forms/event_date.py:40 project/forms/event_suggestion.py:60 +#: project/templates/_macros.html:495 project/templates/_macros.html:667 #: project/templates/event/create.html:257 #: project/templates/event/update.html:160 #: project/templates/manage/events.html:104 @@ -970,7 +985,7 @@ msgstr "" msgid "PublicStatus.published" msgstr "" -#: project/forms/event.py:402 project/templates/_macros.html:257 +#: project/forms/event.py:402 project/templates/_macros.html:266 msgid "PublicStatus.draft" msgstr "" @@ -983,35 +998,35 @@ msgstr "" msgid "Update event" msgstr "" -#: project/forms/event.py:423 project/templates/_macros.html:1255 +#: project/forms/event.py:423 project/templates/_macros.html:1275 #: project/templates/event/actions.html:66 #: project/templates/event/delete.html:6 msgid "Delete event" msgstr "" -#: project/forms/event.py:430 project/forms/event_date.py:15 +#: project/forms/event.py:430 project/forms/event_date.py:14 #: project/forms/planing.py:14 msgid "From" msgstr "" -#: project/forms/event.py:432 project/forms/event_date.py:17 +#: project/forms/event.py:432 project/forms/event_date.py:16 #: project/forms/planing.py:16 msgid "to" msgstr "" -#: project/forms/event.py:434 project/forms/event_date.py:19 +#: project/forms/event.py:434 project/forms/event_date.py:18 msgid "Keyword" msgstr "" -#: project/forms/event.py:436 project/forms/event_date.py:21 -#: project/forms/planing.py:19 project/templates/_macros.html:371 +#: project/forms/event.py:436 project/forms/event_date.py:20 +#: project/forms/planing.py:19 project/templates/_macros.html:391 msgid "Category" msgstr "" -#: project/forms/event.py:446 project/forms/event_date.py:30 -#: project/forms/planing.py:22 project/templates/_macros.html:305 -#: project/templates/admin_unit/create.html:38 -#: project/templates/admin_unit/update.html:46 +#: project/forms/event.py:446 project/forms/event_date.py:26 +#: project/forms/planing.py:22 project/templates/_macros.html:320 +#: project/templates/admin_unit/create.html:39 +#: project/templates/admin_unit/update.html:47 #: project/templates/event_place/create.html:40 #: project/templates/event_place/update.html:40 #: project/templates/manage/organizers.html:19 @@ -1021,22 +1036,22 @@ msgstr "" msgid "Location" msgstr "" -#: project/forms/event.py:448 project/forms/event_date.py:32 +#: project/forms/event.py:448 project/forms/event_date.py:28 #: project/forms/planing.py:24 msgid "Distance" msgstr "" -#: project/forms/event.py:455 project/forms/event_date.py:53 +#: project/forms/event.py:455 project/forms/event_date.py:49 msgid "Exclude recurring events" msgstr "" -#: project/forms/event.py:459 project/forms/event_date.py:58 +#: project/forms/event.py:459 project/forms/event_date.py:54 msgid "Find events" msgstr "" -#: project/forms/event_date.py:39 project/forms/reference.py:11 -#: project/forms/reference_request.py:16 project/templates/_macros.html:491 -#: project/templates/_macros.html:664 +#: project/forms/event_date.py:35 project/forms/reference.py:11 +#: project/forms/reference_request.py:16 project/templates/_macros.html:511 +#: project/templates/_macros.html:684 #: project/templates/admin/delete_admin_unit.html:13 #: project/templates/admin_unit/cancel_deletion.html:13 #: project/templates/admin_unit/create.html:28 @@ -1044,14 +1059,16 @@ msgstr "" #: project/templates/admin_unit/update.html:36 #: project/templates/layout.html:257 #: project/templates/manage/delete_membership.html:13 +#: project/templates/verification_request/delete.html:13 +#: project/templates/verification_request/review.html:28 msgid "Organization" msgstr "" -#: project/forms/event_date.py:49 +#: project/forms/event_date.py:45 msgid "Show unreferenced events only" msgstr "" -#: project/forms/event_date.py:67 project/forms/planing.py:36 +#: project/forms/event_date.py:63 project/forms/planing.py:36 #: project/templates/widget/event_date/list.html:82 msgid "Find" msgstr "" @@ -1111,6 +1128,7 @@ msgid "Create event suggestion" msgstr "" #: project/forms/event_suggestion.py:124 project/forms/reference_request.py:48 +#: project/forms/verification_request.py:44 msgid "Rejection reason" msgstr "" @@ -1198,12 +1216,17 @@ msgid "Save request" msgstr "" #: project/forms/reference_request.py:22 +#: project/forms/verification_request.py:18 +#: project/templates/manage/verification_requests_outgoing.html:24 msgid "Delete request" msgstr "" -#: project/forms/reference_request.py:28 project/templates/_macros.html:1453 +#: project/forms/reference_request.py:28 +#: project/forms/verification_request.py:24 project/templates/_macros.html:1473 #: project/templates/event_suggestion/review_status.html:18 #: project/templates/reference_request/review_status.html:12 +#: project/templates/verification_request/review_status.html:4 +#: project/templates/verification_request/review_status.html:12 msgid "Review status" msgstr "" @@ -1220,6 +1243,7 @@ msgid "EventReferenceRequestReviewStatus.rejected" msgstr "" #: project/forms/reference_request.py:44 +#: project/forms/verification_request.py:40 msgid "Choose the result of your review." msgstr "" @@ -1244,10 +1268,12 @@ msgid "EventReferenceRequestRejectionReason.illegal" msgstr "" #: project/forms/reference_request.py:72 +#: project/forms/verification_request.py:82 msgid "Choose why you rejected the request." msgstr "" #: project/forms/reference_request.py:90 +#: project/forms/verification_request.py:90 msgid "Save review" msgstr "" @@ -1281,6 +1307,52 @@ msgstr "" msgid "Information about new features and improvements." msgstr "" +#: project/forms/verification_request.py:14 +#: project/templates/manage/verification_requests_outgoing.html:11 +#: project/templates/manage/verification_requests_outgoing_create_select.html:37 +msgid "Request verification" +msgstr "" + +#: project/forms/verification_request.py:29 +msgid "AdminUnitVerificationRequestReviewStatus.inbox" +msgstr "" + +#: project/forms/verification_request.py:33 +msgid "AdminUnitVerificationRequestReviewStatus.verified" +msgstr "" + +#: project/forms/verification_request.py:37 +msgid "AdminUnitVerificationRequestReviewStatus.rejected" +msgstr "" + +#: project/forms/verification_request.py:49 +msgid "AdminUnitVerificationRequestRejectionReason.noreason" +msgstr "" + +#: project/forms/verification_request.py:53 +msgid "AdminUnitVerificationRequestRejectionReason.notresponsible" +msgstr "" + +#: project/forms/verification_request.py:59 +msgid "AdminUnitVerificationRequestRejectionReason.missinginformation" +msgstr "" + +#: project/forms/verification_request.py:65 +msgid "AdminUnitVerificationRequestRejectionReason.unknown" +msgstr "" + +#: project/forms/verification_request.py:69 +msgid "AdminUnitVerificationRequestRejectionReason.untrustworthy" +msgstr "" + +#: project/forms/verification_request.py:75 +msgid "AdminUnitVerificationRequestRejectionReason.illegal" +msgstr "" + +#: project/forms/verification_request.py:79 +msgid "AdminUnitVerificationRequestRejectionReason.irrelevant" +msgstr "" + #: project/forms/widgets.py:155 msgid "This field is required." msgstr "" @@ -1289,35 +1361,35 @@ msgstr "" msgid "Show on Google Maps" msgstr "" -#: project/templates/_macros.html:228 +#: project/templates/_macros.html:237 msgid "Link" msgstr "" -#: project/templates/_macros.html:284 +#: project/templates/_macros.html:299 msgid "Verified" msgstr "" -#: project/templates/_macros.html:348 +#: project/templates/_macros.html:368 #, python-format msgid "Created at %(created_at)s by %(created_by)s." msgstr "" -#: project/templates/_macros.html:350 +#: project/templates/_macros.html:370 #, python-format msgid "Created at %(created_at)s." msgstr "" -#: project/templates/_macros.html:355 +#: project/templates/_macros.html:375 #, python-format msgid "Last updated at %(updated_at)s by %(updated_by)s." msgstr "" -#: project/templates/_macros.html:357 +#: project/templates/_macros.html:377 #, python-format msgid "Last updated at %(updated_at)s." msgstr "" -#: project/templates/_macros.html:387 project/templates/_macros.html:557 +#: project/templates/_macros.html:407 project/templates/_macros.html:577 #: project/templates/event/actions.html:25 #: project/templates/event/create.html:234 #: project/templates/event/update.html:126 @@ -1326,44 +1398,44 @@ msgstr "" msgid "Event" msgstr "" -#: project/templates/_macros.html:393 project/templates/_macros.html:979 +#: project/templates/_macros.html:413 project/templates/_macros.html:999 msgid "Date" msgstr "" -#: project/templates/_macros.html:420 project/templates/_macros.html:579 -#: project/templates/_macros.html:1522 project/templates/event/actions.html:51 +#: project/templates/_macros.html:440 project/templates/_macros.html:599 +#: project/templates/_macros.html:1542 project/templates/event/actions.html:51 msgid "Share" msgstr "" -#: project/templates/_macros.html:424 project/templates/_macros.html:583 -#: project/templates/_macros.html:1552 +#: project/templates/_macros.html:444 project/templates/_macros.html:603 +#: project/templates/_macros.html:1572 msgid "Add to calendar" msgstr "" -#: project/templates/_macros.html:432 project/templates/_macros.html:597 +#: project/templates/_macros.html:452 project/templates/_macros.html:617 #: project/templates/event/report.html:4 msgid "Report event" msgstr "" -#: project/templates/_macros.html:459 project/templates/_macros.html:630 +#: project/templates/_macros.html:479 project/templates/_macros.html:650 msgid "Show directions" msgstr "" -#: project/templates/_macros.html:464 project/templates/_macros.html:622 +#: project/templates/_macros.html:484 project/templates/_macros.html:642 msgid "The event takes place online." msgstr "" -#: project/templates/_macros.html:466 project/templates/_macros.html:624 +#: project/templates/_macros.html:486 project/templates/_macros.html:644 msgid "The event takes place both offline and online." msgstr "" -#: project/templates/_macros.html:587 project/templates/layout.html:183 +#: project/templates/_macros.html:607 project/templates/layout.html:183 #: project/templates/user/favorite_events.html:4 msgid "Favorite events" msgstr "" -#: project/templates/_macros.html:590 project/templates/_macros.html:633 -#: project/templates/_macros.html:765 +#: project/templates/_macros.html:610 project/templates/_macros.html:653 +#: project/templates/_macros.html:785 #: project/templates/admin/admin_units.html:36 #: project/templates/admin/users.html:36 #: project/templates/manage/events.html:118 @@ -1376,11 +1448,11 @@ msgstr "" msgid "Edit" msgstr "" -#: project/templates/_macros.html:691 +#: project/templates/_macros.html:711 msgid "Referenced by" msgstr "" -#: project/templates/_macros.html:703 project/templates/_macros.html:1265 +#: project/templates/_macros.html:723 project/templates/_macros.html:1285 #: project/templates/event/actions.html:38 #: project/templates/event_date/list.html:251 #: project/templates/manage/events.html:125 @@ -1388,39 +1460,39 @@ msgstr "" msgid "Reference event" msgstr "" -#: project/templates/_macros.html:712 +#: project/templates/_macros.html:732 #: project/templates/manage/reference_requests_incoming.html:5 #: project/templates/manage/reference_requests_outgoing.html:5 msgid "Reference requests" msgstr "" -#: project/templates/_macros.html:723 project/templates/_macros.html:1262 +#: project/templates/_macros.html:743 project/templates/_macros.html:1282 #: project/templates/event/actions.html:32 #: project/templates/manage/events.html:123 msgid "Request reference" msgstr "" -#: project/templates/_macros.html:731 project/templates/event_date/list.html:6 +#: project/templates/_macros.html:751 project/templates/event_date/list.html:6 #: project/templates/event_date/list.html:461 #: project/templates/reference_request/review.html:32 msgid "Event Dates" msgstr "" -#: project/templates/_macros.html:829 +#: project/templates/_macros.html:849 msgid "Search location on Google" msgstr "" -#: project/templates/_macros.html:896 +#: project/templates/_macros.html:916 #, python-format msgid "%(count)d event dates" msgstr "" -#: project/templates/_macros.html:919 project/templates/_macros.html:921 +#: project/templates/_macros.html:939 project/templates/_macros.html:941 #: project/templates/event_date/list.html:510 msgid "First" msgstr "" -#: project/templates/_macros.html:924 project/templates/_macros.html:926 +#: project/templates/_macros.html:944 project/templates/_macros.html:946 #: project/templates/event_date/list.html:511 #: project/templates/widget/event_suggestion/create.html:193 #: project/templates/widget/event_suggestion/create.html:218 @@ -1431,12 +1503,12 @@ msgstr "" msgid "Previous" msgstr "" -#: project/templates/_macros.html:928 +#: project/templates/_macros.html:948 #, python-format msgid "Page %(page)d of %(pages)d (%(total)d total)" msgstr "" -#: project/templates/_macros.html:930 project/templates/_macros.html:932 +#: project/templates/_macros.html:950 project/templates/_macros.html:952 #: project/templates/event_date/list.html:513 #: project/templates/widget/event_suggestion/create.html:194 #: project/templates/widget/event_suggestion/create.html:219 @@ -1446,98 +1518,98 @@ msgstr "" msgid "Next" msgstr "" -#: project/templates/_macros.html:935 project/templates/_macros.html:937 +#: project/templates/_macros.html:955 project/templates/_macros.html:957 #: project/templates/event_date/list.html:514 msgid "Last" msgstr "" -#: project/templates/_macros.html:1002 +#: project/templates/_macros.html:1022 msgid "Radius" msgstr "" -#: project/templates/_macros.html:1184 +#: project/templates/_macros.html:1204 msgid "Edit image" msgstr "" -#: project/templates/_macros.html:1205 +#: project/templates/_macros.html:1225 msgid "Close" msgstr "" -#: project/templates/_macros.html:1206 +#: project/templates/_macros.html:1226 msgid "Okay" msgstr "" -#: project/templates/_macros.html:1218 +#: project/templates/_macros.html:1238 msgid "Choose image file" msgstr "" -#: project/templates/_macros.html:1254 project/templates/event/actions.html:65 +#: project/templates/_macros.html:1274 project/templates/event/actions.html:65 #: project/templates/event/delete.html:12 msgid "Edit event" msgstr "" -#: project/templates/_macros.html:1258 project/templates/event/actions.html:58 +#: project/templates/_macros.html:1278 project/templates/event/actions.html:58 msgid "Duplicate event" msgstr "" -#: project/templates/_macros.html:1269 project/templates/event/actions.html:44 +#: project/templates/_macros.html:1289 project/templates/event/actions.html:44 #: project/templates/manage/events.html:129 msgid "Add to list" msgstr "" -#: project/templates/_macros.html:1272 project/templates/manage/events.html:132 +#: project/templates/_macros.html:1292 project/templates/manage/events.html:132 msgid "More" msgstr "" -#: project/templates/_macros.html:1319 +#: project/templates/_macros.html:1339 msgid "Please enter a valid time, between 00:00 and 23:59." msgstr "" -#: project/templates/_macros.html:1347 +#: project/templates/_macros.html:1367 #, python-format msgid "Just use %(term)s" msgstr "" -#: project/templates/_macros.html:1413 +#: project/templates/_macros.html:1433 msgid "Event suggestion" msgstr "" -#: project/templates/_macros.html:1531 +#: project/templates/_macros.html:1551 msgid "Link copied" msgstr "" -#: project/templates/_macros.html:1531 +#: project/templates/_macros.html:1551 msgid "Copy link" msgstr "" -#: project/templates/_macros.html:1561 +#: project/templates/_macros.html:1581 msgid "Google calendar" msgstr "" -#: project/templates/_macros.html:1563 +#: project/templates/_macros.html:1583 msgid "Apple calendar" msgstr "" -#: project/templates/_macros.html:1564 +#: project/templates/_macros.html:1584 msgid "Yahoo calendar" msgstr "" -#: project/templates/_macros.html:1565 +#: project/templates/_macros.html:1585 msgid "Other calendar" msgstr "" -#: project/templates/_macros.html:1750 +#: project/templates/_macros.html:1770 msgid "Remove event date" msgstr "" -#: project/templates/_macros.html:1783 project/templates/event/create.html:180 +#: project/templates/_macros.html:1803 project/templates/event/create.html:180 #: project/templates/event/update.html:103 #: project/templates/event_date/list.html:446 #: project/templates/widget/event_suggestion/create.html:129 msgid "Enter organizer" msgstr "" -#: project/templates/_macros.html:1811 +#: project/templates/_macros.html:1831 msgid "Enter list name" msgstr "" @@ -1548,6 +1620,7 @@ msgstr "" #: project/templates/home.html:37 project/templates/layout.html:173 #: project/templates/manage/admin_units.html:28 #: project/templates/manage/verification_requests_outgoing.html:13 +#: project/templates/manage/verification_requests_outgoing_create_select.html:13 #: project/templates/security/login_user.html:21 #: project/templates/security/register_user.html:43 msgid "Docs" @@ -1578,7 +1651,7 @@ msgstr "" msgid "Planing" msgstr "" -#: project/templates/layout.html:182 project/templates/layout.html:275 +#: project/templates/layout.html:182 project/templates/layout.html:294 #: project/templates/oauth2_client/list.html:10 #: project/templates/oauth2_client/read.html:10 #: project/templates/oauth2_token/list.html:10 project/templates/profile.html:4 @@ -1649,29 +1722,42 @@ msgstr "" msgid "Outgoing reference requests" msgstr "" -#: project/templates/layout.html:260 project/templates/manage/organizers.html:5 +#: project/templates/layout.html:264 +#: project/templates/manage/verification_requests_outgoing.html:5 +#: project/templates/manage/verification_requests_outgoing.html:10 +msgid "Outgoing verification requests" +msgstr "" + +#: project/templates/layout.html:268 project/templates/manage/organizers.html:5 #: project/templates/manage/organizers.html:10 #: project/templates/organizer/main.html:4 msgid "Organizers" msgstr "" #: project/templates/event_place/list.html:3 -#: project/templates/event_place/list.html:7 project/templates/layout.html:261 +#: project/templates/event_place/list.html:7 project/templates/layout.html:269 #: project/templates/manage/places.html:5 #: project/templates/manage/places.html:10 msgid "Places" msgstr "" -#: project/templates/layout.html:263 project/templates/manage/members.html:5 +#: project/templates/layout.html:271 project/templates/manage/members.html:5 #: project/templates/manage/members.html:28 +#: project/templates/verification_request/review.html:54 msgid "Members" msgstr "" -#: project/templates/layout.html:264 project/templates/manage/relations.html:4 +#: project/templates/layout.html:272 project/templates/manage/relations.html:4 msgid "Relations" msgstr "" -#: project/templates/layout.html:266 +#: project/templates/layout.html:276 +#: project/templates/manage/verification_requests_incoming.html:5 +#: project/templates/manage/verification_requests_incoming.html:9 +msgid "Incoming verification requests" +msgstr "" + +#: project/templates/layout.html:284 #: project/templates/manage/admin_units.html:17 #: project/templates/manage/organization_invitations.html:4 #: project/templates/user/organization_invitations.html:4 @@ -1683,33 +1769,33 @@ msgstr "" #: project/templates/admin/settings.html:11 #: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:30 -#: project/templates/layout.html:269 project/templates/manage/widgets.html:11 +#: project/templates/layout.html:288 project/templates/manage/widgets.html:11 #: project/templates/manage/widgets.html:15 project/templates/profile.html:32 msgid "Settings" msgstr "" -#: project/templates/layout.html:270 project/templates/manage/export.html:3 +#: project/templates/layout.html:289 project/templates/manage/export.html:3 #: project/templates/manage/export.html:63 msgid "Export" msgstr "" -#: project/templates/layout.html:272 +#: project/templates/layout.html:291 #: project/templates/manage/custom_widgets.html:13 msgid "Custom widgets" msgstr "" -#: project/templates/layout.html:273 project/templates/manage/reviews.html:10 +#: project/templates/layout.html:292 project/templates/manage/reviews.html:10 #: project/templates/manage/widgets.html:5 #: project/templates/manage/widgets.html:9 msgid "Widgets" msgstr "" -#: project/templates/layout.html:285 +#: project/templates/layout.html:304 msgid "Switch organization" msgstr "" #: project/templates/developer/read.html:4 -#: project/templates/developer/read.html:8 project/templates/layout.html:332 +#: project/templates/developer/read.html:8 project/templates/layout.html:351 #: project/templates/profile.html:45 msgid "Developer" msgstr "" @@ -1795,8 +1881,8 @@ msgstr "" msgid "Reset acceptance of terms of service and privacy" msgstr "" -#: project/templates/admin_unit/create.html:58 -#: project/templates/admin_unit/update.html:66 +#: project/templates/admin_unit/create.html:59 +#: project/templates/admin_unit/update.html:67 #: project/templates/event/create.html:351 #: project/templates/event/update.html:208 #: project/templates/event_place/create.html:57 @@ -1806,7 +1892,7 @@ msgstr "" msgid "Additional information" msgstr "" -#: project/templates/admin_unit/create.html:71 +#: project/templates/admin_unit/create.html:72 #, python-format msgid "Relation to %(admin_unit_name)s" msgstr "" @@ -1827,9 +1913,9 @@ msgstr "" msgid "The organization is scheduled for deletion." msgstr "" -#: project/templates/admin_unit/update.html:79 -#: project/templates/manage/verification_requests_outgoing.html:6 -#: project/templates/manage/verification_requests_outgoing.html:11 +#: project/templates/admin_unit/update.html:80 +#: project/templates/manage/verification_requests_outgoing_create_select.html:6 +#: project/templates/manage/verification_requests_outgoing_create_select.html:11 msgid "Verification requests" msgstr "" @@ -1950,10 +2036,12 @@ msgid "There is a new event reference request that needs to be reviewed." msgstr "" #: project/templates/email/reference_request_notice.html:5 +#: project/templates/email/verification_request_notice.html:5 msgid "Click here to review the request" msgstr "" #: project/templates/email/reference_request_notice.txt:2 +#: project/templates/email/verification_request_notice.txt:2 msgid "Click the link below to review the request" msgstr "" @@ -1964,11 +2052,13 @@ msgstr "" #: project/templates/email/reference_request_review_status_notice.html:5 #: project/templates/email/review_status_notice.html:5 +#: project/templates/email/verification_request_review_status_notice.html:5 msgid "Click here to view the status" msgstr "" #: project/templates/email/reference_request_review_status_notice.txt:2 #: project/templates/email/review_status_notice.txt:2 +#: project/templates/email/verification_request_review_status_notice.txt:2 msgid "Click the link below to view the status" msgstr "" @@ -2014,6 +2104,16 @@ msgstr "" msgid "%(user_email)s is scheduled for deletion." msgstr "" +#: project/templates/email/verification_request_notice.html:4 +#: project/templates/email/verification_request_notice.txt:1 +msgid "There is a new verification request that needs to be reviewed." +msgstr "" + +#: project/templates/email/verification_request_review_status_notice.html:4 +#: project/templates/email/verification_request_review_status_notice.txt:1 +msgid "The review status of your verification request has been updated." +msgstr "" + #: project/templates/event/actions.html:5 #: project/templates/event/actions.html:22 msgid "Actions for event" @@ -2146,6 +2246,8 @@ msgstr "" #: project/templates/event_suggestion/review.html:53 #: project/templates/reference_request/review.html:72 #: project/templates/reference_request/review.html:97 +#: project/templates/verification_request/review.html:90 +#: project/templates/verification_request/review.html:115 msgid "Cancel" msgstr "" @@ -2223,6 +2325,7 @@ msgid "Coordinates" msgstr "" #: project/templates/manage/reference_requests_incoming.html:19 +#: project/templates/manage/verification_requests_incoming.html:18 msgid "Review request" msgstr "" @@ -2232,6 +2335,8 @@ msgid "Empfehlung anfragen" msgstr "" #: project/templates/manage/reference_requests_outgoing.html:19 +#: project/templates/manage/verification_requests_incoming.html:17 +#: project/templates/manage/verification_requests_outgoing.html:23 msgid "Show review status" msgstr "" @@ -2240,7 +2345,18 @@ msgstr "" msgid "Reviews" msgstr "" -#: project/templates/manage/verification_requests_outgoing.html:16 +#: project/templates/manage/verification_requests_outgoing_create.html:5 +#: project/templates/manage/verification_requests_outgoing_create.html:9 +#, python-format +msgid "Request verification for organization \"%(name)s\"" +msgstr "" + +#: project/templates/manage/verification_requests_outgoing_create.html:12 +#, python-format +msgid "Ask \"%(name)s\" to verify your organization." +msgstr "" + +#: project/templates/manage/verification_requests_outgoing_create_select.html:18 msgid "Here you can find organizations that can verify other organizations." msgstr "" @@ -2357,6 +2473,26 @@ msgid "" "account will be deleted. Until then, the deletion can be canceled." msgstr "" +#: project/templates/verification_request/delete.html:6 +msgid "Delete verification request" +msgstr "" + +#: project/templates/verification_request/review.html:23 +msgid "Review verification request" +msgstr "" + +#: project/templates/verification_request/review.html:67 +#: project/templates/verification_request/review.html:75 +#: project/templates/verification_request/review.html:91 +msgid "Accept verification request" +msgstr "" + +#: project/templates/verification_request/review.html:68 +#: project/templates/verification_request/review.html:101 +#: project/templates/verification_request/review.html:116 +msgid "Reject verification request" +msgstr "" + #: project/templates/widget/event_date/list.html:5 msgid "Widget" msgstr "" @@ -2382,7 +2518,8 @@ msgid "Organization successfully updated" msgstr "" #: project/views/admin.py:86 project/views/admin_unit.py:187 -#: project/views/admin_unit.py:220 project/views/manage.py:316 +#: project/views/admin_unit.py:220 project/views/manage.py:315 +#: project/views/verification_request.py:163 msgid "Entered name does not match organization name" msgstr "" @@ -2390,7 +2527,7 @@ msgstr "" msgid "Organization successfully deleted" msgstr "" -#: project/views/admin.py:134 project/views/manage.py:486 +#: project/views/admin.py:134 project/views/manage.py:485 #: project/views/user.py:63 msgid "Settings successfully updated" msgstr "" @@ -2540,15 +2677,15 @@ msgstr "" msgid "Places of Google Maps" msgstr "" -#: project/views/manage.py:302 +#: project/views/manage.py:301 msgid "You are not a member of this organization" msgstr "" -#: project/views/manage.py:307 +#: project/views/manage.py:306 msgid "Last remaining administrator can not leave the organization." msgstr "" -#: project/views/manage.py:321 +#: project/views/manage.py:320 msgid "Organization successfully left" msgstr "" @@ -2620,6 +2757,7 @@ msgid "New reference automatically verified" msgstr "" #: project/views/reference_request_review.py:34 +#: project/views/verification_request_review.py:28 msgid "Request already verified" msgstr "" @@ -2628,6 +2766,7 @@ msgid "Request successfully updated" msgstr "" #: project/views/reference_request_review.py:88 +#: project/views/verification_request_review.py:79 #, python-format msgid "" "If all upcoming reference requests of %(admin_unit_name)s should be " @@ -2673,6 +2812,32 @@ msgid "" " the invitation was sent to." msgstr "" +#: project/views/verification_request.py:127 +msgid "" +"Request successfully created. You will be notified after the other " +"organization reviewed the request." +msgstr "" + +#: project/views/verification_request.py:168 +msgid "Verification request successfully deleted" +msgstr "" + +#: project/views/verification_request.py:201 +msgid "New verification request" +msgstr "" + +#: project/views/verification_request_review.py:60 +msgid "Organization successfully verified" +msgstr "" + +#: project/views/verification_request_review.py:62 +msgid "Verification request successfully updated" +msgstr "" + +#: project/views/verification_request_review.py:115 +msgid "Verification request review status updated" +msgstr "" + #: project/views/widget.py:147 msgid "Thank you so much! The event is being verified." msgstr "" diff --git a/migrations/versions/6634c8f0b7fc_.py b/migrations/versions/6634c8f0b7fc_.py new file mode 100644 index 0000000..a030b31 --- /dev/null +++ b/migrations/versions/6634c8f0b7fc_.py @@ -0,0 +1,91 @@ +"""empty message + +Revision ID: 6634c8f0b7fc +Revises: becc71f97606 +Create Date: 2023-05-31 22:37:22.719433 + +""" +import sqlalchemy as sa +import sqlalchemy_utils +from alembic import op + +from project import dbtypes +from project.models import ( + AdminUnitVerificationRequestRejectionReason, + AdminUnitVerificationRequestReviewStatus, +) + +# revision identifiers, used by Alembic. +revision = "6634c8f0b7fc" +down_revision = "becc71f97606" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "adminunitverificationrequest", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("source_admin_unit_id", sa.Integer(), nullable=False), + sa.Column("target_admin_unit_id", sa.Integer(), nullable=False), + sa.Column( + "review_status", + dbtypes.IntegerEnum(AdminUnitVerificationRequestReviewStatus), + nullable=True, + ), + sa.Column( + "rejection_reason", + dbtypes.IntegerEnum(AdminUnitVerificationRequestRejectionReason), + nullable=True, + ), + sa.Column("created_at", sa.DateTime(), nullable=True), + sa.Column("updated_at", sa.DateTime(), nullable=True), + sa.Column("created_by_id", sa.Integer(), nullable=True), + sa.Column("updated_by_id", sa.Integer(), nullable=True), + sa.CheckConstraint( + "source_admin_unit_id != target_admin_unit_id", + name=op.f("ck_adminunitverificationrequest_auvr_source_neq_target"), + ), + sa.ForeignKeyConstraint( + ["created_by_id"], + ["user.id"], + name=op.f("fk_adminunitverificationrequest_created_by_id_user"), + ondelete="SET NULL", + ), + sa.ForeignKeyConstraint( + ["source_admin_unit_id"], + ["adminunit.id"], + name=op.f("fk_adminunitverificationrequest_source_admin_unit_id_adminunit"), + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["target_admin_unit_id"], + ["adminunit.id"], + name=op.f("fk_adminunitverificationrequest_target_admin_unit_id_adminunit"), + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["updated_by_id"], + ["user.id"], + name=op.f("fk_adminunitverificationrequest_updated_by_id_user"), + ondelete="SET NULL", + ), + sa.PrimaryKeyConstraint("id", name=op.f("pk_adminunitverificationrequest")), + sa.UniqueConstraint( + "source_admin_unit_id", + "target_admin_unit_id", + name=op.f("uq_adminunitverificationrequest_source_admin_unit_id"), + ), + ) + op.add_column( + "adminunit", sa.Column("description", sa.UnicodeText(), nullable=True) + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("adminunit", "description") + op.drop_table("adminunitverificationrequest") + # ### end Alembic commands ### diff --git a/project/__init__.py b/project/__init__.py index 65a526a..45318c3 100644 --- a/project/__init__.py +++ b/project/__init__.py @@ -290,7 +290,7 @@ from project.views import ( root, ) from project.views import user as user_view -from project.views import widget +from project.views import verification_request, verification_request_review, widget if __name__ == "__main__": # pragma: no cover app.run() diff --git a/project/api/organization/schemas.py b/project/api/organization/schemas.py index ef67c46..c17f779 100644 --- a/project/api/organization/schemas.py +++ b/project/api/organization/schemas.py @@ -37,6 +37,7 @@ class OrganizationBaseSchema(OrganizationIdSchema): email = marshmallow.auto_field() phone = marshmallow.auto_field() fax = marshmallow.auto_field() + description = marshmallow.auto_field() is_verified = fields.Boolean() diff --git a/project/cli/test.py b/project/cli/test.py index 2a128e0..b9dedb1 100644 --- a/project/cli/test.py +++ b/project/cli/test.py @@ -12,6 +12,8 @@ from project.init_data import create_initial_data from project.models import ( AdminUnit, AdminUnitInvitation, + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, Event, EventAttendanceMode, EventDateDefinition, @@ -152,6 +154,7 @@ def _create_admin_unit(user_id, name, verified=False): admin_unit.name = name admin_unit.short_name = name.lower().replace(" ", "") admin_unit.incoming_reference_requests_allowed = True + admin_unit.incoming_verification_requests_allowed = True admin_unit.suggestions_enabled = True admin_unit.can_create_other = True admin_unit.can_verify_other = True @@ -171,9 +174,10 @@ def _create_admin_unit(user_id, name, verified=False): @test_cli.command("admin-unit-create") @click.argument("user_email") @click.argument("name", default="Meine Crew") -def create_admin_unit(user_email, name): +@click.option("--verified/--no-verified", default=True) +def create_admin_unit(user_email, name, verified): user = find_user_by_email(user_email) - admin_unit_id = _create_admin_unit(user.id, name, verified=True) + admin_unit_id = _create_admin_unit(user.id, name, verified=verified) result = {"admin_unit_id": admin_unit_id} click.echo(json.dumps(result)) @@ -325,6 +329,48 @@ def create_incoming_reference_request(admin_unit_id): click.echo(json.dumps(result)) +def _create_admin_unit_verification_request(source_admin_unit_id, target_admin_unit_id): + target_admin_unit = get_admin_unit_by_id(target_admin_unit_id) + target_admin_unit.can_verify_other = True + target_admin_unit.incoming_verification_requests_allowed = True + + request = AdminUnitVerificationRequest() + request.source_admin_unit_id = source_admin_unit_id + request.target_admin_unit_id = target_admin_unit_id + request.review_status = AdminUnitVerificationRequestReviewStatus.inbox + db.session.add(request) + db.session.commit() + request_id = request.id + return request_id + + +def _create_incoming_admin_unit_verification_request(admin_unit_id): + other_user_id = _create_user("other@test.de") + other_admin_unit_id = _create_admin_unit( + other_user_id, "Other Crew", verified=False + ) + request_id = _create_admin_unit_verification_request( + other_admin_unit_id, admin_unit_id + ) + return (other_user_id, other_admin_unit_id, request_id) + + +@test_cli.command("verification-request-create-incoming") +@click.argument("admin_unit_id") +def create_incoming_admin_unit_verification_request(admin_unit_id): + ( + other_user_id, + other_admin_unit_id, + verification_request_id, + ) = _create_incoming_admin_unit_verification_request(admin_unit_id) + result = { + "other_user_id": other_user_id, + "other_admin_unit_id": other_admin_unit_id, + "verification_request_id": verification_request_id, + } + click.echo(json.dumps(result)) + + def _create_reference(event_id, admin_unit_id): reference = EventReference() reference.event_id = event_id diff --git a/project/forms/admin_unit.py b/project/forms/admin_unit.py index c4e7b93..2831a56 100644 --- a/project/forms/admin_unit.py +++ b/project/forms/admin_unit.py @@ -31,10 +31,12 @@ class AdminUnitLocationForm(FlaskForm): class BaseAdminUnitForm(FlaskForm): name = HTML5StringField( - lazy_gettext("Name"), validators=[DataRequired(), Length(min=5, max=255)] + lazy_gettext("Name of organization"), + description=lazy_gettext("The full name of the organization"), + validators=[DataRequired(), Length(min=5, max=255)], ) short_name = HTML5StringField( - lazy_gettext("Short name"), + lazy_gettext("Short name for organization"), description=lazy_gettext( "The short name is used to create a unique identifier for your events" ), @@ -49,6 +51,11 @@ class BaseAdminUnitForm(FlaskForm): ), ], ) + description = TextAreaField( + lazy_gettext("Description"), + description=lazy_gettext("Describe the organization in a few words"), + validators=[Optional()], + ) url = URLField(lazy_gettext("Link URL"), validators=[Optional(), Length(max=255)]) email = EmailField(lazy_gettext("Email"), validators=[Optional(), Length(max=255)]) phone = TelField(lazy_gettext("Phone"), validators=[Optional(), Length(max=255)]) diff --git a/project/forms/verification_request.py b/project/forms/verification_request.py new file mode 100644 index 0000000..cc7c770 --- /dev/null +++ b/project/forms/verification_request.py @@ -0,0 +1,90 @@ +from flask_babel import lazy_gettext +from flask_wtf import FlaskForm +from wtforms import SelectField, StringField, SubmitField +from wtforms.fields import BooleanField +from wtforms.validators import DataRequired, Optional + +from project.models import ( + AdminUnitVerificationRequestRejectionReason, + AdminUnitVerificationRequestReviewStatus, +) + + +class CreateAdminUnitVerificationRequestForm(FlaskForm): + submit = SubmitField(lazy_gettext("Request verification")) + + +class DeleteVerificationRequestForm(FlaskForm): + submit = SubmitField(lazy_gettext("Delete request")) + name = StringField(lazy_gettext("Name"), validators=[DataRequired()]) + + +class VerificationRequestReviewForm(FlaskForm): + review_status = SelectField( + lazy_gettext("Review status"), + coerce=int, + choices=[ + ( + int(AdminUnitVerificationRequestReviewStatus.inbox), + lazy_gettext("AdminUnitVerificationRequestReviewStatus.inbox"), + ), + ( + int(AdminUnitVerificationRequestReviewStatus.verified), + lazy_gettext("AdminUnitVerificationRequestReviewStatus.verified"), + ), + ( + int(AdminUnitVerificationRequestReviewStatus.rejected), + lazy_gettext("AdminUnitVerificationRequestReviewStatus.rejected"), + ), + ], + description=lazy_gettext("Choose the result of your review."), + ) + + rejection_reason = SelectField( + lazy_gettext("Rejection reason"), + coerce=int, + choices=[ + ( + 0, + lazy_gettext("AdminUnitVerificationRequestRejectionReason.noreason"), + ), + ( + int(AdminUnitVerificationRequestRejectionReason.notresponsible), + lazy_gettext( + "AdminUnitVerificationRequestRejectionReason.notresponsible" + ), + ), + ( + int(AdminUnitVerificationRequestRejectionReason.missinginformation), + lazy_gettext( + "AdminUnitVerificationRequestRejectionReason.missinginformation" + ), + ), + ( + int(AdminUnitVerificationRequestRejectionReason.unknown), + lazy_gettext("AdminUnitVerificationRequestRejectionReason.unknown"), + ), + ( + int(AdminUnitVerificationRequestRejectionReason.untrustworthy), + lazy_gettext( + "AdminUnitVerificationRequestRejectionReason.untrustworthy" + ), + ), + ( + int(AdminUnitVerificationRequestRejectionReason.illegal), + lazy_gettext("AdminUnitVerificationRequestRejectionReason.illegal"), + ), + ( + int(AdminUnitVerificationRequestRejectionReason.irrelevant), + lazy_gettext("AdminUnitVerificationRequestRejectionReason.irrelevant"), + ), + ], + description=lazy_gettext("Choose why you rejected the request."), + ) + + auto_verify = BooleanField( + lazy_gettext("Verify reference requests automatically"), + validators=[Optional()], + ) + + submit = SubmitField(lazy_gettext("Save review")) diff --git a/project/init_data.py b/project/init_data.py index 2134b47..0723733 100644 --- a/project/init_data.py +++ b/project/init_data.py @@ -23,6 +23,11 @@ def create_initial_data(): "admin_unit.members:read", "admin_unit.members:update", "admin_unit.members:delete", + "verification_request:create", + "verification_request:read", + "verification_request:update", + "verification_request:delete", + "verification_request:verify", ] event_permissions = [ "event:verify", diff --git a/project/jinja_filters.py b/project/jinja_filters.py index 2e000d0..7a29a79 100644 --- a/project/jinja_filters.py +++ b/project/jinja_filters.py @@ -83,11 +83,17 @@ def get_context_processors(): from project.services.reference import ( get_reference_requests_incoming_badge_query, ) + from project.services.verification import ( + get_verification_requests_incoming_badge_query, + ) reviews_badge = 0 reference_requests_incoming_badge = get_reference_requests_incoming_badge_query( admin_unit ).count() + verification_requests_incoming_badge = ( + get_verification_requests_incoming_badge_query(admin_unit).count() + ) if has_access(admin_unit, "event:verify"): reviews_badge = get_event_reviews_badge_query(admin_unit).count() @@ -95,6 +101,7 @@ def get_context_processors(): return { "reviews_badge": reviews_badge, "reference_requests_incoming_badge": reference_requests_incoming_badge, + "verification_requests_incoming_badge": verification_requests_incoming_badge, } def has_tos(): diff --git a/project/models/__init__.py b/project/models/__init__.py index fcf2f1f..feb3954 100644 --- a/project/models/__init__.py +++ b/project/models/__init__.py @@ -6,6 +6,11 @@ from project.models.admin_unit import ( AdminUnitMemberRole, AdminUnitRelation, ) +from project.models.admin_unit_verification_request import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestRejectionReason, + AdminUnitVerificationRequestReviewStatus, +) from project.models.custom_widget import CustomWidget from project.models.event import Event, EventStatus, PublicStatus from project.models.event_category import EventCategory diff --git a/project/models/admin_unit.py b/project/models/admin_unit.py index 0f3f6af..afa7417 100644 --- a/project/models/admin_unit.py +++ b/project/models/admin_unit.py @@ -22,6 +22,7 @@ from sqlalchemy.schema import CheckConstraint from sqlalchemy_utils import ColorType from project import db +from project.models.admin_unit_verification_request import AdminUnitVerificationRequest from project.models.trackable_mixin import TrackableMixin from project.utils import make_check_violation @@ -239,6 +240,7 @@ class AdminUnit(db.Model, TrackableMixin): email = deferred(Column(Unicode(255)), group="detail") phone = deferred(Column(Unicode(255)), group="detail") fax = deferred(Column(Unicode(255)), group="detail") + description = deferred(Column(UnicodeText(), nullable=True), group="detail") widget_font = deferred(Column(Unicode(255)), group="widget") widget_background_color = deferred(Column(ColorType), group="widget") widget_primary_color = deferred(Column(ColorType), group="widget") @@ -306,6 +308,27 @@ class AdminUnit(db.Model, TrackableMixin): lazy=True, ), ) + outgoing_verification_requests = relationship( + "AdminUnitVerificationRequest", + primaryjoin=remote(AdminUnitVerificationRequest.source_admin_unit_id) == id, + single_parent=True, + cascade="all, delete-orphan", + passive_deletes=True, + backref=backref( + "source_admin_unit", + lazy=True, + ), + ) + incoming_verification_requests = relationship( + "AdminUnitVerificationRequest", + primaryjoin=remote(AdminUnitVerificationRequest.target_admin_unit_id) == id, + cascade="all, delete-orphan", + passive_deletes=True, + backref=backref( + "target_admin_unit", + lazy=True, + ), + ) @hybrid_property def is_verified(self): diff --git a/project/models/admin_unit_verification_request.py b/project/models/admin_unit_verification_request.py new file mode 100644 index 0000000..2d92c2a --- /dev/null +++ b/project/models/admin_unit_verification_request.py @@ -0,0 +1,69 @@ +from enum import IntEnum + +from sqlalchemy import CheckConstraint, Column, Integer, UniqueConstraint +from sqlalchemy.event import listens_for +from sqlalchemy.ext.hybrid import hybrid_property + +from project import db +from project.dbtypes import IntegerEnum +from project.models.trackable_mixin import TrackableMixin +from project.utils import make_check_violation + + +class AdminUnitVerificationRequestReviewStatus(IntEnum): + inbox = 1 + verified = 2 + rejected = 3 + + +class AdminUnitVerificationRequestRejectionReason(IntEnum): + notresponsible = 1 + missinginformation = 2 + unknown = 3 + untrustworthy = 4 + illegal = 5 + irrelevant = 6 + + +class AdminUnitVerificationRequest(db.Model, TrackableMixin): + __tablename__ = "adminunitverificationrequest" + __table_args__ = ( + UniqueConstraint("source_admin_unit_id", "target_admin_unit_id"), + CheckConstraint( + "source_admin_unit_id != target_admin_unit_id", + name="auvr_source_neq_target", + ), + ) + id = Column(Integer(), primary_key=True) + source_admin_unit_id = db.Column( + db.Integer, db.ForeignKey("adminunit.id", ondelete="CASCADE"), nullable=False + ) + target_admin_unit_id = db.Column( + db.Integer, db.ForeignKey("adminunit.id", ondelete="CASCADE"), nullable=False + ) + review_status = Column(IntegerEnum(AdminUnitVerificationRequestReviewStatus)) + rejection_reason = Column(IntegerEnum(AdminUnitVerificationRequestRejectionReason)) + + @hybrid_property + def verified(self): + return self.review_status == AdminUnitVerificationRequestReviewStatus.verified + + def validate(self): + source_id = ( + self.source_admin_unit.id + if self.source_admin_unit + else self.source_admin_unit_id + ) + target_id = ( + self.target_admin_unit.id + if self.target_admin_unit + else self.target_admin_unit_id + ) + if source_id == target_id: # pragma: no cover + raise make_check_violation("There must be no self-reference.") + + +@listens_for(AdminUnitVerificationRequest, "before_insert") +@listens_for(AdminUnitVerificationRequest, "before_update") +def before_saving_admin_unit_verification_request(mapper, connect, self): + self.validate() diff --git a/project/services/verification.py b/project/services/verification.py new file mode 100644 index 0000000..c6c4ffc --- /dev/null +++ b/project/services/verification.py @@ -0,0 +1,29 @@ +from sqlalchemy import and_ +from sqlalchemy.orm import load_only + +from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, +) + + +def get_verification_requests_incoming_query(admin_unit): + return AdminUnitVerificationRequest.query.filter( + and_( + AdminUnitVerificationRequest.review_status + != AdminUnitVerificationRequestReviewStatus.verified, + AdminUnitVerificationRequest.target_admin_unit_id == admin_unit.id, + ) + ) + + +def get_verification_requests_incoming_badge_query(admin_unit): + return AdminUnitVerificationRequest.query.options( + load_only(AdminUnitVerificationRequest.id) + ).filter( + and_( + AdminUnitVerificationRequest.review_status + == AdminUnitVerificationRequestReviewStatus.inbox, + AdminUnitVerificationRequest.target_admin_unit_id == admin_unit.id, + ) + ) diff --git a/project/static/vue/organization/read.vue.js b/project/static/vue/organization/read.vue.js index 70d7526..6afbfe5 100644 --- a/project/static/vue/organization/read.vue.js +++ b/project/static/vue/organization/read.vue.js @@ -39,6 +39,10 @@ const OrganizationRead = { {{ organization.location.postalCode }} {{ organization.location.city }} +
+ {{ organization.description }} +
+ diff --git a/project/templates/_macros.html b/project/templates/_macros.html index 7d8150a..291298a 100644 --- a/project/templates/_macros.html +++ b/project/templates/_macros.html @@ -177,6 +177,15 @@ {% endif %} {% endmacro %} +{% macro render_text_prop(prop, icon = None, label_key = None) %} +{% if prop %} +
+ {% if icon %}{% endif %} + {{ prop }} +
+{% endif %} +{% endmacro %} + {% macro render_int_prop(prop, icon = None, label_key = None) %} {% if prop %}
@@ -280,6 +289,12 @@ {% endif %} {% endmacro %} +{% macro render_verification_request_review_status_pill(reference_request) %} +{% if reference_request.review_status %} + {{ reference_request.review_status | loc_enum }} +{% endif %} +{% endmacro %} + {% macro render_admin_unit_badges(admin_unit) %} {% if admin_unit.is_verified %}{% endif %} {% endmacro %} @@ -340,6 +355,11 @@ {{ render_enum_prop(reference_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }} {% endmacro %} +{% macro render_verification_request_review_status(verification_request) %} + {{ render_enum_prop(verification_request.review_status, 'fa-certificate', 'Review status') }} + {{ render_enum_prop(verification_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }} +{% endmacro %} + {% macro render_audit(tracking_mixing, show_user=False) %} {% set created_at = tracking_mixing.created_at | datetimeformat('short') %} {% set updated_at = tracking_mixing.updated_at | datetimeformat('short') %} diff --git a/project/templates/admin_unit/create.html b/project/templates/admin_unit/create.html index d0e077e..de7e200 100644 --- a/project/templates/admin_unit/create.html +++ b/project/templates/admin_unit/create.html @@ -30,6 +30,7 @@
{{ render_field_with_errors(form.name) }} {{ render_field_with_errors(form.short_name) }} + {{ render_field_with_errors(form.description) }}
diff --git a/project/templates/admin_unit/update.html b/project/templates/admin_unit/update.html index fd3cfeb..df1be05 100644 --- a/project/templates/admin_unit/update.html +++ b/project/templates/admin_unit/update.html @@ -38,6 +38,7 @@
{{ render_field_with_errors(form.name) }} {{ render_field_with_errors(form.short_name) }} + {{ render_field_with_errors(form.description) }}
diff --git a/project/templates/email/verification_request_notice.html b/project/templates/email/verification_request_notice.html new file mode 100644 index 0000000..47dc2a0 --- /dev/null +++ b/project/templates/email/verification_request_notice.html @@ -0,0 +1,6 @@ +{% extends "email/layout.html" %} +{% from "_macros.html" import render_email_button %} +{% block content %} +

{{ _('There is a new verification request that needs to be reviewed.') }}

+{{ render_email_button(url_for('admin_unit_verification_request_review', id=request.id, _external=True), _('Click here to review the request')) }} +{% endblock %} \ No newline at end of file diff --git a/project/templates/email/verification_request_notice.txt b/project/templates/email/verification_request_notice.txt new file mode 100644 index 0000000..23dceaf --- /dev/null +++ b/project/templates/email/verification_request_notice.txt @@ -0,0 +1,3 @@ +{{ _('There is a new verification request that needs to be reviewed.') }} +{{ _('Click the link below to review the request') }} +{{ url_for('admin_unit_verification_request_review', id=request.id, _external=True) }} diff --git a/project/templates/email/verification_request_review_status_notice.html b/project/templates/email/verification_request_review_status_notice.html new file mode 100644 index 0000000..4275e4c --- /dev/null +++ b/project/templates/email/verification_request_review_status_notice.html @@ -0,0 +1,6 @@ +{% extends "email/layout.html" %} +{% from "_macros.html" import render_email_button %} +{% block content %} +

{{ _('The review status of your verification request has been updated.') }}

+{{ render_email_button(url_for('admin_unit_verification_request_review_status', id=request.id, _external=True), _('Click here to view the status')) }} +{% endblock %} \ No newline at end of file diff --git a/project/templates/email/verification_request_review_status_notice.txt b/project/templates/email/verification_request_review_status_notice.txt new file mode 100644 index 0000000..a613c3b --- /dev/null +++ b/project/templates/email/verification_request_review_status_notice.txt @@ -0,0 +1,3 @@ +{{ _('The review status of your verification request has been updated.') }} +{{ _('Click the link below to view the status') }} +{{ url_for('admin_unit_verification_request_review_status', id=request.id, _external=True) }} diff --git a/project/templates/event/reference_request.html b/project/templates/event/reference_request.html index 31a9be2..75c000d 100644 --- a/project/templates/event/reference_request.html +++ b/project/templates/event/reference_request.html @@ -1,5 +1,5 @@ {% extends "layout.html" %} -{% from "_macros.html" import render_radio_buttons, render_phone_prop, render_email_prop, render_string_prop, render_field_with_errors, render_field, render_event_props, render_image_with_link, render_place, render_link_prop %} +{% from "_macros.html" import render_field_with_errors, render_field %} {%- block title -%} {{ event.name }} {%- endblock -%} diff --git a/project/templates/layout.html b/project/templates/layout.html index cdd1af0..0b13db4 100644 --- a/project/templates/layout.html +++ b/project/templates/layout.html @@ -255,16 +255,35 @@ + {% endfor %} +
{{ render_pagination(pagination) }}
diff --git a/project/templates/manage/verification_requests_outgoing_create.html b/project/templates/manage/verification_requests_outgoing_create.html new file mode 100644 index 0000000..2f1e722 --- /dev/null +++ b/project/templates/manage/verification_requests_outgoing_create.html @@ -0,0 +1,42 @@ +{% extends "layout.html" %} +{% set active_id = "verification_requests_outgoing" %} +{% from "_macros.html" import render_admin_unit_badges, render_logo, render_location_prop, render_text_prop, render_field_with_errors, render_field %} +{%- block title -%} +{{ _('Request verification for organization "%(name)s"', name=admin_unit.name) }} +{%- endblock -%} +{% block content %} + +

{{ _('Request verification for organization "%(name)s"', name=admin_unit.name) }}

+ +
+

{{ _('Ask "%(name)s" to verify your organization.', name=target_admin_unit.name) }}

+ +
+
+

+ {{ + target_admin_unit.name }} + {{ render_admin_unit_badges(target_admin_unit) }} +

+
+ {% if target_admin_unit.logo_id %} +
{{ render_logo(target_admin_unit.logo) }}
+ {% endif %} + +
+ {{ render_location_prop(target_admin_unit.location) }} +

{{ render_text_prop(target_admin_unit.description) }}

+

{{ render_text_prop(target_admin_unit.incoming_verification_requests_text) }}

+
+
+
+
+ +
+ {{ form.hidden_tag() }} + + {{ render_field(form.submit) }} +
+
+ +{% endblock %} diff --git a/project/templates/manage/verification_requests_outgoing_create_select.html b/project/templates/manage/verification_requests_outgoing_create_select.html new file mode 100644 index 0000000..3843491 --- /dev/null +++ b/project/templates/manage/verification_requests_outgoing_create_select.html @@ -0,0 +1,47 @@ +{% extends "layout.html" %} +{% set active_id = "verification_requests_outgoing" %} +{% from "_macros.html" import render_text_prop, render_logo, render_location_prop, render_fax_prop, render_phone_prop, render_email_prop, +render_link_prop, render_admin_unit_badges, render_pagination %} +{%- block title -%} +{{ _('Verification requests') }} +{%- endblock -%} +{% block content %} + +

+ {{ _('Verification requests') }} + {% if config["DOCS_URL"] %} + {{ _('Docs') }} + {% endif %} +

+ +
+

{{ _('Here you can find organizations that can verify other organizations.') }}

+ + {% for other_admin_unit in admin_units %} +
+
+

+ {{ + other_admin_unit.name }} + {{ render_admin_unit_badges(other_admin_unit) }} +

+
+ {% if other_admin_unit.logo_id %} +
{{ render_logo(other_admin_unit.logo) }}
+ {% endif %} + +
+ {{ render_location_prop(other_admin_unit.location) }} +

{{ render_text_prop(other_admin_unit.description) }}

+

{{ render_text_prop(other_admin_unit.incoming_verification_requests_text) }}

+ {{ _('Request verification') }}… +
+
+
+
+ {% endfor %} + +
{{ render_pagination(pagination) }}
+
+ +{% endblock %} \ No newline at end of file diff --git a/project/templates/verification_request/delete.html b/project/templates/verification_request/delete.html new file mode 100644 index 0000000..dddaa51 --- /dev/null +++ b/project/templates/verification_request/delete.html @@ -0,0 +1,24 @@ +{% extends "layout.html" %} +{% from "_macros.html" import render_field_with_errors, render_field %} + +{% block content %} + +

{{ _('Delete verification request') }} "{{ verification_request.target_admin_unit.name }}"

+ +
+ {{ form.hidden_tag() }} + +
+
+ {{ _('Organization') }} +
+
+ {{ render_field_with_errors(form.name) }} +
+
+ + {{ render_field(form.submit) }} + +
+ +{% endblock %} diff --git a/project/templates/verification_request/review.html b/project/templates/verification_request/review.html new file mode 100644 index 0000000..5853991 --- /dev/null +++ b/project/templates/verification_request/review.html @@ -0,0 +1,124 @@ +{% extends "layout.html" %} +{% from "_macros.html" import render_roles, render_text_prop, render_location_prop, render_admin_unit_badges, render_fax_prop, render_logo, render_jquery_steps_header, render_phone_prop, render_email_prop, render_string_prop, render_field_with_errors, render_field, render_image_with_link, render_place, render_link_prop %} +{%- block title -%} +{{ request.source_admin_unit.name }} +{%- endblock -%} +{% block header_before_site_js %} +{{ render_jquery_steps_header() }} + +{% endblock %} +{% block content %} + +

{{ _('Review verification request') }}

+ +
+
+
+ {{ _('Organization') }} +
+
+
{{ request.source_admin_unit.name }}{{ render_admin_unit_badges(request.source_admin_unit) }}
+ + {% if request.source_admin_unit.logo_id %} +
{{ render_logo(request.source_admin_unit.logo) }}
+ {% endif %} + +
+ {{ render_link_prop(request.source_admin_unit.url) }} + {{ render_email_prop(request.source_admin_unit.email) }} + {{ render_phone_prop(request.source_admin_unit.phone) }} + {{ render_fax_prop(request.source_admin_unit.fax) }} + {{ render_location_prop(request.source_admin_unit.location) }} + {% if request.source_admin_unit.description %} +
+ {{ render_text_prop(request.source_admin_unit.description) }} +
+ {% endif %} +
+
+
+ +
+
+ {{ _('Members') }} +
+
    + {% for member in request.source_admin_unit.members %} +
  • + {{ member.user.email }} + {{ render_roles(member.roles)}} +
  • + {% endfor %} +
+
+ +
+ + +
+ + + + + +
+ +{% endblock %} \ No newline at end of file diff --git a/project/templates/verification_request/review_status.html b/project/templates/verification_request/review_status.html new file mode 100644 index 0000000..050d5ff --- /dev/null +++ b/project/templates/verification_request/review_status.html @@ -0,0 +1,19 @@ +{% extends "layout.html" %} +{% from "_macros.html" import render_verification_request_review_status %} +{%- block title -%} +{{ _('Review status') }} +{%- endblock -%} +{% block content %} + +

{{ verification_request.source_admin_unit.name }} - {{ verification_request.target_admin_unit.name }}

+ +
+
+ {{ _('Review status') }} +
+
+ {{ render_verification_request_review_status(verification_request) }} +
+
+ +{% endblock %} \ No newline at end of file diff --git a/project/translations/de/LC_MESSAGES/messages.mo b/project/translations/de/LC_MESSAGES/messages.mo index 8e502a0..62e6261 100644 Binary files a/project/translations/de/LC_MESSAGES/messages.mo and b/project/translations/de/LC_MESSAGES/messages.mo differ diff --git a/project/translations/de/LC_MESSAGES/messages.po b/project/translations/de/LC_MESSAGES/messages.po index 1f27aa1..15551d9 100644 --- a/project/translations/de/LC_MESSAGES/messages.po +++ b/project/translations/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-05-30 14:22+0200\n" +"POT-Creation-Date: 2023-06-02 12:16+0200\n" "PO-Revision-Date: 2020-06-07 18:51+0200\n" "Last-Translator: FULL NAME \n" "Language: de\n" @@ -203,24 +203,24 @@ msgstr "message" msgid "You have received an invitation" msgstr "Du hast eine Einladung erhalten" -#: project/forms/admin.py:11 project/templates/layout.html:315 +#: project/forms/admin.py:11 project/templates/layout.html:334 #: project/views/root.py:55 msgid "Terms of service" msgstr "Nutzungsbedingungen" -#: project/forms/admin.py:12 project/templates/layout.html:320 +#: project/forms/admin.py:12 project/templates/layout.html:339 #: project/views/root.py:67 msgid "Legal notice" msgstr "Impressum" -#: project/forms/admin.py:13 project/templates/_macros.html:1441 -#: project/templates/layout.html:324 +#: project/forms/admin.py:13 project/templates/_macros.html:1461 +#: project/templates/layout.html:343 #: project/templates/widget/event_suggestion/create.html:204 #: project/views/admin_unit.py:83 project/views/root.py:75 msgid "Contact" msgstr "Kontakt" -#: project/forms/admin.py:14 project/templates/layout.html:328 +#: project/forms/admin.py:14 project/templates/layout.html:347 #: project/views/root.py:83 msgid "Privacy" msgstr "Datenschutz" @@ -256,12 +256,12 @@ msgstr "Nutzer aktualisieren" msgid "Delete user" msgstr "Nutzer löschen" -#: project/forms/admin.py:34 project/forms/admin_unit.py:53 +#: project/forms/admin.py:34 project/forms/admin_unit.py:60 #: project/forms/admin_unit_member.py:12 project/forms/admin_unit_member.py:25 #: project/forms/admin_unit_member.py:30 project/forms/event.py:107 #: project/forms/event_suggestion.py:38 project/forms/organizer.py:33 #: project/forms/user.py:18 project/forms/user.py:23 -#: project/templates/_macros.html:237 project/templates/_macros.html:1537 +#: project/templates/_macros.html:246 project/templates/_macros.html:1557 #: project/templates/admin/admin.html:27 project/templates/admin/email.html:4 #: project/templates/admin/email.html:66 project/templates/admin/users.html:19 #: project/templates/manage/organizers.html:21 @@ -325,17 +325,18 @@ msgstr "Organisation aktualisieren" #: project/forms/admin.py:75 project/templates/admin/delete_admin_unit.html:6 #: project/templates/admin_unit/request_deletion.html:6 -#: project/templates/admin_unit/update.html:93 +#: project/templates/admin_unit/update.html:94 msgid "Delete organization" msgstr "Organisation löschen" -#: project/forms/admin.py:76 project/forms/admin_unit.py:34 -#: project/forms/admin_unit.py:142 project/forms/admin_unit.py:147 -#: project/forms/admin_unit.py:152 project/forms/event.py:85 -#: project/forms/event.py:114 project/forms/event_place.py:30 -#: project/forms/event_place.py:56 project/forms/event_suggestion.py:26 -#: project/forms/oauth2_client.py:66 project/forms/organizer.py:30 -#: project/forms/organizer.py:58 project/forms/reference_request.py:23 +#: project/forms/admin.py:76 project/forms/admin_unit.py:149 +#: project/forms/admin_unit.py:154 project/forms/admin_unit.py:159 +#: project/forms/event.py:85 project/forms/event.py:114 +#: project/forms/event_place.py:30 project/forms/event_place.py:56 +#: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 +#: project/forms/organizer.py:30 project/forms/organizer.py:58 +#: project/forms/reference_request.py:23 +#: project/forms/verification_request.py:19 #: project/templates/admin/admin_units.html:19 #: project/templates/event_place/list.html:19 #: project/templates/manage/organizers.html:18 @@ -374,7 +375,7 @@ msgid "Street" msgstr "Straße" #: project/forms/admin_unit.py:18 project/forms/event.py:453 -#: project/forms/event_date.py:56 project/forms/event_place.py:16 +#: project/forms/event_date.py:52 project/forms/event_place.py:16 #: project/forms/organizer.py:16 msgid "Postal code" msgstr "Postleitzahl" @@ -399,60 +400,77 @@ msgstr "Breitengrad" msgid "Longitude" msgstr "Längengrad" -#: project/forms/admin_unit.py:37 -msgid "Short name" -msgstr "Kurzname" +#: project/forms/admin_unit.py:34 +msgid "Name of organization" +msgstr "Name der Organisation" -#: project/forms/admin_unit.py:38 +#: project/forms/admin_unit.py:35 +msgid "The full name of the organization" +msgstr "Vollständiger Name der Organisation" + +#: project/forms/admin_unit.py:39 +msgid "Short name for organization" +msgstr "Kurzname für die Organisation" + +#: project/forms/admin_unit.py:40 msgid "The short name is used to create a unique identifier for your events" msgstr "" "Der Kurzname wird verwendet, um die Veranstaltungen der Organisation " "eindeutig zu identifizieren. Der Kurzname darf nur Buchstaben, Nummern " "und Unterstriche enthalten." -#: project/forms/admin_unit.py:46 project/templates/_macros.html:1579 +#: project/forms/admin_unit.py:48 project/templates/_macros.html:1599 msgid "Short name must contain only letters numbers or underscore" msgstr "Der Kurzname darf nur Buchstaben, Nummern und Unterstriche enthalten" -#: project/forms/admin_unit.py:52 project/forms/event.py:106 +#: project/forms/admin_unit.py:55 project/forms/event.py:119 +#: project/forms/event_place.py:34 +msgid "Description" +msgstr "Beschreibung" + +#: project/forms/admin_unit.py:56 +msgid "Describe the organization in a few words" +msgstr "Beschreibe die Organisation in wenigen Worten" + +#: project/forms/admin_unit.py:59 project/forms/event.py:106 #: project/forms/event.py:124 project/forms/event_place.py:32 #: project/forms/organizer.py:32 project/templates/manage/organizers.html:21 msgid "Link URL" msgstr "Link URL" -#: project/forms/admin_unit.py:54 project/forms/event.py:108 +#: project/forms/admin_unit.py:61 project/forms/event.py:108 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:34 -#: project/templates/_macros.html:290 +#: project/templates/_macros.html:305 #: project/templates/manage/organizers.html:20 msgid "Phone" msgstr "Telefon" -#: project/forms/admin_unit.py:55 project/forms/event.py:109 -#: project/forms/organizer.py:35 project/templates/_macros.html:298 +#: project/forms/admin_unit.py:62 project/forms/event.py:109 +#: project/forms/organizer.py:35 project/templates/_macros.html:313 msgid "Fax" msgstr "Fax" -#: project/forms/admin_unit.py:56 project/forms/organizer.py:36 +#: project/forms/admin_unit.py:63 project/forms/organizer.py:36 #: project/templates/manage/organizers.html:22 #: project/templates/manage/organizers.html:47 msgid "Logo" msgstr "Logo" -#: project/forms/admin_unit.py:60 +#: project/forms/admin_unit.py:67 msgid "Allow verification requests" msgstr "Verifizierungsanfragen erlauben" -#: project/forms/admin_unit.py:61 +#: project/forms/admin_unit.py:68 msgid "If set, unverified organizations may ask you for verification." msgstr "" "Wenn gesetzt, können nicht verifizierte Organisationen um eine " "Verifizierung bitten." -#: project/forms/admin_unit.py:67 +#: project/forms/admin_unit.py:74 msgid "Verification requests information" msgstr "Text für Verifizierungsanfragen" -#: project/forms/admin_unit.py:69 +#: project/forms/admin_unit.py:76 msgid "" "This text is shown to unverified organizations to help them decide " "whether they ask you for verification." @@ -460,21 +478,22 @@ msgstr "" "Dieser Text wird nicht verifizierten Organisationen angezeigt, um ihnen " "bei der Entscheidung zu helfen, ob sie um eine Verifizierung bitten." -#: project/forms/admin_unit.py:85 +#: project/forms/admin_unit.py:92 msgid "Verify new organization" msgstr "Neue Organisation verifizieren" -#: project/forms/admin_unit.py:86 +#: project/forms/admin_unit.py:93 msgid "If set, events of the new organization are publicly visible." msgstr "" "Wenn gesetzt, sind Veranstaltungen der neuen Organisation öffentlich " "sichtbar." -#: project/forms/admin_unit.py:92 project/forms/reference_request.py:86 +#: project/forms/admin_unit.py:99 project/forms/reference_request.py:86 +#: project/forms/verification_request.py:86 msgid "Verify reference requests automatically" msgstr "Empfehlungsanfragen automatisch verifizieren" -#: project/forms/admin_unit.py:93 +#: project/forms/admin_unit.py:100 msgid "" "If set, all upcoming reference requests of the new organization are " "verified automatically." @@ -482,37 +501,37 @@ msgstr "" "Wenn gesetzt, werden alle zukünftigen Empfehlungsanfragen der neuen " "Organisation automatisch verifiziert." -#: project/forms/admin_unit.py:104 project/templates/admin_unit/create.html:5 +#: project/forms/admin_unit.py:111 project/templates/admin_unit/create.html:5 #: project/templates/admin_unit/create.html:22 #: project/templates/manage/admin_units.html:32 msgid "Create organization" msgstr "Organisation erstellen" -#: project/forms/admin_unit.py:112 project/forms/admin_unit.py:137 +#: project/forms/admin_unit.py:119 project/forms/admin_unit.py:144 msgid "Update settings" msgstr "Einstellungen speichern" -#: project/forms/admin_unit.py:117 +#: project/forms/admin_unit.py:124 msgid "Font" msgstr "Schriftart" -#: project/forms/admin_unit.py:120 +#: project/forms/admin_unit.py:127 msgid "Background Color" msgstr "Hintergrundfarbe" -#: project/forms/admin_unit.py:126 +#: project/forms/admin_unit.py:133 msgid "Primary Color" msgstr "Hauptfarbe" -#: project/forms/admin_unit.py:132 +#: project/forms/admin_unit.py:139 msgid "Link Color" msgstr "Linkfarbe" -#: project/forms/admin_unit.py:141 project/forms/user.py:17 +#: project/forms/admin_unit.py:148 project/forms/user.py:17 msgid "Request deletion" msgstr "Löschung beantragen" -#: project/forms/admin_unit.py:146 project/forms/user.py:22 +#: project/forms/admin_unit.py:153 project/forms/user.py:22 #: project/templates/admin_unit/cancel_deletion.html:6 #: project/templates/admin_unit/update.html:26 #: project/templates/manage/events.html:49 project/templates/profile.html:13 @@ -520,7 +539,7 @@ msgstr "Löschung beantragen" msgid "Cancel deletion" msgstr "Löschen abbrechen" -#: project/forms/admin_unit.py:151 project/templates/layout.html:286 +#: project/forms/admin_unit.py:158 project/templates/layout.html:305 #: project/templates/manage/delete_membership.html:6 msgid "Leave organization" msgstr "Organisation verlassen" @@ -663,16 +682,16 @@ msgstr "Gib an, wann der Termin endet. Ein Termin darf maximal 14 Tage dauern." msgid "All-day" msgstr "Ganztägig" -#: project/forms/event.py:54 project/templates/_macros.html:1749 +#: project/forms/event.py:54 project/templates/_macros.html:1769 #: project/templates/widget/event_suggestion/create.html:240 msgid "Recurring event" msgstr "Serientermin" -#: project/forms/event.py:61 project/templates/_macros.html:1298 +#: project/forms/event.py:61 project/templates/_macros.html:1318 msgid "The start must be before the end." msgstr "Der Start muss vor dem Ende sein." -#: project/forms/event.py:67 project/templates/_macros.html:1315 +#: project/forms/event.py:67 project/templates/_macros.html:1335 msgid "An event can last a maximum of 14 days." msgstr "Eine Veranstaltung darf maximal 14 Tage dauern." @@ -684,10 +703,6 @@ msgstr "Veranstalter" msgid "Enter a short, meaningful name for the event." msgstr "Gib einen kurzen, aussagekräftigen Namen für die Veranstaltung ein." -#: project/forms/event.py:119 project/forms/event_place.py:34 -msgid "Description" -msgstr "Beschreibung" - #: project/forms/event.py:121 msgid "Add an description of the event." msgstr "Füge der Veranstaltung eine Beschreibung hinzu." @@ -708,7 +723,7 @@ msgstr "Ticket Link" msgid "Enter a link where tickets can be purchased." msgstr "Gib einen Link ein, über den Tickets gekauft werden können." -#: project/forms/event.py:136 project/templates/_macros.html:219 +#: project/forms/event.py:136 project/templates/_macros.html:228 msgid "Tags" msgstr "Stichworte" @@ -761,7 +776,7 @@ msgstr "Anmeldung erforderlich" msgid "If the participants needs to register for the event." msgstr "Wenn sich die Teilnehmer für die Veranstaltung anmelden müssen." -#: project/forms/event.py:170 project/templates/_macros.html:251 +#: project/forms/event.py:170 project/templates/_macros.html:260 #: project/templates/layout.html:115 msgid "Booked up" msgstr "Ausgebucht" @@ -851,8 +866,8 @@ msgstr "" "Wir empfehlen dir, ein Foto für die Veranstaltung hochzuladen. Es macht " "schon deutlich mehr her, aber es geht natürlich auch ohne." -#: project/forms/event.py:242 project/templates/_macros.html:398 -#: project/templates/_macros.html:561 +#: project/forms/event.py:242 project/templates/_macros.html:418 +#: project/templates/_macros.html:581 msgid "Previous start date" msgstr "Vorheriges Startdatum" @@ -904,8 +919,8 @@ msgstr "Ungültiger Mitveranstalter." #: project/forms/event.py:286 project/forms/event.py:295 #: project/forms/event.py:368 project/forms/event.py:442 -#: project/forms/event_suggestion.py:50 project/templates/_macros.html:438 -#: project/templates/_macros.html:604 project/templates/event/create.html:288 +#: project/forms/event_suggestion.py:50 project/templates/_macros.html:458 +#: project/templates/_macros.html:624 project/templates/event/create.html:288 #: project/templates/event/update.html:170 #: project/templates/event_place/create.html:31 #: project/templates/event_place/delete.html:13 @@ -924,8 +939,8 @@ msgstr "Neuen Ort eingeben" #: project/forms/event.py:302 project/forms/event.py:311 #: project/forms/event.py:376 project/forms/event.py:439 -#: project/forms/event_date.py:44 project/forms/event_suggestion.py:60 -#: project/templates/_macros.html:475 project/templates/_macros.html:647 +#: project/forms/event_date.py:40 project/forms/event_suggestion.py:60 +#: project/templates/_macros.html:495 project/templates/_macros.html:667 #: project/templates/event/create.html:257 #: project/templates/event/update.html:160 #: project/templates/manage/events.html:104 @@ -1016,7 +1031,7 @@ msgstr "Öffentlicher Status" msgid "PublicStatus.published" msgstr "Veröffentlicht" -#: project/forms/event.py:402 project/templates/_macros.html:257 +#: project/forms/event.py:402 project/templates/_macros.html:266 msgid "PublicStatus.draft" msgstr "Entwurf" @@ -1029,35 +1044,35 @@ msgstr "Wähle den öffentlichen Status der Veranstaltung." msgid "Update event" msgstr "Veranstaltung aktualisieren" -#: project/forms/event.py:423 project/templates/_macros.html:1255 +#: project/forms/event.py:423 project/templates/_macros.html:1275 #: project/templates/event/actions.html:66 #: project/templates/event/delete.html:6 msgid "Delete event" msgstr "Veranstaltung löschen" -#: project/forms/event.py:430 project/forms/event_date.py:15 +#: project/forms/event.py:430 project/forms/event_date.py:14 #: project/forms/planing.py:14 msgid "From" msgstr "Von" -#: project/forms/event.py:432 project/forms/event_date.py:17 +#: project/forms/event.py:432 project/forms/event_date.py:16 #: project/forms/planing.py:16 msgid "to" msgstr "bis" -#: project/forms/event.py:434 project/forms/event_date.py:19 +#: project/forms/event.py:434 project/forms/event_date.py:18 msgid "Keyword" msgstr "Stichwort" -#: project/forms/event.py:436 project/forms/event_date.py:21 -#: project/forms/planing.py:19 project/templates/_macros.html:371 +#: project/forms/event.py:436 project/forms/event_date.py:20 +#: project/forms/planing.py:19 project/templates/_macros.html:391 msgid "Category" msgstr "Kategorie" -#: project/forms/event.py:446 project/forms/event_date.py:30 -#: project/forms/planing.py:22 project/templates/_macros.html:305 -#: project/templates/admin_unit/create.html:38 -#: project/templates/admin_unit/update.html:46 +#: project/forms/event.py:446 project/forms/event_date.py:26 +#: project/forms/planing.py:22 project/templates/_macros.html:320 +#: project/templates/admin_unit/create.html:39 +#: project/templates/admin_unit/update.html:47 #: project/templates/event_place/create.html:40 #: project/templates/event_place/update.html:40 #: project/templates/manage/organizers.html:19 @@ -1067,22 +1082,22 @@ msgstr "Kategorie" msgid "Location" msgstr "Standort" -#: project/forms/event.py:448 project/forms/event_date.py:32 +#: project/forms/event.py:448 project/forms/event_date.py:28 #: project/forms/planing.py:24 msgid "Distance" msgstr "Distanz" -#: project/forms/event.py:455 project/forms/event_date.py:53 +#: project/forms/event.py:455 project/forms/event_date.py:49 msgid "Exclude recurring events" msgstr "Serientermine nicht anzeigen" -#: project/forms/event.py:459 project/forms/event_date.py:58 +#: project/forms/event.py:459 project/forms/event_date.py:54 msgid "Find events" msgstr "Veranstaltungen finden" -#: project/forms/event_date.py:39 project/forms/reference.py:11 -#: project/forms/reference_request.py:16 project/templates/_macros.html:491 -#: project/templates/_macros.html:664 +#: project/forms/event_date.py:35 project/forms/reference.py:11 +#: project/forms/reference_request.py:16 project/templates/_macros.html:511 +#: project/templates/_macros.html:684 #: project/templates/admin/delete_admin_unit.html:13 #: project/templates/admin_unit/cancel_deletion.html:13 #: project/templates/admin_unit/create.html:28 @@ -1090,14 +1105,16 @@ msgstr "Veranstaltungen finden" #: project/templates/admin_unit/update.html:36 #: project/templates/layout.html:257 #: project/templates/manage/delete_membership.html:13 +#: project/templates/verification_request/delete.html:13 +#: project/templates/verification_request/review.html:28 msgid "Organization" msgstr "Organisation" -#: project/forms/event_date.py:49 +#: project/forms/event_date.py:45 msgid "Show unreferenced events only" msgstr "Nur nicht empfohlene Veranstaltungen anzeigen" -#: project/forms/event_date.py:67 project/forms/planing.py:36 +#: project/forms/event_date.py:63 project/forms/planing.py:36 #: project/templates/widget/event_date/list.html:82 msgid "Find" msgstr "Finden" @@ -1161,6 +1178,7 @@ msgid "Create event suggestion" msgstr "Veranstaltung vorschlagen" #: project/forms/event_suggestion.py:124 project/forms/reference_request.py:48 +#: project/forms/verification_request.py:44 msgid "Rejection reason" msgstr "Ablehnungsgrund" @@ -1248,12 +1266,17 @@ msgid "Save request" msgstr "Anfrage speichern" #: project/forms/reference_request.py:22 +#: project/forms/verification_request.py:18 +#: project/templates/manage/verification_requests_outgoing.html:24 msgid "Delete request" msgstr "Anfrage löschen" -#: project/forms/reference_request.py:28 project/templates/_macros.html:1453 +#: project/forms/reference_request.py:28 +#: project/forms/verification_request.py:24 project/templates/_macros.html:1473 #: project/templates/event_suggestion/review_status.html:18 #: project/templates/reference_request/review_status.html:12 +#: project/templates/verification_request/review_status.html:4 +#: project/templates/verification_request/review_status.html:12 msgid "Review status" msgstr "Prüfungsstatus" @@ -1270,6 +1293,7 @@ msgid "EventReferenceRequestReviewStatus.rejected" msgstr "Abgelehnt" #: project/forms/reference_request.py:44 +#: project/forms/verification_request.py:40 msgid "Choose the result of your review." msgstr "Wähle das Ergebnis deiner Prüfung." @@ -1294,10 +1318,12 @@ msgid "EventReferenceRequestRejectionReason.illegal" msgstr "Unzulässig" #: project/forms/reference_request.py:72 +#: project/forms/verification_request.py:82 msgid "Choose why you rejected the request." msgstr "Wähle aus, warum du die Anfrage abgelehnt hast." #: project/forms/reference_request.py:90 +#: project/forms/verification_request.py:90 msgid "Save review" msgstr "Prüfung speichern" @@ -1338,6 +1364,52 @@ msgstr "Newsletter" msgid "Information about new features and improvements." msgstr "Informationen über neue Features und Verbesserungen." +#: project/forms/verification_request.py:14 +#: project/templates/manage/verification_requests_outgoing.html:11 +#: project/templates/manage/verification_requests_outgoing_create_select.html:37 +msgid "Request verification" +msgstr "Verifizierung anfragen" + +#: project/forms/verification_request.py:29 +msgid "AdminUnitVerificationRequestReviewStatus.inbox" +msgstr "Ungeprüft" + +#: project/forms/verification_request.py:33 +msgid "AdminUnitVerificationRequestReviewStatus.verified" +msgstr "Verifiziert" + +#: project/forms/verification_request.py:37 +msgid "AdminUnitVerificationRequestReviewStatus.rejected" +msgstr "Abgelehnt" + +#: project/forms/verification_request.py:49 +msgid "AdminUnitVerificationRequestRejectionReason.noreason" +msgstr "Ohne Grund" + +#: project/forms/verification_request.py:53 +msgid "AdminUnitVerificationRequestRejectionReason.notresponsible" +msgstr "Nicht zuständig" + +#: project/forms/verification_request.py:59 +msgid "AdminUnitVerificationRequestRejectionReason.missinginformation" +msgstr "Fehlende Informationen" + +#: project/forms/verification_request.py:65 +msgid "AdminUnitVerificationRequestRejectionReason.unknown" +msgstr "Unbekannt" + +#: project/forms/verification_request.py:69 +msgid "AdminUnitVerificationRequestRejectionReason.untrustworthy" +msgstr "Unseriös" + +#: project/forms/verification_request.py:75 +msgid "AdminUnitVerificationRequestRejectionReason.illegal" +msgstr "Unzulässig" + +#: project/forms/verification_request.py:79 +msgid "AdminUnitVerificationRequestRejectionReason.irrelevant" +msgstr "Nicht relevant" + #: project/forms/widgets.py:155 msgid "This field is required." msgstr "Dieses Feld ist erforderlich." @@ -1346,35 +1418,35 @@ msgstr "Dieses Feld ist erforderlich." msgid "Show on Google Maps" msgstr "Auf Google Maps anzeigen" -#: project/templates/_macros.html:228 +#: project/templates/_macros.html:237 msgid "Link" msgstr "Link" -#: project/templates/_macros.html:284 +#: project/templates/_macros.html:299 msgid "Verified" msgstr "Verifiziert" -#: project/templates/_macros.html:348 +#: project/templates/_macros.html:368 #, python-format msgid "Created at %(created_at)s by %(created_by)s." msgstr "Erstellt am %(created_at)s von %(created_by)s." -#: project/templates/_macros.html:350 +#: project/templates/_macros.html:370 #, python-format msgid "Created at %(created_at)s." msgstr "Erstellt am %(created_at)s." -#: project/templates/_macros.html:355 +#: project/templates/_macros.html:375 #, python-format msgid "Last updated at %(updated_at)s by %(updated_by)s." msgstr "Zuletzt aktualisiert am %(updated_at)s von %(updated_by)s." -#: project/templates/_macros.html:357 +#: project/templates/_macros.html:377 #, python-format msgid "Last updated at %(updated_at)s." msgstr "Zuletzt aktualisiert am %(updated_at)s." -#: project/templates/_macros.html:387 project/templates/_macros.html:557 +#: project/templates/_macros.html:407 project/templates/_macros.html:577 #: project/templates/event/actions.html:25 #: project/templates/event/create.html:234 #: project/templates/event/update.html:126 @@ -1383,46 +1455,46 @@ msgstr "Zuletzt aktualisiert am %(updated_at)s." msgid "Event" msgstr "Veranstaltung" -#: project/templates/_macros.html:393 project/templates/_macros.html:979 +#: project/templates/_macros.html:413 project/templates/_macros.html:999 msgid "Date" msgstr "Datum" -#: project/templates/_macros.html:420 project/templates/_macros.html:579 -#: project/templates/_macros.html:1522 project/templates/event/actions.html:51 +#: project/templates/_macros.html:440 project/templates/_macros.html:599 +#: project/templates/_macros.html:1542 project/templates/event/actions.html:51 msgid "Share" msgstr "Teilen" -#: project/templates/_macros.html:424 project/templates/_macros.html:583 -#: project/templates/_macros.html:1552 +#: project/templates/_macros.html:444 project/templates/_macros.html:603 +#: project/templates/_macros.html:1572 msgid "Add to calendar" msgstr "Zum Kalender" -#: project/templates/_macros.html:432 project/templates/_macros.html:597 +#: project/templates/_macros.html:452 project/templates/_macros.html:617 #: project/templates/event/report.html:4 msgid "Report event" msgstr "Veranstaltung melden" -#: project/templates/_macros.html:459 project/templates/_macros.html:630 +#: project/templates/_macros.html:479 project/templates/_macros.html:650 msgid "Show directions" msgstr "Anreise planen" -#: project/templates/_macros.html:464 project/templates/_macros.html:622 +#: project/templates/_macros.html:484 project/templates/_macros.html:642 msgid "The event takes place online." msgstr "Die Veranstaltung findet online statt." -#: project/templates/_macros.html:466 project/templates/_macros.html:624 +#: project/templates/_macros.html:486 project/templates/_macros.html:644 msgid "The event takes place both offline and online." msgstr "" "Die Veranstaltung findet sowohl als Präsenzveranstaltung als auch online " "statt." -#: project/templates/_macros.html:587 project/templates/layout.html:183 +#: project/templates/_macros.html:607 project/templates/layout.html:183 #: project/templates/user/favorite_events.html:4 msgid "Favorite events" msgstr "Merkzettel" -#: project/templates/_macros.html:590 project/templates/_macros.html:633 -#: project/templates/_macros.html:765 +#: project/templates/_macros.html:610 project/templates/_macros.html:653 +#: project/templates/_macros.html:785 #: project/templates/admin/admin_units.html:36 #: project/templates/admin/users.html:36 #: project/templates/manage/events.html:118 @@ -1435,11 +1507,11 @@ msgstr "Merkzettel" msgid "Edit" msgstr "Bearbeiten" -#: project/templates/_macros.html:691 +#: project/templates/_macros.html:711 msgid "Referenced by" msgstr "Empfohlen von" -#: project/templates/_macros.html:703 project/templates/_macros.html:1265 +#: project/templates/_macros.html:723 project/templates/_macros.html:1285 #: project/templates/event/actions.html:38 #: project/templates/event_date/list.html:251 #: project/templates/manage/events.html:125 @@ -1447,39 +1519,39 @@ msgstr "Empfohlen von" msgid "Reference event" msgstr "Veranstaltung empfehlen" -#: project/templates/_macros.html:712 +#: project/templates/_macros.html:732 #: project/templates/manage/reference_requests_incoming.html:5 #: project/templates/manage/reference_requests_outgoing.html:5 msgid "Reference requests" msgstr "Empfehlungsanfragen" -#: project/templates/_macros.html:723 project/templates/_macros.html:1262 +#: project/templates/_macros.html:743 project/templates/_macros.html:1282 #: project/templates/event/actions.html:32 #: project/templates/manage/events.html:123 msgid "Request reference" msgstr "Empfehlung anfragen" -#: project/templates/_macros.html:731 project/templates/event_date/list.html:6 +#: project/templates/_macros.html:751 project/templates/event_date/list.html:6 #: project/templates/event_date/list.html:461 #: project/templates/reference_request/review.html:32 msgid "Event Dates" msgstr "Termine" -#: project/templates/_macros.html:829 +#: project/templates/_macros.html:849 msgid "Search location on Google" msgstr "Ort bei Google suchen" -#: project/templates/_macros.html:896 +#: project/templates/_macros.html:916 #, python-format msgid "%(count)d event dates" msgstr "%(count)d Termine" -#: project/templates/_macros.html:919 project/templates/_macros.html:921 +#: project/templates/_macros.html:939 project/templates/_macros.html:941 #: project/templates/event_date/list.html:510 msgid "First" msgstr "Letzte" -#: project/templates/_macros.html:924 project/templates/_macros.html:926 +#: project/templates/_macros.html:944 project/templates/_macros.html:946 #: project/templates/event_date/list.html:511 #: project/templates/widget/event_suggestion/create.html:193 #: project/templates/widget/event_suggestion/create.html:218 @@ -1490,12 +1562,12 @@ msgstr "Letzte" msgid "Previous" msgstr "Zurück" -#: project/templates/_macros.html:928 +#: project/templates/_macros.html:948 #, python-format msgid "Page %(page)d of %(pages)d (%(total)d total)" msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)" -#: project/templates/_macros.html:930 project/templates/_macros.html:932 +#: project/templates/_macros.html:950 project/templates/_macros.html:952 #: project/templates/event_date/list.html:513 #: project/templates/widget/event_suggestion/create.html:194 #: project/templates/widget/event_suggestion/create.html:219 @@ -1505,98 +1577,98 @@ msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)" msgid "Next" msgstr "Weiter" -#: project/templates/_macros.html:935 project/templates/_macros.html:937 +#: project/templates/_macros.html:955 project/templates/_macros.html:957 #: project/templates/event_date/list.html:514 msgid "Last" msgstr "Erste" -#: project/templates/_macros.html:1002 +#: project/templates/_macros.html:1022 msgid "Radius" msgstr "Umkreis" -#: project/templates/_macros.html:1184 +#: project/templates/_macros.html:1204 msgid "Edit image" msgstr "Bild bearbeiten" -#: project/templates/_macros.html:1205 +#: project/templates/_macros.html:1225 msgid "Close" msgstr "Schließen" -#: project/templates/_macros.html:1206 +#: project/templates/_macros.html:1226 msgid "Okay" msgstr "OK" -#: project/templates/_macros.html:1218 +#: project/templates/_macros.html:1238 msgid "Choose image file" msgstr "Bild-Datei auswählen" -#: project/templates/_macros.html:1254 project/templates/event/actions.html:65 +#: project/templates/_macros.html:1274 project/templates/event/actions.html:65 #: project/templates/event/delete.html:12 msgid "Edit event" msgstr "Veranstaltung bearbeiten" -#: project/templates/_macros.html:1258 project/templates/event/actions.html:58 +#: project/templates/_macros.html:1278 project/templates/event/actions.html:58 msgid "Duplicate event" msgstr "Veranstaltung duplizieren" -#: project/templates/_macros.html:1269 project/templates/event/actions.html:44 +#: project/templates/_macros.html:1289 project/templates/event/actions.html:44 #: project/templates/manage/events.html:129 msgid "Add to list" msgstr "Zu Liste hinzufügen" -#: project/templates/_macros.html:1272 project/templates/manage/events.html:132 +#: project/templates/_macros.html:1292 project/templates/manage/events.html:132 msgid "More" msgstr "Mehr" -#: project/templates/_macros.html:1319 +#: project/templates/_macros.html:1339 msgid "Please enter a valid time, between 00:00 and 23:59." msgstr "Bitte gib eine gültige Uhrzeit zwischen 00:00 und 23:59 ein." -#: project/templates/_macros.html:1347 +#: project/templates/_macros.html:1367 #, python-format msgid "Just use %(term)s" msgstr "Verwende einfach %(term)s" -#: project/templates/_macros.html:1413 +#: project/templates/_macros.html:1433 msgid "Event suggestion" msgstr "Veranstaltungsvorschlag" -#: project/templates/_macros.html:1531 +#: project/templates/_macros.html:1551 msgid "Link copied" msgstr "Link kopiert" -#: project/templates/_macros.html:1531 +#: project/templates/_macros.html:1551 msgid "Copy link" msgstr "Link kopieren" -#: project/templates/_macros.html:1561 +#: project/templates/_macros.html:1581 msgid "Google calendar" msgstr "Google Kalender" -#: project/templates/_macros.html:1563 +#: project/templates/_macros.html:1583 msgid "Apple calendar" msgstr "Apple Kalender" -#: project/templates/_macros.html:1564 +#: project/templates/_macros.html:1584 msgid "Yahoo calendar" msgstr "Yahoo Kalender" -#: project/templates/_macros.html:1565 +#: project/templates/_macros.html:1585 msgid "Other calendar" msgstr "Anderer Kalender" -#: project/templates/_macros.html:1750 +#: project/templates/_macros.html:1770 msgid "Remove event date" msgstr "Termin entfernen" -#: project/templates/_macros.html:1783 project/templates/event/create.html:180 +#: project/templates/_macros.html:1803 project/templates/event/create.html:180 #: project/templates/event/update.html:103 #: project/templates/event_date/list.html:446 #: project/templates/widget/event_suggestion/create.html:129 msgid "Enter organizer" msgstr "Veranstalter eingeben" -#: project/templates/_macros.html:1811 +#: project/templates/_macros.html:1831 msgid "Enter list name" msgstr "Listenname eingeben" @@ -1607,6 +1679,7 @@ msgstr "Verwaltung" #: project/templates/home.html:37 project/templates/layout.html:173 #: project/templates/manage/admin_units.html:28 #: project/templates/manage/verification_requests_outgoing.html:13 +#: project/templates/manage/verification_requests_outgoing_create_select.html:13 #: project/templates/security/login_user.html:21 #: project/templates/security/register_user.html:43 msgid "Docs" @@ -1637,7 +1710,7 @@ msgstr "Organisationen" msgid "Planing" msgstr "Planung" -#: project/templates/layout.html:182 project/templates/layout.html:275 +#: project/templates/layout.html:182 project/templates/layout.html:294 #: project/templates/oauth2_client/list.html:10 #: project/templates/oauth2_client/read.html:10 #: project/templates/oauth2_token/list.html:10 project/templates/profile.html:4 @@ -1671,7 +1744,7 @@ msgstr "Veranstaltung erstellen" #: project/templates/layout.html:223 msgid "Import event" -msgstr "Veranstaltung imporierten" +msgstr "Veranstaltung importieren" #: project/templates/layout.html:225 #: project/templates/manage/event_lists.html:4 @@ -1708,29 +1781,42 @@ msgstr "Eingehende Empfehlungsanfragen" msgid "Outgoing reference requests" msgstr "Ausgehende Empfehlungsanfragen" -#: project/templates/layout.html:260 project/templates/manage/organizers.html:5 +#: project/templates/layout.html:264 +#: project/templates/manage/verification_requests_outgoing.html:5 +#: project/templates/manage/verification_requests_outgoing.html:10 +msgid "Outgoing verification requests" +msgstr "Ausgehende Verifizierungsanfragen" + +#: project/templates/layout.html:268 project/templates/manage/organizers.html:5 #: project/templates/manage/organizers.html:10 #: project/templates/organizer/main.html:4 msgid "Organizers" msgstr "Veranstalter" #: project/templates/event_place/list.html:3 -#: project/templates/event_place/list.html:7 project/templates/layout.html:261 +#: project/templates/event_place/list.html:7 project/templates/layout.html:269 #: project/templates/manage/places.html:5 #: project/templates/manage/places.html:10 msgid "Places" msgstr "Orte" -#: project/templates/layout.html:263 project/templates/manage/members.html:5 +#: project/templates/layout.html:271 project/templates/manage/members.html:5 #: project/templates/manage/members.html:28 +#: project/templates/verification_request/review.html:54 msgid "Members" msgstr "Mitglieder" -#: project/templates/layout.html:264 project/templates/manage/relations.html:4 +#: project/templates/layout.html:272 project/templates/manage/relations.html:4 msgid "Relations" msgstr "Beziehungen" -#: project/templates/layout.html:266 +#: project/templates/layout.html:276 +#: project/templates/manage/verification_requests_incoming.html:5 +#: project/templates/manage/verification_requests_incoming.html:9 +msgid "Incoming verification requests" +msgstr "Eingehende Verifizierungsanfragen" + +#: project/templates/layout.html:284 #: project/templates/manage/admin_units.html:17 #: project/templates/manage/organization_invitations.html:4 #: project/templates/user/organization_invitations.html:4 @@ -1742,33 +1828,33 @@ msgstr "Organisationseinladungen" #: project/templates/admin/settings.html:11 #: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:30 -#: project/templates/layout.html:269 project/templates/manage/widgets.html:11 +#: project/templates/layout.html:288 project/templates/manage/widgets.html:11 #: project/templates/manage/widgets.html:15 project/templates/profile.html:32 msgid "Settings" msgstr "Einstellungen" -#: project/templates/layout.html:270 project/templates/manage/export.html:3 +#: project/templates/layout.html:289 project/templates/manage/export.html:3 #: project/templates/manage/export.html:63 msgid "Export" msgstr "Export" -#: project/templates/layout.html:272 +#: project/templates/layout.html:291 #: project/templates/manage/custom_widgets.html:13 msgid "Custom widgets" msgstr "Custom widgets" -#: project/templates/layout.html:273 project/templates/manage/reviews.html:10 +#: project/templates/layout.html:292 project/templates/manage/reviews.html:10 #: project/templates/manage/widgets.html:5 #: project/templates/manage/widgets.html:9 msgid "Widgets" msgstr "Widgets" -#: project/templates/layout.html:285 +#: project/templates/layout.html:304 msgid "Switch organization" msgstr "Organisation wechseln" #: project/templates/developer/read.html:4 -#: project/templates/developer/read.html:8 project/templates/layout.html:332 +#: project/templates/developer/read.html:8 project/templates/layout.html:351 #: project/templates/profile.html:45 msgid "Developer" msgstr "Entwickler" @@ -1854,8 +1940,8 @@ msgstr "Mails erfolgreich gesendet" msgid "Reset acceptance of terms of service and privacy" msgstr "Akzeptanz der Nutzungsbedingungen und des Datenschutzes zurücksetzen" -#: project/templates/admin_unit/create.html:58 -#: project/templates/admin_unit/update.html:66 +#: project/templates/admin_unit/create.html:59 +#: project/templates/admin_unit/update.html:67 #: project/templates/event/create.html:351 #: project/templates/event/update.html:208 #: project/templates/event_place/create.html:57 @@ -1865,7 +1951,7 @@ msgstr "Akzeptanz der Nutzungsbedingungen und des Datenschutzes zurücksetzen" msgid "Additional information" msgstr "Zusätzliche Informationen" -#: project/templates/admin_unit/create.html:71 +#: project/templates/admin_unit/create.html:72 #, python-format msgid "Relation to %(admin_unit_name)s" msgstr "Beziehung zu %(admin_unit_name)s" @@ -1888,9 +1974,9 @@ msgstr "" msgid "The organization is scheduled for deletion." msgstr "Die Organisation ist zur Löschung vorgesehen." -#: project/templates/admin_unit/update.html:79 -#: project/templates/manage/verification_requests_outgoing.html:6 -#: project/templates/manage/verification_requests_outgoing.html:11 +#: project/templates/admin_unit/update.html:80 +#: project/templates/manage/verification_requests_outgoing_create_select.html:6 +#: project/templates/manage/verification_requests_outgoing_create_select.html:11 msgid "Verification requests" msgstr "Verifizierungsanfragen" @@ -2013,10 +2099,12 @@ msgid "There is a new event reference request that needs to be reviewed." msgstr "Es gibt eine neue Empfehlungsanfrage, die geprüft werden muss." #: project/templates/email/reference_request_notice.html:5 +#: project/templates/email/verification_request_notice.html:5 msgid "Click here to review the request" msgstr "Klicke hier, um die Anfrage anzuzeigen" #: project/templates/email/reference_request_notice.txt:2 +#: project/templates/email/verification_request_notice.txt:2 msgid "Click the link below to review the request" msgstr "Klicke auf den unten stehenden Link, um die Anfrage anzuzeigen" @@ -2027,11 +2115,13 @@ msgstr "Der Prüfungsstatus deiner Empfehlungsanfrage wurde aktualisiert" #: project/templates/email/reference_request_review_status_notice.html:5 #: project/templates/email/review_status_notice.html:5 +#: project/templates/email/verification_request_review_status_notice.html:5 msgid "Click here to view the status" msgstr "Klicke hier, um den Status anzuzeigen" #: project/templates/email/reference_request_review_status_notice.txt:2 #: project/templates/email/review_status_notice.txt:2 +#: project/templates/email/verification_request_review_status_notice.txt:2 msgid "Click the link below to view the status" msgstr "Klicke auf den unten stehenden Link, um den Status anzuzeigen" @@ -2077,6 +2167,16 @@ msgstr "Klicke auf den unten stehenden Link, um die Seite zu öffnen" msgid "%(user_email)s is scheduled for deletion." msgstr "%(user_email)s ist zur Löschung vorgesehen." +#: project/templates/email/verification_request_notice.html:4 +#: project/templates/email/verification_request_notice.txt:1 +msgid "There is a new verification request that needs to be reviewed." +msgstr "Es gibt eine neue Verifizierungsanfrage, die geprüft werden muss." + +#: project/templates/email/verification_request_review_status_notice.html:4 +#: project/templates/email/verification_request_review_status_notice.txt:1 +msgid "The review status of your verification request has been updated." +msgstr "Der Prüfungsstatus deiner Verifizierungsanfrage wurde aktualisiert" + #: project/templates/event/actions.html:5 #: project/templates/event/actions.html:22 msgid "Actions for event" @@ -2214,6 +2314,8 @@ msgstr "Erstelle eine Veranstaltung aus dem Vorschlag" #: project/templates/event_suggestion/review.html:53 #: project/templates/reference_request/review.html:72 #: project/templates/reference_request/review.html:97 +#: project/templates/verification_request/review.html:90 +#: project/templates/verification_request/review.html:115 msgid "Cancel" msgstr "Abbrechen" @@ -2293,6 +2395,7 @@ msgid "Coordinates" msgstr "Koordinaten" #: project/templates/manage/reference_requests_incoming.html:19 +#: project/templates/manage/verification_requests_incoming.html:18 msgid "Review request" msgstr "Anfrage prüfen" @@ -2302,6 +2405,8 @@ msgid "Empfehlung anfragen" msgstr "Empfehlung anfragen" #: project/templates/manage/reference_requests_outgoing.html:19 +#: project/templates/manage/verification_requests_incoming.html:17 +#: project/templates/manage/verification_requests_outgoing.html:23 msgid "Show review status" msgstr "Prüfungsstatus anzeigen" @@ -2310,7 +2415,18 @@ msgstr "Prüfungsstatus anzeigen" msgid "Reviews" msgstr "Prüfungen" -#: project/templates/manage/verification_requests_outgoing.html:16 +#: project/templates/manage/verification_requests_outgoing_create.html:5 +#: project/templates/manage/verification_requests_outgoing_create.html:9 +#, python-format +msgid "Request verification for organization \"%(name)s\"" +msgstr "Verifizierung für Organisation \"%(name)s\" anfragen" + +#: project/templates/manage/verification_requests_outgoing_create.html:12 +#, python-format +msgid "Ask \"%(name)s\" to verify your organization." +msgstr "Bitte \"%(name)s\" deine Organisation zu verifizieren." + +#: project/templates/manage/verification_requests_outgoing_create_select.html:18 msgid "Here you can find organizations that can verify other organizations." msgstr "" "Hier findest du Organisationen, die deine Organisationen verifizieren " @@ -2431,6 +2547,26 @@ msgstr "" "Dein Account wird nicht sofort gelöscht. Nach einer Frist wird dein " "Account gelöscht. Bis dahin kann die Löschung abgebrochen werden." +#: project/templates/verification_request/delete.html:6 +msgid "Delete verification request" +msgstr "Verifizierungsanfrage löschen" + +#: project/templates/verification_request/review.html:23 +msgid "Review verification request" +msgstr "Verifizierungsanfrage prüfen" + +#: project/templates/verification_request/review.html:67 +#: project/templates/verification_request/review.html:75 +#: project/templates/verification_request/review.html:91 +msgid "Accept verification request" +msgstr "Verifizierungsanfrage akzeptieren" + +#: project/templates/verification_request/review.html:68 +#: project/templates/verification_request/review.html:101 +#: project/templates/verification_request/review.html:116 +msgid "Reject verification request" +msgstr "Verifizierungsanfrage ablehnen" + #: project/templates/widget/event_date/list.html:5 msgid "Widget" msgstr "Widget" @@ -2456,7 +2592,8 @@ msgid "Organization successfully updated" msgstr "Organisation erfolgreich aktualisiert" #: project/views/admin.py:86 project/views/admin_unit.py:187 -#: project/views/admin_unit.py:220 project/views/manage.py:316 +#: project/views/admin_unit.py:220 project/views/manage.py:315 +#: project/views/verification_request.py:163 msgid "Entered name does not match organization name" msgstr "Der eingegebene Name entspricht nicht dem Namen der Organisation" @@ -2464,7 +2601,7 @@ msgstr "Der eingegebene Name entspricht nicht dem Namen der Organisation" msgid "Organization successfully deleted" msgstr "Organisation erfolgreich gelöscht" -#: project/views/admin.py:134 project/views/manage.py:486 +#: project/views/admin.py:134 project/views/manage.py:485 #: project/views/user.py:63 msgid "Settings successfully updated" msgstr "Einstellungen erfolgreich aktualisiert" @@ -2617,17 +2754,17 @@ msgstr "Orte der Organisation" msgid "Places of Google Maps" msgstr "Orte von Google Maps" -#: project/views/manage.py:302 +#: project/views/manage.py:301 msgid "You are not a member of this organization" msgstr "Du bist kein Mitglied dieser Organisation" -#: project/views/manage.py:307 +#: project/views/manage.py:306 msgid "Last remaining administrator can not leave the organization." msgstr "" "Der letzte verbleibende Administrator kann die Organisation nicht " "verlassen." -#: project/views/manage.py:321 +#: project/views/manage.py:320 msgid "Organization successfully left" msgstr "Organisation erfolgreich verlassen" @@ -2701,6 +2838,7 @@ msgid "New reference automatically verified" msgstr "Neue automatisch verifizierte Empfehlung" #: project/views/reference_request_review.py:34 +#: project/views/verification_request_review.py:28 msgid "Request already verified" msgstr "Empfehlungsanfrage ist bereits verifiziert" @@ -2709,6 +2847,7 @@ msgid "Request successfully updated" msgstr "Empfehlungsanfrage erfolgreich aktualisiert" #: project/views/reference_request_review.py:88 +#: project/views/verification_request_review.py:79 #, python-format msgid "" "If all upcoming reference requests of %(admin_unit_name)s should be " @@ -2762,6 +2901,34 @@ msgstr "" "Die Einladung wurde für einen anderen Nutzer ausgestellt. Melde dich mit " "der Email-Adresse an, an die die Einladung geschickt wurde." +#: project/views/verification_request.py:127 +msgid "" +"Request successfully created. You will be notified after the other " +"organization reviewed the request." +msgstr "" +"Verifizierungsanfrage erfolgreich erstellt. Du wirst benachrichtigt, " +"nachdem die andere Organisation die Anfrage geprüft hat." + +#: project/views/verification_request.py:168 +msgid "Verification request successfully deleted" +msgstr "Verifizierungsanfrage erfolgreich gelöscht" + +#: project/views/verification_request.py:201 +msgid "New verification request" +msgstr "Neue Verifizierungsanfrage" + +#: project/views/verification_request_review.py:60 +msgid "Organization successfully verified" +msgstr "Organisation erfolgreich verifiziert" + +#: project/views/verification_request_review.py:62 +msgid "Verification request successfully updated" +msgstr "Verifizierungsanfrage erfolgreich aktualisiert" + +#: project/views/verification_request_review.py:115 +msgid "Verification request review status updated" +msgstr "Prüfungsstatus der Verifizierungsanfrage aktualisiert" + #: project/views/widget.py:147 msgid "Thank you so much! The event is being verified." msgstr "Vielen Dank! Die Veranstaltung wird geprüft." @@ -2851,3 +3018,6 @@ msgstr "Neue Veranstaltung zu prüfen" #~ msgid "Search" #~ msgstr "Suchen" +#~ msgid "Short name" +#~ msgstr "Kurzname" + diff --git a/project/translations/en/LC_MESSAGES/messages.mo b/project/translations/en/LC_MESSAGES/messages.mo index 0eeb16a..f40971a 100644 Binary files a/project/translations/en/LC_MESSAGES/messages.mo and b/project/translations/en/LC_MESSAGES/messages.mo differ diff --git a/project/translations/en/LC_MESSAGES/messages.po b/project/translations/en/LC_MESSAGES/messages.po index 460a947..e8ef0a0 100644 --- a/project/translations/en/LC_MESSAGES/messages.po +++ b/project/translations/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-05-30 14:22+0200\n" +"POT-Creation-Date: 2023-06-02 12:16+0200\n" "PO-Revision-Date: 2021-04-30 15:04+0200\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -203,24 +203,24 @@ msgstr "" msgid "You have received an invitation" msgstr "" -#: project/forms/admin.py:11 project/templates/layout.html:315 +#: project/forms/admin.py:11 project/templates/layout.html:334 #: project/views/root.py:55 msgid "Terms of service" msgstr "" -#: project/forms/admin.py:12 project/templates/layout.html:320 +#: project/forms/admin.py:12 project/templates/layout.html:339 #: project/views/root.py:67 msgid "Legal notice" msgstr "" -#: project/forms/admin.py:13 project/templates/_macros.html:1441 -#: project/templates/layout.html:324 +#: project/forms/admin.py:13 project/templates/_macros.html:1461 +#: project/templates/layout.html:343 #: project/templates/widget/event_suggestion/create.html:204 #: project/views/admin_unit.py:83 project/views/root.py:75 msgid "Contact" msgstr "" -#: project/forms/admin.py:14 project/templates/layout.html:328 +#: project/forms/admin.py:14 project/templates/layout.html:347 #: project/views/root.py:83 msgid "Privacy" msgstr "" @@ -256,12 +256,12 @@ msgstr "" msgid "Delete user" msgstr "" -#: project/forms/admin.py:34 project/forms/admin_unit.py:53 +#: project/forms/admin.py:34 project/forms/admin_unit.py:60 #: project/forms/admin_unit_member.py:12 project/forms/admin_unit_member.py:25 #: project/forms/admin_unit_member.py:30 project/forms/event.py:107 #: project/forms/event_suggestion.py:38 project/forms/organizer.py:33 #: project/forms/user.py:18 project/forms/user.py:23 -#: project/templates/_macros.html:237 project/templates/_macros.html:1537 +#: project/templates/_macros.html:246 project/templates/_macros.html:1557 #: project/templates/admin/admin.html:27 project/templates/admin/email.html:4 #: project/templates/admin/email.html:66 project/templates/admin/users.html:19 #: project/templates/manage/organizers.html:21 @@ -317,17 +317,18 @@ msgstr "" #: project/forms/admin.py:75 project/templates/admin/delete_admin_unit.html:6 #: project/templates/admin_unit/request_deletion.html:6 -#: project/templates/admin_unit/update.html:93 +#: project/templates/admin_unit/update.html:94 msgid "Delete organization" msgstr "" -#: project/forms/admin.py:76 project/forms/admin_unit.py:34 -#: project/forms/admin_unit.py:142 project/forms/admin_unit.py:147 -#: project/forms/admin_unit.py:152 project/forms/event.py:85 -#: project/forms/event.py:114 project/forms/event_place.py:30 -#: project/forms/event_place.py:56 project/forms/event_suggestion.py:26 -#: project/forms/oauth2_client.py:66 project/forms/organizer.py:30 -#: project/forms/organizer.py:58 project/forms/reference_request.py:23 +#: project/forms/admin.py:76 project/forms/admin_unit.py:149 +#: project/forms/admin_unit.py:154 project/forms/admin_unit.py:159 +#: project/forms/event.py:85 project/forms/event.py:114 +#: project/forms/event_place.py:30 project/forms/event_place.py:56 +#: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 +#: project/forms/organizer.py:30 project/forms/organizer.py:58 +#: project/forms/reference_request.py:23 +#: project/forms/verification_request.py:19 #: project/templates/admin/admin_units.html:19 #: project/templates/event_place/list.html:19 #: project/templates/manage/organizers.html:18 @@ -366,7 +367,7 @@ msgid "Street" msgstr "" #: project/forms/admin_unit.py:18 project/forms/event.py:453 -#: project/forms/event_date.py:56 project/forms/event_place.py:16 +#: project/forms/event_date.py:52 project/forms/event_place.py:16 #: project/forms/organizer.py:16 msgid "Postal code" msgstr "" @@ -391,109 +392,127 @@ msgstr "" msgid "Longitude" msgstr "" -#: project/forms/admin_unit.py:37 -msgid "Short name" +#: project/forms/admin_unit.py:34 +msgid "Name of organization" msgstr "" -#: project/forms/admin_unit.py:38 +#: project/forms/admin_unit.py:35 +msgid "The full name of the organization" +msgstr "" + +#: project/forms/admin_unit.py:39 +msgid "Short name for organization" +msgstr "" + +#: project/forms/admin_unit.py:40 msgid "The short name is used to create a unique identifier for your events" msgstr "" -#: project/forms/admin_unit.py:46 project/templates/_macros.html:1579 +#: project/forms/admin_unit.py:48 project/templates/_macros.html:1599 msgid "Short name must contain only letters numbers or underscore" msgstr "" -#: project/forms/admin_unit.py:52 project/forms/event.py:106 +#: project/forms/admin_unit.py:55 project/forms/event.py:119 +#: project/forms/event_place.py:34 +msgid "Description" +msgstr "" + +#: project/forms/admin_unit.py:56 +msgid "Describe the organization in a few words" +msgstr "" + +#: project/forms/admin_unit.py:59 project/forms/event.py:106 #: project/forms/event.py:124 project/forms/event_place.py:32 #: project/forms/organizer.py:32 project/templates/manage/organizers.html:21 msgid "Link URL" msgstr "" -#: project/forms/admin_unit.py:54 project/forms/event.py:108 +#: project/forms/admin_unit.py:61 project/forms/event.py:108 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:34 -#: project/templates/_macros.html:290 +#: project/templates/_macros.html:305 #: project/templates/manage/organizers.html:20 msgid "Phone" msgstr "" -#: project/forms/admin_unit.py:55 project/forms/event.py:109 -#: project/forms/organizer.py:35 project/templates/_macros.html:298 +#: project/forms/admin_unit.py:62 project/forms/event.py:109 +#: project/forms/organizer.py:35 project/templates/_macros.html:313 msgid "Fax" msgstr "" -#: project/forms/admin_unit.py:56 project/forms/organizer.py:36 +#: project/forms/admin_unit.py:63 project/forms/organizer.py:36 #: project/templates/manage/organizers.html:22 #: project/templates/manage/organizers.html:47 msgid "Logo" msgstr "" -#: project/forms/admin_unit.py:60 +#: project/forms/admin_unit.py:67 msgid "Allow verification requests" msgstr "" -#: project/forms/admin_unit.py:61 +#: project/forms/admin_unit.py:68 msgid "If set, unverified organizations may ask you for verification." msgstr "" -#: project/forms/admin_unit.py:67 +#: project/forms/admin_unit.py:74 msgid "Verification requests information" msgstr "" -#: project/forms/admin_unit.py:69 +#: project/forms/admin_unit.py:76 msgid "" "This text is shown to unverified organizations to help them decide " "whether they ask you for verification." msgstr "" -#: project/forms/admin_unit.py:85 +#: project/forms/admin_unit.py:92 msgid "Verify new organization" msgstr "" -#: project/forms/admin_unit.py:86 +#: project/forms/admin_unit.py:93 msgid "If set, events of the new organization are publicly visible." msgstr "" -#: project/forms/admin_unit.py:92 project/forms/reference_request.py:86 +#: project/forms/admin_unit.py:99 project/forms/reference_request.py:86 +#: project/forms/verification_request.py:86 msgid "Verify reference requests automatically" msgstr "" -#: project/forms/admin_unit.py:93 +#: project/forms/admin_unit.py:100 msgid "" "If set, all upcoming reference requests of the new organization are " "verified automatically." msgstr "" -#: project/forms/admin_unit.py:104 project/templates/admin_unit/create.html:5 +#: project/forms/admin_unit.py:111 project/templates/admin_unit/create.html:5 #: project/templates/admin_unit/create.html:22 #: project/templates/manage/admin_units.html:32 msgid "Create organization" msgstr "" -#: project/forms/admin_unit.py:112 project/forms/admin_unit.py:137 +#: project/forms/admin_unit.py:119 project/forms/admin_unit.py:144 msgid "Update settings" msgstr "" -#: project/forms/admin_unit.py:117 +#: project/forms/admin_unit.py:124 msgid "Font" msgstr "" -#: project/forms/admin_unit.py:120 +#: project/forms/admin_unit.py:127 msgid "Background Color" msgstr "" -#: project/forms/admin_unit.py:126 +#: project/forms/admin_unit.py:133 msgid "Primary Color" msgstr "" -#: project/forms/admin_unit.py:132 +#: project/forms/admin_unit.py:139 msgid "Link Color" msgstr "" -#: project/forms/admin_unit.py:141 project/forms/user.py:17 +#: project/forms/admin_unit.py:148 project/forms/user.py:17 msgid "Request deletion" msgstr "" -#: project/forms/admin_unit.py:146 project/forms/user.py:22 +#: project/forms/admin_unit.py:153 project/forms/user.py:22 #: project/templates/admin_unit/cancel_deletion.html:6 #: project/templates/admin_unit/update.html:26 #: project/templates/manage/events.html:49 project/templates/profile.html:13 @@ -501,7 +520,7 @@ msgstr "" msgid "Cancel deletion" msgstr "" -#: project/forms/admin_unit.py:151 project/templates/layout.html:286 +#: project/forms/admin_unit.py:158 project/templates/layout.html:305 #: project/templates/manage/delete_membership.html:6 msgid "Leave organization" msgstr "" @@ -639,16 +658,16 @@ msgstr "" msgid "All-day" msgstr "" -#: project/forms/event.py:54 project/templates/_macros.html:1749 +#: project/forms/event.py:54 project/templates/_macros.html:1769 #: project/templates/widget/event_suggestion/create.html:240 msgid "Recurring event" msgstr "" -#: project/forms/event.py:61 project/templates/_macros.html:1298 +#: project/forms/event.py:61 project/templates/_macros.html:1318 msgid "The start must be before the end." msgstr "" -#: project/forms/event.py:67 project/templates/_macros.html:1315 +#: project/forms/event.py:67 project/templates/_macros.html:1335 msgid "An event can last a maximum of 14 days." msgstr "" @@ -660,10 +679,6 @@ msgstr "" msgid "Enter a short, meaningful name for the event." msgstr "" -#: project/forms/event.py:119 project/forms/event_place.py:34 -msgid "Description" -msgstr "" - #: project/forms/event.py:121 msgid "Add an description of the event." msgstr "" @@ -682,7 +697,7 @@ msgstr "" msgid "Enter a link where tickets can be purchased." msgstr "" -#: project/forms/event.py:136 project/templates/_macros.html:219 +#: project/forms/event.py:136 project/templates/_macros.html:228 msgid "Tags" msgstr "" @@ -732,7 +747,7 @@ msgstr "" msgid "If the participants needs to register for the event." msgstr "" -#: project/forms/event.py:170 project/templates/_macros.html:251 +#: project/forms/event.py:170 project/templates/_macros.html:260 #: project/templates/layout.html:115 msgid "Booked up" msgstr "" @@ -816,8 +831,8 @@ msgid "" " course it works without it." msgstr "" -#: project/forms/event.py:242 project/templates/_macros.html:398 -#: project/templates/_macros.html:561 +#: project/forms/event.py:242 project/templates/_macros.html:418 +#: project/templates/_macros.html:581 msgid "Previous start date" msgstr "" @@ -863,8 +878,8 @@ msgstr "" #: project/forms/event.py:286 project/forms/event.py:295 #: project/forms/event.py:368 project/forms/event.py:442 -#: project/forms/event_suggestion.py:50 project/templates/_macros.html:438 -#: project/templates/_macros.html:604 project/templates/event/create.html:288 +#: project/forms/event_suggestion.py:50 project/templates/_macros.html:458 +#: project/templates/_macros.html:624 project/templates/event/create.html:288 #: project/templates/event/update.html:170 #: project/templates/event_place/create.html:31 #: project/templates/event_place/delete.html:13 @@ -883,8 +898,8 @@ msgstr "" #: project/forms/event.py:302 project/forms/event.py:311 #: project/forms/event.py:376 project/forms/event.py:439 -#: project/forms/event_date.py:44 project/forms/event_suggestion.py:60 -#: project/templates/_macros.html:475 project/templates/_macros.html:647 +#: project/forms/event_date.py:40 project/forms/event_suggestion.py:60 +#: project/templates/_macros.html:495 project/templates/_macros.html:667 #: project/templates/event/create.html:257 #: project/templates/event/update.html:160 #: project/templates/manage/events.html:104 @@ -971,7 +986,7 @@ msgstr "" msgid "PublicStatus.published" msgstr "" -#: project/forms/event.py:402 project/templates/_macros.html:257 +#: project/forms/event.py:402 project/templates/_macros.html:266 msgid "PublicStatus.draft" msgstr "" @@ -984,35 +999,35 @@ msgstr "" msgid "Update event" msgstr "" -#: project/forms/event.py:423 project/templates/_macros.html:1255 +#: project/forms/event.py:423 project/templates/_macros.html:1275 #: project/templates/event/actions.html:66 #: project/templates/event/delete.html:6 msgid "Delete event" msgstr "" -#: project/forms/event.py:430 project/forms/event_date.py:15 +#: project/forms/event.py:430 project/forms/event_date.py:14 #: project/forms/planing.py:14 msgid "From" msgstr "" -#: project/forms/event.py:432 project/forms/event_date.py:17 +#: project/forms/event.py:432 project/forms/event_date.py:16 #: project/forms/planing.py:16 msgid "to" msgstr "" -#: project/forms/event.py:434 project/forms/event_date.py:19 +#: project/forms/event.py:434 project/forms/event_date.py:18 msgid "Keyword" msgstr "" -#: project/forms/event.py:436 project/forms/event_date.py:21 -#: project/forms/planing.py:19 project/templates/_macros.html:371 +#: project/forms/event.py:436 project/forms/event_date.py:20 +#: project/forms/planing.py:19 project/templates/_macros.html:391 msgid "Category" msgstr "" -#: project/forms/event.py:446 project/forms/event_date.py:30 -#: project/forms/planing.py:22 project/templates/_macros.html:305 -#: project/templates/admin_unit/create.html:38 -#: project/templates/admin_unit/update.html:46 +#: project/forms/event.py:446 project/forms/event_date.py:26 +#: project/forms/planing.py:22 project/templates/_macros.html:320 +#: project/templates/admin_unit/create.html:39 +#: project/templates/admin_unit/update.html:47 #: project/templates/event_place/create.html:40 #: project/templates/event_place/update.html:40 #: project/templates/manage/organizers.html:19 @@ -1022,22 +1037,22 @@ msgstr "" msgid "Location" msgstr "" -#: project/forms/event.py:448 project/forms/event_date.py:32 +#: project/forms/event.py:448 project/forms/event_date.py:28 #: project/forms/planing.py:24 msgid "Distance" msgstr "" -#: project/forms/event.py:455 project/forms/event_date.py:53 +#: project/forms/event.py:455 project/forms/event_date.py:49 msgid "Exclude recurring events" msgstr "" -#: project/forms/event.py:459 project/forms/event_date.py:58 +#: project/forms/event.py:459 project/forms/event_date.py:54 msgid "Find events" msgstr "" -#: project/forms/event_date.py:39 project/forms/reference.py:11 -#: project/forms/reference_request.py:16 project/templates/_macros.html:491 -#: project/templates/_macros.html:664 +#: project/forms/event_date.py:35 project/forms/reference.py:11 +#: project/forms/reference_request.py:16 project/templates/_macros.html:511 +#: project/templates/_macros.html:684 #: project/templates/admin/delete_admin_unit.html:13 #: project/templates/admin_unit/cancel_deletion.html:13 #: project/templates/admin_unit/create.html:28 @@ -1045,14 +1060,16 @@ msgstr "" #: project/templates/admin_unit/update.html:36 #: project/templates/layout.html:257 #: project/templates/manage/delete_membership.html:13 +#: project/templates/verification_request/delete.html:13 +#: project/templates/verification_request/review.html:28 msgid "Organization" msgstr "" -#: project/forms/event_date.py:49 +#: project/forms/event_date.py:45 msgid "Show unreferenced events only" msgstr "" -#: project/forms/event_date.py:67 project/forms/planing.py:36 +#: project/forms/event_date.py:63 project/forms/planing.py:36 #: project/templates/widget/event_date/list.html:82 msgid "Find" msgstr "" @@ -1112,6 +1129,7 @@ msgid "Create event suggestion" msgstr "" #: project/forms/event_suggestion.py:124 project/forms/reference_request.py:48 +#: project/forms/verification_request.py:44 msgid "Rejection reason" msgstr "" @@ -1199,12 +1217,17 @@ msgid "Save request" msgstr "" #: project/forms/reference_request.py:22 +#: project/forms/verification_request.py:18 +#: project/templates/manage/verification_requests_outgoing.html:24 msgid "Delete request" msgstr "" -#: project/forms/reference_request.py:28 project/templates/_macros.html:1453 +#: project/forms/reference_request.py:28 +#: project/forms/verification_request.py:24 project/templates/_macros.html:1473 #: project/templates/event_suggestion/review_status.html:18 #: project/templates/reference_request/review_status.html:12 +#: project/templates/verification_request/review_status.html:4 +#: project/templates/verification_request/review_status.html:12 msgid "Review status" msgstr "" @@ -1221,6 +1244,7 @@ msgid "EventReferenceRequestReviewStatus.rejected" msgstr "Rejected" #: project/forms/reference_request.py:44 +#: project/forms/verification_request.py:40 msgid "Choose the result of your review." msgstr "" @@ -1245,10 +1269,12 @@ msgid "EventReferenceRequestRejectionReason.illegal" msgstr "Illegal" #: project/forms/reference_request.py:72 +#: project/forms/verification_request.py:82 msgid "Choose why you rejected the request." msgstr "" #: project/forms/reference_request.py:90 +#: project/forms/verification_request.py:90 msgid "Save review" msgstr "" @@ -1289,6 +1315,52 @@ msgstr "" msgid "Information about new features and improvements." msgstr "" +#: project/forms/verification_request.py:14 +#: project/templates/manage/verification_requests_outgoing.html:11 +#: project/templates/manage/verification_requests_outgoing_create_select.html:37 +msgid "Request verification" +msgstr "" + +#: project/forms/verification_request.py:29 +msgid "AdminUnitVerificationRequestReviewStatus.inbox" +msgstr "" + +#: project/forms/verification_request.py:33 +msgid "AdminUnitVerificationRequestReviewStatus.verified" +msgstr "" + +#: project/forms/verification_request.py:37 +msgid "AdminUnitVerificationRequestReviewStatus.rejected" +msgstr "" + +#: project/forms/verification_request.py:49 +msgid "AdminUnitVerificationRequestRejectionReason.noreason" +msgstr "" + +#: project/forms/verification_request.py:53 +msgid "AdminUnitVerificationRequestRejectionReason.notresponsible" +msgstr "" + +#: project/forms/verification_request.py:59 +msgid "AdminUnitVerificationRequestRejectionReason.missinginformation" +msgstr "" + +#: project/forms/verification_request.py:65 +msgid "AdminUnitVerificationRequestRejectionReason.unknown" +msgstr "" + +#: project/forms/verification_request.py:69 +msgid "AdminUnitVerificationRequestRejectionReason.untrustworthy" +msgstr "" + +#: project/forms/verification_request.py:75 +msgid "AdminUnitVerificationRequestRejectionReason.illegal" +msgstr "" + +#: project/forms/verification_request.py:79 +msgid "AdminUnitVerificationRequestRejectionReason.irrelevant" +msgstr "" + #: project/forms/widgets.py:155 msgid "This field is required." msgstr "" @@ -1297,35 +1369,35 @@ msgstr "" msgid "Show on Google Maps" msgstr "" -#: project/templates/_macros.html:228 +#: project/templates/_macros.html:237 msgid "Link" msgstr "" -#: project/templates/_macros.html:284 +#: project/templates/_macros.html:299 msgid "Verified" msgstr "" -#: project/templates/_macros.html:348 +#: project/templates/_macros.html:368 #, python-format msgid "Created at %(created_at)s by %(created_by)s." msgstr "" -#: project/templates/_macros.html:350 +#: project/templates/_macros.html:370 #, python-format msgid "Created at %(created_at)s." msgstr "" -#: project/templates/_macros.html:355 +#: project/templates/_macros.html:375 #, python-format msgid "Last updated at %(updated_at)s by %(updated_by)s." msgstr "" -#: project/templates/_macros.html:357 +#: project/templates/_macros.html:377 #, python-format msgid "Last updated at %(updated_at)s." msgstr "" -#: project/templates/_macros.html:387 project/templates/_macros.html:557 +#: project/templates/_macros.html:407 project/templates/_macros.html:577 #: project/templates/event/actions.html:25 #: project/templates/event/create.html:234 #: project/templates/event/update.html:126 @@ -1334,44 +1406,44 @@ msgstr "" msgid "Event" msgstr "" -#: project/templates/_macros.html:393 project/templates/_macros.html:979 +#: project/templates/_macros.html:413 project/templates/_macros.html:999 msgid "Date" msgstr "" -#: project/templates/_macros.html:420 project/templates/_macros.html:579 -#: project/templates/_macros.html:1522 project/templates/event/actions.html:51 +#: project/templates/_macros.html:440 project/templates/_macros.html:599 +#: project/templates/_macros.html:1542 project/templates/event/actions.html:51 msgid "Share" msgstr "" -#: project/templates/_macros.html:424 project/templates/_macros.html:583 -#: project/templates/_macros.html:1552 +#: project/templates/_macros.html:444 project/templates/_macros.html:603 +#: project/templates/_macros.html:1572 msgid "Add to calendar" msgstr "" -#: project/templates/_macros.html:432 project/templates/_macros.html:597 +#: project/templates/_macros.html:452 project/templates/_macros.html:617 #: project/templates/event/report.html:4 msgid "Report event" msgstr "" -#: project/templates/_macros.html:459 project/templates/_macros.html:630 +#: project/templates/_macros.html:479 project/templates/_macros.html:650 msgid "Show directions" msgstr "" -#: project/templates/_macros.html:464 project/templates/_macros.html:622 +#: project/templates/_macros.html:484 project/templates/_macros.html:642 msgid "The event takes place online." msgstr "" -#: project/templates/_macros.html:466 project/templates/_macros.html:624 +#: project/templates/_macros.html:486 project/templates/_macros.html:644 msgid "The event takes place both offline and online." msgstr "" -#: project/templates/_macros.html:587 project/templates/layout.html:183 +#: project/templates/_macros.html:607 project/templates/layout.html:183 #: project/templates/user/favorite_events.html:4 msgid "Favorite events" msgstr "" -#: project/templates/_macros.html:590 project/templates/_macros.html:633 -#: project/templates/_macros.html:765 +#: project/templates/_macros.html:610 project/templates/_macros.html:653 +#: project/templates/_macros.html:785 #: project/templates/admin/admin_units.html:36 #: project/templates/admin/users.html:36 #: project/templates/manage/events.html:118 @@ -1384,11 +1456,11 @@ msgstr "" msgid "Edit" msgstr "" -#: project/templates/_macros.html:691 +#: project/templates/_macros.html:711 msgid "Referenced by" msgstr "" -#: project/templates/_macros.html:703 project/templates/_macros.html:1265 +#: project/templates/_macros.html:723 project/templates/_macros.html:1285 #: project/templates/event/actions.html:38 #: project/templates/event_date/list.html:251 #: project/templates/manage/events.html:125 @@ -1396,39 +1468,39 @@ msgstr "" msgid "Reference event" msgstr "" -#: project/templates/_macros.html:712 +#: project/templates/_macros.html:732 #: project/templates/manage/reference_requests_incoming.html:5 #: project/templates/manage/reference_requests_outgoing.html:5 msgid "Reference requests" msgstr "" -#: project/templates/_macros.html:723 project/templates/_macros.html:1262 +#: project/templates/_macros.html:743 project/templates/_macros.html:1282 #: project/templates/event/actions.html:32 #: project/templates/manage/events.html:123 msgid "Request reference" msgstr "" -#: project/templates/_macros.html:731 project/templates/event_date/list.html:6 +#: project/templates/_macros.html:751 project/templates/event_date/list.html:6 #: project/templates/event_date/list.html:461 #: project/templates/reference_request/review.html:32 msgid "Event Dates" msgstr "" -#: project/templates/_macros.html:829 +#: project/templates/_macros.html:849 msgid "Search location on Google" msgstr "" -#: project/templates/_macros.html:896 +#: project/templates/_macros.html:916 #, python-format msgid "%(count)d event dates" msgstr "" -#: project/templates/_macros.html:919 project/templates/_macros.html:921 +#: project/templates/_macros.html:939 project/templates/_macros.html:941 #: project/templates/event_date/list.html:510 msgid "First" msgstr "" -#: project/templates/_macros.html:924 project/templates/_macros.html:926 +#: project/templates/_macros.html:944 project/templates/_macros.html:946 #: project/templates/event_date/list.html:511 #: project/templates/widget/event_suggestion/create.html:193 #: project/templates/widget/event_suggestion/create.html:218 @@ -1439,12 +1511,12 @@ msgstr "" msgid "Previous" msgstr "" -#: project/templates/_macros.html:928 +#: project/templates/_macros.html:948 #, python-format msgid "Page %(page)d of %(pages)d (%(total)d total)" msgstr "" -#: project/templates/_macros.html:930 project/templates/_macros.html:932 +#: project/templates/_macros.html:950 project/templates/_macros.html:952 #: project/templates/event_date/list.html:513 #: project/templates/widget/event_suggestion/create.html:194 #: project/templates/widget/event_suggestion/create.html:219 @@ -1454,98 +1526,98 @@ msgstr "" msgid "Next" msgstr "" -#: project/templates/_macros.html:935 project/templates/_macros.html:937 +#: project/templates/_macros.html:955 project/templates/_macros.html:957 #: project/templates/event_date/list.html:514 msgid "Last" msgstr "" -#: project/templates/_macros.html:1002 +#: project/templates/_macros.html:1022 msgid "Radius" msgstr "" -#: project/templates/_macros.html:1184 +#: project/templates/_macros.html:1204 msgid "Edit image" msgstr "" -#: project/templates/_macros.html:1205 +#: project/templates/_macros.html:1225 msgid "Close" msgstr "" -#: project/templates/_macros.html:1206 +#: project/templates/_macros.html:1226 msgid "Okay" msgstr "" -#: project/templates/_macros.html:1218 +#: project/templates/_macros.html:1238 msgid "Choose image file" msgstr "" -#: project/templates/_macros.html:1254 project/templates/event/actions.html:65 +#: project/templates/_macros.html:1274 project/templates/event/actions.html:65 #: project/templates/event/delete.html:12 msgid "Edit event" msgstr "" -#: project/templates/_macros.html:1258 project/templates/event/actions.html:58 +#: project/templates/_macros.html:1278 project/templates/event/actions.html:58 msgid "Duplicate event" msgstr "" -#: project/templates/_macros.html:1269 project/templates/event/actions.html:44 +#: project/templates/_macros.html:1289 project/templates/event/actions.html:44 #: project/templates/manage/events.html:129 msgid "Add to list" msgstr "" -#: project/templates/_macros.html:1272 project/templates/manage/events.html:132 +#: project/templates/_macros.html:1292 project/templates/manage/events.html:132 msgid "More" msgstr "" -#: project/templates/_macros.html:1319 +#: project/templates/_macros.html:1339 msgid "Please enter a valid time, between 00:00 and 23:59." msgstr "" -#: project/templates/_macros.html:1347 +#: project/templates/_macros.html:1367 #, python-format msgid "Just use %(term)s" msgstr "" -#: project/templates/_macros.html:1413 +#: project/templates/_macros.html:1433 msgid "Event suggestion" msgstr "" -#: project/templates/_macros.html:1531 +#: project/templates/_macros.html:1551 msgid "Link copied" msgstr "" -#: project/templates/_macros.html:1531 +#: project/templates/_macros.html:1551 msgid "Copy link" msgstr "" -#: project/templates/_macros.html:1561 +#: project/templates/_macros.html:1581 msgid "Google calendar" msgstr "" -#: project/templates/_macros.html:1563 +#: project/templates/_macros.html:1583 msgid "Apple calendar" msgstr "" -#: project/templates/_macros.html:1564 +#: project/templates/_macros.html:1584 msgid "Yahoo calendar" msgstr "" -#: project/templates/_macros.html:1565 +#: project/templates/_macros.html:1585 msgid "Other calendar" msgstr "" -#: project/templates/_macros.html:1750 +#: project/templates/_macros.html:1770 msgid "Remove event date" msgstr "" -#: project/templates/_macros.html:1783 project/templates/event/create.html:180 +#: project/templates/_macros.html:1803 project/templates/event/create.html:180 #: project/templates/event/update.html:103 #: project/templates/event_date/list.html:446 #: project/templates/widget/event_suggestion/create.html:129 msgid "Enter organizer" msgstr "" -#: project/templates/_macros.html:1811 +#: project/templates/_macros.html:1831 msgid "Enter list name" msgstr "" @@ -1556,6 +1628,7 @@ msgstr "" #: project/templates/home.html:37 project/templates/layout.html:173 #: project/templates/manage/admin_units.html:28 #: project/templates/manage/verification_requests_outgoing.html:13 +#: project/templates/manage/verification_requests_outgoing_create_select.html:13 #: project/templates/security/login_user.html:21 #: project/templates/security/register_user.html:43 msgid "Docs" @@ -1586,7 +1659,7 @@ msgstr "" msgid "Planing" msgstr "" -#: project/templates/layout.html:182 project/templates/layout.html:275 +#: project/templates/layout.html:182 project/templates/layout.html:294 #: project/templates/oauth2_client/list.html:10 #: project/templates/oauth2_client/read.html:10 #: project/templates/oauth2_token/list.html:10 project/templates/profile.html:4 @@ -1657,29 +1730,42 @@ msgstr "" msgid "Outgoing reference requests" msgstr "" -#: project/templates/layout.html:260 project/templates/manage/organizers.html:5 +#: project/templates/layout.html:264 +#: project/templates/manage/verification_requests_outgoing.html:5 +#: project/templates/manage/verification_requests_outgoing.html:10 +msgid "Outgoing verification requests" +msgstr "" + +#: project/templates/layout.html:268 project/templates/manage/organizers.html:5 #: project/templates/manage/organizers.html:10 #: project/templates/organizer/main.html:4 msgid "Organizers" msgstr "" #: project/templates/event_place/list.html:3 -#: project/templates/event_place/list.html:7 project/templates/layout.html:261 +#: project/templates/event_place/list.html:7 project/templates/layout.html:269 #: project/templates/manage/places.html:5 #: project/templates/manage/places.html:10 msgid "Places" msgstr "" -#: project/templates/layout.html:263 project/templates/manage/members.html:5 +#: project/templates/layout.html:271 project/templates/manage/members.html:5 #: project/templates/manage/members.html:28 +#: project/templates/verification_request/review.html:54 msgid "Members" msgstr "" -#: project/templates/layout.html:264 project/templates/manage/relations.html:4 +#: project/templates/layout.html:272 project/templates/manage/relations.html:4 msgid "Relations" msgstr "" -#: project/templates/layout.html:266 +#: project/templates/layout.html:276 +#: project/templates/manage/verification_requests_incoming.html:5 +#: project/templates/manage/verification_requests_incoming.html:9 +msgid "Incoming verification requests" +msgstr "" + +#: project/templates/layout.html:284 #: project/templates/manage/admin_units.html:17 #: project/templates/manage/organization_invitations.html:4 #: project/templates/user/organization_invitations.html:4 @@ -1691,33 +1777,33 @@ msgstr "" #: project/templates/admin/settings.html:11 #: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:30 -#: project/templates/layout.html:269 project/templates/manage/widgets.html:11 +#: project/templates/layout.html:288 project/templates/manage/widgets.html:11 #: project/templates/manage/widgets.html:15 project/templates/profile.html:32 msgid "Settings" msgstr "" -#: project/templates/layout.html:270 project/templates/manage/export.html:3 +#: project/templates/layout.html:289 project/templates/manage/export.html:3 #: project/templates/manage/export.html:63 msgid "Export" msgstr "" -#: project/templates/layout.html:272 +#: project/templates/layout.html:291 #: project/templates/manage/custom_widgets.html:13 msgid "Custom widgets" msgstr "" -#: project/templates/layout.html:273 project/templates/manage/reviews.html:10 +#: project/templates/layout.html:292 project/templates/manage/reviews.html:10 #: project/templates/manage/widgets.html:5 #: project/templates/manage/widgets.html:9 msgid "Widgets" msgstr "" -#: project/templates/layout.html:285 +#: project/templates/layout.html:304 msgid "Switch organization" msgstr "" #: project/templates/developer/read.html:4 -#: project/templates/developer/read.html:8 project/templates/layout.html:332 +#: project/templates/developer/read.html:8 project/templates/layout.html:351 #: project/templates/profile.html:45 msgid "Developer" msgstr "" @@ -1803,8 +1889,8 @@ msgstr "" msgid "Reset acceptance of terms of service and privacy" msgstr "" -#: project/templates/admin_unit/create.html:58 -#: project/templates/admin_unit/update.html:66 +#: project/templates/admin_unit/create.html:59 +#: project/templates/admin_unit/update.html:67 #: project/templates/event/create.html:351 #: project/templates/event/update.html:208 #: project/templates/event_place/create.html:57 @@ -1814,7 +1900,7 @@ msgstr "" msgid "Additional information" msgstr "" -#: project/templates/admin_unit/create.html:71 +#: project/templates/admin_unit/create.html:72 #, python-format msgid "Relation to %(admin_unit_name)s" msgstr "" @@ -1835,9 +1921,9 @@ msgstr "" msgid "The organization is scheduled for deletion." msgstr "" -#: project/templates/admin_unit/update.html:79 -#: project/templates/manage/verification_requests_outgoing.html:6 -#: project/templates/manage/verification_requests_outgoing.html:11 +#: project/templates/admin_unit/update.html:80 +#: project/templates/manage/verification_requests_outgoing_create_select.html:6 +#: project/templates/manage/verification_requests_outgoing_create_select.html:11 msgid "Verification requests" msgstr "" @@ -1958,10 +2044,12 @@ msgid "There is a new event reference request that needs to be reviewed." msgstr "" #: project/templates/email/reference_request_notice.html:5 +#: project/templates/email/verification_request_notice.html:5 msgid "Click here to review the request" msgstr "" #: project/templates/email/reference_request_notice.txt:2 +#: project/templates/email/verification_request_notice.txt:2 msgid "Click the link below to review the request" msgstr "" @@ -1972,11 +2060,13 @@ msgstr "" #: project/templates/email/reference_request_review_status_notice.html:5 #: project/templates/email/review_status_notice.html:5 +#: project/templates/email/verification_request_review_status_notice.html:5 msgid "Click here to view the status" msgstr "" #: project/templates/email/reference_request_review_status_notice.txt:2 #: project/templates/email/review_status_notice.txt:2 +#: project/templates/email/verification_request_review_status_notice.txt:2 msgid "Click the link below to view the status" msgstr "" @@ -2022,6 +2112,16 @@ msgstr "" msgid "%(user_email)s is scheduled for deletion." msgstr "" +#: project/templates/email/verification_request_notice.html:4 +#: project/templates/email/verification_request_notice.txt:1 +msgid "There is a new verification request that needs to be reviewed." +msgstr "" + +#: project/templates/email/verification_request_review_status_notice.html:4 +#: project/templates/email/verification_request_review_status_notice.txt:1 +msgid "The review status of your verification request has been updated." +msgstr "" + #: project/templates/event/actions.html:5 #: project/templates/event/actions.html:22 msgid "Actions for event" @@ -2154,6 +2254,8 @@ msgstr "" #: project/templates/event_suggestion/review.html:53 #: project/templates/reference_request/review.html:72 #: project/templates/reference_request/review.html:97 +#: project/templates/verification_request/review.html:90 +#: project/templates/verification_request/review.html:115 msgid "Cancel" msgstr "" @@ -2231,6 +2333,7 @@ msgid "Coordinates" msgstr "" #: project/templates/manage/reference_requests_incoming.html:19 +#: project/templates/manage/verification_requests_incoming.html:18 msgid "Review request" msgstr "" @@ -2240,6 +2343,8 @@ msgid "Empfehlung anfragen" msgstr "" #: project/templates/manage/reference_requests_outgoing.html:19 +#: project/templates/manage/verification_requests_incoming.html:17 +#: project/templates/manage/verification_requests_outgoing.html:23 msgid "Show review status" msgstr "" @@ -2248,7 +2353,18 @@ msgstr "" msgid "Reviews" msgstr "" -#: project/templates/manage/verification_requests_outgoing.html:16 +#: project/templates/manage/verification_requests_outgoing_create.html:5 +#: project/templates/manage/verification_requests_outgoing_create.html:9 +#, python-format +msgid "Request verification for organization \"%(name)s\"" +msgstr "" + +#: project/templates/manage/verification_requests_outgoing_create.html:12 +#, python-format +msgid "Ask \"%(name)s\" to verify your organization." +msgstr "" + +#: project/templates/manage/verification_requests_outgoing_create_select.html:18 msgid "Here you can find organizations that can verify other organizations." msgstr "" @@ -2365,6 +2481,26 @@ msgid "" "account will be deleted. Until then, the deletion can be canceled." msgstr "" +#: project/templates/verification_request/delete.html:6 +msgid "Delete verification request" +msgstr "" + +#: project/templates/verification_request/review.html:23 +msgid "Review verification request" +msgstr "" + +#: project/templates/verification_request/review.html:67 +#: project/templates/verification_request/review.html:75 +#: project/templates/verification_request/review.html:91 +msgid "Accept verification request" +msgstr "" + +#: project/templates/verification_request/review.html:68 +#: project/templates/verification_request/review.html:101 +#: project/templates/verification_request/review.html:116 +msgid "Reject verification request" +msgstr "" + #: project/templates/widget/event_date/list.html:5 msgid "Widget" msgstr "" @@ -2390,7 +2526,8 @@ msgid "Organization successfully updated" msgstr "" #: project/views/admin.py:86 project/views/admin_unit.py:187 -#: project/views/admin_unit.py:220 project/views/manage.py:316 +#: project/views/admin_unit.py:220 project/views/manage.py:315 +#: project/views/verification_request.py:163 msgid "Entered name does not match organization name" msgstr "" @@ -2398,7 +2535,7 @@ msgstr "" msgid "Organization successfully deleted" msgstr "" -#: project/views/admin.py:134 project/views/manage.py:486 +#: project/views/admin.py:134 project/views/manage.py:485 #: project/views/user.py:63 msgid "Settings successfully updated" msgstr "" @@ -2548,15 +2685,15 @@ msgstr "" msgid "Places of Google Maps" msgstr "" -#: project/views/manage.py:302 +#: project/views/manage.py:301 msgid "You are not a member of this organization" msgstr "" -#: project/views/manage.py:307 +#: project/views/manage.py:306 msgid "Last remaining administrator can not leave the organization." msgstr "" -#: project/views/manage.py:321 +#: project/views/manage.py:320 msgid "Organization successfully left" msgstr "" @@ -2628,6 +2765,7 @@ msgid "New reference automatically verified" msgstr "" #: project/views/reference_request_review.py:34 +#: project/views/verification_request_review.py:28 msgid "Request already verified" msgstr "" @@ -2636,6 +2774,7 @@ msgid "Request successfully updated" msgstr "" #: project/views/reference_request_review.py:88 +#: project/views/verification_request_review.py:79 #, python-format msgid "" "If all upcoming reference requests of %(admin_unit_name)s should be " @@ -2681,6 +2820,32 @@ msgid "" " the invitation was sent to." msgstr "" +#: project/views/verification_request.py:127 +msgid "" +"Request successfully created. You will be notified after the other " +"organization reviewed the request." +msgstr "" + +#: project/views/verification_request.py:168 +msgid "Verification request successfully deleted" +msgstr "" + +#: project/views/verification_request.py:201 +msgid "New verification request" +msgstr "" + +#: project/views/verification_request_review.py:60 +msgid "Organization successfully verified" +msgstr "" + +#: project/views/verification_request_review.py:62 +msgid "Verification request successfully updated" +msgstr "" + +#: project/views/verification_request_review.py:115 +msgid "Verification request review status updated" +msgstr "" + #: project/views/widget.py:147 msgid "Thank you so much! The event is being verified." msgstr "" @@ -2763,3 +2928,6 @@ msgstr "" #~ msgid "Search" #~ msgstr "" +#~ msgid "Short name" +#~ msgstr "" + diff --git a/project/views/manage.py b/project/views/manage.py index b909006..e6c037e 100644 --- a/project/views/manage.py +++ b/project/views/manage.py @@ -40,7 +40,6 @@ from project.models import ( from project.services.admin_unit import ( get_admin_unit_member_invitations, get_admin_unit_organization_invitations, - get_admin_unit_query, get_member_for_admin_unit_by_user_id, ) from project.services.event import get_events_query @@ -492,17 +491,3 @@ def manage_admin_unit_widgets(id): flash_errors(form) return render_template("manage/widgets.html", form=form, admin_unit=admin_unit) - - -@app.route("/manage/admin_unit//verification_requests/outgoing") -@auth_required() -def manage_admin_unit_verification_requests_outgoing(id): - admin_unit = get_admin_unit_for_manage_or_404(id) - admin_units = get_admin_unit_query(only_verifier=True).paginate() - - return render_template( - "manage/verification_requests_outgoing.html", - admin_unit=admin_unit, - admin_units=admin_units.items, - pagination=get_pagination_urls(admin_units, id=id), - ) diff --git a/project/views/verification_request.py b/project/views/verification_request.py new file mode 100644 index 0000000..8fef491 --- /dev/null +++ b/project/views/verification_request.py @@ -0,0 +1,204 @@ +from flask import flash, g, redirect, render_template, url_for +from flask_babel import gettext +from flask_security import auth_required +from sqlalchemy.exc import SQLAlchemyError + +from project import app, db +from project.access import access_or_401, get_admin_unit_members_with_permission +from project.forms.verification_request import ( + CreateAdminUnitVerificationRequestForm, + DeleteVerificationRequestForm, +) +from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, +) +from project.models.admin_unit import AdminUnit +from project.services.admin_unit import get_admin_unit_query +from project.services.verification import get_verification_requests_incoming_query +from project.views.utils import ( + flash_errors, + get_pagination_urls, + handleSqlError, + manage_required, + non_match_for_deletion, + send_mails, +) + + +@app.route("/manage/admin_unit//verification_requests/incoming") +@auth_required() +@manage_required("verification_request:read") +def manage_admin_unit_verification_requests_incoming(id): + admin_unit = g.manage_admin_unit + requests = ( + get_verification_requests_incoming_query(admin_unit) + .order_by(AdminUnitVerificationRequest.created_at.desc()) + .paginate() + ) + + return render_template( + "manage/verification_requests_incoming.html", + admin_unit=admin_unit, + requests=requests.items, + pagination=get_pagination_urls(requests, id=id), + ) + + +@app.route("/manage/admin_unit//verification_requests/outgoing") +@auth_required() +@manage_required("verification_request:read") +def manage_admin_unit_verification_requests_outgoing(id): + admin_unit = g.manage_admin_unit + requests = ( + AdminUnitVerificationRequest.query.filter( + AdminUnitVerificationRequest.source_admin_unit_id == admin_unit.id + ) + .order_by(AdminUnitVerificationRequest.created_at.desc()) + .paginate() + ) + + if not admin_unit.is_verified and requests.total == 0: + return redirect( + url_for( + "manage_admin_unit_verification_requests_outgoing_create_select", + id=admin_unit.id, + ) + ) + + return render_template( + "manage/verification_requests_outgoing.html", + admin_unit=admin_unit, + requests=requests.items, + pagination=get_pagination_urls(requests, id=id), + ) + + +@app.route("/manage/admin_unit//verification_requests/outgoing/create/select") +@auth_required() +@manage_required("verification_request:create") +def manage_admin_unit_verification_requests_outgoing_create_select(id): + admin_unit = g.manage_admin_unit + admin_units = get_admin_unit_query(only_verifier=True).paginate() + + return render_template( + "manage/verification_requests_outgoing_create_select.html", + admin_unit=admin_unit, + admin_units=admin_units.items, + pagination=get_pagination_urls(admin_units, id=id), + ) + + +@app.route( + "/manage/admin_unit//verification_requests/outgoing/create/target/", + methods=("GET", "POST"), +) +@auth_required() +@manage_required("verification_request:create") +def manage_admin_unit_verification_requests_outgoing_create(id, target_id): + admin_unit = g.manage_admin_unit + target_admin_unit = AdminUnit.query.get_or_404(target_id) + + if ( + target_admin_unit.id == admin_unit.id + or not target_admin_unit.can_verify_other + or not target_admin_unit.incoming_verification_requests_allowed + ): # pragma: no cover + return redirect( + url_for( + "manage_admin_unit_verification_requests_outgoing_create_select", + id=admin_unit.id, + ) + ) + + form = CreateAdminUnitVerificationRequestForm() + + if form.validate_on_submit(): + request = AdminUnitVerificationRequest() + form.populate_obj(request) + request.source_admin_unit = admin_unit + request.target_admin_unit = target_admin_unit + + try: + db.session.add(request) + + request.review_status = AdminUnitVerificationRequestReviewStatus.inbox + send_verification_request_inbox_mails(request) + msg = gettext( + "Request successfully created. You will be notified after the other organization reviewed the request." + ) + + db.session.commit() + flash(msg, "success") + return redirect( + url_for( + "manage_admin_unit_verification_requests_outgoing", + id=admin_unit.id, + ) + ) + except SQLAlchemyError as e: + db.session.rollback() + flash(handleSqlError(e), "danger") + else: + flash_errors(form) + + return render_template( + "manage/verification_requests_outgoing_create.html", + form=form, + admin_unit=admin_unit, + target_admin_unit=target_admin_unit, + ) + + +@app.route("/verification_request//delete", methods=("GET", "POST")) +@auth_required() +def admin_unit_verification_request_delete(id): + request = AdminUnitVerificationRequest.query.get_or_404(id) + access_or_401(request.source_admin_unit, "verification_request:delete") + + form = DeleteVerificationRequestForm() + + if form.validate_on_submit(): + if non_match_for_deletion(form.name.data, request.target_admin_unit.name): + flash(gettext("Entered name does not match organization name"), "danger") + else: + try: + db.session.delete(request) + db.session.commit() + flash(gettext("Verification request successfully deleted"), "success") + return redirect( + url_for( + "manage_admin_unit_verification_requests_outgoing", + id=request.source_admin_unit.id, + ) + ) + except SQLAlchemyError as e: + db.session.rollback() + flash(handleSqlError(e), "danger") + else: + flash_errors(form) + + return render_template( + "verification_request/delete.html", form=form, verification_request=request + ) + + +def send_member_verification_request_verify_mails( + admin_unit_id, subject, template, **context +): + # Benachrichtige alle Mitglieder der AdminUnit, die Requests verifizieren können + members = get_admin_unit_members_with_permission( + admin_unit_id, "verification_request:verify" + ) + emails = list(map(lambda member: member.user.email, members)) + + send_mails(emails, subject, template, **context) + + +def send_verification_request_inbox_mails(request): + send_member_verification_request_verify_mails( + request.target_admin_unit_id or request.target_admin_unit.id, + gettext("New verification request"), + "verification_request_notice", + request=request, + ) diff --git a/project/views/verification_request_review.py b/project/views/verification_request_review.py new file mode 100644 index 0000000..170d823 --- /dev/null +++ b/project/views/verification_request_review.py @@ -0,0 +1,118 @@ +from flask import abort, flash, redirect, render_template, url_for +from flask_babel import gettext +from flask_security import auth_required +from sqlalchemy.exc import SQLAlchemyError + +from project import app, db +from project.access import ( + access_or_401, + get_admin_unit_members_with_permission, + has_access, +) +from project.forms.verification_request import VerificationRequestReviewForm +from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, +) +from project.services.admin_unit import upsert_admin_unit_relation +from project.views.utils import flash_errors, handleSqlError, send_mails + + +@app.route("/verification_request//review", methods=("GET", "POST")) +@auth_required() +def admin_unit_verification_request_review(id): + request = AdminUnitVerificationRequest.query.get_or_404(id) + access_or_401(request.target_admin_unit, "verification_request:verify") + + if request.review_status == AdminUnitVerificationRequestReviewStatus.verified: + flash(gettext("Request already verified"), "danger") + return redirect( + url_for( + "manage_admin_unit_verification_requests_incoming", + id=request.target_admin_unit_id, + ) + ) + + form = VerificationRequestReviewForm(obj=request) + + if form.validate_on_submit(): + form.populate_obj(request) + + if request.review_status != AdminUnitVerificationRequestReviewStatus.rejected: + request.rejection_reason = None + + if request.rejection_reason == 0: + request.rejection_reason = None + + try: + if ( + request.review_status + == AdminUnitVerificationRequestReviewStatus.verified + ): + relation = upsert_admin_unit_relation( + request.target_admin_unit_id, request.source_admin_unit_id + ) + relation.verify = True + + if form.auto_verify.data: + relation.auto_verify_event_reference_requests = True + + msg = gettext("Organization successfully verified") + else: + msg = gettext("Verification request successfully updated") + + db.session.commit() + send_verification_request_review_status_mails(request) + flash(msg, "success") + return redirect( + url_for( + "manage_admin_unit_verification_requests_incoming", + id=request.target_admin_unit_id, + ) + ) + except SQLAlchemyError as e: + db.session.rollback() + flash(handleSqlError(e), "danger") + else: + flash_errors(form) + + form.auto_verify.description = gettext( + "If all upcoming reference requests of %(admin_unit_name)s should be verified automatically.", + admin_unit_name=request.source_admin_unit.name, + ) + + return render_template( + "verification_request/review.html", + form=form, + request=request, + ) + + +@app.route("/verification_request//review_status") +def admin_unit_verification_request_review_status(id): + request = AdminUnitVerificationRequest.query.get_or_404(id) + + if not has_access( + request.target_admin_unit, "verification_request:verify" + ) and not has_access(request.source_admin_unit, "verification_request:create"): + abort(401) + + return render_template( + "verification_request/review_status.html", + verification_request=request, + ) + + +def send_verification_request_review_status_mails(request): + # Benachrichtige alle Mitglieder der AdminUnit, die diesen Request erstellt hatte + members = get_admin_unit_members_with_permission( + request.source_admin_unit_id, "verification_request:create" + ) + emails = list(map(lambda member: member.user.email, members)) + + send_mails( + emails, + gettext("Verification request review status updated"), + "verification_request_review_status_notice", + request=request, + ) diff --git a/tests/seeder.py b/tests/seeder.py index a0739da..4c9efb3 100644 --- a/tests/seeder.py +++ b/tests/seeder.py @@ -677,6 +677,68 @@ class Seeder(object): ) return (other_user_id, other_admin_unit_id, relation_id) + def setup_admin_unit_missing_verification_scenario(self, log_in_verifier=False): + verifier_user_id = self.create_user() + verifier_admin_unit_id = self.create_admin_unit( + verifier_user_id, + "Stadtmarketing", + verified=True, + can_verify_other=True, + incoming_verification_requests_allowed=True, + incoming_verification_requests_text="Please give us a call", + ) + + unverified_user_id, unverified_admin_unit_id = self.setup_base( + log_in=not log_in_verifier, + admin_unit_verified=False, + email="mitglied@verein.de", + name="Verein", + ) + + if log_in_verifier: + self._utils.login() + + return ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) + + def create_admin_unit_verification_request( + self, source_admin_unit_id, target_admin_unit_id + ): + from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, + ) + + with self._app.app_context(): + from project.services.admin_unit import get_admin_unit_by_id + + target_admin_unit = get_admin_unit_by_id(target_admin_unit_id) + target_admin_unit.can_verify_other = True + target_admin_unit.incoming_verification_requests_allowed = True + + request = AdminUnitVerificationRequest() + request.source_admin_unit_id = source_admin_unit_id + request.target_admin_unit_id = target_admin_unit_id + request.review_status = AdminUnitVerificationRequestReviewStatus.inbox + self._db.session.add(request) + self._db.session.commit() + request_id = request.id + return request_id + + def create_incoming_admin_unit_verification_request(self, admin_unit_id): + other_user_id = self.create_user("other@test.de") + other_admin_unit_id = self.create_admin_unit( + other_user_id, "Other Crew", verified=False + ) + request_id = self.create_admin_unit_verification_request( + other_admin_unit_id, admin_unit_id + ) + return (other_user_id, other_admin_unit_id, request_id) + def create_reference_request(self, event_id, admin_unit_id): from project.models import ( EventReferenceRequest, diff --git a/tests/test_models.py b/tests/test_models.py index e3f3f29..a3b8800 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -14,7 +14,7 @@ def test_location_update_coordinate(client, app, db): assert location.coordinate is not None -def test_event_category(client, app, db, seeder): +def test_event_category(client, app, db, seeder: Seeder): user_id, admin_unit_id = seeder.setup_base() event_id = seeder.create_event(admin_unit_id) @@ -28,7 +28,7 @@ def test_event_category(client, app, db, seeder): assert event.category is None -def test_event_properties(client, app, db, seeder): +def test_event_properties(client, app, db, seeder: Seeder): with app.app_context(): from sqlalchemy.exc import IntegrityError @@ -51,7 +51,7 @@ def test_event_properties(client, app, db, seeder): assert event.min_start == start -def test_event_allday(client, app, db, seeder): +def test_event_allday(client, app, db, seeder: Seeder): from project.dateutils import create_berlin_date user_id, admin_unit_id = seeder.setup_base() @@ -93,7 +93,7 @@ def test_event_allday(client, app, db, seeder): assert event_date.end == create_berlin_date(2031, 1, 1, 23, 59, 59) -def test_event_has_multiple_dates(client, app, db, seeder): +def test_event_has_multiple_dates(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base() event_with_recc_id = seeder.create_event( admin_unit_id, recurrence_rule="RRULE:FREQ=DAILY;COUNT=7" @@ -110,7 +110,7 @@ def test_event_has_multiple_dates(client, app, db, seeder): assert event_without_recc.has_multiple_dates() is False -def test_oauth2_token(client, app, seeder): +def test_oauth2_token(client, app, seeder: Seeder): import time from project.models import OAuth2Token @@ -124,7 +124,7 @@ def test_oauth2_token(client, app, seeder): assert not token.is_refresh_token_active() -def test_admin_unit_relations(client, app, db, seeder): +def test_admin_unit_relations(client, app, db, seeder: Seeder): user_id, admin_unit_id = seeder.setup_base(log_in=False) ( other_user_id, @@ -145,7 +145,34 @@ def test_admin_unit_relations(client, app, db, seeder): assert len(admin_unit.outgoing_relations) == 0 -def test_event_date_defintion_deletion(client, app, db, seeder): +def test_admin_unit_verification_requests(client, app, db, seeder: Seeder): + user_id, admin_unit_id = seeder.setup_base(log_in=False) + ( + other_user_id, + other_admin_unit_id, + request_id, + ) = seeder.create_incoming_admin_unit_verification_request(admin_unit_id) + + with app.app_context(): + from project.services.admin_unit import get_admin_unit_by_id + + admin_unit = get_admin_unit_by_id(admin_unit_id) + assert len(admin_unit.incoming_verification_requests) == 1 + request = admin_unit.incoming_verification_requests[0] + assert request.id == request_id + + other_admin_unit = get_admin_unit_by_id(other_admin_unit_id) + assert len(other_admin_unit.outgoing_verification_requests) == 1 + request = other_admin_unit.outgoing_verification_requests[0] + assert request.id == request_id + + db.session.delete(request) + db.session.commit() + assert len(admin_unit.incoming_verification_requests) == 0 + assert len(other_admin_unit.outgoing_verification_requests) == 0 + + +def test_event_date_defintion_deletion(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) event_id = seeder.create_event(admin_unit_id) @@ -180,7 +207,7 @@ def test_event_date_defintion_deletion(client, app, db, seeder): assert event.date_definitions[0].id == date_definition2_id -def test_admin_unit_deletion(client, app, db, seeder): +def test_admin_unit_deletion(client, app, db, seeder: Seeder): user_id, admin_unit_id = seeder.setup_base(log_in=False) my_event_id = seeder.create_event(admin_unit_id) suggestion_id = seeder.create_event_suggestion(admin_unit_id) @@ -206,12 +233,19 @@ def test_admin_unit_deletion(client, app, db, seeder): ) incoming_reference_id = seeder.create_reference(other_event_id, admin_unit_id) outgoing_reference_id = seeder.create_reference(my_event_id, other_admin_unit_id) + incoming_verification_request_id = seeder.create_admin_unit_verification_request( + other_admin_unit_id, admin_unit_id + ) + outgoing_verification_request_id = seeder.create_admin_unit_verification_request( + admin_unit_id, other_admin_unit_id + ) with app.app_context(): from project.models import ( AdminUnit, AdminUnitMemberInvitation, AdminUnitRelation, + AdminUnitVerificationRequest, Event, EventDate, EventDateDefinition, @@ -247,6 +281,18 @@ def test_admin_unit_deletion(client, app, db, seeder): assert ( db.session.get(EventReferenceRequest, outgoing_reference_request_id) is None ) + assert ( + db.session.get( + AdminUnitVerificationRequest, incoming_verification_request_id + ) + is None + ) + assert ( + db.session.get( + AdminUnitVerificationRequest, outgoing_verification_request_id + ) + is None + ) assert db.session.get(EventSuggestion, suggestion_id) is None assert db.session.get(EventPlace, event_place_id) is None assert db.session.get(EventOrganizer, organizer_id) is None @@ -257,7 +303,7 @@ def test_admin_unit_deletion(client, app, db, seeder): assert db.session.get(Event, other_event_id) is not None -def test_event_co_organizers_deletion(client, app, db, seeder): +def test_event_co_organizers_deletion(client, app, db, seeder: Seeder): user_id, admin_unit_id = seeder.setup_base(log_in=False) event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers( admin_unit_id @@ -282,7 +328,7 @@ def test_event_co_organizers_deletion(client, app, db, seeder): assert db.session.get(EventOrganizer, organizer_b_id).id is not None -def test_admin_unit_verification(client, app, db, seeder): +def test_admin_unit_verification(client, app, db, seeder: Seeder): user_id, admin_unit_id = seeder.setup_base(log_in=False, admin_unit_verified=False) other_user_id = seeder.create_user("other@test.de") other_admin_unit_id = seeder.create_admin_unit(other_user_id, "Other Crew") @@ -323,7 +369,7 @@ def test_admin_unit_verification(client, app, db, seeder): assert len(all_verified) == 0 -def test_admin_unit_invitations(client, app, db, seeder): +def test_admin_unit_invitations(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) invitation_id = seeder.create_admin_unit_invitation(admin_unit_id) @@ -342,7 +388,7 @@ def test_admin_unit_invitations(client, app, db, seeder): assert invitation is None -def test_event_list_deletion(client, app, db, seeder): +def test_event_list_deletion(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) event_id = seeder.create_event(admin_unit_id) event_list_a_id = seeder.create_event_list(admin_unit_id, event_id, "List A") @@ -381,7 +427,7 @@ def test_event_list_deletion(client, app, db, seeder): assert len(event_list_b.events) == 0 -def test_event_is_favored_by_current_user(client, app, db, seeder): +def test_event_is_favored_by_current_user(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) event_id = seeder.create_event(admin_unit_id) @@ -392,7 +438,7 @@ def test_event_is_favored_by_current_user(client, app, db, seeder): assert event.is_favored_by_current_user() is False -def test_purge_event_photo(client, app, db, seeder): +def test_purge_event_photo(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) event_id = seeder.create_event(admin_unit_id) first_image_id = seeder.upsert_default_image() @@ -414,7 +460,7 @@ def test_purge_event_photo(client, app, db, seeder): assert image is None -def test_purge_event_place_photo(client, app, db, seeder): +def test_purge_event_place_photo(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) place_id = seeder.upsert_default_event_place(admin_unit_id) first_image_id = seeder.upsert_default_image() @@ -451,7 +497,7 @@ def test_purge_event_place_photo(client, app, db, seeder): assert image is None -def test_purge_eventsuggestion_photo(client, app, db, seeder): +def test_purge_eventsuggestion_photo(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) suggestion_id = seeder.create_event_suggestion(admin_unit_id) image_id = seeder.upsert_default_image() @@ -475,7 +521,7 @@ def test_purge_eventsuggestion_photo(client, app, db, seeder): assert image is None -def test_purge_adminunit(client, app, db, seeder): +def test_purge_adminunit(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) instance_id = admin_unit_id image_id = seeder.upsert_default_image() @@ -507,7 +553,7 @@ def test_purge_adminunit(client, app, db, seeder): assert location is None -def test_purge_eventorganizer(client, app, db, seeder): +def test_purge_eventorganizer(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) instance_id = seeder.upsert_default_event_organizer(admin_unit_id) image_id = seeder.upsert_default_image() @@ -539,7 +585,7 @@ def test_purge_eventorganizer(client, app, db, seeder): assert location is None -def test_delete_admin_unit(client, app, db, seeder): +def test_delete_admin_unit(client, app, db, seeder: Seeder): _, admin_unit_id = seeder.setup_base(log_in=False) instance_id = seeder.upsert_default_event_organizer(admin_unit_id) image_id = seeder.upsert_default_image() diff --git a/tests/views/test_manage.py b/tests/views/test_manage.py index 2cf9016..db0466e 100644 --- a/tests/views/test_manage.py +++ b/tests/views/test_manage.py @@ -24,7 +24,7 @@ def test_index_withValidCookie(client, seeder, app, utils): utils.assert_response_redirect(response, "manage_admin_unit", id=admin_unit_id) -def test_index_withInvalidCookie(client, seeder, utils): +def test_index_withInvalidCookie(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() client.set_cookie("localhost", "manage_admin_unit_id", "invalid") @@ -70,7 +70,7 @@ def test_index_after_login_organization_invitation(client, app, db, utils, seede ) -def test_admin_unit(client, seeder, utils): +def test_admin_unit(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() response = utils.get_endpoint("manage_admin_unit", id=admin_unit_id) @@ -79,7 +79,7 @@ def test_admin_unit(client, seeder, utils): ) -def test_admin_unit_404(client, seeder, utils): +def test_admin_unit_404(client, seeder: Seeder, utils: UtilActions): owner_id = seeder.create_user("owner@owner") admin_unit_id = seeder.create_admin_unit(owner_id, "Other crew") seeder.create_user() @@ -89,13 +89,13 @@ def test_admin_unit_404(client, seeder, utils): utils.assert_response_notFound(response) -def test_admin_unit_event_reviews(client, seeder, utils): +def test_admin_unit_event_reviews(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() utils.get_endpoint_ok("manage_admin_unit_event_reviews", id=admin_unit_id) -def test_admin_unit_events(client, seeder, utils): +def test_admin_unit_events(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base(admin_unit_verified=False) utils.get_endpoint_ok( @@ -112,7 +112,9 @@ def test_admin_unit_events(client, seeder, utils): utils.assert_response_contains(response, event_url) -def test_admin_unit_events_invalidDateFormat(client, seeder, utils): +def test_admin_unit_events_invalidDateFormat( + client, seeder: Seeder, utils: UtilActions +): user_id, admin_unit_id = seeder.setup_base() utils.get_endpoint_ok( @@ -126,7 +128,7 @@ def test_admin_unit_events_invalidDateFormat(client, seeder, utils): ) -def test_admin_unit_events_place(client, seeder, utils): +def test_admin_unit_events_place(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base(admin_unit_verified=False) seeder.create_event(admin_unit_id, draft=True) event_place_id = seeder.upsert_default_event_place(admin_unit_id) @@ -136,25 +138,27 @@ def test_admin_unit_events_place(client, seeder, utils): ) -def test_admin_unit_organizers(client, seeder, utils): +def test_admin_unit_organizers(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() utils.get_endpoint_ok("manage_admin_unit_organizers", id=admin_unit_id) -def test_admin_unit_event_places(client, seeder, utils): +def test_admin_unit_event_places(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() utils.get_endpoint_ok("manage_admin_unit_event_places", id=admin_unit_id) -def test_admin_unit_members(client, seeder, utils): +def test_admin_unit_members(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() utils.get_endpoint_ok("manage_admin_unit_members", id=admin_unit_id) -def test_admin_unit_members_permission_missing(client, seeder, utils): +def test_admin_unit_members_permission_missing( + client, seeder: Seeder, utils: UtilActions +): owner_id, admin_unit_id, member_id = seeder.setup_base_event_verifier() response = utils.get_endpoint("manage_admin_unit_members", id=admin_unit_id) @@ -164,7 +168,9 @@ def test_admin_unit_members_permission_missing(client, seeder, utils): @pytest.mark.parametrize("db_error", [True, False]) -def test_admin_unit_widgets(client, seeder, utils, mocker, db_error): +def test_admin_unit_widgets( + client, seeder: Seeder, utils: UtilActions, mocker, db_error +): user_id, admin_unit_id = seeder.setup_base() url = utils.get_url("manage_admin_unit_widgets", id=admin_unit_id) @@ -184,7 +190,9 @@ def test_admin_unit_widgets(client, seeder, utils, mocker, db_error): ) -def test_admin_unit_widgets_permission_missing(client, seeder, utils, mocker): +def test_admin_unit_widgets_permission_missing( + client, seeder: Seeder, utils: UtilActions, mocker +): owner_id, admin_unit_id, member_id = seeder.setup_base_event_verifier() url = utils.get_url("manage_admin_unit_widgets", id=admin_unit_id) @@ -196,63 +204,43 @@ def test_admin_unit_widgets_permission_missing(client, seeder, utils, mocker): ) -def test_admin_unit_relations(client, seeder, utils): +def test_admin_unit_relations(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() url = utils.get_url("manage_admin_unit_relations", id=admin_unit_id) utils.get_ok(url) -def test_admin_unit_organization_invitations(client, seeder, utils): +def test_admin_unit_organization_invitations( + client, seeder: Seeder, utils: UtilActions +): user_id, admin_unit_id = seeder.setup_base() url = utils.get_url("manage_admin_unit_organization_invitations", id=admin_unit_id) utils.get_ok(url) -def test_admin_unit_event_lists(client, seeder, utils): +def test_admin_unit_event_lists(client, seeder: Seeder, utils: UtilActions): user_id, admin_unit_id = seeder.setup_base() url = utils.get_url("manage_admin_unit_event_lists", id=admin_unit_id) utils.get_ok(url) -def test_admin_unit_custom_widgets(client, seeder, utils): +def test_admin_unit_custom_widgets(client, seeder: Seeder, utils: UtilActions): _, admin_unit_id = seeder.setup_base() url = utils.get_url("manage_admin_unit_custom_widgets", id=admin_unit_id) utils.get_ok(url) -def test_admin_unit_events_import(client, seeder, utils): +def test_admin_unit_events_import(client, seeder: Seeder, utils: UtilActions): _, admin_unit_id = seeder.setup_base() url = utils.get_url("manage_admin_unit_events_import", id=admin_unit_id) utils.get_ok(url) -def test_verification_requests_outgoing(client, seeder, utils): - user_id = seeder.create_user() - seeder.create_admin_unit( - user_id, - "Stadtmarketing", - verified=True, - can_verify_other=True, - incoming_verification_requests_allowed=True, - incoming_verification_requests_text="Please give us a call", - ) - - _, other_admin_unit_id = seeder.setup_base( - admin_unit_verified=False, email="mitglied@verein.de", name="Verein" - ) - - response = utils.get_endpoint_ok( - "manage_admin_unit_verification_requests_outgoing", id=other_admin_unit_id - ) - utils.assert_response_contains(response, "Stadtmarketing") - utils.assert_response_contains(response, "Please give us a call") - - @pytest.mark.parametrize("scenario", ["db_error", "default", "last_admin", "non_match"]) def test_manage_admin_unit_delete_membership( client, utils: UtilActions, seeder: Seeder, app, db, mocker, scenario: str diff --git a/tests/views/test_verification_request.py b/tests/views/test_verification_request.py new file mode 100644 index 0000000..0514d08 --- /dev/null +++ b/tests/views/test_verification_request.py @@ -0,0 +1,166 @@ +import pytest + +from tests.seeder import Seeder +from tests.utils import UtilActions + + +@pytest.mark.parametrize("db_error", [True, False]) +def test_create(client, app, utils: UtilActions, seeder: Seeder, mocker, db_error): + ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) = seeder.setup_admin_unit_missing_verification_scenario() + + url = utils.get_url( + "manage_admin_unit_verification_requests_outgoing_create", + id=unverified_admin_unit_id, + target_id=verifier_admin_unit_id, + ) + response = utils.get_ok(url) + + if db_error: + utils.mock_db_commit(mocker) + + mail_mock = utils.mock_send_mails(mocker) + response = utils.post_form( + url, + response, + {}, + ) + + if db_error: + utils.assert_response_db_error(response) + return + + utils.assert_response_redirect( + response, + "manage_admin_unit_verification_requests_outgoing", + id=unverified_admin_unit_id, + ) + utils.assert_send_mail_called(mail_mock, "test@test.de") + + with app.app_context(): + from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, + ) + + verification_request = ( + AdminUnitVerificationRequest.query.filter( + AdminUnitVerificationRequest.source_admin_unit_id + == unverified_admin_unit_id + ) + .filter( + AdminUnitVerificationRequest.target_admin_unit_id + == verifier_admin_unit_id + ) + .first() + ) + assert verification_request is not None + assert ( + verification_request.review_status + == AdminUnitVerificationRequestReviewStatus.inbox + ) + + +def test_admin_unit_verification_requests_incoming( + client, utils: UtilActions, seeder: Seeder +): + user_id, admin_unit_id = seeder.setup_base() + seeder.create_incoming_admin_unit_verification_request(admin_unit_id) + + utils.get_endpoint_ok( + "manage_admin_unit_verification_requests_incoming", id=admin_unit_id + ) + + +def test_verification_requests_outgoing(client, seeder: Seeder, utils: UtilActions): + ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) = seeder.setup_admin_unit_missing_verification_scenario() + + response = utils.get_endpoint( + "manage_admin_unit_verification_requests_outgoing", id=unverified_admin_unit_id + ) + utils.assert_response_redirect( + response, + "manage_admin_unit_verification_requests_outgoing_create_select", + id=unverified_admin_unit_id, + ) + + response = utils.get_endpoint_ok( + "manage_admin_unit_verification_requests_outgoing_create_select", + id=unverified_admin_unit_id, + ) + utils.assert_response_contains(response, "Stadtmarketing") + utils.assert_response_contains(response, "Please give us a call") + + seeder.create_admin_unit_verification_request( + unverified_admin_unit_id, verifier_admin_unit_id + ) + response = utils.get_endpoint_ok( + "manage_admin_unit_verification_requests_outgoing", + id=unverified_admin_unit_id, + ) + + +@pytest.mark.parametrize("db_error", [True, False]) +@pytest.mark.parametrize("non_match", [True, False]) +def test_delete( + client, seeder: Seeder, utils: UtilActions, app, db, mocker, db_error, non_match +): + ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) = seeder.setup_admin_unit_missing_verification_scenario() + request_id = seeder.create_admin_unit_verification_request( + unverified_admin_unit_id, verifier_admin_unit_id + ) + + url = utils.get_url("admin_unit_verification_request_delete", id=request_id) + response = utils.get_ok(url) + + if db_error: + utils.mock_db_commit(mocker) + + form_name = "Stadtmarketing" + + if non_match: + form_name = "Falscher Name" + + response = utils.post_form( + url, + response, + { + "name": form_name, + }, + ) + + if non_match: + utils.assert_response_error_message( + response, "Der eingegebene Name entspricht nicht dem Namen der Organisation" + ) + return + + if db_error: + utils.assert_response_db_error(response) + return + + utils.assert_response_redirect( + response, + "manage_admin_unit_verification_requests_outgoing", + id=unverified_admin_unit_id, + ) + + with app.app_context(): + from project.models import AdminUnitVerificationRequest + + request = db.session.get(AdminUnitVerificationRequest, request_id) + assert request is None diff --git a/tests/views/test_verification_request_review.py b/tests/views/test_verification_request_review.py new file mode 100644 index 0000000..9eb431d --- /dev/null +++ b/tests/views/test_verification_request_review.py @@ -0,0 +1,174 @@ +import pytest + +from tests.seeder import Seeder +from tests.utils import UtilActions + + +@pytest.mark.parametrize("db_error", [True, False]) +@pytest.mark.parametrize("is_verified", [True, False]) +def test_review_verify( + client, seeder: Seeder, utils: UtilActions, app, mocker, db, db_error, is_verified +): + ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) = seeder.setup_admin_unit_missing_verification_scenario(log_in_verifier=True) + verification_request_id = seeder.create_admin_unit_verification_request( + unverified_admin_unit_id, verifier_admin_unit_id + ) + + url = utils.get_url( + "admin_unit_verification_request_review", id=verification_request_id + ) + + if is_verified: + with app.app_context(): + from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, + ) + + verification_request = db.session.get( + AdminUnitVerificationRequest, verification_request_id + ) + verification_request.review_status = ( + AdminUnitVerificationRequestReviewStatus.verified + ) + db.session.commit() + + response = client.get(url) + utils.assert_response_redirect( + response, + "manage_admin_unit_verification_requests_incoming", + id=verifier_admin_unit_id, + ) + return + + response = utils.get_ok(url) + + if db_error: + utils.mock_db_commit(mocker) + + mail_mock = utils.mock_send_mails(mocker) + response = utils.post_form( + url, + response, + { + "review_status": 2, + "auto_verify": 1, + }, + ) + + if db_error: + utils.assert_response_db_error(response) + return + + utils.assert_response_redirect( + response, + "manage_admin_unit_verification_requests_incoming", + id=verifier_admin_unit_id, + ) + utils.assert_send_mail_called(mail_mock, "mitglied@verein.de") + + with app.app_context(): + from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, + ) + from project.services.admin_unit import get_admin_unit_relation + + verification_request = db.session.get( + AdminUnitVerificationRequest, verification_request_id + ) + assert verification_request.verified + + relation = get_admin_unit_relation( + verifier_admin_unit_id, unverified_admin_unit_id + ) + assert relation is not None + assert relation.verify + assert relation.auto_verify_event_reference_requests + + +def test_review_reject(client, seeder: Seeder, utils: UtilActions, app, db, mocker): + ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) = seeder.setup_admin_unit_missing_verification_scenario(log_in_verifier=True) + verification_request_id = seeder.create_admin_unit_verification_request( + unverified_admin_unit_id, verifier_admin_unit_id + ) + + url = utils.get_url( + "admin_unit_verification_request_review", id=verification_request_id + ) + response = utils.get_ok(url) + + response = utils.post_form( + url, + response, + { + "review_status": 3, + "rejection_reason": 0, + }, + ) + + utils.assert_response_redirect( + response, + "manage_admin_unit_verification_requests_incoming", + id=verifier_admin_unit_id, + ) + + with app.app_context(): + from project.models import ( + AdminUnitVerificationRequest, + AdminUnitVerificationRequestReviewStatus, + ) + + verification_request = db.session.get( + AdminUnitVerificationRequest, verification_request_id + ) + assert ( + verification_request.review_status + == AdminUnitVerificationRequestReviewStatus.rejected + ) + assert verification_request.rejection_reason is None + + +def test_review_status(client, seeder: Seeder, utils: UtilActions): + ( + verifier_user_id, + verifier_admin_unit_id, + unverified_user_id, + unverified_admin_unit_id, + ) = seeder.setup_admin_unit_missing_verification_scenario(log_in_verifier=True) + verification_request_id = seeder.create_admin_unit_verification_request( + unverified_admin_unit_id, verifier_admin_unit_id + ) + + url = utils.get_url( + "admin_unit_verification_request_review_status", id=verification_request_id + ) + utils.get_ok(url) + + +def test_review_status_401_unauthorized(client, seeder: Seeder, utils: UtilActions): + seeder.create_user() + + third_user_id = seeder.create_user("third@third.de") + third_admin_unit_id = seeder.create_admin_unit(third_user_id, "Third Crew") + ( + other_user_id, + other_admin_unit_id, + verification_request_id, + ) = seeder.create_incoming_admin_unit_verification_request(third_admin_unit_id) + + url = utils.get_url( + "admin_unit_verification_request_review_status", id=verification_request_id + ) + response = client.get(url) + assert response.status_code == 401