Skip to content

Commit

Permalink
enhance person entry
Browse files Browse the repository at this point in the history
  • Loading branch information
openscript committed Aug 20, 2024
1 parent e80c26b commit 278b598
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 93 deletions.
4 changes: 3 additions & 1 deletion app/domain/sac_imports/csv_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ class SacImports::CsvSource
town: "City",
zip_code: "Post Code",
email: "E-Mail",
phone_private: "Phone No_",
phone: "Phone No_",
phone_mobile: "Mobile Phone No_",
phone_direct: "Telefon direkt",
phone_private: "Telefon Privat",
phone_fax: "Fax No_",
birthday: "Date of Birth",
gender: "Geschlecht",
Expand Down
12 changes: 11 additions & 1 deletion app/domain/sac_imports/people_importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,18 @@ def create
@csv_report.finalize(output: @output)
end

def target_group
@target_group ||= Group::ExterneKontakte.find_or_create_by!(
name: "Navision Import",
parent_id: Group::SacCas.first!.id
)
end

def process_row(row)
@output.print("Reading row #{row[:navision_name]} ...")
@output.print("#{row[:navision_id]} (#{row[:navision_name]}):\n")
entry = PersonEntry.new(row, target_group)
@output.print("-> #{entry.errors.full_messages.join(", ")}\n")
# entry.import!
end
end
end
133 changes: 69 additions & 64 deletions app/domain/sac_imports/person_entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,27 @@

module SacImports
class PersonEntry
attr_reader :row

GENDERS = {
"Männlich" => "m",
"Weiblich" => "w"
}.freeze

LANGUAGES = {
"DES" => "de",
"FRS" => "fr",
"ITS" => "it"
}.freeze

GENDERS = {"0": "m", "1": "w"}.freeze
DEFAULT_LANGUAGE = "de"
LANGUAGES = {DES: "de", FRS: "fr", ITS: "it"}.freeze
DEFAULT_COUNTRY = "CH"
TARGET_ROLE = Group::ExterneKontakte::Kontakt.sti_name

def initialize(row, group:, emails: [])
attr_reader :row, :group

def initialize(row, group)
@row = row
@group = group
@emails = emails
end

def person
@person ||= ::Person.find_or_initialize_by(id: navision_id).tap do |person|
@person ||= ::Person.new(id: navision_id).tap do |person|
assign_attributes(person)
build_phone_numbers(person)
build_role(person)
end
end

def email
@email ||= row.fetch(:email) if @emails.exclude?(row.fetch(:email))
end

def valid?
@valid ||= person.valid?
end
Expand All @@ -58,70 +46,87 @@ def to_s

private

def assign_attributes(person) # rubocop:disable Metrics/AbcSize
person.primary_group = @group
person.first_name = row.fetch(:first_name)
person.last_name = row.fetch(:last_name)
person.zip_code = row.fetch(:zip_code)
person.country = row.fetch(:country)
person.town = row.fetch(:town)
person.address_care_of = row.fetch(:address_supplement)
person.street, person.housenumber = parse_address
person.postbox = row.fetch(:postfach)

if email.present?
person.email = email
# Do not call person#confirm here as it persists the record.
# Instead we set confirmed_at manually.
person.confirmed_at = Time.zone.at(0)
end

person.birthday = parse_datetime(row.fetch(:birthday))
person.gender = GENDERS[row.fetch(:gender).to_s]
person.language = LANGUAGES[row.fetch(:language)] || "de"
def navision_id
@navision_id ||= Integer(row[:navision_id].to_s.sub!(/^0*/, ""))
end

def build_phone_numbers(person)
phone = row.fetch(:phone)
mobile = row.fetch(:phone_mobile)
direct = row.fetch(:phone_direct)

# reset phone numbers first since import might be run multiple times
person.phone_numbers = []
def country
row[:country] || DEFAULT_COUNTRY
end

person.phone_numbers.build(number: phone, label: "Privat") if phone_valid?(phone)
person.phone_numbers.build(number: mobile, label: "Mobil") if phone_valid?(mobile)
person.phone_numbers.build(number: direct, label: "Direkt") if phone_valid?(direct)
def gender
GENDERS[row[:gender]&.to_sym]
end

def build_role(person)
return if person.roles.exists?
def language
LANGUAGES[row[:language]&.to_sym] || DEFAULT_LANGUAGE
end

person.roles.build(
group: @group,
type: TARGET_ROLE
)
def email
row[:email]
end

def parse_address
address = row.fetch(:address)
address = row[:address]
return if address.blank?

Address::Parser.new(address).parse
end

def assign_attributes(person) # rubocop:disable Metrics/AbcSize
person.primary_group = group
person.first_name = row[:first_name]
person.last_name = row[:last_name]
person.address_care_of = row[:address_care_of]
person.postbox = row[:postbox]
person.address = row[:address]
person.street = row[:street]
person.housenumber = row[:housenumber]
person.country = country
person.town = row[:town]
person.zip_code = row[:zip_code]
person.birthday = row[:birthday]
person.gender = gender
person.language = language
person.sac_remark_section_1 = row[:sac_remark_section_1]
person.sac_remark_section_2 = row[:sac_remark_section_2]
person.sac_remark_section_3 = row[:sac_remark_section_3]
person.sac_remark_section_4 = row[:sac_remark_section_4]
person.sac_remark_section_5 = row[:sac_remark_section_5]
person.sac_remark_national_office = row[:sac_remark_national_office]

person.street, person.housenumber = parse_address

if email.present?
person.email = email
# Do not call person#confirm here as it persists the record.
# Instead we set confirmed_at manually.
person.confirmed_at = Time.zone.at(0)
end
end

def phone_valid?(number)
number.present? && Phonelib.valid?(number)
end

def parse_datetime(value, default: nil)
DateTime.parse(value.to_s)
rescue Date::Error
default
def build_phone_numbers(person)
# rubocop:disable Lint/SymbolConversion
phone_numbers = {
"Privat": row[:phone],
"Mobil": row[:phone_mobile],
"Arbeit": row[:phone_direct],
"Haupt-Telefon": row[:phone_private],
"Fax": row[:phone_fax]
}.freeze
# rubocop:enable Lint/SymbolConversion

phone_numbers.each do |label, number|
person.phone_numbers.build(number: number, label: label) if phone_valid?(number)
end
end

def navision_id
Integer(row.fetch(:navision_id).to_s.sub!(/^0*/, ""))
def build_role(person)
person.roles.build(group: group, type: TARGET_ROLE)
end

def build_error_messages
Expand Down
36 changes: 9 additions & 27 deletions spec/domain/sac_imports/person_entry_spec.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
# frozen_string_literal: true

# Copyright (c) 2023, Schweizer Alpen-Club. This file is part of
# 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.

require "spec_helper"

describe SacImports::PersonEntry do
let(:emails) { [] }
let(:group) { Group::ExterneKontakte.new(id: 1) }
let(:row) do
SacImports::PeopleImporter.headers.keys.index_with { |_symbol| nil }.merge(
SacImports::CsvSource::SOURCE_HEADERS[:NAV1].keys.index_with { |_symbol| nil }.merge(
navision_id: 123,
first_name: "Max",
last_name: "Muster",
email: "[email protected]",
gender: "Weiblich",
gender: "0",
language: "DES",
birthday: 40.years.ago.to_date
)
end

subject(:entry) { described_class.new(row, group: group, emails: emails) }
subject(:entry) { described_class.new(row, group) }

before { travel_to(Time.zone.local(2022, 10, 20, 11, 11)) }

Expand Down Expand Up @@ -51,7 +50,7 @@
end

it "is invalid without group" do
person = described_class.new(row.merge(birthday: 6.years.ago), group: nil)
person = described_class.new(row.merge(birthday: 6.years.ago), nil)
expect(person).not_to be_valid
expect(person.errors).to eq "Muster Max (123): Rollen ist nicht gültig, Group muss ausgefüllt werden"
end
Expand All @@ -64,22 +63,14 @@
expect(person.confirmed_at).to eq Time.zone.at(0)
end

it "assigns attributes to existing person found by navision_id" do
Fabricate(:person, id: 123)
row[:navision_id] = 123
row[:first_name] = :test
expect(person.first_name).to eq "test"
expect(person.primary_group).to eq group
end

it "sets various attributes via through values" do
row[:first_name] = :first
row[:last_name] = :last
row[:zip_code] = 3000
row[:town] = :town
row[:country] = "CH"
row[:birthday] = "1.1.2000"
row[:gender] = "Männlich"
row[:gender] = "0"
row[:language] = "DES"
expect(person.first_name).to eq "first"
expect(person.last_name).to eq "last"
Expand All @@ -93,9 +84,9 @@
end

it "sets address attributes" do
row[:address_supplement] = "test"
row[:address_care_of] = "test"
row[:address] = "Landweg 1a"
row[:postfach] = "Postfach 3000"
row[:postbox] = "Postfach 3000"

expect(person.address_care_of).to eq "test"
expect(person.street).to eq "Landweg"
Expand All @@ -109,13 +100,6 @@
row[:language] = nil
expect(person.language).to eq "de"
end

it "sets email to nil if email is included in passed emails array" do
emails << "[email protected]"
row[:email] = "[email protected]"
expect(entry).to be_valid
expect(entry.person.email).to be_blank
end
end

describe "phone numbers" do
Expand All @@ -126,14 +110,12 @@
row[:phone_mobile] = "079 12 123 11"
row[:phone_direct] = "079 12 123 12"
expect(numbers).to have(3).items

expect(numbers[0][:label]).to eq "Privat"
expect(numbers[1][:label]).to eq "Mobil"
expect(numbers[2][:label]).to eq "Direkt"
expect(numbers[2][:label]).to eq "Arbeit"
expect(numbers[0][:number]).to eq "079 12 123 10"
expect(numbers[1][:number]).to eq "079 12 123 11"
expect(numbers[2][:number]).to eq "079 12 123 12"

expect(numbers.collect(&:public).uniq).to eq [true]
end

Expand Down
10 changes: 10 additions & 0 deletions spec/fixtures/files/sac_imports_src/NAV1_Kontakte_NAV-20240726.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
timestamp,No_,Name,Search Name,Name 2,Address,Address 2,City,Phone No_,Telex No_,Territory Code,Currency Code,Language Code,Salesperson Code,Country_Region Code,Last Date Modified,Fax No_,Telex Answer Back,VAT Registration No_,Picture,Post Code,County,E-Mail,Home Page,No_ Series,Image,Privacy Blocked,Minor,Parental Consent Received,Type,Company No_,Company Name,Lookup Contact No_,First Name,Middle Name,Surname,Job Title,Initials,Extension No_,Mobile Phone No_,Pager,Organizational Level Code,Exclude from Segment,External ID,Correspondence Type,Salutation Code,Search E-Mail,Last Time Modified,E-Mail 2,Xrm Id,Updated For GEWA On,PUK-Code,Section,Category,Do Not Replicate On IDS,WSO2 UUID,Code FMH Titel,Funktionsgruppe PX,Funktion PX,FMH Titel,Eröffnet am,Eröffnet um,Eröffnet von,Geändert von,Löschen,Briefanrede,Telefon direkt,Telefon Privat,Set Adressaufbereitung,Personentyp,Nur Kontaktperson aufbereiten,Date of Birth,Last Maintenance Batch No_,Post Code Id,Aufbereitete Namenzeile,Street Id,Street No_,Switch Address Fields,Street Name,Gültige Adresse,Zweitname,Zweitvorname,Status,Salutation Code 2,Briefanrede 2,Geschlecht,Sync Homepage to Hut,Singular Salutation Text,Vereinsmitgliederjahre,Sektionsinfo 1 Bemerkung,Sektionsinfo 1 Datum,Sektionsinfo 2 Bemerkung,Sektionsinfo 2 Datum,Sektionsinfo 3 Bemerkung,Sektionsinfo 3 Datum,Sektionsinfo 4 Bemerkung,Sektionsinfo 4 Datum,Sektionsinfo 5 Bemerkung,Sektionsinfo 5 Datum,Geschäftsstelle Bemerkung,Geschäftsstelle Bemerkung Datum
0x0000000046060F2D,513544,Müller Hans,MÜLLER HANS,,Bahnhofstrasse 1,,Zürich,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,6003,LU,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513544,,,Hans,,Müller,,,,079-1234567,,,0,,0,HERR,,1754-01-01 15:35:23.407,,00000000-0000-0000-0000-000000000000,2024-06-28 00:00:00.000,,4250,FREI FAM,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 15:34:54.837,SAC\PAMA,SAC\PAMA,0,Sehr geehrter Herr Müller,,,STD,1,0,1976-09-25 00:00:00.000,,3217,,15348,1,0,Bahnhofstrasse,1,,,,,,0,0,,42,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x00000000460610D2,513546,Meier Ursula,MEIER URSULA,,Seestrasse 2,,Genf,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,9475,SG,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513546,,,Ursula,,Meier,,,,079-2345678,,,0,,0,FRAU,,1754-01-01 15:38:56.630,,00000000-0000-0000-0000-000000000000,1753-01-01 00:00:00.000,,,,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 15:38:25.900,SAC\PAMA,SAC\PAMA,0,Sehr geehrte Frau Meier,,,STD,1,0,2006-02-16 00:00:00.000,,5384,,0,2,0,Seestrasse,0,,,,,,1,0,,3,Super Einsatz beim Frondienst,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x000000004606141E,513549,Schneider Peter,SCHNEIDER PETER,,Hauptstrasse 3,,Bern,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,6083,BE,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513549,,,Peter,,Schneider,,,,079-3456789,,,0,,0,HERR,,1754-01-01 15:56:59.113,,00000000-0000-0000-0000-000000000000,2024-06-28 00:00:00.000,,4000,FAMILIE,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 15:55:53.893,SAC\PAMA,SAC\PAMA,0,Sehr geehrter Herr Schneider,,,STD,1,0,1967-01-08 00:00:00.000,,3281,,0,3,0,Hauptstrasse,0,,,,,,0,0,,24,NULL,NULL,Interesse Tourenleiter,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x000000004606165F,513550,Weber Anna,WEBER ANNA,,Ringstrasse 4,,Luzern,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,6083,BE,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513550,,,Anna,,Weber,,,,079-4567890,,,0,,0,FRAU,,1754-01-01 16:03:37.350,,00000000-0000-0000-0000-000000000000,2024-06-28 00:00:00.000,,4000,FREI FAM,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 15:57:45.513,SAC\PAMA,SAC\PAMA,0,Sehr geehrte Frau Weber,,,STD,1,0,1970-09-17 00:00:00.000,,3281,,0,4,0,Ringstrasse,0,,,,,,1,0,,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x0000000046061501,513551,Fischer Thomas,FISCHER THOMAS,,Bahnhofstrasse 5,,Zürich,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,6083,BE,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513551,,,Thomas,,Fischer,,,,079-5678901,,,0,,0,HERR,,1754-01-01 16:00:14.100,,00000000-0000-0000-0000-000000000000,1753-01-01 00:00:00.000,,,,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 16:00:14.053,SAC\PAMA,SAC\PAMA,0,Sehr geehrter Herr Fischer,,,STD,1,0,1970-09-17 00:00:00.000,,3281,,0,5,0,Bahnhofstrasse,0,,,,,,1,0,,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,Hat Rechnung immer noch nicht bezahlt,NULL
0x0000000046061547,513552,Huber Laura,HUBER LAURA,,Seestrasse 6,,Genf,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,6083,BE,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513552,,,Laura,,Huber,,,,079-6789012,,,0,,0,FRAU,,1754-01-01 16:00:30.023,,00000000-0000-0000-0000-000000000000,1753-01-01 00:00:00.000,,,,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 16:00:29.963,SAC\PAMA,SAC\PAMA,0,Sehr geehrte Frau Huber,,,STD,1,0,2008-02-26 00:00:00.000,,3281,,0,6,0,Seestrasse,0,,,,,,1,0,,56,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x00000000460615AB,513553,Keller Martin,KELLER MARTIN,,Hauptstrasse 7,,Bern,,,,,DES,PAMA,,2024-06-28 00:00:00.000,,,,NULL,6083,BE,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513553,,,Hans,,Müller,,,,,,,0,,0,HERR,,1754-01-01 16:01:56.470,,00000000-0000-0000-0000-000000000000,1753-01-01 00:00:00.000,,,,0,,,,,,2024-06-28 00:00:00.000,1754-01-01 16:01:56.423,SAC\PAMA,SAC\PAMA,0,Sehr geehrter Herr Müller,,,STD,1,0,2010-05-25 00:00:00.000,,3281,,0,7,0,Hauptstrasse,0,,,,,,0,0,,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x000000004609169E,513615,Müller Hans,MÜLLER HANS,,Bahnhofstrasse 1,,Zürich,,,,,DES,PAMA,,2024-06-29 00:00:00.000,,,,NULL,7502,GR,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513615,,,Ursula,,Meier,,,,,,,0,,0,FRAU,,1754-01-01 21:45:41.930,,00000000-0000-0000-0000-000000000000,1753-01-01 00:00:00.000,,,,0,,,,,,2024-06-29 00:00:00.000,1754-01-01 21:44:42.613,SAC\PAMA,SAC\PAMA,0,Sehr geehrte Frau Meier,,,STD,1,0,1994-08-08 00:00:00.000,,4300,,0,1,0,Bahnhofstrasse,0,,,,,,1,0,,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
0x00000000460A4160,513666,Meier Ursula,MEIER URSULA,,Seestrasse 2,,Genf,,,,,DES,PAMA,,2024-07-01 00:00:00.000,,,,NULL,3700,BE,[email protected],,AD,00000000-0000-0000-0000-000000000000,0,0,0,0,513666,,,Peter,,Schneider,,,,,,,0,,0,HERR,,1754-01-01 10:53:33.257,,00000000-0000-0000-0000-000000000000,2024-07-01 00:00:00.000,,3900,FAMILIE,0,,,,,,2024-06-30 00:00:00.000,1754-01-01 16:32:09.237,SAC\PAMA,SAC\PAMA,0,Sehr geehrter Herr Schneider,,,STD,1,0,1973-12-10 00:00:00.000,,2158,,8000430,2,0,Seestrasse,1,,,,,,0,0,,5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL

0 comments on commit 278b598

Please sign in to comment.