diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bb4ccd65..172ecf0a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ on: default: 'master' jobs: wagon_tests: - uses: hitobito/hitobito/.github/workflows/wagon-tests.yml@master + uses: hitobito/hitobito/.github/workflows/wagon-tests.yml@psql-migration with: wagon_repository: ${{ github.event.repository.name }} core_ref: ${{ inputs.core_ref }} diff --git a/Rakefile b/Rakefile index 50c04c89..09a73901 100644 --- a/Rakefile +++ b/Rakefile @@ -22,5 +22,3 @@ load "rspec/rails/tasks/rspec.rake" require "ci/reporter/rake/rspec" unless Rails.env.production? HitobitoInsieme::Wagon.load_tasks - -task "test:prepare" => "db:test:prepare" diff --git a/app/domain/fp2015/course_reporting/aggregation.rb b/app/domain/fp2015/course_reporting/aggregation.rb index 96caa067..cdfdf935 100644 --- a/app/domain/fp2015/course_reporting/aggregation.rb +++ b/app/domain/fp2015/course_reporting/aggregation.rb @@ -135,10 +135,10 @@ def total(course_records) end def select_clause - columns = ["event_course_records.year", - "event_course_records.kursart", - "event_course_records.inputkriterien", - "event_course_records.event_id"] + columns = ["MIN(event_course_records.year) AS year", + "MIN(event_course_records.kursart) AS kursart", + "MIN(event_course_records.inputkriterien) AS inputkriterien", + "MIN(event_course_records.event_id) AS event_id"] columns.concat(sql_summed_attrs) columns << sql_sum_unterkunft columns.join(", ") diff --git a/app/domain/fp2020/course_reporting/aggregation.rb b/app/domain/fp2020/course_reporting/aggregation.rb index 315c5af5..40e974cf 100644 --- a/app/domain/fp2020/course_reporting/aggregation.rb +++ b/app/domain/fp2020/course_reporting/aggregation.rb @@ -106,7 +106,8 @@ def build_totals(hash) end def records_for(attr, value) - records.select { |record| record.send(attr) == value } + Event::Course.first.fachkonzept + records.select { |record| record.event.send(attr) == value } end def find_record(fachkonzept, kursart) @@ -136,10 +137,10 @@ def total(course_records) end def select_clause - columns = ["event_course_records.year", - "event_course_records.kursart", - "events.fachkonzept", - "event_course_records.event_id"] + columns = ["MIN(event_course_records.year) AS year", + "MIN(event_course_records.kursart) AS kursart", + "MIN(events.fachkonzept) AS fachkonzept", + "MIN(event_course_records.event_id) AS event_id"] columns.concat(sql_summed_attrs) columns << sql_sum_unterkunft columns.join(", ") diff --git a/app/domain/fp2020/course_reporting/client_statistics.rb b/app/domain/fp2020/course_reporting/client_statistics.rb index 1bc9e493..ba670556 100644 --- a/app/domain/fp2020/course_reporting/client_statistics.rb +++ b/app/domain/fp2020/course_reporting/client_statistics.rb @@ -68,7 +68,7 @@ def group_canton_participants def group_canton_participants_relation # rubocop:disable Metrics/MethodLength,Metrics/AbcSize columns = [ - "`groups`.id AS group_id", + "MAX(groups.id) AS group_id", "events.leistungskategorie AS event_leistungskategorie" ] @@ -103,7 +103,7 @@ def group_canton_participants_relation # rubocop:disable Metrics/MethodLength,Me CASE events.leistungskategorie WHEN 'tp' THEN 0 ELSE - CASE events.type + CASE MAX(events.type) WHEN 'Event::AggregateCourse' THEN SUM(COALESCE(event_course_records.tage_weitere, 0)) ELSE diff --git a/app/domain/fp2020/time_record/lufeb_pro_verein.rb b/app/domain/fp2020/time_record/lufeb_pro_verein.rb index e0929371..e05e7756 100644 --- a/app/domain/fp2020/time_record/lufeb_pro_verein.rb +++ b/app/domain/fp2020/time_record/lufeb_pro_verein.rb @@ -36,10 +36,10 @@ def time_records # rubocop:disable Metrics/MethodLength .group(:group_id) .select([ "group_id", - "SUM(total_lufeb_general) AS `general`", - "SUM(total_lufeb_specific) AS `specific`", - "SUM(total_lufeb_promoting) AS `promoting`", - "SUM(lufeb_grundlagen) AS `lufeb_grundlagen`", + "SUM(total_lufeb_general) AS general", + "SUM(total_lufeb_specific) AS specific", + "SUM(total_lufeb_promoting) AS promoting", + "SUM(lufeb_grundlagen) AS lufeb_grundlagen", "SUM(kurse_grundlagen) AS kurse_grundlagen" ].join(", ")) .all diff --git a/app/domain/fp2022/course_reporting/aggregation.rb b/app/domain/fp2022/course_reporting/aggregation.rb index d1f54372..0dfe4f13 100644 --- a/app/domain/fp2022/course_reporting/aggregation.rb +++ b/app/domain/fp2022/course_reporting/aggregation.rb @@ -106,7 +106,7 @@ def build_totals(hash) end def records_for(attr, value) - records.select { |record| record.send(attr) == value } + records.select { |record| record.event.send(attr) == value } end def find_record(fachkonzept, kursart) @@ -136,10 +136,10 @@ def total(course_records) end def select_clause - columns = ["event_course_records.year", - "event_course_records.kursart", - "events.fachkonzept", - "event_course_records.event_id"] + columns = ["MIN(event_course_records.year) AS year", + "MIN(event_course_records.kursart) AS kursart", + "MIN(events.fachkonzept) AS fachkonzept", + "MIN(event_course_records.event_id) AS event_id"] columns.concat(sql_summed_attrs) columns << sql_sum_unterkunft columns.join(", ") diff --git a/app/domain/fp2022/course_reporting/client_statistics.rb b/app/domain/fp2022/course_reporting/client_statistics.rb index 2de7d016..16ef1ff6 100644 --- a/app/domain/fp2022/course_reporting/client_statistics.rb +++ b/app/domain/fp2022/course_reporting/client_statistics.rb @@ -68,7 +68,7 @@ def group_canton_participants def group_canton_participants_relation # rubocop:disable Metrics/MethodLength,Metrics/AbcSize columns = [ - "`groups`.id AS group_id", + "MAX(groups.id) AS group_id", "events.leistungskategorie AS event_leistungskategorie" ] @@ -103,7 +103,7 @@ def group_canton_participants_relation # rubocop:disable Metrics/MethodLength,Me CASE events.leistungskategorie WHEN 'tp' THEN 0 ELSE - CASE events.type + CASE MAX(events.type) WHEN 'Event::AggregateCourse' THEN SUM(COALESCE(event_course_records.tage_weitere, 0)) ELSE diff --git a/app/domain/fp2022/time_record/lufeb_pro_verein.rb b/app/domain/fp2022/time_record/lufeb_pro_verein.rb index 3a826242..262aa409 100644 --- a/app/domain/fp2022/time_record/lufeb_pro_verein.rb +++ b/app/domain/fp2022/time_record/lufeb_pro_verein.rb @@ -36,10 +36,10 @@ def time_records # rubocop:disable Metrics/MethodLength .group(:group_id) .select([ "group_id", - "SUM(total_lufeb_general) AS `general`", - "SUM(total_lufeb_specific) AS `specific`", - "SUM(total_lufeb_promoting) AS `promoting`", - "SUM(lufeb_grundlagen) AS `lufeb_grundlagen`", + "SUM(total_lufeb_general) AS general", + "SUM(total_lufeb_specific) AS specific", + "SUM(total_lufeb_promoting) AS promoting", + "SUM(lufeb_grundlagen) AS lufeb_grundlagen", "SUM(kurse_grundlagen) AS kurse_grundlagen" ].join(", ")) .all diff --git a/app/domain/statistics/vereinsmitglieder.rb b/app/domain/statistics/vereinsmitglieder.rb index aee16e0a..70858cc8 100644 --- a/app/domain/statistics/vereinsmitglieder.rb +++ b/app/domain/statistics/vereinsmitglieder.rb @@ -37,10 +37,10 @@ def type_counts end def type_counts_per_layer - result = Role.connection.execute(type_counts_per_layer_query) + result = Role.connection.execute(type_counts_per_layer_query).to_a result.each_with_object({}) do |row, hash| - hash[row[0]] ||= Hash.new(0) - hash[row[0]][row[1]] = row[2] + hash[row["layer_group_id"]] ||= Hash.new(0) + hash[row["layer_group_id"]][row["type_index"]] = row["count"] end end @@ -54,16 +54,16 @@ def type_counts_per_layer_query def person_roles_per_layer_query <<-SQL - SELECT `groups`.layer_group_id AS layer_group_id, + SELECT "groups".layer_group_id AS layer_group_id, MIN(#{type_index_switch}) AS type_index, roles.person_id AS person_id FROM roles - INNER JOIN `groups` `groups` ON `groups`.id = roles.group_id - INNER JOIN `groups` layers ON layers.id = `groups`.layer_group_id + INNER JOIN "groups" "groups" ON "groups".id = roles.group_id + INNER JOIN "groups" layers ON layers.id = "groups".layer_group_id WHERE layers.type = '#{Group::Regionalverein.sti_name}' AND roles.deleted_at IS NULL AND roles.type IN (#{role_types_param}) - GROUP BY `groups`.layer_group_id, + GROUP BY "groups".layer_group_id, roles.person_id SQL end diff --git a/app/indices/person_index.rb b/app/indices/person_index.rb deleted file mode 100644 index 272151cc..00000000 --- a/app/indices/person_index.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -# Copyright (c) 2012-2014, insieme Schweiz. This file is part of -# hitobito_insieme and licensed under the Affero General Public License version 3 -# or later. See the COPYING file at the top-level directory or at -# https://github.com/hitobito/hitobito_insieme. - -module PersonIndex; end - -ThinkingSphinx::Index.define_partial :person do - indexes number, salutation, canton -end diff --git a/app/models/insieme/person.rb b/app/models/insieme/person.rb index b4919385..fd42891a 100644 --- a/app/models/insieme/person.rb +++ b/app/models/insieme/person.rb @@ -24,6 +24,9 @@ module Insieme::Person Person::PUBLIC_ATTRS << :number << :salutation << :correspondence_language + Person::SEARCHABLE_ATTRS << :number << :salutation << :canton + include PgSearchable + ADDRESS_TYPES.each do |prefix| ADDRESS_FIELDS.each do |field| Person::PUBLIC_ATTRS << :"#{prefix}_#{field}" @@ -72,7 +75,7 @@ def grouped_active_membership_roles if @grouped_active_membership_roles.nil? active_memberships = roles.includes(:group) .joins(:group) - .where(groups: {type: ::Group::Aktivmitglieder}) + .where(groups: {type: ::Group::Aktivmitglieder.sti_name}) @grouped_active_membership_roles = Hash.new { |h, k| h[k] = [] } active_memberships.each do |role| @grouped_active_membership_roles[role.group] << role diff --git a/spec/domain/fp2015/export/tabular/statistics/group_figures_spec.rb b/spec/domain/fp2015/export/tabular/statistics/group_figures_spec.rb index 735062d4..7a6f66ee 100644 --- a/spec/domain/fp2015/export/tabular/statistics/group_figures_spec.rb +++ b/spec/domain/fp2015/export/tabular/statistics/group_figures_spec.rb @@ -191,6 +191,23 @@ def export(figures) ] expect(data.second).to eq [ + "Biel-Seeland", "Bern", nil, 3115, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, + 0.0, 0.0, 0.0, 0.0, 0.0, + -200000.0, 0.0, 0.0, 0.0, 0.0 + ] + + expect(data.third).to eq [ "Freiburg", "Freiburg", nil, 12607, 1, 0.0, 1545.0, 0.0, 0.0, 1545.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -207,7 +224,7 @@ def export(figures) -185550.0, 0.0, 1100.0, 0.0, -1100.0 ] - expect(data.third).to eq [ + expect(data.fourth).to eq [ "Kanton Bern", "Bern", nil, 2024, 2, 1100.0, 1000.0, 1111.0, 0.0, 2111.0, 1, 800.0, 5400.0, 0.0, 0.0, 5400.0, @@ -223,23 +240,6 @@ def export(figures) 0.25, 0.25, (50.0 / 1900).round(5), (50.0 / 1900).round(5), (20.0 / 1900).round(5), 10_074_000.0, 100.0, 2050.0, 20.0, -2000.0 ] - - expect(data.fourth).to eq [ - "Biel-Seeland", "Bern", nil, 3115, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, - 0.0, 0.0, 0.0, 0.0, 0.0, - -200000.0, 0.0, 0.0, 0.0, 0.0 - ] end def create_course(year, group_key, leistungskategorie, kategorie, attrs) diff --git a/spec/domain/fp2015/export/tabular/time_records/vereinsliste_spec.rb b/spec/domain/fp2015/export/tabular/time_records/vereinsliste_spec.rb index d476510c..8df4aae5 100644 --- a/spec/domain/fp2015/export/tabular/time_records/vereinsliste_spec.rb +++ b/spec/domain/fp2015/export/tabular/time_records/vereinsliste_spec.rb @@ -126,7 +126,7 @@ context "for employee time" do it "contains all data" do data = export - expect(data[2]).to eq(["Kanton Bern", + expect(data[3]).to eq(["Kanton Bern", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 200, nil, nil, 330, 530, nil, nil, nil, nil, nil, 0, @@ -154,7 +154,7 @@ it "contains all data" do data = export - expect(data[2]).to eq(["Kanton Bern", + expect(data[3]).to eq(["Kanton Bern", 300, nil, nil, diff --git a/spec/domain/fp2020/export/tabular/statistics/group_figures_spec.rb b/spec/domain/fp2020/export/tabular/statistics/group_figures_spec.rb index 7b5056b8..80b09211 100644 --- a/spec/domain/fp2020/export/tabular/statistics/group_figures_spec.rb +++ b/spec/domain/fp2020/export/tabular/statistics/group_figures_spec.rb @@ -398,7 +398,7 @@ end it "for Freiburg" do - expect(data.second).to include(empty_row.merge({ + expect(data.third).to include(empty_row.merge({ "Vollständiger Name" => "Freiburg", "Kanton" => "Freiburg", "VID" => nil, @@ -443,7 +443,7 @@ it "for Kanton Bern" do # 30 Stunden für LUFEB / 1900 BSV-Stunden - expect(data.third).to include(empty_row.merge({ + expect(data.fourth).to include(empty_row.merge({ "Vollständiger Name" => "Kanton Bern", "Kanton" => "Bern", "BSV Nummer" => 2024, @@ -510,7 +510,7 @@ end it "for Biel-Seeland" do - expect(data.fourth).to include(empty_row.merge({ + expect(data.second).to include(empty_row.merge({ "Vollständiger Name" => "Biel-Seeland", "Kanton" => "Bern", "BSV Nummer" => 3115, diff --git a/spec/domain/fp2020/export/tabular/time_records/vereinsliste_spec.rb b/spec/domain/fp2020/export/tabular/time_records/vereinsliste_spec.rb index 9790d2dc..1422ee88 100644 --- a/spec/domain/fp2020/export/tabular/time_records/vereinsliste_spec.rb +++ b/spec/domain/fp2020/export/tabular/time_records/vereinsliste_spec.rb @@ -128,7 +128,7 @@ context "for employee time" do it "contains all data" do data = export - expect(data[2]).to eq(["Kanton Bern", + expect(data[3]).to eq(["Kanton Bern", nil, nil, nil, nil, 0, nil, nil, nil, nil, 0, nil, nil, nil, nil, 0, 0, @@ -163,7 +163,7 @@ it "contains all data" do data = export - expect(labels.zip(data[2]).to_h).to eq empty_row.merge({ + expect(labels.zip(data[3]).to_h).to eq empty_row.merge({ "Gruppe" => "Kanton Bern", "Allgemeine Medien- und Öffentlichkeitsarbeit" => 300, diff --git a/spec/domain/fp2022/export/tabular/statistics/group_figures_spec.rb b/spec/domain/fp2022/export/tabular/statistics/group_figures_spec.rb index 6993644a..6d02046a 100644 --- a/spec/domain/fp2022/export/tabular/statistics/group_figures_spec.rb +++ b/spec/domain/fp2022/export/tabular/statistics/group_figures_spec.rb @@ -406,7 +406,7 @@ end it "for Freiburg" do - expect(data.second).to include(empty_row.merge({ + expect(data.third).to include(empty_row.merge({ "Vollständiger Name" => "Freiburg", "Kanton" => "Freiburg", "VID" => nil, @@ -452,7 +452,7 @@ it "for Kanton Bern" do # 30 Stunden für LUFEB / 1900 BSV-Stunden - expect(data.third).to include(empty_row.merge({ + expect(data.fourth).to include(empty_row.merge({ "Vollständiger Name" => "Kanton Bern", "Kanton" => "Bern", "BSV Nummer" => 2024, @@ -522,7 +522,7 @@ end it "for Biel-Seeland" do - expect(data.fourth).to include(empty_row.merge({ + expect(data.second).to include(empty_row.merge({ "Vollständiger Name" => "Biel-Seeland", "Kanton" => "Bern", "BSV Nummer" => 3115, diff --git a/spec/domain/fp2022/export/tabular/time_records/vereinsliste_spec.rb b/spec/domain/fp2022/export/tabular/time_records/vereinsliste_spec.rb index 80ad034e..0c9c0401 100644 --- a/spec/domain/fp2022/export/tabular/time_records/vereinsliste_spec.rb +++ b/spec/domain/fp2022/export/tabular/time_records/vereinsliste_spec.rb @@ -130,7 +130,7 @@ context "for employee time" do it "contains all data" do data = export - expect(data[2]).to eq(["Kanton Bern", + expect(data[3]).to eq(["Kanton Bern", nil, nil, nil, nil, 0, nil, nil, nil, nil, 0, nil, nil, nil, nil, 0, 0, @@ -165,7 +165,7 @@ it "contains all data" do data = export - expect(labels.zip(data[2]).to_h).to eq empty_row.merge({ + expect(labels.zip(data[3]).to_h).to eq empty_row.merge({ "Gruppe" => "Kanton Bern", "Allgemeine Medien- und Öffentlichkeitsarbeit" => 300, diff --git a/spec/domain/search_strategies/person_search_spec.rb b/spec/domain/search_strategies/person_search_spec.rb new file mode 100644 index 00000000..d54f8252 --- /dev/null +++ b/spec/domain/search_strategies/person_search_spec.rb @@ -0,0 +1,32 @@ +# Copyright (c) 2012-2024, Hitobito AG. This file is part of +# hitobito and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito. + +require "spec_helper" + +describe SearchStrategies::PersonSearch do + before do + people(:regio_leader).update!(number: 12345, salutation: "Wassup Regio Leader") + end + + describe "#search_fulltext" do + let(:user) { people(:top_leader) } + + it "finds accessible person by number" do + result = search_class(people(:regio_leader).number.to_s).search_fulltext + + expect(result).to include(people(:regio_leader)) + end + + it "finds accessible person by salutation" do + result = search_class(people(:regio_leader).salutation[0..5]).search_fulltext + + expect(result).to include(people(:regio_leader)) + end + end + + def search_class(term = nil, page = nil) + described_class.new(user, term, page) + end +end diff --git a/spec/domain/statistics/group_figures_spec.rb b/spec/domain/statistics/group_figures_spec.rb index 66a37bcb..edf5f766 100644 --- a/spec/domain/statistics/group_figures_spec.rb +++ b/spec/domain/statistics/group_figures_spec.rb @@ -84,10 +84,12 @@ context "#groups" do it "returns group sorted by type" do - expect(figures.groups).to eq [groups(:dachverein), + expect(figures.groups).to eq [ + groups(:dachverein), + groups(:seeland), groups(:fr), - groups(:be), - groups(:seeland)] + groups(:be) + ] end end diff --git a/spec/fixtures/group_type_orders.yml b/spec/fixtures/group_type_orders.yml new file mode 100644 index 00000000..eeefbe96 --- /dev/null +++ b/spec/fixtures/group_type_orders.yml @@ -0,0 +1,51 @@ +dachverein: + name: Group::Dachverein + order_weight: 1 + +dachverein_liste: + name: Group::DachvereinListe + order_weight: 2 + +dachverein_gremium: + name: Group::DachvereinGremium + order_weight: 3 + +dachverein_abonnemente: + name: Group::DachvereinAbonnemente + order_weight: 4 + +regionalverein: + name: Group::Regionalverein + order_weight: 5 + +regionalverein_liste: + name: Group::RegionalvereinListe + order_weight: 6 + +regionalverein_gremium: + name: Group::RegionalvereinGremium + order_weight: 7 + +externe_organisation: + name: Group::ExterneOrganisation + order_weight: 8 + +aktivmitglieder: + name: Group::Aktivmitglieder + order_weight: 9 + +passivmitglieder: + name: Group::Passivmitglieder + order_weight: 10 + +kollektivmitglieder: + name: Group::Kollektivmitglieder + order_weight: 11 + +externe_organisation_liste: + name: Group::ExterneOrganisationListe + order_weight: 12 + +externe_organisation_gremium: + name: Group::ExterneOrganisationGremium + order_weight: 13 diff --git a/spec/fixtures/role_type_orders.yml b/spec/fixtures/role_type_orders.yml new file mode 100644 index 00000000..e225229a --- /dev/null +++ b/spec/fixtures/role_type_orders.yml @@ -0,0 +1,203 @@ +dachverein_praesident: + name: Group::Dachverein::Praesident + order_weight: 1 + +dachverein_vorstandsmitglied: + name: Group::Dachverein::Vorstandsmitglied + order_weight: 2 + +dachverein_geschaeftsfuehrung: + name: Group::Dachverein::Geschaeftsfuehrung + order_weight: 3 + +dachverein_sekretariat: + name: Group::Dachverein::Sekretariat + order_weight: 4 + +dachverein_adressverwaltung: + name: Group::Dachverein::Adressverwaltung + order_weight: 5 + +dachverein_controlling: + name: Group::Dachverein::Controlling + order_weight: 6 + +dachverein_invoicing: + name: Group::Dachverein::Invoicing + order_weight: 7 + +dachverein_it_support: + name: Group::Dachverein::ItSupport + order_weight: 8 + +dachverein_external: + name: Group::Dachverein::External + order_weight: 9 + +dachverein_liste_listenverwaltung: + name: Group::DachvereinListe::Listenverwaltung + order_weight: 10 + +dachverein_liste_person: + name: Group::DachvereinListe::Person + order_weight: 11 + +dachverein_gremium_leitung: + name: Group::DachvereinGremium::Leitung + order_weight: 12 + +dachverein_gremium_mitglied: + name: Group::DachvereinGremium::Mitglied + order_weight: 13 + +dachverein_abonnemente_einzelabo: + name: Group::DachvereinAbonnemente::Einzelabo + order_weight: 14 + +dachverein_abonnemente_geschenkabo: + name: Group::DachvereinAbonnemente::Geschenkabo + order_weight: 15 + +dachverein_abonnemente_gratisabo: + name: Group::DachvereinAbonnemente::Gratisabo + order_weight: 16 + +regionalverein_praesident: + name: Group::Regionalverein::Praesident + order_weight: 17 + +regionalverein_vorstandsmitglied: + name: Group::Regionalverein::Vorstandsmitglied + order_weight: 18 + +regionalverein_geschaeftsfuehrung: + name: Group::Regionalverein::Geschaeftsfuehrung + order_weight: 19 + +regionalverein_sekretariat: + name: Group::Regionalverein::Sekretariat + order_weight: 20 + +regionalverein_adressverwaltung: + name: Group::Regionalverein::Adressverwaltung + order_weight: 21 + +regionalverein_versandadresse: + name: Group::Regionalverein::Versandadresse + order_weight: 22 + +regionalverein_rechnungsadresse: + name: Group::Regionalverein::Rechnungsadresse + order_weight: 23 + +regionalverein_controlling: + name: Group::Regionalverein::Controlling + order_weight: 24 + +regionalverein_invoicing: + name: Group::Regionalverein::Invoicing + order_weight: 25 + +regionalverein_external: + name: Group::Regionalverein::External + order_weight: 26 + +regionalverein_liste_listenverwaltung: + name: Group::RegionalvereinListe::Listenverwaltung + order_weight: 27 + +regionalverein_liste_person: + name: Group::RegionalvereinListe::Person + order_weight: 28 + +regionalverein_gremium_leitung: + name: Group::RegionalvereinGremium::Leitung + order_weight: 29 + +regionalverein_gremium_mitglied: + name: Group::RegionalvereinGremium::Mitglied + order_weight: 30 + +externe_organisation_praesident: + name: Group::ExterneOrganisation::Praesident + order_weight: 31 + +externe_organisation_vorstandsmitglied: + name: Group::ExterneOrganisation::Vorstandsmitglied + order_weight: 32 + +externe_organisation_geschaeftsfuehrung: + name: Group::ExterneOrganisation::Geschaeftsfuehrung + order_weight: 33 + +externe_organisation_sekretariat: + name: Group::ExterneOrganisation::Sekretariat + order_weight: 34 + +externe_organisation_adressverwaltung: + name: Group::ExterneOrganisation::Adressverwaltung + order_weight: 35 + +externe_organisation_versandadresse: + name: Group::ExterneOrganisation::Versandadresse + order_weight: 36 + +externe_organisation_rechnungsadresse: + name: Group::ExterneOrganisation::Rechnungsadresse + order_weight: 37 + +externe_organisation_controlling: + name: Group::ExterneOrganisation::Controlling + order_weight: 38 + +externe_organisation_invoicing: + name: Group::ExterneOrganisation::Invoicing + order_weight: 39 + +externe_organisation_external: + name: Group::ExterneOrganisation::External + order_weight: 40 + +aktivmitglieder_aktivmitglied: + name: Group::Aktivmitglieder::Aktivmitglied + order_weight: 41 + +aktivmitglieder_aktivmitglied_ohne_abo: + name: Group::Aktivmitglieder::AktivmitgliedOhneAbo + order_weight: 42 + +aktivmitglieder_zweitmitgliedschaft: + name: Group::Aktivmitglieder::Zweitmitgliedschaft + order_weight: 43 + +passivmitglieder_passivmitglied: + name: Group::Passivmitglieder::Passivmitglied + order_weight: 44 + +passivmitglieder_passivmitglied_mit_abo: + name: Group::Passivmitglieder::PassivmitgliedMitAbo + order_weight: 45 + +kollektivmitglieder_kollektivmitglied: + name: Group::Kollektivmitglieder::Kollektivmitglied + order_weight: 46 + +kollektivmitglieder_kollektivmitglied_mit_abo: + name: Group::Kollektivmitglieder::KollektivmitgliedMitAbo + order_weight: 47 + +externe_organisation_liste_listenverwaltung: + name: Group::ExterneOrganisationListe::Listenverwaltung + order_weight: 48 + +externe_organisation_liste_person: + name: Group::ExterneOrganisationListe::Person + order_weight: 49 + +externe_organisation_gremium_leitung: + name: Group::ExterneOrganisationGremium::Leitung + order_weight: 50 + +externe_organisation_gremium_mitglied: + name: Group::ExterneOrganisationGremium::Mitglied + order_weight: 51