File size: 15,110 Bytes
8ef276c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# contacts_data.py
"""
Contact database with 500 fake contacts covering all departments and divisions.
Each contact has Arabic and English names for better search support.
"""

from typing import List, Dict
from division_hierarchy import DIVISION_TO_DEPARTMENT
import random

# Common Arabic first names (male and female)
ARABIC_FIRST_NAMES_MALE = [
    "محمد", "أحمد", "عبدالله", "عمر", "خالد", "سعد", "فيصل", "سلطان", "ناصر", "طلال",
    "عبدالعزيز", "فهد", "تركي", "سلمان", "بندر", "مشعل", "ماجد", "يوسف", "حسن", "علي",
    "وليد", "زياد", "رامي", "كريم", "عادل", "راشد", "مازن", "طارق", "إبراهим", "عيسى",
    "نواف", "سامي", "بدر", "عاصم", "وسام", "هاني", "ثامر", "صالح", "ياسر", "جاسم",
    "هشام", "فواز", "معاذ", "عثمان", "أسامة", "باسل", "عمار", "نبيل", "توفيق", "جمال"
]

ARABIC_FIRST_NAMES_FEMALE = [
    "فاطمة", "نورة", "سارة", "منى", "هند", "ريم", "لينا", "دانة", "شهد", "جود",
    "رهف", "غلا", "عبير", "أمل", "ندى", "رنا", "لمى", "ديمة", "بشرى", "سمية",
    "هيفاء", "ليلى", "زينب", "خلود", "شروق", "أريج", "جميلة", "رباب", "سلمى", "وفاء",
    "عائشة", "خديجة", "مريم", "رقية", "زهراء", "نجود", "حصة", "عزة", "صفية", "ملاك",
    "روان", "تالا", "جنى", "لين", "ريتاج", "أسماء", "سديم", "لمار", "بيان", "شيماء"
]

# Common Arabic last names
ARABIC_LAST_NAMES = [
    "العتيبي", "الدوسري", "القحطاني", "الشهري", "الغامدي", "الزهراني", "العنزي", "الحربي",
    "المطيري", "العسيري", "السبيعي", "الشمري", "الجهني", "العمري", "البقمي", "الفهد",
    "السديري", "الثبيتي", "الصقري", "الأحمد", "الخالد", "السليمان", "العبدالله", "الفهيد",
    "الشايع", "الرشيد", "العجمي", "المالك", "الفريح", "الحمود", "الناصر", "الشريف",
    "البلوي", "اليامي", "الوادعي", "الفيفي", "الشهراني", "البكري", "العسكر", "الراشد",
    "الفايز", "الخليف", "المنيع", "العبيد", "السحيم", "الغنام", "السلمان", "الهاجري",
    "النهدي", "الرويلي", "المري", "السواط", "الربيعان", "الدغيثر", "الفضلي", "القرني",
    "الثنيان", "العريفي", "الهويدي", "الجريسي", "البدراني", "المهيدب", "السالم", "الحارثي",
    "العطوي", "الصخري", "الرحيلي", "السعيد", "الحافظ", "الوهيبي", "البراك", "الضويان"
]

# Job titles in English and Arabic by category
JOB_TITLES = {
    "executive": [
        ("Chief Executive Officer", "المدير التنفيذي"),
        ("Executive Director", "المدير التنفيذي"),
        ("Vice President", "نائب الرئيس"),
        ("Senior Vice President", "نائب الرئيس الأول"),
    ],
    "management": [
        ("Director", "مدير"),
        ("Senior Manager", "مدير أول"),
        ("Manager", "مدير"),
        ("Assistant Manager", "مساعد مدير"),
        ("Team Leader", "قائد فريق"),
        ("Supervisor", "مشرف"),
    ],
    "specialist": [
        ("Senior Specialist", "أخصائي أول"),
        ("Specialist", "أخصائي"),
        ("Senior Analyst", "محلل أول"),
        ("Analyst", "محلل"),
        ("Senior Consultant", "مستشار أول"),
        ("Consultant", "مستشار"),
        ("Senior Officer", "موظف أول"),
        ("Officer", "موظف"),
    ],
    "technical": [
        ("Senior Engineer", "مهندس أول"),
        ("Engineer", "مهندس"),
        ("Technical Lead", "قائد تقني"),
        ("Developer", "مطور"),
        ("Architect", "مهندس معماري"),
    ],
    "support": [
        ("Coordinator", "منسق"),
        ("Administrator", "إداري"),
        ("Assistant", "مساعد"),
        ("Associate", "معاون"),
    ]
}

# Phone extensions (4-digit)
def generate_extension() -> str:
    """Generate a 4-digit phone extension"""
    return str(random.randint(1000, 9999))

# Email generation
def generate_email(first_name_en: str, last_name_en: str) -> str:
    """Generate an email address"""
    # Remove spaces and special characters
    first = first_name_en.lower().replace(" ", "").replace("-", "")
    last = last_name_en.lower().replace(" ", "").replace("-", "")
    return f"{first}.{last}@sidf.gov.sa"


def transliterate_arabic_name(arabic_name: str) -> str:
    """
    Simple transliteration of Arabic names to English.
    This is a basic mapping for common names.
    """
    transliteration_map = {
        # Male names
        "محمد": "Mohammed", "أحمد": "Ahmed", "عبدالله": "Abdullah", "عمر": "Omar", "خالد": "Khalid",
        "سعد": "Saad", "فيصل": "Faisal", "سلطان": "Sultan", "ناصر": "Nasser", "طلال": "Talal",
        "عبدالعزيز": "Abdulaziz", "فهد": "Fahad", "تركي": "Turki", "سلمان": "Salman", "بندر": "Bandar",
        "مشعل": "Mishaal", "ماجد": "Majed", "يوسف": "Yousef", "حسن": "Hassan", "علي": "Ali",
        "وليد": "Waleed", "زياد": "Ziyad", "رامي": "Rami", "كريم": "Kareem", "عادل": "Adel",
        "راشد": "Rashed", "مازن": "Mazen", "طارق": "Tariq", "إبراهim": "Ibrahim", "عيسى": "Issa",
        "نواف": "Nawaf", "سامي": "Sami", "بدر": "Badr", "عاصم": "Asim", "وسام": "Wissam",
        "هاني": "Hani", "ثامر": "Thamer", "صالح": "Saleh", "ياسر": "Yasser", "جاسم": "Jasim",
        "هشام": "Hisham", "فواز": "Fawaz", "معاذ": "Muath", "عثمان": "Othman", "أسامة": "Osama",
        "باسل": "Basel", "عمار": "Ammar", "نبيل": "Nabil", "توفيق": "Tawfiq", "جمال": "Jamal",

        # Female names
        "فاطمة": "Fatima", "نورة": "Noura", "سارة": "Sarah", "منى": "Mona", "هند": "Hind",
        "ريم": "Reem", "لينا": "Lina", "دانة": "Dana", "شهد": "Shahad", "جود": "Joud",
        "رهف": "Rahaf", "غلا": "Ghala", "عبير": "Abeer", "أمل": "Amal", "ندى": "Nada",
        "رنا": "Rana", "لمى": "Lama", "ديمة": "Dima", "بشرى": "Bushra", "سمية": "Somaya",
        "هيفاء": "Haifa", "ليلى": "Layla", "زينب": "Zainab", "خلود": "Kholoud", "شروق": "Shorouq",
        "أريج": "Areej", "جميلة": "Jamila", "رباب": "Rabab", "سلمى": "Salma", "وفاء": "Wafa",
        "عائشة": "Aisha", "خديجة": "Khadija", "مريم": "Maryam", "رقية": "Ruqaya", "زهراء": "Zahra",
        "نجود": "Nujoud", "حصة": "Hessa", "عزة": "Azza", "صفية": "Safiya", "ملاك": "Malak",
        "روان": "Rawan", "تالا": "Tala", "جنى": "Jana", "لين": "Leen", "ريتاج": "Ritaj",
        "أسماء": "Asma", "سديم": "Sadeem", "لمار": "Lamar", "بيان": "Bayan", "شيماء": "Shaima",

        # Last names
        "العتيبي": "Al-Otaibi", "الدوسري": "Al-Dosari", "القحطاني": "Al-Qahtani", "الشهري": "Al-Shahri",
        "الغامدي": "Al-Ghamdi", "الزهراني": "Al-Zahrani", "العنزي": "Al-Anazi", "الحربي": "Al-Harbi",
        "المطيري": "Al-Mutairi", "العسيري": "Al-Asiri", "السبيعي": "Al-Subaie", "الشمري": "Al-Shammari",
        "الجهني": "Al-Juhani", "العمري": "Al-Omari", "البقمي": "Al-Buqami", "الفهد": "Al-Fahad",
        "السديري": "Al-Sudairi", "الثبيتي": "Al-Thubaiti", "الصقري": "Al-Saqri", "الأحمد": "Al-Ahmad",
        "الخالد": "Al-Khalid", "السليمان": "Al-Sulaiman", "العبدالله": "Al-Abdullah", "الفهيد": "Al-Fahaid",
        "الشايع": "Al-Shaya", "الرشيد": "Al-Rasheed", "العجمي": "Al-Ajmi", "المالك": "Al-Malek",
        "الفريح": "Al-Fraihi", "الحمود": "Al-Hamoud", "الناصر": "Al-Nasser", "الشريف": "Al-Shareef",
        "البلوي": "Al-Balawi", "اليامي": "Al-Yami", "الوادعي": "Al-Wadei", "الفيفي": "Al-Faifi",
        "الشهراني": "Al-Shahrani", "البكري": "Al-Bakri", "العسكر": "Al-Askar", "الراشد": "Al-Rashed",
        "الفايز": "Al-Fayez", "الخليف": "Al-Khleif", "المنيع": "Al-Manie", "العبيد": "Al-Obaid",
        "السحيم": "Al-Suhaim", "الغنام": "Al-Ghannam", "السلمان": "Al-Salman", "الهاجري": "Al-Hajri",
        "النهدي": "Al-Nahdi", "الرويلي": "Al-Ruwaili", "المري": "Al-Marri", "السواط": "Al-Sawat",
        "الربيعان": "Al-Rabian", "الدغيثر": "Al-Dughither", "الفضلي": "Al-Fadhli", "القرني": "Al-Qarni",
        "الثنيان": "Al-Thuniyan", "العريفي": "Al-Arifi", "الهويدي": "Al-Huwaidi", "الجريسي": "Al-Juraysi",
        "البدراني": "Al-Badrani", "المهيدب": "Al-Muhaidib", "السالم": "Al-Salem", "الحارثي": "Al-Harthi",
        "العطوي": "Al-Atawi", "الصخري": "Al-Sakhri", "الرحيلي": "Al-Rahili", "السعيد": "Al-Saeed",
        "الحافظ": "Al-Hafiz", "الوهيبي": "Al-Wahaibi", "البراك": "Al-Barrak", "الضويان": "Al-Dhuwayan",
    }
    return transliteration_map.get(arabic_name, arabic_name)


def generate_contacts() -> List[Dict]:
    """
    Generate 500 fake contacts distributed across all divisions.
    Returns a list of contact dictionaries.
    """
    contacts = []
    contact_id = 1000  # Starting ID

    # Get all divisions
    divisions = list(DIVISION_TO_DEPARTMENT.keys())

    # Calculate contacts per division (aim for ~7-8 per division)
    contacts_per_division = 500 // len(divisions)
    extra_contacts = 500 % len(divisions)

    for div_index, division in enumerate(divisions):
        department_name, department_id = DIVISION_TO_DEPARTMENT[division]

        # Number of contacts for this division
        num_contacts = contacts_per_division
        if div_index < extra_contacts:
            num_contacts += 1

        # Determine seniority distribution (more junior staff than senior)
        # 10% executive, 20% management, 50% specialist, 15% technical, 5% support
        seniority_distribution = []
        seniority_distribution.extend(["executive"] * max(1, int(num_contacts * 0.10)))
        seniority_distribution.extend(["management"] * max(1, int(num_contacts * 0.20)))
        seniority_distribution.extend(["specialist"] * max(1, int(num_contacts * 0.50)))
        seniority_distribution.extend(["technical"] * max(1, int(num_contacts * 0.15)))
        seniority_distribution.extend(["support"] * max(1, int(num_contacts * 0.05)))

        # Ensure we have exactly num_contacts
        while len(seniority_distribution) < num_contacts:
            seniority_distribution.append("specialist")
        seniority_distribution = seniority_distribution[:num_contacts]

        random.shuffle(seniority_distribution)

        for i in range(num_contacts):
            # Mix male and female names (60% male, 40% female)
            is_male = random.random() < 0.6

            if is_male:
                first_name_ar = random.choice(ARABIC_FIRST_NAMES_MALE)
            else:
                first_name_ar = random.choice(ARABIC_FIRST_NAMES_FEMALE)

            last_name_ar = random.choice(ARABIC_LAST_NAMES)

            # Transliterate to English
            first_name_en = transliterate_arabic_name(first_name_ar)
            last_name_en = transliterate_arabic_name(last_name_ar)

            # Full names
            full_name_ar = f"{first_name_ar} {last_name_ar}"
            full_name_en = f"{first_name_en} {last_name_en}"

            # Get job title based on seniority
            seniority = seniority_distribution[i]
            title_en, title_ar = random.choice(JOB_TITLES[seniority])

            # Generate contact info
            extension = generate_extension()
            email = generate_email(first_name_en, last_name_en)

            contact = {
                "id": contact_id,
                "first_name_ar": first_name_ar,
                "last_name_ar": last_name_ar,
                "full_name_ar": full_name_ar,
                "first_name_en": first_name_en,
                "last_name_en": last_name_en,
                "full_name_en": full_name_en,
                "title_en": title_en,
                "title_ar": title_ar,
                "division": division,
                "department": department_name,
                "department_id": department_id,
                "email": email,
                "extension": extension,
                "phone": f"+966-11-218-{extension}",
            }

            contacts.append(contact)
            contact_id += 1

    return contacts


# Generate contacts on module load
CONTACTS_DATABASE = generate_contacts()

# Create indexes for fast lookup
CONTACTS_BY_NAME_AR = {contact["full_name_ar"]: contact for contact in CONTACTS_DATABASE}
CONTACTS_BY_NAME_EN = {contact["full_name_en"]: contact for contact in CONTACTS_DATABASE}
CONTACTS_BY_DIVISION = {}
for contact in CONTACTS_DATABASE:
    division = contact["division"]
    if division not in CONTACTS_BY_DIVISION:
        CONTACTS_BY_DIVISION[division] = []
    CONTACTS_BY_DIVISION[division].append(contact)


def get_all_contacts() -> List[Dict]:
    """Get all contacts"""
    return CONTACTS_DATABASE


def get_contacts_by_division(division: str) -> List[Dict]:
    """Get contacts for a specific division"""
    return CONTACTS_BY_DIVISION.get(division, [])


def get_contact_by_name(name: str) -> Dict:
    """Get contact by exact name (Arabic or English)"""
    # Try Arabic first
    contact = CONTACTS_BY_NAME_AR.get(name)
    if contact:
        return contact

    # Try English
    contact = CONTACTS_BY_NAME_EN.get(name)
    if contact:
        return contact

    return None


if __name__ == "__main__":
    # Test the contact generation
    contacts = get_all_contacts()
    print(f"Generated {len(contacts)} contacts")
    print(f"\nSample contacts:")
    for i, contact in enumerate(contacts[:5]):
        print(f"{i+1}. {contact['full_name_en']} ({contact['full_name_ar']})")
        print(f"   {contact['title_en']} - {contact['division']}")
        print(f"   {contact['email']} | Ext: {contact['extension']}")
        print()

    # Show distribution by department
    from collections import Counter
    dept_counts = Counter(contact["department"] for contact in contacts)
    print("\nContacts by Department:")
    for dept, count in sorted(dept_counts.items(), key=lambda x: -x[1]):
        print(f"  {dept}: {count}")