Skip to content

Commit

Permalink
Merge pull request #289 from hitobito/#2147_siblings-in-layer
Browse files Browse the repository at this point in the history
PEOPLE: Geschwister in Abteilung als computed value
  • Loading branch information
TheWalkingLeek authored Dec 11, 2023
2 parents c9ada40 + 16e03cf commit 9fea7ed
Show file tree
Hide file tree
Showing 19 changed files with 220 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Hitobito PBS Changelog

## unreleased

* Das Feld "Geschwister in der Abteilung" wird neu von eingetragenen Geschwistern abgeleitet und pro Ebene bzw. pro Anlass berechnet und angezeigt. (hitobito#2147)

## Version 1.30

* Das Anwesenheiten-Tab bei Kursen im Status "Qualifikationen erfasst" und "Abgeschlossen" wird neu mit einem Ausrufezeichen markiert, wenn die Anwesenheiten noch gespeichert werden müssen. Merci @ewangler! (hitobito/hitobito_pbs#262)
Expand Down
8 changes: 8 additions & 0 deletions app/decorators/pbs/person_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ def roles_grouped(scope:)
end
end

def siblings_in_context(context)
family_member_finder.family_members_in_context(context, kind: :sibling)
end

end

private

def family_member_finder
@family_member_finder ||= Person::FamilyMemberFinder.new(self)
end

def layer_group_ids
@layer_group_ids ||= current_user&.layer_group_ids ||
[current_service_token&.layer_group_id].compact.presence ||
Expand Down
7 changes: 7 additions & 0 deletions app/domain/pbs/export/tabular/people/participation_row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ def bsv_days
participation.bsv_days || participation.event.bsv_days
end

def has_siblings_in_event
event = participation.event

::Person::FamilyMemberFinder.new(participation.person)
.family_members_in_context(event, kind: :sibling).any?
end

end
end
end
Expand Down
7 changes: 7 additions & 0 deletions app/domain/pbs/export/tabular/people/participations_full.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ module ParticipationsFull
extend ActiveSupport::Concern

included do
alias_method_chain :person_attributes, :pbs
alias_method_chain :build_attribute_labels, :pbs
end

def person_attributes_with_pbs
person_attributes_without_pbs + [:has_siblings_in_event]
end

def build_attribute_labels_with_pbs
build_attribute_labels_without_pbs.tap do |labels|
labels[:bsv_days] = ::Event::Participation.human_attribute_name(:bsv_days)
labels[:has_siblings_in_event] =
::Event::Participation.human_attribute_name(:has_siblings_in_event)
end
end
end
Expand Down
18 changes: 17 additions & 1 deletion app/domain/pbs/export/tabular/people/people_full.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,24 @@ module PeopleFull
end

def person_attributes_with_pbs
person_attributes_without_pbs + [:id, :layer_group_id, :pbs_number]
attrs = person_attributes_without_pbs + [:id, :layer_group_id, :pbs_number]
attrs += [:has_siblings_in_layer] if @group.present?
attrs
end

def initialize(list, group = nil)
super(list)
@group = group
end

private

def row_for(entry, format = nil)
return super unless row_class == ::Export::Tabular::People::PersonRow &&
@group.present?
row_class.new(entry, format, @group)
end

end
end
end
Expand Down
9 changes: 9 additions & 0 deletions app/domain/pbs/export/tabular/people/person_row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ module People
module PersonRow
extend ActiveSupport::Concern

def initialize(entry, format = nil, group = nil)
super(entry, format)
@group = group
end

def salutation
entry.salutation_value
end
Expand All @@ -24,6 +29,10 @@ def layer_group_id
entry.try(:primary_group).try(:layer_group).try(:id)
end

def has_siblings_in_layer
::Person::FamilyMemberFinder.new(entry)
.family_members_in_context(@group, kind: :sibling)&.any?
end
end
end
end
Expand Down
33 changes: 33 additions & 0 deletions app/domain/person/family_member_finder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (c) 2023, Pfadibewegung Schweiz. This file is part of
# hitobito_pbs 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_pbs.

class Person::FamilyMemberFinder
attr_reader :person

def initialize(person)
@person = person
end

def family_members_in_layer(group, kind: :sibling)
Role.joins(person: :family_members)
.where(group: group.groups_in_same_layer,
person: { family_members: { kind: kind, other: person } })
end

def family_members_in_event(event, kind: :sibling)
Event::Participation.joins(person: :family_members)
.where(person: { family_members: { kind: kind, other: person } },
event: event)
end

def family_members_in_context(context, kind: :sibling)
case context
when Event
family_members_in_event(context, kind: kind)
when Group
family_members_in_layer(context, kind: kind)
end
end
end
5 changes: 5 additions & 0 deletions app/jobs/pbs/export/event_participations_export_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,10 @@ def unfiltered_participants
references(:people).
distinct
end

def data
return super unless exporter == ::Export::Tabular::People::ParticipationsFull
::Export::Tabular::People::ParticipationsFull.export(@format, entries, @filter.event)
end

end
6 changes: 5 additions & 1 deletion app/jobs/pbs/export/people_export_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ module Pbs::Export::PeopleExportJob
end

def exporter_with_detail
return Pbs::Export::Tabular::People::HouseholdsFull if @options[:household_details]
return Pbs::Export::Tabular::People::HouseholdsFull if @options[:household_details]
exporter_without_detail
end

def data
return super unless exporter == ::Export::Tabular::People::PeopleFull
::Export::Tabular::People::PeopleFull.export(@format, entries, group)
end
end
3 changes: 1 addition & 2 deletions app/models/pbs/person.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ module Pbs::Person

alias_method_chain :full_name, :title

i18n_boolean_setter :brother_and_sisters, :prefers_digital_correspondence

i18n_boolean_setter :prefers_digital_correspondence

belongs_to :kantonalverband, class_name: 'Group' # might also be Group::Bund
has_many :crises, foreign_key: :creator_id
Expand Down
4 changes: 4 additions & 0 deletions app/serializers/pbs/event_participation_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ module Pbs::EventParticipationSerializer
translated_label: number.translated_label
}
end)

property(:has_siblings_in_event,
::Person::FamilyMemberFinder.new(item.person)
.family_members_in_context(item.event, kind: :sibling).any?)
end
end
end
8 changes: 6 additions & 2 deletions app/serializers/pbs/person_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ module Pbs::PersonSerializer
included do
extension(:details) do |_|
map_properties :pbs_number, :salutation_value, :correspondence_language,
:prefers_digital_correspondence, :grade_of_school, :brother_and_sisters,
:entry_date, :leaving_date
:prefers_digital_correspondence, :grade_of_school, :entry_date, :leaving_date

if context[:group].present?
property :has_siblings_in_layer, item.siblings_in_context(context[:group]).any?
end
end

end

end
13 changes: 12 additions & 1 deletion app/views/people/_details_pbs.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
-# https://github.com/hitobito/hitobito_pbs.
= render_attrs(entry, :pbs_number, :salutation, :correspondence_language,
:grade_of_school, :brother_and_sisters)
:grade_of_school)

%dl.dl-horizontal
- sibling_context = parent.try(:layer_group) || parent
- siblings_in_context = entry.siblings_in_context(sibling_context)
= labeled(t('people.fields_pbs.siblings_in_context', context: sibling_context)) do
- if siblings_in_context.any?
= t('global.yes')
= simple_list(siblings_in_context, class: 'unstyled mb-0') do |sibling_role|
- assoc_link(sibling_role.person)
- else
= t('global.no')

= render_attrs(entry, :entry_date, :leaving_date)
3 changes: 0 additions & 3 deletions app/views/people/_fields_pbs.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,3 @@

= field_set_tag do
= f.labeled_input_fields(:entry_date, :leaving_date)

= field_set_tag do
= f.labeled_boolean_field(:brother_and_sisters, caption: t('.in_abteilung'))
4 changes: 2 additions & 2 deletions config/locales/models.pbs.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,7 @@ de:
additional_information: Wie möchtest du dich im Anlass ernähren? Was sind deine Essgewohnheiten?
bsv_days: BSV-Tage
j_s_data_sharing_accepted: J+S Datenweitergabe
has_siblings_in_event: Geschwister im Anlass

event/question:
pass_on_to_supercamp: An übergeordnetes Lager weitergeben
Expand All @@ -1259,8 +1260,7 @@ de:
leaving_date: Austrittsdatum
j_s_number: J+S Personennummer
correspondence_language: Korrespondenzsprache
brother_and_sisters: Geschwister
relations_to_tails: Geschwister
has_siblings_in_layer: Geschwister in der Ebene
kv: Kantonalverband
prefers_digital_correspondence: Digitale Korrespondenz bevorzugt

Expand Down
2 changes: 1 addition & 1 deletion config/locales/views.pbs.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ de:
no_sensitive_information: In diesem Feld keine besonders schützenswerte Personendaten erfassen.
fields_pbs:
non_automatic_field: Dies ist kein automatisches Feld und muss manuell angepasst werden.
in_abteilung: (in der Abteilung)
siblings_in_context: Geschwister in %{context}
qualification_buttons_pbs:
print_course_confirmation: Kursbestätigung drucken
household_attrs_pbs:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class RemoveBrotherAndSisterFromPersons < ActiveRecord::Migration[6.1]
def change
remove_column :people, :brother_and_sisters, :boolean, default: false, null: false
end
end
2 changes: 1 addition & 1 deletion lib/hitobito_pbs/wagon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Wagon < Rails::Engine
### controllers
PeopleController.permitted_attrs += [:salutation, :title, :grade_of_school, :entry_date,
:leaving_date, :j_s_number, :correspondence_language,
:prefers_digital_correspondence, :brother_and_sisters]
:prefers_digital_correspondence]
GroupsController.permitted_attrs += [:hostname]
Event::KindsController.permitted_attrs += [:documents_text, :campy, :can_have_confirmations,
:confirmation_name]
Expand Down
93 changes: 93 additions & 0 deletions spec/domain/person/family_member_finder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# encoding: utf-8

# Copyright (c) 2017, Pfadibewegung Schweiz. This file is part of
# hitobito_pbs 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_pbs.

require 'spec_helper'

describe Person::FamilyMemberFinder do

let(:service) { described_class.new(person) }
let(:person) { Fabricate(:person) }
let(:sibling) { Fabricate(:person) }

let!(:sibling_relation) { Fabricate(:family_member, person: person, other: sibling, kind: :sibling) }

describe '#family_members_in_event' do

let(:person_event) { Fabricate(:event) }
let!(:person_participation) { Fabricate(:event_participation, person: person, event: person_event) }
let(:sibling_event) { Fabricate(:event) }
let!(:sibling_participation) { Fabricate(:event_participation, person: sibling, event: sibling_event) }

subject do
service.family_members_in_event(person_event, kind: :sibling)
end

context 'without siblings' do
let!(:sibling_relation) { nil }
it { is_expected.to be_empty }
end

context 'with siblings in different events' do
it { is_expected.to be_empty }
end

context 'with siblings in same event' do
let(:sibling_event) { person_event }
it { is_expected.to contain_exactly(sibling_participation) }
end

context 'with siblings with deleted role in same group' do
let!(:sibling_participation) { Fabricate(:event_participation, person: sibling, event: sibling_event, active: false) }
it { is_expected.to be_empty }
end

end

describe '#family_members_in_layer' do

let(:layer) { Fabricate(Group::Abteilung.name) }

let(:person_group) { Fabricate(Group::Pfadi.name, parent: layer)}
let!(:person_role) { Fabricate(person_group.default_role.name, person: person, group: person_group) }

let(:sibling_group) { Fabricate(Group::Woelfe.name, parent: layer)}
let!(:sibling_role) { Fabricate(sibling_group.default_role.name, person: sibling, group: sibling_group) }

subject do
service.family_members_in_layer(person_group, kind: :sibling)
end

context 'without siblings' do
let!(:sibling_relation) { nil }
it { is_expected.to be_empty }
end

context 'with siblings in different groups' do
let(:sibling_group) { Fabricate(Group::Woelfe.name, parent: Fabricate(Group::Abteilung.name))}
it { is_expected.to be_empty }
end

context 'with siblings in same group' do
let(:sibling_group) { person_group }
it { is_expected.to contain_exactly(sibling_role) }
end

context 'with siblings in same layer' do
it { is_expected.to contain_exactly(sibling_role) }
end

context 'with siblings with deleted role in same group' do
let!(:sibling_role) do
Fabricate(sibling_group.default_role.name, person: sibling, group: sibling_group,
created_at: 2.months.ago, deleted_at: 1.month.ago)
end
it { is_expected.to be_empty }
end

end

end

0 comments on commit 9fea7ed

Please sign in to comment.