diff --git a/app/domain/people/data_quality_checker.rb b/app/domain/people/data_quality_checker.rb new file mode 100644 index 000000000..d59c85aec --- /dev/null +++ b/app/domain/people/data_quality_checker.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of +# hitobito_sac_cas 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_sac_cas + +class People::DataQualityChecker + ATTRIBUTES_TO_CHECK = %w[email street zip_code town first_name last_name + company_name phone_numbers birthday] + + def initialize(person) + @person = person + + check_invoice_recipient if @person.sac_membership_invoice? + check_stammsektion if @person.roles.exists?(type: SacCas::STAMMSEKTION_ROLES) + + if @person.company? + check("warning", "company_name", "ist leer", invalid: @person.company_name.blank?) + else + check("error", "first_name", "ist leer", invalid: @person.first_name.blank?) + check("error", "last_name", "ist leer", invalid: @person.last_name.blank?) + end + end + + private + + def check_invoice_recipient + check("error", "street", "ist leer", invalid: @person.street.blank?) + check("error", "zip_code", "ist leer", invalid: @person.zip_code.blank?) + check("error", "town", "ist leer", invalid: @person.town.blank?) + check("warning", "email", "ist leer", invalid: @person.email.blank?) + check("warning", "phone_numbers", "sind leer", invalid: @person.phone_numbers.blank?) + end + + def check_stammsektion + join_date = @person.roles.find_by(type: SacCas::STAMMSEKTION_ROLES).created_at + + check("error", "birthday", "ist leer", invalid: @person.birthday.blank?) + check("warning", "birthday", "liegt weniger als 6 Jahre vor dem SAC-Eintritt", + invalid: @person.birthday.present? && (@person.birthday > join_date - 6.years)) + end + + def check(severity, attr, key, invalid: false) + if invalid + issue = @person.data_quality_issues.new(severity: severity, attr: attr, key: key) + issue.save! if issue.valid? + else + @person.data_quality_issues.find_by(severity: severity, attr: attr, key: key)&.destroy! + end + end +end diff --git a/app/models/person/data_quality_issue.rb b/app/models/person/data_quality_issue.rb index 801c62167..6238b3d87 100644 --- a/app/models/person/data_quality_issue.rb +++ b/app/models/person/data_quality_issue.rb @@ -23,6 +23,8 @@ # index_person_data_quality_issues_on_person_and_attribute_and_key (key) UNIQUE class Person::DataQualityIssue < ApplicationRecord + VALID_ATTRIBUTES = Person.column_names + ["phone_numbers"] + belongs_to :person enum severity: {info: 1, warning: 2, error: 3} @@ -43,6 +45,6 @@ def message private def person_attribute_exists - errors.add(:attr, :invalid) unless Person.column_names.include?(attr) + errors.add(:attr, :invalid) unless VALID_ATTRIBUTES.include?(attr) end end diff --git a/app/models/sac_cas/person.rb b/app/models/sac_cas/person.rb index 3ea1ac175..bcd0a9aee 100644 --- a/app/models/sac_cas/person.rb +++ b/app/models/sac_cas/person.rb @@ -44,6 +44,7 @@ module SacCas::Person validates(*Person::SAC_REMARKS, format: {with: /\A[^\n\r]*\z/}) before_save :set_digital_correspondence, if: :password_initialized? + after_save :check_data_quality delegate :salutation_label, to: :class @@ -105,4 +106,12 @@ def data_quality def data_quality=(value) super(value.is_a?(Integer) ? value : DATA_QUALITIES.index(value.to_s)) end + + private + + def check_data_quality + return if (People::DataQualityChecker::ATTRIBUTES_TO_CHECK & saved_changes.keys).empty? + + People::DataQualityChecker.new(self) + end end