feat: implement doctor data migration and update booking link UI in doctor-detail template
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import xml.etree.ElementTree as ET
|
||||
import csv
|
||||
import sys
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
try:
|
||||
tree = ET.parse('/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/bnhvinakhoaquctsiscnth.WordPress.2026-07-28 (5).xml')
|
||||
root = tree.getroot()
|
||||
except Exception as e:
|
||||
print(f"Error parsing XML: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
ns = {
|
||||
'wp': 'http://wordpress.org/export/1.2/',
|
||||
'content': 'http://purl.org/rss/1.0/modules/content/'
|
||||
}
|
||||
|
||||
attachments = {}
|
||||
for channel in root.findall('channel'):
|
||||
for item in channel.findall('item'):
|
||||
pt = item.find('wp:post_type', ns)
|
||||
if pt is not None and pt.text == 'attachment':
|
||||
post_id = item.find('wp:post_id', ns)
|
||||
url = item.find('wp:attachment_url', ns)
|
||||
if post_id is not None and url is not None:
|
||||
attachments[post_id.text] = url.text
|
||||
|
||||
csv_mapping = {}
|
||||
with open('/home/x79/sisvietnamvn_01/Media/HÌNH ẢNH BÁC SĨ NGỒI PHÒNG KHÁM/ALL_IMAGES/DANH SÁCH BÁC SĨ NGỒI PHÒNG KHÁM.csv', 'r', encoding='utf-8-sig') as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
name = row.get('Họ và tên', '').strip()
|
||||
msnv = row.get('MSNV', '').strip()
|
||||
if name:
|
||||
csv_mapping[name.lower()] = msnv
|
||||
|
||||
def escape_sql(text):
|
||||
if not text:
|
||||
return "NULL"
|
||||
return "'" + text.replace("'", "''") + "'"
|
||||
|
||||
def parse_html_content(html):
|
||||
if not html:
|
||||
return None, None, None
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
education = ""
|
||||
experience = ""
|
||||
achievements = ""
|
||||
|
||||
current_section = None
|
||||
|
||||
# We will just split it simply for now, but a more robust way:
|
||||
# Just save the entire raw HTML into work_experience if we can't easily parse
|
||||
return escape_sql(html), "NULL", "NULL"
|
||||
|
||||
sql_statements = []
|
||||
# TRUNCATE TABLE sis_doctor CASCADE? We should probably just insert.
|
||||
# But there might be old data. Let's just generate INSERTs.
|
||||
|
||||
doctor_id = 1000
|
||||
|
||||
for channel in root.findall('channel'):
|
||||
for item in channel.findall('item'):
|
||||
pt = item.find('wp:post_type', ns)
|
||||
if pt is not None and pt.text == 'employee':
|
||||
title_el = item.find('title')
|
||||
raw_title = title_el.text.strip() if title_el is not None and title_el.text else ""
|
||||
|
||||
# Extract name and title (e.g. "TS.BS TRẦN CHÍ CƯỜNG" -> title="TS.BS", name="TRẦN CHÍ CƯỜNG")
|
||||
parts = raw_title.split(' ', 1)
|
||||
doctor_title = parts[0] if '.' in parts[0] else ''
|
||||
doctor_name = parts[1] if doctor_title and len(parts) > 1 else raw_title
|
||||
if not doctor_title:
|
||||
doctor_name = raw_title
|
||||
|
||||
doctor_name_lower = doctor_name.lower()
|
||||
|
||||
msnv = ""
|
||||
for csv_name, code in csv_mapping.items():
|
||||
if csv_name in doctor_name_lower or doctor_name_lower in csv_name:
|
||||
msnv = code
|
||||
break
|
||||
|
||||
meta_dict = {}
|
||||
for meta in item.findall('wp:postmeta', ns):
|
||||
k = meta.find('wp:meta_key', ns)
|
||||
v = meta.find('wp:meta_value', ns)
|
||||
if k is not None and k.text and v is not None:
|
||||
meta_dict[k.text] = v.text or ""
|
||||
|
||||
position = meta_dict.get('position', '')
|
||||
gender = meta_dict.get('gender', '')
|
||||
birthday = meta_dict.get('birthday', '')
|
||||
phone = meta_dict.get('phone_number', '')
|
||||
email = meta_dict.get('email', '')
|
||||
address = meta_dict.get('address', '')
|
||||
order = meta_dict.get('order', '0')
|
||||
image_id = meta_dict.get('image', '')
|
||||
avatar_url = attachments.get(image_id, '')
|
||||
|
||||
content_el = item.find('content:encoded', ns)
|
||||
html_content = content_el.text if content_el is not None else ""
|
||||
exp, edu, ach = parse_html_content(html_content)
|
||||
|
||||
if not order.isdigit():
|
||||
order = '0'
|
||||
|
||||
# INSERT statement
|
||||
# Use sequenceGenerator.nextval or just let JPA handle it? Since we insert via SQL, we use sequence_generator.nextval
|
||||
sql = f"""
|
||||
INSERT INTO sis_doctor (
|
||||
id, name, title, avatar_url, doctor_code, active,
|
||||
position, gender, birthday, phone_number, email, address, display_order,
|
||||
work_experience, created_by, created_date, last_modified_by, last_modified_date
|
||||
) VALUES (
|
||||
{doctor_id}, {escape_sql(doctor_name)}, {escape_sql(doctor_title)}, {escape_sql(avatar_url)}, {escape_sql(msnv)}, 1,
|
||||
{escape_sql(position)}, {escape_sql(gender)}, {escape_sql(birthday)}, {escape_sql(phone)}, {escape_sql(email)}, {escape_sql(address)}, {order},
|
||||
{exp}, 'system', sysdate, 'system', sysdate
|
||||
);"""
|
||||
sql_statements.append(sql.strip())
|
||||
doctor_id += 1
|
||||
|
||||
with open('/home/x79/sisvietnamvn_01/sisvietnamvn_main/import_doctors.sql', 'w', encoding='utf-8') as f:
|
||||
f.write("DELETE FROM sis_doctor;\n")
|
||||
f.write("\n".join(sql_statements))
|
||||
f.write("\nCOMMIT;\n")
|
||||
|
||||
print("Generated import_doctors.sql")
|
||||
Reference in New Issue
Block a user