aonestar
.public
Tables
(current)
Columns
Constraints
Relationships
Orphan Tables
Anomalies
Routines
sp_save_guest_js_ex
Parameters
Name
Type
Mode
guest_data
jsonb
IN
Definition
DECLARE v_guest_info jsonb := guest_data->'guest'; v_doc_info jsonb; v_out_guest_id integer; v_document_id integer; v_doc_type smallint; v_doc_number text; v_country_id integer; v_save_document boolean; v_in_guest_id integer; v_existing_guest_id integer; BEGIN PERFORM sp_log_debug('sp_save_guest_js_ex', jsonb_pretty(guest_data), true); v_in_guest_id := NULLIF(v_guest_info->>'id', '')::integer; v_doc_info := v_guest_info->'document'; v_save_document := NULLIF(v_doc_info->'raw', 'null'::jsonb) IS NOT NULL; IF v_save_document THEN v_doc_type := NULLIF(v_doc_info->>'doc_type', '')::smallint; v_doc_number := NULLIF(v_doc_info->>'doc_number', ''); v_country_id := NULLIF(v_doc_info->>'country_id', '')::integer; IF v_country_id IS NULL AND (v_doc_type IS NOT NULL OR fn_normalize_guest_document_number(v_doc_number) IS NOT NULL) THEN PERFORM sp_raise_error( '21109', 'Please select the country that issued the identification document' ); END IF; IF v_doc_type = 2 THEN v_doc_number := regexp_replace( COALESCE(v_doc_number, ''), '[[:space:]]+', '', 'g' ); IF v_doc_number !~ '^[0-9]{13}$' THEN PERFORM sp_raise_error( '21110', 'Thai national ID number must contain exactly 13 digits' ); END IF; v_doc_info := jsonb_set( v_doc_info, '{doc_number}', to_jsonb(v_doc_number), true ); v_guest_info := jsonb_set( v_guest_info, '{document}', v_doc_info, true ); END IF; END IF; -- ค่าว่างใน contact = "ไม่ได้กรอก" ไม่ใช่ "สั่งลบ": pre-checkin ส่ง emails/mobiles/ -- telephones มาเป็น [] และ address2 เป็น "" ซึ่ง jsonb_to_record แปลงเป็น {} / '' -- ที่ไม่ใช่ NULL แล้ว coalesce ใน sp_save_guest จะเขียนทับของเดิมทิ้ง (อีเมลหาย -> -- ส่งเมล PIN / guest-welcome ไม่ได้) strip key พวกนั้นออกให้ accessor คืน NULL IF v_guest_info ? 'contact' THEN v_guest_info := jsonb_set( v_guest_info, '{contact}', COALESCE( (SELECT jsonb_object_agg(e.key, e.value) FROM jsonb_each(v_guest_info->'contact') AS e WHERE e.value <> '[]'::jsonb AND e.value <> '""'::jsonb AND e.value <> 'null'::jsonb), '{}'::jsonb ), true ); END IF; -- เอกสารที่ส่งมาเป็นของแขกที่มีอยู่แล้วหรือไม่ -- เงื่อนไขตรงกับ tr_guest_identity_guard เป๊ะ (ทั้งคู่อ่านจากตาราง guest ผ่าน -- fn_guest_document_country) ต่างกันแค่ guard จะ RAISE 23505 ส่วนที่นี่จะ -- เปลี่ยนเป้าหมายของการ save ไปเป็นแขกคนนั้นแล้ว update เฉพาะฟิลด์ที่ส่งมา -- (sp_save_guest ใช้ coalesce(ค่าใหม่, ค่าเดิม) อยู่แล้ว) IF v_save_document AND v_doc_type IS NOT NULL AND fn_normalize_guest_document_number(v_doc_number) IS NOT NULL AND NULLIF(v_country_id, 0) IS NOT NULL THEN PERFORM pg_advisory_xact_lock(hashtextextended( v_doc_type::text || ':' || fn_normalize_guest_document_number(v_doc_number) || ':' || v_country_id::text, 0 )); v_existing_guest_id := fn_find_guest_by_document( v_doc_type, v_doc_number, NULLIF(v_country_id, 0) ); IF v_existing_guest_id IS NOT NULL AND v_existing_guest_id IS DISTINCT FROM v_in_guest_id THEN v_guest_info := jsonb_set( v_guest_info, '{id}', to_jsonb(v_existing_guest_id), true ); END IF; END IF; SELECT sp_save_guest( g.id, g.last_name, g.first_name, g.title_id, g.sex, g.birthdate, g.nation_id, g.lang_id, g.vip_id, address1(g.contact), address2(g.contact), city_id(g.contact), country_id(g.contact), g.country_res_id, emails(g.contact), telephones(g.contact), mobiles(g.contact), g.company, g.occupation_id, doc_number(g.document)::citext, doc_type(g.document)::smallint, expire_date(g.document), country_id(g.document), g.credit_limit, g.confidential, g.member_code::citext, g.carplate_no, g.remark, g.social_media, g.likes, g.dislikes, credit_cards, g.photo, g.photo_url, true, true ) FROM jsonb_to_record(v_guest_info) AS g( id integer, first_name text, last_name text, title_id integer, sex char(1), birthdate date, nation_id integer, country_res_id integer, lang_id integer, vip_id integer, company text, occupation_id integer, credit_limit t_money, confidential boolean, member_code text, carplate_no text, photo bytea, photo_url text, remark text, likes text[], dislikes text[], contact t_contact, document t_document, credit_cards t_credit_card[], social_media t_social_account[] ) INTO v_out_guest_id; -- redirect เกิดขึ้นจริง: ยกช่องทางติดต่อ/ที่อยู่ของแขกที่ถูกแทนมาเติมให้แขกเป้าหมาย -- เฉพาะช่องที่เป้าหมายยังว่าง (payload ชนะไปแล้วในขั้น sp_save_guest ข้างบน) -- อีเมลคือช่องที่สำคัญที่สุด ขั้นถัดไปอ่าน guest.emails[1] เพื่อส่ง PIN / guest-welcome IF v_existing_guest_id IS NOT NULL AND v_in_guest_id IS NOT NULL AND v_existing_guest_id IS DISTINCT FROM v_in_guest_id THEN UPDATE guest d SET emails = CASE WHEN COALESCE(array_length(d.emails, 1), 0) = 0 THEN s.emails ELSE d.emails END, mobiles = CASE WHEN COALESCE(array_length(d.mobiles, 1), 0) = 0 THEN s.mobiles ELSE d.mobiles END, telephones = CASE WHEN COALESCE(array_length(d.telephones, 1), 0) = 0 THEN s.telephones ELSE d.telephones END, email = COALESCE(NULLIF(d.email, ''), s.email), mobile = COALESCE(NULLIF(d.mobile, ''), s.mobile), telephone = COALESCE(NULLIF(d.telephone, ''), s.telephone), address1 = COALESCE(NULLIF(d.address1, ''), s.address1), address2 = COALESCE(NULLIF(d.address2, ''), s.address2), city_id = COALESCE(d.city_id, s.city_id), country_id = COALESCE(NULLIF(d.country_id, 0), s.country_id) FROM guest s WHERE d.id = v_out_guest_id AND s.id = v_in_guest_id; END IF; IF NOT v_save_document THEN RETURN v_out_guest_id; END IF; IF v_doc_type IS NULL OR fn_normalize_guest_document_number(v_doc_number) IS NULL THEN RETURN v_out_guest_id; END IF; PERFORM pg_advisory_xact_lock(hashtextextended( v_doc_type::text || ':' || fn_normalize_guest_document_number(v_doc_number) || ':' || v_country_id::text, 0 )); SELECT gd.id INTO v_document_id FROM guest_document gd WHERE gd.doc_type = v_doc_type AND fn_normalize_guest_document_number(gd.doc_number) = fn_normalize_guest_document_number(v_doc_number) AND gd.country_id = v_country_id FOR UPDATE; IF v_document_id IS NULL THEN INSERT INTO guest_document( guest_id, doc_type, doc_number, expire_date, country_id, nation_id, doc_data, photo_url, image_url, signature_url, photo_path, image_path, signature_path, tag, pending_assignment, last_scan_time ) VALUES ( v_out_guest_id, v_doc_type, v_doc_number, NULLIF(v_doc_info->>'expire_date', '')::date, v_country_id, NULLIF(v_guest_info->>'nation_id', '')::integer, v_doc_info->'raw', v_doc_info->>'photo_url', v_doc_info->>'image_url', v_doc_info->>'signature_url', v_doc_info->>'photo_path', v_doc_info->>'image_path', v_doc_info->>'signature_path', current_date::text, false, current_timestamp ) RETURNING id INTO v_document_id; ELSE UPDATE guest_document SET guest_id = v_out_guest_id, expire_date = NULLIF(v_doc_info->>'expire_date', '')::date, nation_id = COALESCE(NULLIF(v_guest_info->>'nation_id', '')::integer, nation_id), doc_data = COALESCE(v_doc_info->'raw', doc_data), photo_url = COALESCE(NULLIF(v_doc_info->>'photo_url', ''), photo_url), image_url = COALESCE(NULLIF(v_doc_info->>'image_url', ''), image_url), signature_url = COALESCE(NULLIF(v_doc_info->>'signature_url', ''), signature_url), photo_path = COALESCE(NULLIF(v_doc_info->>'photo_path', ''), photo_path), image_path = COALESCE(NULLIF(v_doc_info->>'image_path', ''), image_path), signature_path = COALESCE(NULLIF(v_doc_info->>'signature_path', ''), signature_path), tag = current_date::text, pending_assignment = false, last_scan_time = current_timestamp, assign_time = current_timestamp WHERE id = v_document_id; END IF; UPDATE guest SET doc_id = v_document_id WHERE id = v_out_guest_id; RETURN v_out_guest_id; END