• דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    • הרשמה
    • התחברות
    1. דף הבית
    2. בוס
    ב
    מנותק
    • פרופיל
    • עוקב אחרי 10
    • עוקבים 8
    • נושאים 61
    • פוסטים 984
    • קבוצות 0

    בוס

    @בוס

    366
    מוניטין
    251
    צפיות בפרופיל
    984
    פוסטים
    8
    עוקבים
    10
    עוקב אחרי
    תאריך הצטרפות
    נראה לאחרונה

    בוס הפסקת מעקב מעקב

    הפוסטים הטובים ביותר שנוצרו על ידי בוס

    • סוף סוף... בעת פתיחת שלוחה חדשה ההגדרות מופיעות מיד!

      התופעה הידועה שכאשר פותחים שלוחה חדשה באתר הניהול לוקח להגדרות כ 4 דקות להופיע, ואז אם כבר הוספת הגדרות פתאום זה מתאפס לך כי זה פתאום החליט להתעדכן...
      אז זהו, כעת ימות סידרו את זה ועכשיו איך שפותחים את השלוחה ההגדרות מופיעות כבר!
      אצלי אישית זה בשורה אדירה, כי כשרוצים לעבוד על משהו פתאום צריכים להמתין ולהשתגע עם כל מני קומבינות כמו להעתיק שלוחה קיימת ולשנות את מספר השלוחה וכו'

      תודות לחברת ימות המשיח👍

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: בין הזמנים

      @אחד-מאנש-0 כתב בבין הזמנים:

      כל פעם בבין הזמנים ישנם מאוד הרבה התקשקשויות מיותרות כאן בפורום

      כדוגמת השירשור הזה

      פורסם בעל הפורום
      ב
      בוס
    • צינתוקים

      לאחר שיוצאים מרשימת צינתוקים אם עדיין לא רשום אז בעבר היה הודעת מערכת "מספר הטלפון שלכם אינו מופיע ברשימת הצינתוקים"
      חבל שביטלו את זה, זה מאוד שימושי.

      פורסם בבקשות לפיתוח
      ב
      בוס
    • יצירת סיסמאות מרובות לשלוחה

      תמיד רציתם לשים כמה קודים על שלוחה מסויימת (ושכל קוד יעביר את המאזין לשלוחה אחרת)?
      הנה לפניכם!
      מגדירים כך

      type=menu
      שלוחת תפריט
      digits=5
      חמש הקשות
      timeout=1
      להמתין להקשות נוספות רק שניה
      M1001_say=yes
      המקש שהוקש שגוי M1001 אם השלוחה אינה קיימת שיגיד את הודעות
      timeout_goto=..
      מעבר לאחר התפריט באם לא הוקשה בחירה
      attempts=1
      כמה פעמים להשמיע את התפריט לפני שישמיע הודעת לא הוקשה בחירה
      

      עכשיו הסבר.

      ברגע ששלוחה זו מוגדרת צריך להגדיר את כל הסיסמאות, שבעצם הם שלוחת מעבר לשלוחה אחרת.
      לדוגמה: אם שלוחת "הסיסמה" היא שלוחה 1 (לא ניתן לבצע את זה כהטמעה אלה צריך לזה שלוחה בפני עצמה)
      אז נגדיר את שלוחה 1/01234 כמעבר לשלוחה אחרת ואז בעצם כאשר המאזין מקיש את הסיסמה 1234# הוא עובר לשלוחה שהגדרנו,
      וכן הלאה נפתח שלוחות שהם בעצם הקוד,

      עכשיו להודעות המערכת
      בשלוחת התפריט יש לשים את הודעה M1000 ולהקליט "נא הקש את הסיסמה..."
      ואת הודעה M1001 ולהקליט "הסיסמה שגוייה"

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ב
      בוס
    • בחירת שלוחה למעבר

      ע"י פתיחת שתי שלוחות בלבד ניתן לעבור לכל שלוחה שתירצו ע"י הקשת השלוחה המבוקשת.

      שלוחה 1

      type=add_id_to_list
      add_id_to_list_location_list=/1/1/ext
      add_id_to_list_key=go_to_folder
      add_id_to_list_value_type=digits
      add_id_to_list_end_goto=/1/1
      

      לשנות את הודעת M4358 ל"אנא הקישו את מספר השלוחה שברצונכם לעבור אליה, לתתי שלוחות יש להקיש כוכבית בין השלוחות"
      להשתיק את הודעת M3411.

      שלוחה 1/1

      type=go_to_folder
      
      פורסם בהסברים מסודרים ממשתמשים
      ב
      בוס
    • RE: שכל מאזין יוכל לנייד אוטומטי קו.

      @רק-טוב תגדיר

      type=api
      api_link=https://www.call2all.co.il/ym/api/UpdateExtension
      api_add_0=path=ivr2:/
      api_add_1=type=routing_yemot
      api_add_2=routing_yemot_number=079123456
      api_000=token,,,10,,NO,yes,,*:
      

      במקום 079123456, תכניס את מספר המערכת אליה תרצה שהמערכות ישוייכו.
      תכניס לשלוחה הודעה מספר 000 שבה אתה אומר "אנא הקישו את מספר המערכת והסיסמה ברצף, בין מספר המערכת לבין הסיסמה הקישוא כוכבית".
      תכניס הודעה בשם M1607 שבה תגיד: "הפעולה הסתיימה בהצלחה, באם הקשתם מספר מערכת וסיסמה נכונים המערכת תשויך לקו שלנו"

      פורסם בשאלות ועזרה הדדית
      ב
      בוס
    • מדריך | הגדרת מרווח של זמן בין צינתוק לצינתוק, כך שלא יתאפשר להפעיל צינתוק במידה וכבר הופעל צינתוק בטווח הזמן שתבחרו

      ב"ה
      הרבה מערכות נתקלות בבעיה שיש כמה מנהלים שמסננים את ההודעות ושולחים צינתוק, ולפעמים שני מנהלים שולחים צינתוק בטעות אחד אחרי השני.
      אז ניתן להגביל את השליחה של הצינתוק, כך שלא יתן להפעיל צינתוק במידה וכבר הופעל צינתוק בטווח הזמן שתבחרו, ע"י הקומבינה הבאה:

      עיקרון השלוחה פועל על הוספת הגדרה שתמַחֶק לאחר 5 דקות לשלוחת הצינתוקים שיפעיל פילטר לפי רשימה לבנה, כך שאף אחד לא רשום ברשימה.
      ההגדרות מותאמות לשלוחת צינתוק חינמי, אך אפשרי לשימוש גם בהפעלת קמפיין חוץ מההגדרות שציינתי.

      בשלוחת הצינטוקים מגדירים:
      שיעבור בסיום הצינתוק שלוחה פנימה (אם אתה משתמש בהפעלת קמפיין תבדוק מה ההגדרה המתאימה)

      tzintuk_end=1
      

      לאן יעבור אם לא ניתן להפעיל צינתוק:

      white_list_error_goto=/
      

      ובנוסף מעלים קובץ INI ריק בשם WhiteList
      משתיקים את ההודעה M3338 שמודיעה שהצינתוק הופעל (אם אתה משתמש בהפעלת קמפיין תבדוק מה ההודעת מערכת המתאימה)
      ומעלים הודעת מערכת M1102 שם אומרים שהצינתוק כבר הופעל ב5 דקות האחרונות ולא ניתן להפעיל שוב

      בשלוחה 1 שאחרי הצינתוק מגדירים:

      type=add_id_to_list
      add_id_to_list_location_list=/הנתיב המלא של שלוחת הצינתוק/ext
      add_id_to_list_key=white_list
      add_id_to_list_value=yes
      add_id_to_list_value_change=yes
      add_id_to_list_value_expired=5m
      בהגדרה זו ניתן להדגיר כל זמן. כאן מוגדר 5 דקות
      add_id_to_list_end_goto=/
      

      ובנוסף מעלים את ההודעת מערכת M3411 שמודיעה שהצינתוק הופעל.

        m3411.wav

      יוצא לנו שהמאזין נכנס לשלוחת הצינתוק, מפעיל צינתוק, מוסיף הגדרה של רשימה לבנה לשלוחה הצינתוק, שומע שהצינתוק הופעל, יוצא מהשלוחה.

      לאלו ששואלים למה צריך להשתיק את ההודעה של הפעלת הצינתוק, ולאח"מ לשים הודעה כזו שוב.
      אז כך:
      המאזין הפשוט שומע " הצינתוק הופעל" אז הוא מנתק, בידיעה שעשה מה שצריך לעשות, כך שהוא לא נכנס לשלוחת ההוספה.

      פורסם בהסברים מסודרים ממשתמשים
      ב
      בוס
    • RE: איך מסמנים 'לא נפתר'

      @פלוס אחרי שהסבירו לך, כעת אתה יכול לסמן את הנושא הזה כנפתר😉

      פורסם בעל הפורום
      ב
      בוס
    • RE: ההודעה שהקלטה קצרה מדי, וזה לא קצר?!

      @פיתה כתב בההודעה שהקלטה קצרה מדי, וזה לא קצר?!:

      @y6714453 טוב זה לא כל כך משנה כי זה קורא מידי פעם.... אבל היום זה מאוד יצבן אותי אחרי הודעה הארוכה שנמחקה בגלל זה.

      תמיד תוכל לשמוע את ההקלטות שלא אושרו בסל מחזור בתיקייה שנקראת Record

      ו... משהו שהתגלה לי לאחרונה ממש שאפשר לשמוע שם את ההקלטה תוך כדי שאתה מקליט, הקובץ מתעדכן כל הזמן בהתאם להקלטה בפועל!! ברגע שהתחלת להקליט, אתה כבר יכול לשמוע את ההקלטה.

      @צבי-ד-צ אתה בטח תשמח לשמוע את זה. תעדכן האם זה חידש לך.

      פורסם בשאלות ועזרה הדדית
      ב
      בוס
    • RE: צינתוק למנהל כהשידור חי מתנתק

      @ימהר-0 יש כאן שלוחה שעושה זאת

      פורסם בבקשות לפיתוח
      ב
      בוס

    פוסטים אחרונים שנוצרו על ידי בוס

    • RE: מעבר לשלוחה במהלך שידור חי, יש?

      @יצחק-SH אתה יכול להשתמש בפונקציה של יציאה מחדר ועידה, תגדיר כך:

      conf_bridge_exit=yes
      confbridge_end_goto=/השלוחה למעבר
      

      ואז המאזין יוכל להקיש כוכבית 8 ולעבור לשלוחה המוגדרת

      שים לב, המאזינים יועברו אוטומטית לשלוחה המוגדרת בעת ניתוק הועידה ע"י המנהל, מכיון שזה נחשב ליציאה מחדר הועידה.

      פורסם בשאלות ועזרה הדדית
      ב
      בוס
    • RE: הגדרת חסימה לפי קידומת

      @פלוס נכון שלא סותרות, אך כאשר ההגדרה הראשונה חוסמת את המאזין או לא נותנת לו להתקדם, אז שאר הבדיקות והפילטרים לא יבדקו ולא יעבדו כלל על אותו מאזין

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: תגובה ל"הכירו את מודול ההתראות: חדש וייחודי מבית ימות המשיח 🤩"

      @CUBASE אתה יכול להביא צילו"מ בדיוק איפה ללחוץ?

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: למה אין נתונים לקווים? 🤔

      @121244 נשמח שתביא את הקוד כאן, יותר נחמד שהכנסת הטוקן היא על הדפדפן מאשר על שרת.

      לא שאני חושדך חלילה

      פורסם בבקשות לפיתוח
      ב
      בוס
    • RE: למה אין נתונים לקווים? 🤔

      @אa כדאי גם להוסיף הצגת ההתקדמות בטעינת הלוגים גם ב מספרים/אחוזים, ולא רק בקו מתמלא.
      לי יש לוג של מעל מיליון (!) שורות, וכבר למעלה מחצי שעה הוא לא גומר לטעון הקובץ, כך שאני לא יודע אם הוא מתקדם או נתקע סופית.

      553af961-3c65-483b-b68a-31d1ecb3e228-image.png

      פורסם בבקשות לפיתוח
      ב
      בוס
    • RE: קבצים ותוכנות לשימוש במערכות ימות המשיח

      @אA

      תיכף אחד מ"חכמי" הפורום יפתח ע"ז שרשור שלם...

      רק לי קפץ התראה על שינוי הפורום...

      וכמובן איך אפשק לשכוח, תמונה.

      267358c1-7e2f-43b6-a8b7-caba2e9b6a8e-image.png

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: קבצים ותוכנות לשימוש במערכות ימות המשיח

      @אA

      קפץ פעם אחת, בפועל לא התשנה משהו הנראה לעין.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: קבצים ותוכנות לשימוש במערכות ימות המשיח

      @אA כן אבל בתוך סופוילר

      ככה:

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
          <meta charset="UTF-8">
          <title>ניתוח נתוני מערכות | v26.3</title>
          <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
          <style>
              :root { --bg: #0f172a; --card: #1e293b; --primary: #38bdf8; --accent: #22c55e; --text: #f1f5f9; --border: #334155; --danger: #ef4444; --warning: #f59e0b; }
              body { font-family: 'Segoe UI', sans-serif; background: var(--bg); color: var(--text); margin: 0; display: flex; flex-direction: column; height: 100vh; }
              header { background: #1e293b; padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border); box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); }
              .logo-box { display: flex; align-items: center; gap: 12px; }
              .logo-icon { background: linear-gradient(135deg, var(--primary), #0ea5e9); color: #0f172a; width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
              .logo-text { font-size: 1.4rem; font-weight: 800; color: var(--text); }
              .config-box { display: flex; gap: 12px; align-items: center; }
              input, select { background: #0f172a; border: 1px solid var(--border); color: white; padding: 10px; border-radius: 8px; outline: none; }
              .btn-run { background: var(--primary); color: #0f172a; border: none; padding: 10px 25px; border-radius: 8px; font-weight: bold; cursor: pointer; transition: 0.3s; }
              .nav-tabs { background: #1e293b; display: flex; padding: 0 20px; border-bottom: 1px solid var(--border); }
              .tab { padding: 15px 25px; cursor: pointer; color: #94a3b8; border-bottom: 3px solid transparent; transition: 0.3s; }
              .tab.active { color: var(--primary); border-bottom-color: var(--primary); background: rgba(56, 189, 248, 0.07); }
              .main-content { flex: 1; padding: 25px; overflow-y: auto; background: #0f172a; }
              .card { background: var(--card); padding: 25px; border-radius: 16px; border: 1px solid var(--border); margin-bottom: 25px; }
              .stat-num { font-size: 2.5rem; font-weight: 800; color: var(--primary); }
              .control-bar { display: flex; gap: 20px; align-items: center; background: #334155; padding: 15px 25px; border-radius: 12px 12px 0 0; }
              .search-input { background: #0f172a; border: 1px solid var(--border); color: white; padding: 8px 15px; border-radius: 8px; width: 250px; }
              table { width: 100%; border-collapse: collapse; background: var(--card); border-radius: 0 0 12px 12px; overflow: hidden; }
              th { text-align: right; padding: 15px; background: #475569; color: white; font-size: 0.85rem; }
              td { padding: 15px; border-bottom: 1px solid var(--border); font-size: 0.95rem; }
              tr.clickable { cursor: pointer; }
              tr.clickable:hover { background: rgba(56, 189, 248, 0.1); }
              .bar-container { width: 100px; background: #0f172a; height: 10px; border-radius: 10px; display: inline-block; overflow: hidden; vertical-align: middle; margin-left: 8px; }
              .bar-fill { height: 100%; background: var(--accent); }
              .modal-overlay { position: fixed; top:0; left:0; width:100%; height:100%; background: rgba(0,0,0,0.85); display: none; justify-content: center; align-items: center; z-index: 1000; }
              .modal-content { background: var(--card); width: 85%; max-height: 85%; border-radius: 20px; border: 1px solid var(--primary); overflow-y: auto; padding: 30px; position: relative; }
              .close-modal { position: absolute; top: 20px; left: 20px; color: white; font-size: 2rem; cursor: pointer; }
              .progress-container { width: 100%; background: #1e293b; height: 6px; display: none; }
              #progress-fill { height: 100%; background: var(--primary); width: 0%; transition: 0.4s; }
              .hidden { display: none; }
              .live-status { display: flex; align-items: center; gap: 6px; font-size: 0.75rem; padding: 4px 10px; border-radius: 20px; background: #334155; }
              .dot { width: 8px; height: 8px; border-radius: 50%; background: #666; }
              .dot.active { background: var(--accent); animation: pulse 2s infinite; }
              @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.4; } 100% { opacity: 1; } }
          </style>
      </head>
      <body>
       
      <header>
          <div class="logo-box">
              <div class="logo-icon"><i class="fas fa-chart-pie"></i></div>
              <div class="logo-text">ניתוח נתוני מערכות</div>
              <div class="live-status"><div id="live-dot" class="dot"></div> <span id="live-text">OFFLINE</span></div>
          </div>
          <div class="config-box">
              <input type="password" id="apiToken" placeholder="טוקן API">
              <input type="date" id="startDate">
              <input type="date" id="endDate">
              <button class="btn-run" onclick="manualStart()">הפעל ניתוח</button>
          </div>
      </header>
       
      <div class="progress-container" id="progBar"><div id="progress-fill"></div></div>
       
      <div class="nav-tabs">
          <div class="tab active" onclick="switchTab(event, 'dash-tab')">דאשבורד</div>
          <div class="tab" onclick="switchTab(event, 'ext-tab')">שלוחות</div>
          <div class="tab" onclick="switchTab(event, 'play-tab')">השמעות</div>
          <div class="tab" onclick="switchTab(event, 'users-tab')">מאזינים</div>
          <div class="tab" style="color: var(--warning)" onclick="switchTab(event, 'debug-tab')">לוג</div>
      </div>
       
      <div class="main-content">
          <div id="dash-tab" class="tab-content">
              <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 25px; margin-bottom: 25px;">
                  <div class="card"><span style="color: #94a3b8">מאזינים ייחודיים</span><br><span id="stat-users" class="stat-num">0</span></div>
                  <div class="card"><span style="color: #94a3b8">סה"כ דקות האזנה</span><br><span id="stat-min" class="stat-num">0</span></div>
                  <div class="card"><span style="color: #94a3b8">שיחות שהושלמו (סוף קובץ)</span><br><span id="stat-comp" class="stat-num">0</span></div>
              </div>
              <div class="card"><h3>גרף פעילות יומי</h3><canvas id="dailyChart" height="100"></canvas></div>
          </div>
       
          <div id="ext-tab" class="tab-content hidden">
              <div class="control-bar">
                  <select id="extSort" onchange="renderExts()"><option value="count">כמות כניסות</option><option value="sec">זמן שהייה</option></select>
                  <input type="text" id="extSearch" class="search-input" placeholder="חפש שלוחה..." onkeyup="renderExts()">
              </div>
              <table id="extTable"><thead><tr><th>שם השלוחה</th><th>כניסות</th><th>דקות שהייה</th><th>ממוצע</th></tr></thead><tbody></tbody></table>
          </div>
       
          <div id="play-tab" class="tab-content hidden">
              <div class="control-bar">
                  <select id="playSort" onchange="renderPlays()"><option value="count">פופולריות</option><option value="pct">אחוז השלמה</option></select>
                  <input type="text" id="playSearch" class="search-input" placeholder="חפש קובץ..." onkeyup="renderPlays()">
              </div>
              <table id="playTable"><thead><tr><th>שם קובץ / שלוחה</th><th>השמעות</th><th>סה"כ דקות</th><th>אחוז השלמה</th><th>נטישה</th></tr></thead><tbody></tbody></table>
          </div>
       
          <div id="users-tab" class="tab-content hidden">
              <div class="control-bar">
                  <select id="userSort" onchange="renderUsers()"><option value="sec">זמן האזנה כולל</option><option value="calls">מספר שיחות</option></select>
                  <input type="text" id="userSearch" class="search-input" placeholder="חפש טלפון..." onkeyup="renderUsers()">
              </div>
              <table id="usersTable"><thead><tr><th>מספר טלפון</th><th>דקות האזנה</th><th>מספר שיחות</th><th>סטטוס</th></tr></thead><tbody></tbody></table>
          </div>
       
          <div id="debug-tab" class="tab-content hidden"><div class="card"><div id="debug-console" style="background:#000; color:#22c55e; padding:20px; height:400px; overflow-y:auto; font-family:monospace;"></div></div></div>
      </div>
       
      <div id="userModal" class="modal-overlay" onclick="closeModal()">
          <div class="modal-content" onclick="event.stopPropagation()">
              <span class="close-modal" onclick="closeModal()">&times;</span>
              <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
                  <h2 id="modalTitle" style="color: var(--primary); margin:0;"></h2>
                  <select id="modalFilter" onchange="filterModalContent()" style="background: var(--bg); border: 1px solid var(--primary); padding: 5px 15px;">
                      <option value="all">הכל</option>
                      <option value="שלוחה">שלוחות בלבד</option>
                      <option value="השמעה">השמעות בלבד</option>
                  </select>
              </div>
              <table id="modalTable">
                  <thead>
                      <tr>
                          <th>סוג פעילות</th>
                          <th>שלוחה/קובץ</th>
                          <th>זמן שהייה</th>
                          <th>תאריך</th>
                      </tr>
                  </thead>
                  <tbody></tbody>
              </table>
          </div>
      </div>
       
      <script>
          const API = "https://www.call2all.co.il/ym/api/";
          let dataStore = { exts: {}, plays: {}, users: {}, daily: {}, rawActivity: [], totalSec: 0, completed: 0 };
          let currentModalPhone = "";
          let dailyChart = null;
          let autoRefreshTimer = null;
       
          function addLog(msg, color = '#22c55e') {
              const console = document.getElementById('debug-console');
              if(!console) return;
              const div = document.createElement('div');
              div.style.color = color;
              div.innerText = `[${new Date().toLocaleTimeString()}] ${msg}`;
              console.appendChild(div);
          }
       
          function cleanExt(val) {
              if (!val) return "ראשית";
              let s = val.toString().trim().replace(/^\ufeff/, "");
              if (s === "" || s === "/" || s === "." || s.toLowerCase() === "root" || s.toLowerCase() === "main") return "ראשית";
              return s;
          }
       
          function parseSec(t) {
              if (!t) return 0;
              if (t.toString().includes(':')) {
                  const p = t.split(':').map(Number);
                  return p.length === 3 ? (p[0]*3600)+(p[1]*60)+p[2] : (p[0]*60)+p[1];
              }
              return parseInt(t) || 0;
          }
       
          async function manualStart() {
              if(autoRefreshTimer) clearInterval(autoRefreshTimer);
              await startFullAnalysis();
              document.getElementById('live-dot').classList.add('active');
              document.getElementById('live-text').innerText = "LIVE (עדכון אוטומטי)";
              autoRefreshTimer = setInterval(startFullAnalysis, 60000); 
          }
       
          async function startFullAnalysis() {
              const token = document.getElementById('apiToken').value;
              const start = document.getElementById('startDate').value;
              const end = document.getElementById('endDate').value;
              if (!token) return alert("נא להזין טוקן API");
       
              addLog("מתחיל סנכרון נתונים...");
              dataStore = { exts: {}, plays: {}, users: {}, daily: {}, rawActivity: [], totalSec: 0, completed: 0 };
              document.getElementById('progBar').style.display = 'block';
       
              const monthStr = start.substring(0, 7); 
              
              try {
                  const res = await fetch(`${API}RenderYMGRFile?token=${token}&wath=ivr2:/Log/LogFolderEnterExit-${monthStr}.ymgr&convertType=json`);
                  const json = await res.json();
                  if (json.data) {
                      json.data.forEach(row => {
                          const extName = cleanExt(row["שלוחה"]);
                          const phone = row["טלפון"] || "חסוי";
                          const sec = parseInt(row["סה\"כ שניות"]) || 0;
                          const date = row["תאריך"] || "";
                          const time = row["התחלה שעה"] || "";
                          
                          if (!dataStore.exts[extName]) dataStore.exts[extName] = { count: 0, sec: 0 };
                          dataStore.exts[extName].count++;
                          dataStore.exts[extName].sec += sec;
                          
                          dataStore.totalSec += sec;
                          if (!dataStore.users[phone]) dataStore.users[phone] = { sec: 0, calls: 0 };
                          dataStore.users[phone].sec += sec;
       
                          dataStore.rawActivity.push({ 
                              phone, 
                              type: 'שלוחה', 
                              name: extName, 
                              sec: sec + " ש'", 
                              date: date + " " + time
                          });
                      });
                  }
              } catch(e) { addLog("שגיאה בגישה לקובץ LogFolderEnterExit", "red"); }
       
              let dates = [];
              for(let d=new Date(start); d<=new Date(end); d.setDate(d.getDate()+1)) dates.push(new Date(d).toISOString().split('T')[0]);
       
              for (let day of dates) {
                  updateProgress(dates.indexOf(day)+1, dates.length);
                  try {
                      const res = await fetch(`${API}RenderYMGRFile?token=${token}&wath=ivr2:/Log/LogPlaybackPlayStop/LogPlaybackPlayStop.${day}.ymgr&convertType=json`);
                      const json = await res.json();
                      if (json.data) {
                          if (!dataStore.daily[day]) dataStore.daily[day] = 0;
                          json.data.forEach(row => {
                              const file = row["השמעה"] || "לא ידוע";
                              const phone = row["טלפון"] || "חסוי";
                              const sec = parseInt(row["סה\"כ שניות"]) || 0;
                              const len = parseSec(row["אורך הקובץ"]);
                              const isEnd = row["נקודת יציאה"] === "סוף";
                              
                              dataStore.daily[day]++;
                              dataStore.totalSec += sec;
                              if (isEnd) dataStore.completed++;
       
                              if (!dataStore.users[phone]) dataStore.users[phone] = { sec: 0, calls: 0 };
                              dataStore.users[phone].sec += sec;
                              dataStore.users[phone].calls++;
       
                              if (!dataStore.plays[file]) dataStore.plays[file] = { count: 0, sec: 0, drops: 0, pcts: [] };
                              dataStore.plays[file].count++;
                              dataStore.plays[file].sec += sec;
                              dataStore.plays[file].pcts.push(len > 0 ? Math.min(100, Math.round((sec/len)*100)) : 0);
                              if (!isEnd) dataStore.plays[file].drops++;
       
                              dataStore.rawActivity.push({ 
                                  phone, 
                                  type: 'השמעה', 
                                  name: file, 
                                  sec: sec + " ש'", 
                                  date: day + " " + (row["שעה"] || "") 
                              });
                          });
                      }
                  } catch(e) {}
              }
              renderUI();
          }
       
          function renderUI() {
              document.getElementById('progBar').style.display = 'none';
              document.getElementById('stat-users').innerText = Object.keys(dataStore.users).length.toLocaleString();
              document.getElementById('stat-min').innerText = Math.floor(dataStore.totalSec / 60).toLocaleString();
              document.getElementById('stat-comp').innerText = dataStore.completed.toLocaleString();
              renderExts(); renderPlays(); renderUsers(); updateChart();
              addLog("הנתונים מעודכנים.");
          }
       
          function renderExts() {
              const sort = document.getElementById('extSort').value;
              const q = document.getElementById('extSearch').value.toLowerCase();
              let items = Object.entries(dataStore.exts).map(([name, d]) => ({name, ...d})).filter(i => i.name.toLowerCase().includes(q));
              items.sort((a,b) => b[sort] - a[sort]);
              document.querySelector('#extTable tbody').innerHTML = items.map(i => `
                  <tr><td style="color:var(--primary); font-weight:600">${i.name}</td><td>${i.count}</td><td>${(i.sec/60).toFixed(1)}</td><td>${i.count ? Math.round(i.sec/i.count) : 0} ש'</td></tr>
              `).join('');
          }
       
          function renderPlays() {
              const sort = document.getElementById('playSort').value;
              const q = document.getElementById('playSearch').value.toLowerCase();
              let items = Object.entries(dataStore.plays).map(([name, d]) => {
                  const avg = d.pcts.length ? Math.round(d.pcts.reduce((a,b)=>a+b,0)/d.pcts.length) : 0;
                  const drop = Math.round((d.drops/d.count)*100);
                  return {name, avg, drop, ...d};
              }).filter(i => i.name.toLowerCase().includes(q));
              items.sort((a,b) => sort === 'count' ? b.count - a.count : b.avg - a.avg);
              document.querySelector('#playTable tbody').innerHTML = items.map(i => `
                  <tr><td>${i.name}</td><td>${i.count}</td><td>${(i.sec/60).toFixed(1)}</td>
                  <td><div class="bar-container"><div class="bar-fill" style="width:${i.avg}%"></div></div> ${i.avg}%</td>
                  <td style="color:${i.drop > 50 ? 'var(--danger)' : 'var(--accent)'}">${i.drop}%</td></tr>
              `).join('');
          }
       
          function renderUsers() {
              const sortKey = document.getElementById('userSort').value;
              const q = document.getElementById('userSearch').value;
              let items = Object.entries(dataStore.users).map(([phone, d]) => ({phone, ...d})).filter(i => i.phone.includes(q));
              items.sort((a,b) => b[sortKey] - a[sortKey]);
              document.querySelector('#usersTable tbody').innerHTML = items.map((i, idx) => `
                  <tr class="clickable" onclick="openUserDetail('${i.phone}')">
                      <td style="font-weight:bold">${i.phone}</td>
                      <td style="color:var(--primary); font-weight:bold">${(i.sec/60).toFixed(1)}</td>
                      <td>${i.calls}</td>
                      <td>${idx < 3 ? '🏆 מוביל' : 'מאזין'}</td>
                  </tr>
              `).join('');
          }
       
          function openUserDetail(phone) {
              currentModalPhone = phone;
              document.getElementById('modalTitle').innerText = `פירוט מאזין: ${phone}`;
              document.getElementById('modalFilter').value = 'all';
              filterModalContent();
              document.getElementById('userModal').style.display = 'flex';
          }
       
          function filterModalContent() {
              const filter = document.getElementById('modalFilter').value;
              const activity = dataStore.rawActivity.filter(a => a.phone === currentModalPhone);
              const filtered = filter === 'all' ? activity : activity.filter(a => a.type === filter);
       
              document.querySelector('#modalTable tbody').innerHTML = filtered.map(a => `
                  <tr>
                      <td style="color:${a.type==='השמעה'?'var(--primary)':'var(--accent)'}; font-weight:bold">${a.type}</td>
                      <td>${a.name}</td>
                      <td>${a.sec}</td>
                      <td>${a.date}</td>
                  </tr>
              `).join('');
          }
       
          function closeModal() { document.getElementById('userModal').style.display = 'none'; }
          function updateProgress(c, t) { document.getElementById('progress-fill').style.width = (c/t*100) + '%'; }
          function switchTab(e, id) {
              document.querySelectorAll('.tab-content').forEach(c => c.classList.add('hidden'));
              document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
              document.getElementById(id).classList.remove('hidden');
              e.currentTarget.classList.add('active');
          }
          function updateChart() {
              if (dailyChart) dailyChart.destroy();
              const ctx = document.getElementById('dailyChart').getContext('2d');
              dailyChart = new Chart(ctx, {
                  type: 'line',
                  data: { labels: Object.keys(dataStore.daily), datasets: [{ label: 'שיחות', data: Object.values(dataStore.daily), borderColor: '#38bdf8', tension: 0.4, fill: true, backgroundColor: 'rgba(56, 189, 248, 0.1)' }] },
                  options: { plugins: { legend: { display: false } } }
              });
          }
          document.getElementById('startDate').value = document.getElementById('endDate').value = new Date().toISOString().split('T')[0];
      </script>
      </body>
      </html>
      

      ובשרשור הזה תשנה את הכותרת ל"תגובות על..."

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: קבצים ותוכנות לשימוש במערכות ימות המשיח

      @אA את הקודים עצמם תשים בספוילר למניאת גלילה ארוכה ומיותרת, ואם יש שני גרסאות שימושיות של תוכנה כל שהיא אפשר להביא את שניהם ולציין זאת.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס
    • RE: קבצים ותוכנות לשימוש במערכות ימות המשיח

      @אA אולי כדאי שתפתח פוסט חדש במדריכים עם כל הקבצים, זה קצת איבד כאן את הרצף...
      תודה רבה על כל הפעילות.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ב
      בוס