• דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    • הרשמה
    • התחברות
    1. דף הבית
    2. יב
    3. פוסטים
    י
    מנותק
    • פרופיל
    • עוקב אחרי 7
    • עוקבים 0
    • נושאים 50
    • פוסטים 452
    • קבוצות 0

    פוסטים

    פוסטים אחרונים הגבוה ביותר שנוי במחלוקת
    • RE: הפניה לפי מחוייג בשלוחה פנימית מפנה לפי הקובץ בשלוחה הראשית

      @אבו אם הבנתי נכון, ככה זה אמור לפעול.
      בשלוחה ראשית יש לך 3 אופציות, רשימה לבנה, רשימה שחורה, והפנייה לפי מספר מחייג ו/או מחויג.
      אבל לפי סדר הפעולות, הוא מתייחס רק לרשימה לבנה.
      מי שמורשה עובר הלאה - מי שלא מורשה עובר לשלוחה 00.
      כלומר, רשימה שחורה והפנייה לפי מספר מחייג ו/או מחויג מיותר ולא מתייחס אליו, כי ברגע שהוא תקין/חסום לפי רשימה לבנה, אז הוא כבר לא נמצא בשלוחה.
      אז מה קורה בפועל?
      גם כל אלו של רשימה שחורה והפנייה לפי מספר מחייג ו/או מחויג מגיעים לשלוחה 00.

      ועל זה אני אשאל - יש לך מישהו שמגיע לשלוחה חסום?
      אם כן, מהיכן הוא מגיע?

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

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

      ראה כאן סדר הפעולות

      פורסם בבאגים במערכת
      י
      יב
    • RE: איך להגדיר שמאזין מסויים לא יצטרך סיסמה?

      @אA איך כתבת?

      פורסם בשאלות ועזרה הדדית
      י
      יב
    • RE: איך להגדיר שמאזין מסויים לא יצטרך סיסמה?

      @אA לכאו' לפי מחוייג זה אמור לעבוד ככה;

      1. בודק את מספר המחוייג - ובקובץ מוגדר להעביר אותו לשלוחה אחרת.
      2. במידה ואין מוגדר, הוא נשאר בשלוחה, ששם יש את הסיסמה/פילטר

      על פניו זה מהלך אחר מהרעיון הנ"ל.

      פורסם בשאלות ועזרה הדדית
      י
      יב
    • RE: איך להגדיר שמאזין מסויים לא יצטרך סיסמה?

      @אA מעניין.
      אבל מה ההגדרות? כי לכאורה לא אמור להיות בעיה.

      פורסם בשאלות ועזרה הדדית
      י
      יב
    • RE: איך להגדיר שמאזין מסויים לא יצטרך סיסמה?

      @יעקב-יצחק תקח את הרעיון מכאן

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

      @איל-משולש אולי עשית לינק קשיח לשלוחה 2?

      פורסם בבאגים במערכת
      י
      יב
    • RE: שיום רשימת צנתוקים

      @מנסה מה לא טוב עם הקובץ PhonesName ?

      פורסם בבקשות לפיתוח
      י
      יב
    • תגובה | דוח ניתוח האזנה

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

      1. שמות השלוחות.
      2. חיפוש חופשי (לא יודע אם זה נוגע לכולם, אבל לי אישית זה הועיל).
      3. קבצים/מאזינים מובילים.
      4. במידה ומישהו שמע כמה פעמים קובץ, יש אפשרות לראות את מספר הפעמים.
      5. חלוקה של הדוח לדפים (ברירת מחדל 20 שורות בדף, ניתן לשינוי)

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>מערכת ניתוח נתוני האזנה - Pro Dashboard</title>
          <!-- Tailwind CSS -->
          <script src="https://cdn.tailwindcss.com"></script>
          <!-- XLSX Library -->
          <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
          <!-- Lucide Icons -->
          <script src="https://unpkg.com/lucide@latest"></script>
          <style>
              @import url('https://fonts.googleapis.com/css2?family=Assistant:wght@300;400;600;700&display=swap');
              
              body {
                  font-family: 'Assistant', sans-serif;
                  background-color: #f8fafc;
                  color: #1e293b;
              }
      
              .glass-card {
                  background: rgba(255, 255, 255, 0.95);
                  backdrop-filter: blur(10px);
                  border: 1px solid rgba(255, 255, 255, 0.2);
                  box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
              }
      
              .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; }
              .custom-scrollbar::-webkit-scrollbar-track { background: #f1f5f9; }
              .custom-scrollbar::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
              .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
      
              .animate-fade-in { animation: fadeIn 0.5s ease-out forwards; }
              @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
      
              .progress-fill { transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1); }
              .bg-green-gradient { background: linear-gradient(90deg, #10b981, #34d399); }
              .bg-orange-gradient { background: linear-gradient(90deg, #f59e0b, #fbbf24); }
              .bg-red-gradient { background: linear-gradient(90deg, #ef4444, #f87171); }
      
              .filter-row input, .filter-row select {
                  background: #ffffff;
                  border: 1px solid #e2e8f0;
                  font-size: 11px;
                  padding: 4px 6px;
                  border-radius: 4px;
                  width: 100%;
                  outline: none;
                  transition: all 0.2s;
              }
              .filter-row input:focus { border-color: #6366f1; box-shadow: 0 0 0 1px #6366f1; }
      
              .page-btn {
                  padding-left: 0.75rem;
                  padding-right: 0.75rem;
                  padding-top: 0.25rem;
                  padding-bottom: 0.25rem;
                  border-radius: 0.5rem;
                  border-width: 1px;
                  border-color: #e2e8f0;
                  font-size: 0.875rem;
                  line-height: 1.25rem;
                  font-weight: 500;
                  transition-property: all;
                  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
                  transition-duration: 150ms;
              }
              .page-btn:hover { background-color: #f8fafc; }
              .page-btn:disabled { opacity: 0.5; }
              .page-btn.active {
                  background-color: #4f46e5;
                  color: #ffffff;
                  border-color: #4f46e5;
              }
      
              .detail-row { background-color: #f8fafc; }
          </style>
      </head>
      <body class="min-h-screen pb-12">
      
          <!-- Header -->
          <nav class="sticky top-0 z-50 bg-white/80 backdrop-blur-md border-b border-slate-200">
              <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                  <div class="flex justify-between h-16 items-center">
                      <div class="flex items-center gap-3">
                          <div class="bg-indigo-600 p-2 rounded-lg shadow-lg shadow-indigo-200">
                              <i data-lucide="bar-chart-3" class="text-white w-6 h-6"></i>
                          </div>
                          <h1 class="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-indigo-600 to-violet-600">
                              מנתח נתוני האזנה Pro
                          </h1>
                      </div>
                      <div id="statusIndicator" class="text-sm font-medium text-slate-500 flex items-center gap-2">
                          <span class="w-2 h-2 rounded-full bg-slate-300"></span>
                          ממתין לפעולה
                      </div>
                  </div>
              </div>
          </nav>
      
          <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-8 space-y-8">
              
              <!-- Info & Setup Section -->
              <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
                  
                  <!-- Setup Panel -->
                  <div class="lg:col-span-2 glass-card rounded-2xl p-6 animate-fade-in">
                      <div class="flex items-center gap-2 mb-6">
                          <i data-lucide="settings" class="text-indigo-600 w-5 h-5"></i>
                          <h2 class="text-lg font-semibold">הגדרות שליפה</h2>
                      </div>
                      
                      <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                          <div class="space-y-2">
                              <label class="text-sm font-medium text-slate-700">מתאריך</label>
                              <input type="date" id="from-date" class="w-full px-4 py-2 rounded-xl border border-slate-200 focus:ring-2 focus:ring-indigo-500 outline-none">
                          </div>
                          <div class="space-y-2">
                              <label class="text-sm font-medium text-slate-700">עד תאריך</label>
                              <input type="date" id="to-date" class="w-full px-4 py-2 rounded-xl border border-slate-200 focus:ring-2 focus:ring-indigo-500 outline-none">
                          </div>
                          <div class="md:col-span-2 space-y-2">
                              <label class="text-sm font-medium text-slate-700">טוקן API</label>
                              <div class="flex gap-2">
                                  <div class="relative flex-1">
                                      <input type="password" id="api-token" placeholder="הזן טוקן..." class="w-full px-4 py-2 pr-10 rounded-xl border border-slate-200 focus:ring-2 focus:ring-indigo-500 outline-none">
                                      <i data-lucide="key" class="absolute left-3 top-2.5 text-slate-400 w-4 h-4"></i>
                                  </div>
                                  <button onclick="clearToken()" class="px-3 py-2 text-rose-500 hover:bg-rose-50 rounded-xl transition-colors" title="נקה טוקן">
                                      <i data-lucide="trash-2" class="w-5 h-5"></i>
                                  </button>
                              </div>
                          </div>
                      </div>
      
                      <div class="mt-8 flex flex-wrap gap-4">
                          <button onclick="fetchData()" id="fetch-btn" class="flex items-center gap-2 bg-indigo-600 hover:bg-indigo-700 text-white px-8 py-3 rounded-xl font-semibold transition-all shadow-lg shadow-indigo-200 active:scale-95">
                              <i data-lucide="download" class="w-5 h-5"></i>
                              משוך נתונים
                          </button>
                          <button onclick="exportToExcel()" id="export-btn" class="flex items-center gap-2 bg-emerald-600 hover:bg-emerald-700 text-white px-6 py-3 rounded-xl font-semibold transition-all shadow-lg shadow-emerald-200 active:scale-95 hidden">
                              <i data-lucide="file-spreadsheet" class="w-5 h-5"></i>
                              ייצא לאקסל
                          </button>
                      </div>
                  </div>
      
                  <!-- Important Info Box -->
                  <div class="glass-card rounded-2xl p-6 bg-indigo-50/50 border-indigo-100 animate-fade-in" style="animation-delay: 0.1s">
                      <div class="flex items-center gap-2 mb-4">
                          <i data-lucide="info" class="text-indigo-600 w-5 h-5"></i>
                          <h2 class="text-lg font-semibold text-indigo-900">מידע חשוב</h2>
                      </div>
                      <div class="text-xs text-indigo-800 space-y-4 leading-relaxed">
                          <div class="bg-white/80 p-3 rounded-lg border border-indigo-100 shadow-sm">
                              <p class="font-bold mb-1 text-indigo-900">דרישות מערכת:</p>
                              <p>המערכת מיועדת למערכות בהן מוגדר שמירת דוח יומי. יש לוודא שבקובץ <code class="bg-indigo-100 px-1 rounded">ivr.ini</code> מופיעה ההגדרה:</p>
                              <code class="block mt-1 font-mono text-indigo-600 bg-indigo-100/50 p-1 rounded text-center font-bold">log_playback_play_stop=yes</code>
                          </div>
                          <div class="space-y-2 opacity-90">
                              <p class="flex items-start gap-2">
                                  <span class="mt-1 w-1.5 h-1.5 rounded-full bg-indigo-400 shrink-0"></span>
                                  <span>המערכת משקללת רצף האזנה אמיתי ומסננת כפילויות האזנה או דילוגים.</span>
                              </p>
                              <p class="flex items-start gap-2">
                                  <span class="mt-1 w-1.5 h-1.5 rounded-full bg-indigo-400 shrink-0"></span>
                                  <span>התוצאה משקפת זמן האזנה בפועל לתוכן הקובץ.</span>
                              </p>
                              <p class="flex items-start gap-2">
                                  <span class="mt-1 w-1.5 h-1.5 rounded-full bg-indigo-400 shrink-0"></span>
                                  <span>לא מומלץ להפיק דוחות בין 4 ל-5 לפנות בוקר (זמן עדכון שרתים).</span>
                              </p>
                          </div>
                      </div>
                  </div>
              </div>
      
              <!-- Stats Grid -->
              <div id="statsContainer" class="grid grid-cols-1 md:grid-cols-4 gap-6 hidden animate-fade-in">
                  <div class="glass-card rounded-2xl p-5 border-r-4 border-indigo-500">
                      <p class="text-sm text-slate-500 font-medium">סה"כ רשומות</p>
                      <h3 id="statTotal" class="text-2xl font-bold mt-1">0</h3>
                  </div>
                  <div class="glass-card rounded-2xl p-5 border-r-4 border-emerald-500">
                      <p class="text-sm text-slate-500 font-medium">ממוצע האזנה</p>
                      <h3 id="statAvg" class="text-2xl font-bold mt-1">0%</h3>
                  </div>
                  <div class="glass-card rounded-2xl p-5 border-r-4 border-amber-500">
                      <p class="text-sm text-slate-500 font-medium">האזנה נטו (שעות)</p>
                      <h3 id="statNetHours" class="text-2xl font-bold mt-1">0</h3>
                  </div>
                  <div class="glass-card rounded-2xl p-5 border-r-4 border-rose-500">
                      <p class="text-sm text-slate-500 font-medium">האזנה ברוטו (שעות)</p>
                      <h3 id="statGrossHours" class="text-2xl font-bold mt-1">0</h3>
                  </div>
              </div>
      
              <!-- Top Files & Top Listeners -->
              <div id="insightsContainer" class="grid grid-cols-1 lg:grid-cols-2 gap-8 hidden animate-fade-in">
                  <!-- Top Files -->
                  <div class="glass-card rounded-2xl p-6">
                      <div class="flex items-center gap-2 mb-6">
                          <i data-lucide="trending-up" class="text-indigo-600 w-5 h-5"></i>
                          <h2 class="text-lg font-semibold">קבצים מובילים בהאזנה</h2>
                      </div>
                      <div id="topFilesList" class="space-y-4">
                          <!-- Top files will be injected here -->
                      </div>
                  </div>
                  <!-- Top Listeners -->
                  <div class="glass-card rounded-2xl p-6">
                      <div class="flex items-center gap-2 mb-6">
                          <i data-lucide="award" class="text-amber-500 w-5 h-5"></i>
                          <h2 class="text-lg font-semibold text-slate-800">מאזינים מובילים (נטו)</h2>
                      </div>
                      <div id="topListenersList" class="space-y-4">
                          <!-- Top listeners will be injected here -->
                      </div>
                  </div>
              </div>
      
              <!-- Main Table Area -->
              <div class="glass-card rounded-2xl overflow-hidden animate-fade-in" style="animation-delay: 0.2s">
                  <div class="p-6 border-b border-slate-100 bg-slate-50/50 flex flex-wrap gap-4 items-end justify-between">
                      <div class="flex flex-wrap gap-4 items-end">
                          <div class="w-64 space-y-2">
                              <label class="text-xs font-bold text-slate-500 uppercase tracking-wider">חיפוש חופשי</label>
                              <div class="relative">
                                  <input type="text" id="searchInput" oninput="applyMultiFilter()" placeholder="שם, טלפון, קובץ..." class="w-full px-4 py-2 pr-10 rounded-xl border border-slate-200 outline-none focus:ring-2 focus:ring-indigo-500">
                                  <i data-lucide="search" class="absolute left-3 top-2.5 text-slate-400 w-4 h-4"></i>
                              </div>
                          </div>
                          <div class="w-32 space-y-2">
                              <label class="text-xs font-bold text-slate-500 uppercase tracking-wider">אחוז מינימלי</label>
                              <input type="number" id="filter-percent" oninput="applyMultiFilter()" class="w-full px-4 py-2 rounded-xl border border-slate-200 outline-none focus:ring-2 focus:ring-indigo-500" placeholder="0">
                          </div>
                      </div>
                      <div id="statFiltered" class="text-xs font-bold text-indigo-600 bg-indigo-50 px-3 py-1 rounded-full">0 רשומות מוצגות</div>
                  </div>
      
                  <div class="custom-scrollbar overflow-x-auto">
                      <table id="results-table" class="w-full text-right border-collapse hidden">
                          <thead>
                              <tr id="header-row" class="bg-slate-50 text-slate-500 text-[11px] font-bold uppercase tracking-wider">
                                  <!-- Dynamic Headers -->
                              </tr>
                              <tr id="filter-row" class="filter-row bg-white border-b border-slate-100">
                                  <!-- Dynamic Filters -->
                              </tr>
                          </thead>
                          <tbody id="table-body" class="divide-y divide-slate-100 text-sm">
                              <!-- Results -->
                          </tbody>
                      </table>
                      <div id="emptyState" class="p-20 text-center text-slate-400">
                          <div class="flex flex-col items-center gap-4">
                              <i data-lucide="database" class="w-12 h-12 opacity-20"></i>
                              <p class="text-lg">טרם נטענו נתונים</p>
                          </div>
                      </div>
                  </div>
      
                  <!-- Pagination -->
                  <div id="pagination-container" class="px-6 py-4 bg-slate-50 border-t border-slate-200 flex flex-wrap items-center justify-between gap-4 hidden">
                      <div class="flex items-center gap-4">
                          <span class="text-sm text-slate-500">הצג</span>
                          <select id="rows-per-page" onchange="updateRowsPerPage()" class="px-2 py-1 rounded border border-slate-200 text-sm outline-none">
                              <option value="10">10</option>
                              <option value="20" selected>20</option>
                              <option value="50">50</option>
                              <option value="100">100</option>
                          </select>
                      </div>
                      <div class="flex items-center gap-2" id="page-numbers"></div>
                      <div class="text-sm text-slate-500" id="pagination-info"></div>
                  </div>
              </div>
          </main>
      
          <!-- Loading Overlay -->
          <div id="loadingOverlay" class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm z-[100] flex items-center justify-center hidden">
              <div class="bg-white rounded-2xl p-8 flex flex-col items-center gap-4 shadow-2xl max-w-sm w-full mx-4">
                  <div class="w-16 h-16 border-4 border-indigo-100 border-t-indigo-600 rounded-full animate-spin"></div>
                  <div class="text-center">
                      <h3 class="text-lg font-bold text-slate-800">מעבד נתונים...</h3>
                      <p id="loadingStatus" class="text-sm text-slate-500 mt-1">מתחבר לשרת</p>
                  </div>
                  <div class="w-full bg-slate-100 rounded-full h-2 mt-2 overflow-hidden">
                      <div id="loadingProgress" class="bg-indigo-600 h-full transition-all duration-300" style="width: 0%"></div>
                  </div>
              </div>
          </div>
      
          <script>
              // --- Initialization ---
              lucide.createIcons();
              
              // Helper: Remove Hebrew Nikud (diacritics)
              function removeNikud(str) {
                  if (!str) return "";
                  return str.replace(/[\u0591-\u05C7]/g, "");
              }
      
              // Default dates: From 7 days ago to today
              const todayDate = new Date();
              const lastWeekDate = new Date();
              lastWeekDate.setDate(todayDate.getDate() - 7);
              
              document.getElementById('from-date').value = lastWeekDate.toISOString().split('T')[0];
              document.getElementById('to-date').value = todayDate.toISOString().split('T')[0];
      
              const savedToken = localStorage.getItem('api_token_cached');
              if (savedToken) document.getElementById('api-token').value = savedToken;
      
              let currentData = [];
              let filteredData = [];
              let sortDirections = Array(12).fill(true);
              let hasEnterId = true;
              let currentPage = 1;
              let rowsPerPage = 20;
              let expandedRows = new Set();
              const extensionTitlesCache = {};
      
              // --- Core Logic ---
      
              function clearToken() {
                  if (confirm("האם למחוק את הטוקן השמור?")) {
                      localStorage.removeItem('api_token_cached');
                      document.getElementById('api-token').value = '';
                  }
              }
      
              async function fetchData() {
                  const fromDate = document.getElementById('from-date').value;
                  const toDate = document.getElementById('to-date').value;
                  const token = document.getElementById('api-token').value;
                  
                  if (!fromDate || !toDate || !token) { alert("נא להזין את כל הפרטים"); return; }
                  localStorage.setItem('api_token_cached', token);
      
                  const overlay = document.getElementById('loadingOverlay');
                  const statusText = document.getElementById('loadingStatus');
                  const progressBar = document.getElementById('loadingProgress');
                  overlay.classList.remove('hidden');
      
                  const dates = getDatesRange(new Date(fromDate), new Date(toDate));
                  const dataMap = {};
                  hasEnterId = true;
      
                  try {
                      for (let i = 0; i < dates.length; i++) {
                          const date = dates[i];
                          statusText.innerText = `מושך נתונים: ${date}`;
                          progressBar.style.width = `${Math.round(((i + 1) / dates.length) * 100)}%`;
      
                          const url = `https://www.call2all.co.il/ym/api/RenderYMGRFile?token=${token}&wath=ivr2:/Log/LogPlaybackPlayStop/LogPlaybackPlayStop.${date}.ymgr&convertType=csv&notLoadLang=1`;
                          const response = await fetch(url);
                          if (response.ok) {
                              const csv = await response.text();
                              processCsvSegment(csv, dataMap, date);
                          }
                      }
      
                      // Fetch Extension Titles
                      const uniquePaths = [...new Set(Object.values(dataMap).map(item => item.info.Folder))];
                      await fetchExtensionTitles(uniquePaths, token);
      
                      finalizeData(dataMap);
                  } catch (err) {
                      alert(`שגיאה: ${err.message}`);
                  } finally {
                      overlay.classList.add('hidden');
                  }
              }
      
              async function fetchExtensionTitles(paths, token) {
                  const statusText = document.getElementById('loadingStatus');
                  const parents = new Set();
                  
                  paths.forEach(p => {
                      if (!p) return;
                      const parts = p.split('/').filter(x => x);
                      if (parts.length === 0) return;
                      
                      if (parts.length === 1) {
                          parents.add("/");
                      } else {
                          parts.pop();
                          parents.add(parts.join('/'));
                      }
                  });
      
                  const parentPaths = Array.from(parents);
                  for (let i = 0; i < parentPaths.length; i++) {
                      const pPath = parentPaths[i];
                      statusText.innerText = `מעדכן שמות שלוחות: ${pPath}`;
                      try {
                          const url = `https://www.call2all.co.il/ym/api/GetIVR2Dir?token=${token}&path=${pPath}`;
                          const response = await fetch(url);
                          if (response.ok) {
                              const res = await response.json();
                              if (res.dirs && Array.isArray(res.dirs)) {
                                  res.dirs.forEach(d => {
                                      const fullPath = (pPath === "/" || pPath === "") ? d.name : `${pPath}/${d.name}`;
                                      if (d.extTitle) {
                                          extensionTitlesCache[fullPath] = d.extTitle;
                                      }
                                  });
                              }
                          }
                      } catch (e) {
                          console.error(`Error fetching titles for ${pPath}:`, e);
                      }
                  }
              }
      
              function processCsvSegment(text, dataMap, date) {
                  const rows = text.replace(/^\uFEFF/, "").trim().split(/\r?\n/).map(r => r.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/));
                  if (rows.length < 2) return;
                  const headers = rows[0].map(h => h.replace(/"/g, '').trim());
      
                  if (!headers.includes("EnterId")) hasEnterId = false;
      
                  for (let i = 1; i < rows.length; i++) {
                      let row = {};
                      headers.forEach((h, idx) => row[h] = (rows[i][idx] || "").replace(/"/g, '').trim());
                      if (!row["FileLength"] || row["FileLength"] === "0:0:0") continue;
      
                      // Normalize folder path
                      row["Folder"] = (row["Folder"] || "").replace(/^\/+|\/+$/g, '');
      
                      const flenSec = timeToSeconds(row["FileLength"]);
                      const identityKey = hasEnterId ? row["EnterId"] : row["Phone"];
                      const key = `${identityKey}_${row["Folder"]}_${row["Current"]}_${row["FileLength"]}`;
                      
                      if (!dataMap[key]) {
                          dataMap[key] = { info: row, intervals: [], flenSec: flenSec, rawSessions: [] };
                      }
      
                      let start = (parseInt(row["PositionPlay"]) || 0) / 1000;
                      let stop = (isNaN(parseInt(row["PositionStop"])) || parseInt(row["PositionStop"]) === -1) ? flenSec : parseInt(row["PositionStop"]) / 1000;
                      
                      dataMap[key].intervals.push([start, stop]);
                      dataMap[key].rawSessions.push({
                          date: date,
                          start: start,
                          stop: stop,
                          duration: stop - start,
                          time: row["Time"] || ""
                      });
                  }
              }
      
              function finalizeData(dataMap) {
                  currentData = Object.values(dataMap).map(item => {
                      const netSec = mergeIntervals(item.intervals);
                      const grossSec = item.rawSessions.reduce((acc, s) => acc + s.duration, 0);
                      
                      // Find last session
                      const last = item.rawSessions.reduce((prev, current) => {
                          const prevDt = `${prev.date} ${prev.time}`;
                          const currDt = `${current.date} ${current.time}`;
                          return currDt > prevDt ? current : prev;
                      });
      
                      return {
                          ...item,
                          netSec: netSec,
                          grossSec: grossSec,
                          lastDate: last.date,
                          lastTime: last.time,
                          percent: item.flenSec > 0 ? Math.min(100, Math.round((netSec / item.flenSec) * 100)) : 0
                      };
                  });
                  
                  if (currentData.length > 0) {
                      setupTableStructure();
                      updateStats();
                      updateInsights();
                      applyMultiFilter();
                      
                      document.getElementById('results-table').classList.remove('hidden');
                      document.getElementById('emptyState').classList.add('hidden');
                      document.getElementById('statsContainer').classList.remove('hidden');
                      document.getElementById('insightsContainer').classList.remove('hidden');
                      document.getElementById('export-btn').classList.remove('hidden');
                      document.getElementById('pagination-container').classList.remove('hidden');
                      document.getElementById('statusIndicator').innerHTML = `<span class="w-2 h-2 rounded-full bg-emerald-500"></span> נתונים נטענו`;
                  } else {
                      alert("לא נמצאו נתונים לטווח זה");
                  }
              }
      
              function updateInsights() {
                  // Top Files
                  const fileStats = {};
                  currentData.forEach(d => {
                      const key = `${d.info.Folder} > ${d.info.Current}`;
                      if (!fileStats[key]) fileStats[key] = { name: d.info.Current, folder: d.info.Folder, totalNet: 0, count: 0 };
                      fileStats[key].totalNet += d.netSec;
                      fileStats[key].count++;
                  });
                  const topFiles = Object.values(fileStats).sort((a, b) => b.totalNet - a.totalNet).slice(0, 5);
                  const maxFileNet = topFiles[0]?.totalNet || 1;
                  document.getElementById('topFilesList').innerHTML = topFiles.map(f => {
                      const folderTitle = extensionTitlesCache[f.folder] ? ` (${extensionTitlesCache[f.folder]})` : '';
                      return `
                      <div class="space-y-1">
                          <div class="flex justify-between text-sm">
                              <span class="font-bold text-slate-700 truncate ml-4">${f.name}</span>
                              <span class="text-slate-400 font-mono text-xs">${formatSeconds(f.totalNet)}</span>
                          </div>
                          <div class="w-full bg-slate-100 h-2 rounded-full overflow-hidden">
                              <div class="bg-indigo-500 h-full" style="width: ${(f.totalNet / maxFileNet) * 100}%"></div>
                          </div>
                          <div class="text-[10px] text-slate-400">${f.folder}${folderTitle} | ${f.count} מאזינים</div>
                      </div>
                  `}).join('');
      
                  // Top Listeners
                  const listenerStats = {};
                  currentData.forEach(d => {
                      const id = hasEnterId ? d.info.EnterId : d.info.Phone;
                      const name = hasEnterId ? d.info.ValName : d.info.Phone;
                      if (!listenerStats[id]) listenerStats[id] = { name: name, id: id, totalNet: 0 };
                      listenerStats[id].totalNet += d.netSec;
                  });
                  const topListeners = Object.values(listenerStats).sort((a, b) => b.totalNet - a.totalNet).slice(0, 5);
                  const maxListenerNet = topListeners[0]?.totalNet || 1;
                  document.getElementById('topListenersList').innerHTML = topListeners.map(l => `
                      <div class="space-y-1">
                          <div class="flex justify-between text-sm">
                              <div class="flex flex-col">
                                  <span class="font-bold text-slate-700">${l.name}</span>
                                  <span class="text-[10px] text-slate-400 font-mono">${l.id}</span>
                              </div>
                              <span class="text-amber-600 font-mono text-xs font-bold">${formatSeconds(l.totalNet)}</span>
                          </div>
                          <div class="w-full bg-slate-50 h-2 rounded-full overflow-hidden">
                              <div class="bg-amber-400 h-full" style="width: ${(l.totalNet / maxListenerNet) * 100}%"></div>
                          </div>
                      </div>
                  `).join('');
              }
      
              function setupTableStructure() {
                  const headerRow = document.getElementById('header-row');
                  const filterRow = document.getElementById('filter-row');
                  
                  const commonHeaders = `
                      <th class="px-4 py-3 cursor-pointer" onclick="sortTable('folder')">שלוחה ↕</th>
                      <th class="px-4 py-3 cursor-pointer" onclick="sortTable('file')">קובץ ↕</th>
                      <th class="px-4 py-3 text-center cursor-pointer" onclick="sortTable('last')">האזנה אחרונה ↕</th>
                      <th class="px-4 py-3 text-center cursor-pointer" onclick="sortTable('length')">אורך ↕</th>
                      <th class="px-4 py-3 text-center cursor-pointer" onclick="sortTable('net')">נטו ↕</th>
                      <th class="px-4 py-3 text-center cursor-pointer" onclick="sortTable('gross')">ברוטו ↕</th>
                      <th class="px-4 py-3 text-center cursor-pointer" onclick="sortTable('percent')">אחוז ↕</th>
                      <th class="px-4 py-3 text-center">פעולות</th>
                  `;
                  
                  const commonFilters = `
                      <th class="px-2 py-2"><input type="text" id="f-folder" oninput="applyMultiFilter()" placeholder="סנן שלוחה..."></th>
                      <th class="px-2 py-2"><input type="text" id="f-file" oninput="applyMultiFilter()" placeholder="סנן קובץ..."></th>
                      <th></th><th></th><th></th><th></th><th></th><th></th>
                  `;
      
                  if (hasEnterId) {
                      headerRow.innerHTML = `<th class="px-4 py-3 cursor-pointer" onclick="sortTable('school')">כיתה ↕</th><th class="px-4 py-3 cursor-pointer" onclick="sortTable('name')">שם וזיהוי ↕</th>` + commonHeaders;
                      filterRow.innerHTML = `<th class="px-2 py-2"><input type="text" id="f-school" oninput="applyMultiFilter()" placeholder="סנן כיתה..."></th><th class="px-2 py-2"><input type="text" id="f-name" oninput="applyMultiFilter()" placeholder="סנן שם או זיהוי..."></th>` + commonFilters;
                  } else {
                      headerRow.innerHTML = `<th class="px-4 py-3 cursor-pointer" onclick="sortTable('name')">טלפון ↕</th>` + commonHeaders;
                      filterRow.innerHTML = `<th class="px-2 py-2"><input type="text" id="f-name" oninput="applyMultiFilter()" placeholder="סנן טלפון..."></th>` + commonFilters;
                  }
              }
      
              function renderTable() {
                  const tbody = document.getElementById('table-body');
                  const totalItems = filteredData.length;
                  const startIdx = (currentPage - 1) * rowsPerPage;
                  const pageData = filteredData.slice(startIdx, startIdx + rowsPerPage);
      
                  let html = '';
                  pageData.forEach((item, idx) => {
                      const colorClass = item.percent > 80 ? 'bg-green-gradient' : (item.percent > 40 ? 'bg-orange-gradient' : 'bg-red-gradient');
                      const textClass = item.percent > 80 ? 'text-emerald-600' : (item.percent > 40 ? 'text-amber-600' : 'text-rose-600');
                      const rowId = `row-${startIdx + idx}`;
                      const isExpanded = expandedRows.has(rowId);
                      const hasDuplicates = item.rawSessions.length > 1;
      
                      let identityCell = '';
                      if (hasEnterId) {
                          identityCell = `<td class="px-4 py-3 text-slate-500">${item.info.School || '-'}</td>
                                         <td class="px-4 py-3">
                                             <div class="font-bold text-slate-800">${item.info.ValName}</div>
                                             <div class="text-[10px] text-slate-400">${item.info.EnterId}</div>
                                         </td>`;
                      } else {
                          identityCell = `<td class="px-4 py-3 font-bold text-slate-800">${item.info.Phone}</td>`;
                      }
      
                      html += `
                          <tr class="hover:bg-slate-50 transition-colors">
                              ${identityCell}
                              <td class="px-4 py-3">
                                  <div class="flex flex-col">
                                      <span class="bg-slate-100 px-2 py-1 rounded text-[10px] font-bold text-slate-500 w-fit">${item.info.Folder}</span>
                                      ${extensionTitlesCache[item.info.Folder] ? `<span class="text-[10px] text-indigo-600 font-medium mt-1 leading-tight">${extensionTitlesCache[item.info.Folder]}</span>` : ''}
                                  </div>
                              </td>
                              <td class="px-4 py-3 text-slate-600 truncate max-w-[150px]">${item.info.Current}</td>
                              <td class="px-4 py-3 text-center">
                                  <div class="text-[11px] font-bold text-slate-700">${item.lastDate}</div>
                                  <div class="text-[10px] text-slate-400 font-mono">${item.lastTime}</div>
                              </td>
                              <td class="px-4 py-3 text-center font-mono text-slate-400">${formatSeconds(item.flenSec)}</td>
                              <td class="px-4 py-3 text-center font-mono text-indigo-600 font-bold">${formatSeconds(item.netSec)}</td>
                              <td class="px-4 py-3 text-center font-mono text-slate-400 text-xs">${formatSeconds(item.grossSec)}</td>
                              <td class="px-4 py-3">
                                  <div class="flex items-center gap-3 min-w-[100px]">
                                      <div class="flex-1 bg-slate-100 rounded-full h-1.5 overflow-hidden">
                                          <div class="progress-fill h-full ${colorClass}" style="width: ${item.percent}%"></div>
                                      </div>
                                      <span class="text-xs font-bold ${textClass}">${item.percent}%</span>
                                  </div>
                              </td>
                              <td class="px-4 py-3 text-center">
                                  <button onclick="toggleRow('${rowId}')" class="flex items-center gap-1 mx-auto px-3 py-1.5 rounded-lg text-[10px] font-bold transition-all shadow-sm ${hasDuplicates ? 'bg-indigo-600 text-white hover:bg-indigo-700' : 'bg-slate-100 text-slate-300 cursor-default'}">
                                      <i data-lucide="${isExpanded ? 'chevron-up' : 'list-plus'}" class="w-3.5 h-3.5"></i>
                                      ${isExpanded ? 'סגור' : 'פירוט האזנות'}
                                  </button>
                              </td>
                          </tr>
                      `;
      
                      if (isExpanded) {
                          html += `
                              <tr class="detail-row animate-fade-in">
                                  <td colspan="12" class="px-8 py-4">
                                      <div class="bg-white rounded-xl border border-indigo-100 shadow-sm overflow-hidden">
                                          <div class="bg-indigo-50 px-4 py-2 text-[10px] font-bold text-indigo-600 border-b border-indigo-100">פירוט האזנות כפולות / חוזרות</div>
                                          <table class="w-full text-[11px] text-right">
                                              <thead class="bg-slate-50 text-slate-400 font-bold uppercase">
                                                  <tr>
                                                      <th class="px-4 py-2">תאריך</th>
                                                      <th class="px-4 py-2">שעה</th>
                                                      <th class="px-4 py-2">התחלה בקובץ</th>
                                                      <th class="px-4 py-2">סיום בקובץ</th>
                                                      <th class="px-4 py-2">משך האזנה</th>
                                                  </tr>
                                              </thead>
                                              <tbody class="divide-y divide-slate-50">
                                                  ${item.rawSessions.map(s => `
                                                      <tr>
                                                          <td class="px-4 py-2">${s.date}</td>
                                                          <td class="px-4 py-2">${s.time}</td>
                                                          <td class="px-4 py-2 font-mono">${formatSeconds(s.start)}</td>
                                                          <td class="px-4 py-2 font-mono">${formatSeconds(s.stop)}</td>
                                                          <td class="px-4 py-2 font-bold text-indigo-600">${formatSeconds(s.duration)}</td>
                                                      </tr>
                                                  `).join('')}
                                              </tbody>
                                          </table>
                                      </div>
                                  </td>
                              </tr>
                          `;
                      }
                  });
                  
                  tbody.innerHTML = html || `<tr><td colspan="12" class="p-10 text-center text-slate-400">אין תוצאות</td></tr>`;
                  renderPaginationControls(totalItems, Math.ceil(totalItems / rowsPerPage));
                  lucide.createIcons();
              }
      
              function toggleRow(id) {
                  if (expandedRows.has(id)) expandedRows.delete(id);
                  else expandedRows.add(id);
                  renderTable();
              }
      
              function applyMultiFilter() {
                  const search = removeNikud(document.getElementById('searchInput').value.toLowerCase());
                  const minP = parseInt(document.getElementById('filter-percent').value) || 0;
                  
                  const fSchool = removeNikud(document.getElementById('f-school')?.value.toLowerCase() || "");
                  const fName = removeNikud(document.getElementById('f-name')?.value.toLowerCase() || "");
                  const fFolder = removeNikud(document.getElementById('f-folder')?.value.toLowerCase() || "");
                  const fFile = removeNikud(document.getElementById('f-file')?.value.toLowerCase() || "");
      
                  filteredData = currentData.filter(item => {
                      const tSchool = removeNikud((item.info.School || "").toLowerCase());
                      const tName = removeNikud((hasEnterId ? (item.info.ValName || "") : item.info.Phone).toLowerCase());
                      const tFolder = removeNikud(item.info.Folder.toLowerCase());
                      const tFolderTitle = removeNikud((extensionTitlesCache[item.info.Folder] || "").toLowerCase());
                      const tFile = removeNikud(item.info.Current.toLowerCase());
                      const tId = removeNikud((item.info.EnterId || "").toLowerCase());
                      
                      const matchSearch = tName.includes(search) || tFolder.includes(search) || tFile.includes(search) || tId.includes(search) || tFolderTitle.includes(search);
                      const matchPercent = item.percent >= minP;
                      
                      const matchSpecific = tSchool.includes(fSchool) && 
                                          (tName.includes(fName) || tId.includes(fName)) && 
                                          (tFolder.includes(fFolder) || tFolderTitle.includes(fFolder)) && 
                                          tFile.includes(fFile);
      
                      return matchSearch && matchPercent && matchSpecific;
                  });
      
                  document.getElementById('statFiltered').innerText = `${filteredData.length.toLocaleString()} רשומות מוצגות`;
                  currentPage = 1;
                  renderTable();
              }
      
              function updateStats() {
                  const total = currentData.length;
                  const avg = total > 0 ? Math.round(currentData.reduce((s, d) => s + d.percent, 0) / total) : 0;
                  const netSec = currentData.reduce((s, d) => s + d.netSec, 0);
                  const grossSec = currentData.reduce((s, d) => s + d.grossSec, 0);
      
                  document.getElementById('statTotal').innerText = total.toLocaleString();
                  document.getElementById('statAvg').innerText = `${avg}%`;
                  document.getElementById('statNetHours').innerText = Math.round(netSec / 3600).toLocaleString();
                  document.getElementById('statGrossHours').innerText = Math.round(grossSec / 3600).toLocaleString();
              }
      
              function renderPaginationControls(totalItems, totalPages) {
                  const container = document.getElementById('page-numbers');
                  const info = document.getElementById('pagination-info');
                  if (totalItems === 0) { container.innerHTML = ''; info.innerText = ''; return; }
      
                  info.innerText = `מציג ${((currentPage-1)*rowsPerPage)+1}-${Math.min(currentPage*rowsPerPage, totalItems)} מתוך ${totalItems}`;
                  let btns = `<button onclick="changePage(${currentPage-1})" class="page-btn" ${currentPage===1?'disabled':''}><i data-lucide="chevron-right" class="w-4 h-4"></i></button>`;
                  for (let i = 1; i <= totalPages; i++) {
                      if (i === 1 || i === totalPages || (i >= currentPage - 2 && i <= currentPage + 2)) {
                          btns += `<button onclick="changePage(${i})" class="page-btn ${i===currentPage?'active':''}">${i}</button>`;
                      } else if (i === currentPage - 3 || i === currentPage + 3) {
                          btns += `<span class="px-1 text-slate-300">...</span>`;
                      }
                  }
                  btns += `<button onclick="changePage(${currentPage+1})" class="page-btn" ${currentPage===totalPages?'disabled':''}><i data-lucide="chevron-left" class="w-4 h-4"></i></button>`;
                  container.innerHTML = btns;
              }
      
              function changePage(p) { currentPage = p; renderTable(); }
              function updateRowsPerPage() { rowsPerPage = parseInt(document.getElementById('rows-per-page').value); currentPage = 1; renderTable(); }
      
              function sortTable(key) {
                  const idx = ['school','name','folder','file','last','length','net','gross','percent'].indexOf(key);
                  sortDirections[idx] = !sortDirections[idx];
                  const dir = sortDirections[idx] ? 1 : -1;
                  
                  currentData.sort((a, b) => {
                      let v1, v2;
                      if (key === 'school') { v1 = a.info.School || ""; v2 = b.info.School || ""; }
                      else if (key === 'name') { v1 = (hasEnterId ? a.info.ValName : a.info.Phone) || ""; v2 = (hasEnterId ? b.info.ValName : b.info.Phone) || ""; }
                      else if (key === 'folder') { v1 = a.info.Folder; v2 = b.info.Folder; }
                      else if (key === 'file') { v1 = a.info.Current; v2 = b.info.Current; }
                      else if (key === 'last') { v1 = `${a.lastDate} ${a.lastTime}`; v2 = `${b.lastDate} ${b.lastTime}`; }
                      else if (key === 'length') { v1 = a.flenSec; v2 = b.flenSec; }
                      else if (key === 'net') { v1 = a.netSec; v2 = b.netSec; }
                      else if (key === 'gross') { v1 = a.grossSec; v2 = b.grossSec; }
                      else if (key === 'percent') { v1 = a.percent; v2 = b.percent; }
                      return v1 < v2 ? -1 * dir : (v1 > v2 ? 1 * dir : 0);
                  });
                  applyMultiFilter();
              }
      
              function timeToSeconds(t){
                  const p = t.trim().split(':').map(Number);
                  return p.length === 3 ? p[0]*3600 + p[1]*60 + p[2] : (p.length === 2 ? p[0]*60 + p[1] : 0);
              }
              function formatSeconds(s){
                  let h=Math.floor(s/3600), m=Math.floor((s%3600)/60), sec=Math.floor(s%60);
                  return `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${sec.toString().padStart(2,'0')}`;
              }
              function mergeIntervals(arr){
                  if(!arr.length) return 0;
                  arr.sort((a,b) => a[0]-b[0]);
                  let total = 0, [start, end] = arr[0];
                  for(let i=1; i<arr.length; i++){
                      if(arr[i][0] <= end) end = Math.max(end, arr[i][1]);
                      else { total += (end - start); [start, end] = arr[i]; }
                  }
                  return total + (end - start);
              }
              function getDatesRange(s,e){
                  const d=[]; let c=new Date(s);
                  while(c<=e){ d.push(c.toISOString().split('T')[0]); c.setDate(c.getDate()+1); }
                  return d;
              }
      
              function exportToExcel() {
                  const exportedData = filteredData.map(item => {
                      let obj = {};
                      if (hasEnterId) {
                          obj["כיתה"] = item.info.School || '-';
                          obj["שם תלמיד"] = item.info.ValName || '';
                          obj["זיהוי"] = item.info.EnterId || '';
                          obj["שלוחה"] = item.info.Folder + (extensionTitlesCache[item.info.Folder] ? ` (${extensionTitlesCache[item.info.Folder]})` : '');
                          obj["שם הקובץ"] = item.info.Current;
                          obj["תאריך האזנה אחרונה"] = item.lastDate;
                          obj["שעת האזנה אחרונה"] = item.lastTime;
                          obj["אורך קובץ"] = formatSeconds(item.flenSec);
                          obj["האזנה נטו"] = formatSeconds(item.netSec);
                          obj["האזנה ברוטו"] = formatSeconds(item.grossSec);
                          obj["אחוז האזנה"] = item.percent + '%';
                      } else {
                          obj["טלפון"] = item.info.Phone;
                          obj["שלוחה"] = item.info.Folder + (extensionTitlesCache[item.info.Folder] ? ` (${extensionTitlesCache[item.info.Folder]})` : '');
                          obj["שם הקובץ"] = item.info.Current;
                          obj["תאריך האזנה אחרונה"] = item.lastDate;
                          obj["שעת האזנה אחרונה"] = item.lastTime;
                          obj["אורך קובץ"] = formatSeconds(item.flenSec);
                          obj["האזנה נטו"] = formatSeconds(item.netSec);
                          obj["האזנה ברוטו"] = formatSeconds(item.grossSec);
                          obj["אחוז האזנה"] = item.percent + '%';
                      }
                      return obj;
                  });
                  const ws = XLSX.utils.json_to_sheet(exportedData);
                  const wb = XLSX.utils.book_new();
                  XLSX.utils.book_append_sheet(wb, ws, "דוח האזנה");
                  XLSX.writeFile(wb, `דוח_האזנה_${new Date().toISOString().slice(0,10)}.xlsx`);
              }
          </script>
      </body>
      </html>
      
      

      פורסם בפורום מפתחים API
      י
      יב
    • RE: ביטול חיוג למספר המשני

      @יאיר-32 לפי הפילטר הזה

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

      @יעקב-יצחק אולי תנסה עם זה
      קרדיט @ע.ג.

      פורסם בבאגים במערכת
      י
      יב
    • RE: מערכת מכירות לגוגל שיטס

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

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

      @מושקה אנסה להדריך אותך (זה לא קשה, אבל חשוב צעד צעד)

      דבר ראשון

      שלילת מחיקת נרשמים

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

      דבר שני

      הכרת מבנה הקובץ

      קובץ ymgr בנוי בסימנים של עמודות ושורות.
      התו שמפריד בין שם העמודה לנתון הוא #
      התו שמפריד בין העמודות הוא %
      דוגמה למופיע בקובץ מכירות

      Folder#התיקייה בו בוצעה ההרשמה%Phone#טלפון המזמין%IdType#סוג זיהוי%EnterId#הזיהוי שהוקלט%ValName#שם המזמין%Date#תאריך לועזי%Time#שעה%HebrewDate#תאריך עברי%approval_number#מספר אישור%PaymentType#סוג תשלום%BookingTotal#סך ההזמנות%AmountTotal#סה"כ פריטים%PaymentTotal#תשלום כולל%P070-Name#שם מוצר מקט 70%P070-Price#מחיר מוצר מקט 70%P070-Amount#כמות מוצר מקטט 70%P070-PriceAll#סה"כ לתשלום מקט 70
      

      מקור.

      דבר שלישי

      מחיקה בפועל

      שים לב שאתה מוחק הזמנה אתה מתחיל עם Folder# ומסיים עד Folder# (לא כולל Folder# הבא).

      מקווה שעזרתי

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

      @מושקה שמח לשמוע!!!
      לפעמים הבאות, צריך קצת ידע איך הדוחות עובדים, ואיך הם מתורגמים בJSON 😉.
      עם הזמן ניתן ללמוד את זה (כמובן, צריכים לדעת לתקשר נכון API של ימות המשיח).
      בכל אופן, שמחתי לעזור!

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

      @מושקה כתב במערכת מכירות לגוגל שיטס:

      נראה לך שתצליח לפתור את הבעיה
      כלומר נראה לך שיש לך כיון לפתור את זה

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

      בכל אופן תעדכן אותי אם זה עובד, - פשוט מתעניין

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

      @מושקה העמודות המיותרות הוסרו.
      עובד לך גם באקסס?

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

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

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

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

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

      @מושקה

      זה פתוח?

      ניתן לשנות עכשיו?

      CY

      ככה זה נקרא?

      מה זה נקרא שאני משתמש בו?

      כן!

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

      @מושקה מה שם העמודה המיותרת?

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