diff --git a/sql/v01/10.create.sql b/sql/v01/10.create.sql index 1cf1636..111ec25 100644 --- a/sql/v01/10.create.sql +++ b/sql/v01/10.create.sql @@ -336,8 +336,6 @@ CREATE TABLE member ( postal_dest TEXT NOT NULL, address TEXT NOT NULL, - email TEXT CHECK (email REGEXP '^[^@ ]+@([a-z0-9_\x2Däöüß]+\.)+[a-z]{2,}$') DEFAULT NULL, - default_kgnr INTEGER, contact_postal INTEGER NOT NULL CHECK (contact_postal IN (TRUE, FALSE)) DEFAULT TRUE, contact_email INTEGER NOT NULL CHECK (contact_email IN (TRUE, FALSE)) DEFAULT FALSE, @@ -381,6 +379,7 @@ CREATE TABLE member_billing_address ( CREATE TABLE member_telephone_number ( mgnr INTEGER NOT NULL, nr INTEGER NOT NULL, + type TEXT NOT NULL CHECK (type REGEXP '^[a-z_]+$'), number TEXT NOT NULL CHECK (number REGEXP '^\+[0-9]{1,3}( [0-9]+)+(-[0-9]+)?$' AND LENGTH(REPLACE(REPLACE(REPLACE(number, '+', ''), ' ', ''), '-', '')) <= 15), comment TEXT DEFAULT NULL, @@ -391,6 +390,19 @@ CREATE TABLE member_telephone_number ( ON DELETE CASCADE ) STRICT; +CREATE TABLE member_email_address ( + mgnr INTEGER NOT NULL, + nr INTEGER NOT NULL, + + address TEXT NOT NULL CHECK (address REGEXP '^[^@ ]+@([a-z0-9_\x2Däöüß]+\.)+[a-z]{2,}$'), + comment TEXT DEFAULT NULL, + + CONSTRAINT pk_member_email_address PRIMARY KEY (mgnr, nr), + CONSTRAINT fk_member_email_address_member FOREIGN KEY (mgnr) REFERENCES member (mgnr) + ON UPDATE CASCADE + ON DELETE CASCADE +) STRICT; + CREATE TABLE area_commitment ( fbnr INTEGER NOT NULL, mgnr INTEGER NOT NULL, @@ -756,4 +768,4 @@ CREATE TABLE credit ( CONSTRAINT fk_credit_payment_member FOREIGN KEY (year, avnr, mgnr) REFERENCES payment_member (year, avnr, mgnr) ON UPDATE CASCADE ON DELETE RESTRICT -); +) STRICT; diff --git a/wgmaster/import.py b/wgmaster/import.py index 72ae7f4..2a4dbc3 100755 --- a/wgmaster/import.py +++ b/wgmaster/import.py @@ -12,8 +12,8 @@ import utils DIR: str -TABLES = ['client_parameter', 'branch', 'wb_gl', 'wb_kg', 'wb_rd', 'wine_attribute', 'wine_cultivation', - 'area_commitment_type', 'member', 'member_billing_address', 'member_telephone_number', 'area_commitment', +TABLES = ['client_parameter', 'branch', 'wb_gl', 'wb_kg', 'wb_rd', 'wine_attribute', 'wine_cultivation', 'area_commitment_type', + 'member', 'member_billing_address', 'member_telephone_number', 'member_email_address', 'area_commitment', 'season', 'modifier', 'delivery', 'delivery_part', 'delivery_part_attribute', 'delivery_part_modifier', 'payment_variant', 'payment_delivery_part'] diff --git a/wgmaster/migrate.py b/wgmaster/migrate.py index 4d8db07..a9709c1 100755 --- a/wgmaster/migrate.py +++ b/wgmaster/migrate.py @@ -240,6 +240,8 @@ def normalize_phone_nr(nr: Optional[str], ort: str = None) -> Optional[str]: nr = nr.replace('-', '') if nr[0] == '0': nr = '+43 ' + nr[1:] + elif nr.startswith('43'): + nr = '+' + nr elif CLIENT == WG.WINZERKELLER and ort: ort = ort.upper().strip() if ort in ('PILLICHSDORF', 'OBERSDORF', 'WOLKERSDORF', 'WOLFPASSING', 'PUTZING', 'GROSSENGERSDORF', @@ -750,18 +752,19 @@ def migrate_members(in_dir: str, out_dir: str) -> None: mgnrs = [m['MGNR'] for m in members] fbs = parse_flaechenbindungen(in_dir) - with utils.csv_open(f'{out_dir}/member.csv') as f_m,\ + with utils.csv_open(f'{out_dir}/member.csv') as f_m, \ utils.csv_open(f'{out_dir}/member_billing_address.csv') as f_mba, \ - utils.csv_open(f'{out_dir}/member_telephone_number.csv') as f_tel,\ + utils.csv_open(f'{out_dir}/member_telephone_number.csv') as f_tel, \ + utils.csv_open(f'{out_dir}/member_email_address.csv') as f_email, \ utils.csv_open(f'{out_dir}/wb_kg.csv', 'a') as f_kg: f_m.header( 'mgnr', 'predecessor_mgnr', 'prefix', 'given_name', 'middle_names', 'family_name', 'suffix', 'birthday', 'entry_date', 'exit_date', 'business_shares', 'accounting_nr', 'zwstid', 'lfbis_nr', 'ustid_nr', 'volllieferant', 'buchführend', 'funktionär', 'active', 'deceased', - 'iban', 'bic', 'country', 'postal_dest', 'address', - 'email', 'default_kgnr', 'comment') + 'iban', 'bic', 'country', 'postal_dest', 'address', 'default_kgnr', 'comment') f_mba.header('mgnr', 'name', 'country', 'postal_dest', 'address') f_tel.header('mgnr', 'nr', 'type', 'number', 'comment') + f_email.header('mgnr', 'nr', 'address', 'comment') for m in members: mgnr: int = m['MGNR'] @@ -896,15 +899,16 @@ def migrate_members(in_dir: str, out_dir: str) -> None: convert(mgnr, 'Adresse', address_old, address) email: Optional[str] = m['EMail'] + emails = [] if email is not None: - if email.isupper(): - email = email.lower() - if not EMAIL_RE.fullmatch(email): - invalid(mgnr, 'E-Mail', m['EMail'], active) - email = None - else: - parts = email.split('@') - email = f'{parts[0]}@{parts[1].lower()}' + for email in email.split(' + '): + if email.isupper(): + email = email.lower() + if not EMAIL_RE.fullmatch(email): + invalid(mgnr, 'E-Mail', m['EMail'], active) + else: + parts = email.split('@') + emails.append(f'{parts[0]}@{parts[1].lower()}') zwstid = m['ZNR'] and BRANCH_MAP[m['ZNR']] or len(BRANCH_MAP) == 1 and list(BRANCH_MAP.values())[0] if CLIENT == WG.WINZERKELLER and plz == 1228: @@ -942,7 +946,7 @@ def migrate_members(in_dir: str, out_dir: str) -> None: m['Geburtsjahr'], m['Eintrittsdatum'], m['Austrittsdatum'], m['Geschäftsanteile1'] or 0, m['BHKontonummer'], zwstid, bnr, ustid_nr, m['Volllieferant'] or False, m['Buchführend'] or False, funktionaer, active, deceased, - iban, bic, AUSTRIA, postal_dest, address or '-', email, kgnr, m['Anmerkung'] + iban, bic, AUSTRIA, postal_dest, address or '-', kgnr, m['Anmerkung'] ) phone_1: Optional[str] = m['Telefon'] @@ -1074,6 +1078,9 @@ def migrate_members(in_dir: str, out_dir: str) -> None: else: f_tel.row(mgnr, len(numbers), 'landline', phone_3, None) + for i, email in enumerate(emails): + f_email.row(mgnr, i + 1, email, None) + MEMBER_MAP[mgnr] = { 'default_kgnr': kgnr }