{"id":21334,"date":"2026-05-23T16:29:12","date_gmt":"2026-05-23T14:29:12","guid":{"rendered":"https:\/\/www.drugshortage.ch\/?page_id=21334"},"modified":"2026-08-06T20:48:44","modified_gmt":"2026-08-06T18:48:44","slug":"uebersicht-nach-firmen","status":"publish","type":"page","link":"https:\/\/www.drugshortage.ch\/index.php\/uebersicht-nach-firmen\/","title":{"rendered":"\u00dcbersicht nach Firmen"},"content":{"rendered":"\n<!-- ============================================================\n     ANLEITUNG: In WordPress als \"Benutzerdefiniertes HTML\"-Block einf\u00fcgen.\n     Seite: \"uebersicht-nach-firmen\" (Deutsch)\n     Kein HMAC im Browser \u2013 ds.php signiert serverseitig.\n     Gruppierung, Prozentwert und Link-Ziel kommen aus der API.\n     ============================================================ -->\n<style>\n  #nf-outer { width:100%; box-sizing:border-box; font-family:'Segoe UI',Arial,sans-serif; font-size:13px; color:#2d3748; }\n  .container,.container-fluid,.entry-content,.post-content,.page-content,\n  .site-content,.content-area,#content,#primary,main,article { max-width:100% !important; overflow:visible !important; }\n  #nf-loading { display:flex; align-items:center; gap:12px; padding:30px 20px; color:#718096; font-size:15px; }\n  .nf-spinner { width:24px; height:24px; border:3px solid #e2e8f0; border-top-color:#e53e3e; border-radius:50%; animation:nfspin .8s linear infinite; flex-shrink:0; }\n  @keyframes nfspin { to { transform:rotate(360deg); } }\n  .nf-section-title { font-size:15px; font-weight:700; color:#2d3748; margin:20px 0 10px 0; padding-bottom:6px; border-bottom:2px solid #e53e3e; display:flex; align-items:center; gap:8px; }\n  .nf-icon { background:#e53e3e; color:#fff; border-radius:6px; padding:2px 8px; font-size:11px; font-weight:600; }\n  .nf-legende-box { display:flex; flex-direction:column; gap:6px; margin-bottom:14px; padding:12px 14px; background:#f7fafc; border:1px solid #e2e8f0; border-radius:8px; }\n  .nf-legende-item { display:flex; align-items:flex-start; gap:10px; font-size:12px; color:#4a5568; line-height:1.5; }\n  .nf-wichtig { background:#fff5f5; border-left:4px solid #e53e3e; border-radius:0 8px 8px 0; padding:10px 14px; font-size:13px; color:#742a2a; line-height:1.6; margin-bottom:12px; }\n  .nf-table-wrap { overflow-x:auto; width:100%; border-radius:8px; box-shadow:0 1px 4px rgba(0,0,0,.07); margin-bottom:6px; }\n  .nf-table { width:100%; border-collapse:collapse; background:#fff; }\n  .nf-table thead tr { background:#2d3748; }\n  .nf-table th { padding:10px 12px; text-align:left; font-size:12px; font-weight:600; color:#fff; white-space:nowrap; letter-spacing:.4px; text-transform:uppercase; cursor:pointer; user-select:none; }\n  .nf-table th:hover { background:#4a5568; }\n  .nf-table td { padding:8px 12px; border-bottom:1px solid #edf2f7; font-size:13px; vertical-align:middle; }\n  .nf-table tbody tr:nth-child(even) td { background:#f7fafc; }\n  .nf-table tbody tr:nth-child(odd) td { background:#fff; }\n  .nf-table tbody tr:hover td { background:#ebf8ff !important; }\n  .nf-table tbody tr:last-child td { border-bottom:none; }\n  .nf-table a { color:#e53e3e; text-decoration:none; font-weight:500; }\n  .nf-table a:hover { text-decoration:underline; }\n  .nf-bew { display:inline-flex; width:28px; height:28px; border-radius:6px; align-items:center; justify-content:center; font-weight:700; font-size:13px; flex-shrink:0; }\n  .nf-b1 { background:#276749; color:#fff; }\n  .nf-b2 { background:#9ae6b4; color:#276749; }\n  .nf-b3 { background:#dd6b20; color:#fff; }\n  .nf-b4 { background:#c53030; color:#fff; }\n  .nf-b5 { background:#ecc94b; color:#744210; }\n  .nf-mitglieder { display:block; font-size:11px; color:#718096; margin-top:2px; line-height:1.4; }\n  .nf-quote { display:inline-block; min-width:52px; text-align:right; font-weight:600; font-variant-numeric:tabular-nums; }\n  .nf-q-low { color:#276749; }\n  .nf-q-mid { color:#dd6b20; }\n  .nf-q-high { color:#c53030; }\n  .nf-bar { display:block; height:4px; margin-top:3px; border-radius:2px; background:#edf2f7; overflow:hidden; }\n  .nf-bar span { display:block; height:100%; border-radius:2px; background:currentColor; }\n  .nf-search-wrap { display:flex; gap:10px; align-items:center; margin-bottom:12px; flex-wrap:wrap; }\n  #nf-suche { flex:1; min-width:200px; max-width:400px; padding:10px 14px; border:1px solid #e2e8f0; border-radius:8px; font-size:13px; outline:none; }\n  #nf-suche:focus { border-color:#e53e3e; box-shadow:0 0 0 3px rgba(229,62,62,.1); }\n  .nf-count { font-size:12px; color:#718096; white-space:nowrap; }\n  .nf-fussnote { font-size:13px; color:#718096; margin:6px 0; line-height:1.5; }\n  .nf-footer { font-size:11px; color:#a0aec0; text-align:right; margin-top:8px; }\n  @media (max-width:768px) {\n    .nf-table thead { display:none; }\n    .nf-table tbody tr { display:block; margin-bottom:12px; border:1px solid #e2e8f0; border-radius:8px; overflow:hidden; }\n    .nf-table tbody td { display:flex; justify-content:space-between; align-items:center; padding:7px 12px; border-bottom:1px solid #f0f0f0; font-size:12px; background:#fff !important; }\n    .nf-table tbody td:before { content:attr(data-label); font-weight:600; color:#718096; margin-right:8px; min-width:120px; flex-shrink:0; }\n    .nf-bar { display:none; }\n  }\n<\/style>\n\n<div id=\"nf-outer\">\n  <div id=\"nf-loading\"><div class=\"nf-spinner\"><\/div> Daten werden geladen\u2026<\/div>\n  <div id=\"nf-inhalt\" style=\"display:none;\">\n    <div class=\"nf-section-title\"><span class=\"nf-icon\">&#x2139;<\/span> Bewertung der Firmenmeldungen<\/div>\n    <div class=\"nf-legende-box\" id=\"nf-legende\"><\/div>\n    <div class=\"nf-wichtig\">\n      <strong>Wichtig:<\/strong> Bei Firmen der Kategorie 1+2 sind Produkte m\u00f6glicherweise noch bei Grossisten verf\u00fcgbar.\n      Bei Firmen, die nicht selber melden (Kategorie 3, 4 und 5) stammen die Meldungen in der Regel von Usern.\n    <\/div>\n    <div class=\"nf-section-title\"><span class=\"nf-icon\">&#x1f3ed;<\/span> Lieferengp\u00e4sse nach Firmen<\/div>\n    <div class=\"nf-search-wrap\">\n      <input type=\"text\" id=\"nf-suche\" placeholder=\"&#x1f50d; Firma suchen\u2026\">\n      <span class=\"nf-count\" id=\"nf-count\"><\/span>\n    <\/div>\n    <div class=\"nf-table-wrap\">\n      <table class=\"nf-table\">\n        <thead><tr>\n          <th onclick=\"nfSort('firma')\">Firma &#x2195;<\/th>\n          <th onclick=\"nfSort('bewertungId')\" style=\"text-align:center; width:70px;\">Bew. &#x2195;<\/th>\n          <th onclick=\"nfSort('anzahlEngpaesse')\" style=\"text-align:center; width:130px;\">Offene Engp\u00e4sse &#x2195;<\/th>\n          <th onclick=\"nfSort('anzahlProdukte')\" style=\"text-align:center; width:150px;\">Produkte Total &#x2195;<\/th>\n          <th onclick=\"nfSort('quote')\" style=\"text-align:center; width:130px;\">Anteil betroffen &#x2195;<\/th>\n        <\/tr><\/thead>\n        <tbody id=\"nf-tbody\"><\/tbody>\n      <\/table>\n    <\/div>\n    <p class=\"nf-fussnote\">Hinweis: Die Anzahl registrierter Produkte gibt einen Hinweis auf den Stellenwert des Engpasses, hat aber nichts mit dem therapeutischen Stellenwert zu tun. \u00abAnteil betroffen\u00bb = offene Engp\u00e4sse im Verh\u00e4ltnis zu allen registrierten Produkten der Firma bzw. Firmengruppe.<\/p>\n    <div class=\"nf-footer\">Daten werden w\u00f6chentlich aktualisiert \u00b7 drugshortage.ch<\/div>\n  <\/div>\n<\/div>\n\n<script>\nconst NF_BASE   = \"https:\/\/www.drugshortage.ch\";\nconst NF_API    = \"https:\/\/www.drugshortage.ch\/ds.php?a=uebersicht_firmen\";\nconst NF_DETAIL = NF_BASE + \"\/index.php\/lieferengpaesse-nach-firma\/\";\n\nlet nfAlle = [], nfSortFeld = \"anzahlEngpaesse\", nfAufsteigend = false;\n\nfunction nfAufbereiten(zeilen) {\n  return zeilen.map(function(f) {\n    const e = parseInt(f.anzahlEngpaesse) || 0;\n    const p = parseInt(f.anzahlProdukte)  || 0;\n    let mitglieder = f.mitglieder;\n    if (typeof mitglieder === \"string\") mitglieder = mitglieder.split(\/\\s*[,;\u00b7]\\s*\/).filter(Boolean);\n    if (!Array.isArray(mitglieder) || !mitglieder.length) mitglieder = [f.firma];\n    let quote = (f.anteilProzent !== undefined && f.anteilProzent !== null)\n                ? parseFloat(f.anteilProzent)\n                : (p > 0 ? (e \/ p * 100) : null);\n    if (isNaN(quote)) quote = null;\n    return {\n      firma           : f.firma || \"\u2013\",\n      linkFirma       : f.linkFirma || f.firma || \"\",\n      gruppeId        : f.gruppeId || null,\n      istGruppe       : !!f.istGruppe || mitglieder.length > 1,\n      mitglieder      : mitglieder,\n      bewertungId     : parseInt(f.bewertungId) || 0,\n      bewertung       : f.bewertung || \"\",\n      anzahlEngpaesse : e,\n      anzahlProdukte  : p,\n      quote           : quote,\n      suchtext        : (mitglieder.join(\" \") + \" \" + (f.firma || \"\")).toLowerCase()\n    };\n  });\n}\n\nasync function ladeNachFirma() {\n  try {\n    const res = await fetch(NF_API, {\n      headers: {'X-Requested-With': 'XMLHttpRequest'},\n      credentials: 'same-origin'\n    });\n    const d = await res.json();\n    if (d.fehler) {\n      document.getElementById(\"nf-loading\").innerHTML = \"<div style='color:#c53030;padding:20px;background:#fff5f5;border-radius:8px;'>&#x26a0;&#xfe0f; \" + d.fehler + \"<\/div>\";\n      return;\n    }\n    const legDiv = document.getElementById(\"nf-legende\");\n    (d.bewertungLegende || []).forEach(function(b) {\n      const item = document.createElement(\"div\");\n      item.className = \"nf-legende-item\";\n      item.innerHTML = \"<span class='nf-bew nf-b\" + b.ident + \"'>\" + b.ident + \"<\/span><span><strong>Kategorie \" + b.ident + \":<\/strong> \" + (b.bewertung || \"\") + \"<\/span>\";\n      legDiv.appendChild(item);\n    });\n    nfAlle = nfAufbereiten(d.firmen || []).sort(function(a, b) { return b.anzahlEngpaesse - a.anzahlEngpaesse; });\n    nfZeige(nfAlle);\n    document.getElementById(\"nf-loading\").style.display = \"none\";\n    document.getElementById(\"nf-inhalt\").style.display  = \"block\";\n    document.getElementById(\"nf-suche\").addEventListener(\"input\", function() {\n      const q = this.value.toLowerCase();\n      nfZeige(q ? nfAlle.filter(function(f) { return f.suchtext.includes(q); }) : nfAlle);\n    });\n  } catch(err) {\n    document.getElementById(\"nf-loading\").innerHTML = \"<div style='color:#c53030;padding:20px;background:#fff5f5;border-radius:8px;'>&#x274c; Fehler: \" + err + \"<\/div>\";\n  }\n}\n\n\/* Immer ?Firma= verwenden \u2013 die API l\u00f6st Gruppen serverseitig auf,\n   die Detailseite braucht dadurch keine Anpassung. *\/\nfunction nfUrl(f) {\n  const ziel = f.linkFirma || f.firma || \"\";\n  return NF_DETAIL + \"?Firma=\" + encodeURIComponent(ziel);\n}\n\nfunction nfQuoteZelle(f) {\n  if (f.quote === null) return \"<span style='color:#a0aec0;'>\u2013<\/span>\";\n  const cls = f.quote >= 15 ? \"nf-q-high\" : (f.quote >= 5 ? \"nf-q-mid\" : \"nf-q-low\");\n  return \"<span class='nf-quote \" + cls + \"'>\" + f.quote.toFixed(1) + \" %\"\n       + \"<span class='nf-bar'><span style='width:\" + Math.min(100, f.quote) + \"%;'><\/span><\/span><\/span>\";\n}\n\nfunction nfZeige(daten) {\n  const tbody = document.getElementById(\"nf-tbody\");\n  document.getElementById(\"nf-count\").textContent = daten.length + \" Firmen\";\n  tbody.innerHTML = \"\";\n  daten.forEach(function(f) {\n    const tr  = document.createElement(\"tr\");\n    const url = nfUrl(f);\n    let firmaZelle = \"<a href='\" + url + \"'>\" + f.firma + \"<\/a>\";\n    if (f.istGruppe) firmaZelle += \"<span class='nf-mitglieder'>\" + f.mitglieder.join(\" \u00b7 \") + \"<\/span>\";\n    tr.innerHTML =\n      \"<td data-label='Firma'>\" + firmaZelle + \"<\/td>\" +\n      \"<td style='text-align:center;' data-label='Bewertung'>\" + (f.bewertungId > 0 ? \"<span class='nf-bew nf-b\" + f.bewertungId + \"' title='\" + f.bewertung + \"'>\" + f.bewertungId + \"<\/span>\" : \"\u2013\") + \"<\/td>\" +\n      \"<td style='text-align:center;font-weight:700;color:#e53e3e;' data-label='Offene Engp\u00e4sse'><a href='\" + url + \"' style='color:#e53e3e;'>\" + f.anzahlEngpaesse + \"<\/a><\/td>\" +\n      \"<td style='text-align:center;color:#4a5568;' data-label='Produkte Total'>\" + f.anzahlProdukte + \"<\/td>\" +\n      \"<td style='text-align:center;' data-label='Anteil betroffen'>\" + nfQuoteZelle(f) + \"<\/td>\";\n    tbody.appendChild(tr);\n  });\n}\n\nfunction nfSort(feld) {\n  nfAufsteigend = (nfSortFeld === feld) ? !nfAufsteigend : (feld === \"firma\");\n  nfSortFeld = feld;\n  const q = document.getElementById(\"nf-suche\").value.toLowerCase();\n  const liste = q ? nfAlle.filter(function(f) { return f.suchtext.includes(q); }) : nfAlle.slice();\n  liste.sort(function(a, b) {\n    if (feld === \"quote\") {\n      if (a.quote === null && b.quote === null) return 0;\n      if (a.quote === null) return 1;\n      if (b.quote === null) return -1;\n      return nfAufsteigend ? a.quote - b.quote : b.quote - a.quote;\n    }\n    if (feld === \"bewertungId\" || feld === \"anzahlProdukte\" || feld === \"anzahlEngpaesse\")\n      return nfAufsteigend ? a[feld] - b[feld] : b[feld] - a[feld];\n    const va = (a[feld]||\"\").toLowerCase(), vb = (b[feld]||\"\").toLowerCase();\n    return nfAufsteigend ? va.localeCompare(vb) : vb.localeCompare(va);\n  });\n  nfZeige(liste);\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", ladeNachFirma);\n<\/script>\n\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Daten werden geladen\u2026 &#x2139; Bewertung der Firmenmeldungen Wichtig: Bei Firmen der Kategorie 1+2 sind Produkte m\u00f6glicherweise noch bei Grossisten verf\u00fcgbar. Bei Firmen, die nicht selber melden (Kategorie 3, 4 und 5) stammen die Meldungen in der Regel von Usern. &#x1f3ed; Lieferengp\u00e4sse nach Firmen Firma &#x2195; Bew. &#x2195; Offene Engp\u00e4sse &#x2195; Produkte Total &#x2195; Anteil betroffen&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"","_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":"","_members_access_role":[],"_members_access_error":""},"class_list":["post-21334","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/pages\/21334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/comments?post=21334"}],"version-history":[{"count":12,"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/pages\/21334\/revisions"}],"predecessor-version":[{"id":21926,"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/pages\/21334\/revisions\/21926"}],"wp:attachment":[{"href":"https:\/\/www.drugshortage.ch\/index.php\/wp-json\/wp\/v2\/media?parent=21334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}