diff --git a/sql/v01/10.create.sql b/sql/v01/10.create.sql index 9523fd6..06ae5b8 100644 --- a/sql/v01/10.create.sql +++ b/sql/v01/10.create.sql @@ -252,7 +252,9 @@ CREATE TABLE branch ( postal_dest TEXT DEFAULT NULL, address TEXT DEFAULT NULL, - phone_nr TEXT DEFAULT NULL CHECK (phone_nr REGEXP '^\+[0-9]+$'), + phone_nr TEXT DEFAULT NULL CHECK (phone_nr REGEXP '^\+[0-9]{1,3}( [0-9]+)+(-[0-9]+)?$'), + fax_nr TEXT DEFAULT NULL CHECK (fax_nr REGEXP '^\+[0-9]{1,3}( [0-9]+)+(-[0-9]+)?$'), + mobile_nr TEXT DEFAULT NULL CHECK (mobile_nr REGEXP '^\+[0-9]{1,3}( [0-9]+)+(-[0-9]+)?$'), CONSTRAINT pk_branch PRIMARY KEY (zwstid), CONSTRAINT fk_branch_postal_dest FOREIGN KEY (country, postal_dest) REFERENCES postal_dest (country, id) @@ -309,10 +311,6 @@ CREATE TABLE member ( address TEXT NOT NULL, email TEXT CHECK (email REGEXP '^[^@ ]+@([a-z0-9_\x2Däöüß]+\.)+[a-z]{2,}$') DEFAULT NULL, - phone_landline TEXT CHECK (phone_landline REGEXP '^\+[0-9]+$') DEFAULT NULL, - fax TEXT CHECK (fax REGEXP '^\+[0-9]+$') DEFAULT NULL, - phone_mobile_1 TEXT CHECK (phone_mobile_1 REGEXP '^\+[0-9]+$') DEFAULT NULL, - phone_mobile_2 TEXT CHECK (phone_mobile_2 REGEXP '^\+[0-9]+$') DEFAULT NULL, default_kgnr INTEGER CHECK (NOT active OR default_kgnr IS NOT NULL), contact_postal INTEGER NOT NULL CHECK (contact_postal IN (TRUE, FALSE)) DEFAULT TRUE, @@ -354,6 +352,19 @@ CREATE TABLE member_billing_address ( ON DELETE RESTRICT ) STRICT; +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, + + CONSTRAINT pk_member_telephone_number PRIMARY KEY (mgnr, nr), + CONSTRAINT fk_member_telephone_number_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, diff --git a/sql/v01/11.timestamp-trigger.sql b/sql/v01/11.timestamp-trigger.sql index 0b73b75..7e484f7 100644 --- a/sql/v01/11.timestamp-trigger.sql +++ b/sql/v01/11.timestamp-trigger.sql @@ -49,6 +49,26 @@ END; ---------------------------------------------------------------- +CREATE TRIGGER t_member_telephone_number_i_mtime_member + AFTER INSERT ON member_telephone_number FOR EACH ROW +BEGIN + UPDATE member SET mtime = UNIXEPOCH() WHERE mgnr = NEW.mgnr; +END; + +CREATE TRIGGER t_member_telephone_number_u_mtime_member + AFTER UPDATE ON member_telephone_number FOR EACH ROW +BEGIN + UPDATE member SET mtime = UNIXEPOCH() WHERE mgnr = OLD.mgnr OR mgnr = NEW.mgnr; +END; + +CREATE TRIGGER t_member_telephone_number_d_mtime_member + AFTER DELETE ON member_telephone_number FOR EACH ROW +BEGIN + UPDATE member SET mtime = UNIXEPOCH() WHERE mgnr = OLD.mgnr; +END; + +---------------------------------------------------------------- + CREATE TRIGGER t_area_commitment_i_ctime AFTER INSERT ON area_commitment FOR EACH ROW WHEN NEW.ctime != UNIXEPOCH() diff --git a/wgmaster/import.py b/wgmaster/import.py index 48ad95e..3f53bf2 100755 --- a/wgmaster/import.py +++ b/wgmaster/import.py @@ -14,7 +14,7 @@ import utils DIR: str TABLES = ['client_parameter', 'branch', 'wb_gl', 'wb_kg', 'wb_rd', 'wine_attribute', 'wine_cultivation', - 'member', 'member_billing_address', 'area_commitment', 'area_commitment_attribute', + 'member', 'member_billing_address', 'member_telephone_number', 'area_commitment', 'area_commitment_attribute', 'season', 'modifier', 'delivery', 'delivery_part', 'delivery_part_attribute', 'delivery_part_modifier', ] # 'payment_variant', 'delivery_payment', 'member_payment'] diff --git a/wgmaster/migrate.py b/wgmaster/migrate.py index f34af95..5665159 100755 --- a/wgmaster/migrate.py +++ b/wgmaster/migrate.py @@ -154,10 +154,19 @@ def check_iban(iban: str) -> bool: return modulo(s, 97) == 1 -def normalize_phone_nr(nr: str) -> str: - nr = re.sub('[ /-]', '', nr) +def normalize_phone_nr(nr: Optional[str]) -> Optional[str]: + if nr is None: + return None + nr = nr.replace('/', ' ') if nr[0] == '0': - nr = '+43' + nr[1:] + nr = '+43 ' + nr[1:] + if nr.startswith('+43'): + if nr[4] == '6': + nr = nr.replace(' ', '') + nr = f'{nr[:3]} {nr[3:6]} {nr[6:]}' + elif nr[4] == '2': + nr = nr.replace(' ', '') + nr = f'{nr[:3]} {nr[3:7]} {nr[7:]}' return nr @@ -268,12 +277,16 @@ def migrate_branches(in_dir: str, out_dir: str) -> None: BRANCH_MAP = {} with utils.csv_open(f'{out_dir}/branch.csv') as f: - f.header('zwstid', 'name', 'country', 'postal_dest', 'address', 'phone_nr') + f.header('zwstid', 'name', 'country', 'postal_dest', 'address', 'phone_nr', 'fax_nr', 'mobile_nr') for b in utils.csv_parse_dict(f'{in_dir}/TZweigstellen.csv'): BRANCH_MAP[b['ZNR']] = b['Kennbst'] address = b['Straße'] postal_dest = lookup_plz(int(b['PLZ']) if b['PLZ'] else None, b['Ort'], address) - f.row(b['Kennbst'], b['Name'].strip().title(), 'AT', postal_dest, address, b['Telefon']) + tel, mob = normalize_phone_nr(b['Telefon']), None + if tel and tel[4] == '6': + mob, tel = tel, None + f.row(b['Kennbst'], b['Name'].strip().title(), 'AT', postal_dest, address, + tel, normalize_phone_nr(b['Telefax']), mob) def migrate_grosslagen(in_dir: str, out_dir: str) -> None: @@ -359,16 +372,17 @@ def migrate_members(in_dir: str, out_dir: str) -> None: fbs = parse_flaechenbindungen(in_dir) 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_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}/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', 'volllieferant', 'buchführend', 'funktionär', 'active', 'iban', 'bic', 'country', 'postal_dest', 'address', - 'email', 'phone_landline', 'fax', 'phone_mobile_1', 'phone_mobile_2', - 'default_kgnr', 'comment') + 'email', 'default_kgnr', 'comment') f_mba.header('mgnr', 'name', 'country', 'postal_dest', 'address') + f_tel.header('mgnr', 'nr', 'type', 'number', 'comment') for m in members: mgnr: int = m['MGNR'] @@ -521,12 +535,7 @@ def migrate_members(in_dir: str, out_dir: str) -> None: if address_old != address: convert(mgnr, 'Adresse', address_old, address) - phone_1: Optional[str] = m['Telefon'] - phone_2: Optional[str] = m['Mobiltelefon'] email: Optional[str] = m['EMail'] - phone_landline, fax = None, None - phone_mobile = [] - if email is not None: if email.isupper(): email = email.lower() @@ -534,28 +543,6 @@ def migrate_members(in_dir: str, out_dir: str) -> None: invalid(mgnr, 'E-Mail', m['EMail']) email = None - if phone_1: - phone_1 = normalize_phone_nr(phone_1) - if len(phone_1) <= 8 or phone_1[0] != '+': - invalid(mgnr, 'Tel.Nr.', m['Telefon']) - else: - if phone_1[3] == '6': - phone_mobile.append(phone_1) - else: - phone_landline = phone_1 - if phone_2: - phone_2 = normalize_phone_nr(phone_2) - if len(phone_2) <= 8 or phone_2[0] != '+': - invalid(mgnr, 'Tel.Nr.', m['Mobiltelefon']) - else: - if phone_2[3] == '6': - if phone_2 not in phone_mobile: - phone_mobile.append(phone_2) - elif phone_landline is None: - phone_landline = phone_2 - elif phone_landline != phone_2: - invalid(mgnr, 'Tel.Nr.', phone_2) - zwstid = m['ZNR'] and BRANCH_MAP[m['ZNR']] or len(BRANCH_MAP) == 1 and list(BRANCH_MAP.values())[0] postal_dest = lookup_plz(int(m['PLZ']) if m['PLZ'] else None, m['Ort'], address) @@ -588,10 +575,45 @@ 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, m['Volllieferant'] or False, m['Buchführend'] or False, funktionaer, active, - iban, bic, 'AT', postal_dest, address or '-', email, phone_landline, fax, - phone_mobile[0] if len(phone_mobile) > 0 else None, phone_mobile[1] if len(phone_mobile) > 1 else None, - kgnr, m['Anmerkung'] + iban, bic, 'AT', postal_dest, address or '-', email, kgnr, m['Anmerkung'] ) + + phone_1: Optional[str] = m['Telefon'] + phone_2: Optional[str] = m['Telefax'] + phone_3: Optional[str] = m['Mobiltelefon'] + numbers = [] + + if phone_1: + phone_1 = normalize_phone_nr(phone_1) + if len(phone_1) <= 10 or phone_1[0] != '+': + invalid(mgnr, 'Tel.Nr.', m['Telefon']) + else: + numbers.append(phone_1) + if phone_1[4] == '6': + f_tel.row(mgnr, len(numbers), 'mobile', phone_1, None) + else: + f_tel.row(mgnr, len(numbers), 'landline', phone_1, None) + if phone_2: + phone_2 = normalize_phone_nr(phone_2) + if len(phone_2) <= 8 or phone_2[0] != '+': + invalid(mgnr, 'Fax.Nr.', m['Telefax']) + else: + numbers.append(phone_2) + if phone_2[4] == '6': + f_tel.row(mgnr, len(numbers), 'mobile', phone_2, None) + else: + f_tel.row(mgnr, len(numbers), 'fax', phone_2, None) + if phone_3: + phone_3 = normalize_phone_nr(phone_3) + if len(phone_3) <= 10 or phone_3[0] != '+': + invalid(mgnr, 'Tel.Nr.', m['Mobiltelefon']) + elif phone_3 not in numbers: + numbers.append(phone_3) + if phone_3[4] == '6': + f_tel.row(mgnr, len(numbers), 'mobile', phone_3, None) + else: + f_tel.row(mgnr, len(numbers), 'landline', phone_3, None) + MEMBER_MAP[mgnr] = { 'default_kgnr': kgnr }