Ansicht von 8 Antwort-Threads
  • Autor
    Beiträge
    • #42142
      Sascha Behnsen
      Teilnehmer

        Guten Morgen!

        Man kann über
        Ticket::Frontend::AgentTicketPriority###
        diverse Dinge vorbelegen mit Defaults.

        Wir würden gerne auch die auszuwählende Queue mit einem Default vorbelegen, dazu habe ich aber nichts gefunden. Gibt es ggf. noch eine „versteckte“ Möglichkeit? Oder woanders?

        • Dieses Thema wurde vor 2 Wochen, 6 Tagen von Sascha Behnsen geändert.
      • #42147
        marcel-graf
        Teilnehmer

          Hallo Sascha,

          Tickets werden ja schon beim anlegen einer Queue zugewiesen. Wie stellt ihr euch den Prozess genau vor?

          Oder möchtest zu z.B. erreichen, dass wenn bei einem Ticket die Prio geändert wird, dieses dann automatisch in eine Queue/Unterqueue verschoben wird? Das könntest du mit dem Generic Agent lösen. Als Ereignis Auslöser wäre es dann das „TicketPriorityUpdate“ und dort kannst du auch Ticket Filter setzen.

          Gruß Marcel

        • #42150
          Sascha Behnsen
          Teilnehmer

            Der Prozess bei uns ist recht simpel, weil wir nicht wirklich mit Queues und gar nicht mit Services, etc. arbeiten.

            Ticket kommt per Email rein und landet erst mal in der Raw als Neu.

            Dann schaut einer der Agents drauf und entscheidet: klickt auf Priorität und über den Dialog wird das dann „in einem Rutsch“ der korrekten Queue (standardmäßig und üblicherweise sollte das eben „1st Level“ bei uns sein; es gibt aber auch noch „intern“ (hier berechnen wir nicht)) und im gleichen Dialog auch einem „Neuen Besitzer“ (Agent) zugewiesen und ggf. wird die Prio auch noch angepasst (default 3-normal).

            Das funktioniert eigentlich recht zuverlässig und simpel bei uns. Nur eine Vorbelegung der Queue auf „1st Level“ wäre noch hilfreich, weil spart meist noch mal einen Klick. „Queue – Intern“ kommt bei uns zwar vor, aber selten.

            Man könnte natürlich den „Postmaster“ auch so einstellen, dass es gleich in die „1st Level“ als Neu geht. Aber wir finden das so eigentlich besser und auf der Raw liegt auch eine Eskalationszeit, wenn z.B. bei uns mal nicht schnell genug reagiert wird. Dann gibts zurecht Email Spam an alle Agenten.

          • #42159
            marcel-graf
            Teilnehmer

              Hallo Sascha,

              so kannst du es Einstellen. Dazu musst du in der Systemkonfig das Ticket::Frontend::AgentTicketPriority###Queue aktivieren.

              Gruß Marcel

            • #42160
              Sascha Behnsen
              Teilnehmer

                Moin!

                Ja, das habe ich aktiviert. Sorry, hätte noch ausführlicher den Ist Zustand beschreiben sollen.
                Was ich suche, bzw. vermisse ist hier die Möglichkeit, eine Queue vorzubelegen. Also sowas wie quasi:
                Ticket::Frontend::AgentTicketPriority###QueueDefault

                Den gibt es nämlich nicht. Einen Ticket::Frontend::AgentTicketPriority###PriorityDefault hingegen gibt es z.B…

              • #42161
                marcel-graf
                Teilnehmer

                  Hallo Sascha,

                  da habe ich auch nichts gefunden. Ihr könnt aber einen Button einfügen und dort das gewüschte anpassen.

                  Folgend mal eine kurze Anleitung dazu:

                  #— Add Custom Prio & Queue Button —–

                  —> In den Docker Container wechseln —

                  sudo docker exec -it otobo_web_1 bash

                  —> AgentTicketZoom.tt nach Custom kopieren—

                  cp /opt/otobo/Kernel/Output/HTML/Templates/Standard/AgentTicketZoom.tt /opt/otobo/Custom/Kernel/Output/HTML/Templates/Standard/AgentTicketZoom.tt

                  —> AgentTicketZoom.tt bearbeiten und anpassen

                  nano /opt/otobo/Custom/Kernel/Output/HTML/Templates/Standard/AgentTicketZoom.tt

                  suche nach [% RenderBlockStart(„Header“) %] und ersetze den den kompletten <h1> </h1> Tag mit folgemdem Code.

                  <h1>
                  #[% Data.Hook %][% Config(‚Ticket::HookDivider‘) %][% Data.TicketNumber | html %] &mdash; [% Data.Title | html %]

                  <!– 1. Der Kopier-Button mit erweiterter Breite (150px) –>
                  <button type=“button“
                  class=“Button“
                  style=“margin-left: 15px; padding: 2px 0; font-size: 11px; vertical-align: middle; cursor: pointer; display: inline-block; width: 150px; text-align: center;“
                  onclick=“event.stopPropagation();
                  const tempInput = document.createElement(‚textarea‘);
                  tempInput.value = ‚[% Data.TicketNumber %]‘;
                  document.body.appendChild(tempInput);
                  tempInput.select();
                  document.execCommand(‚copy‘);
                  document.body.removeChild(tempInput);
                  this.textContent = ‚📋 Kopiert!‘;
                  setTimeout(() => this.textContent = ‚📋 Ticketnummer kopieren‘, 2000);“>
                  📋 Ticketnummer kopieren
                  </button>

                  <!– 2 Start: Custom Prio & Queue Button (Direct AJAX Move) –>
                  <button type=“button“
                  class=“Button“
                  id=“CustomPrioQueueBtn“
                  style=“margin-left: 10px; padding: 2px 10px; font-size: 11px; vertical-align: middle; cursor: pointer; display: inline-block; text-align: center;“>
                  🔄 Sofort in Queue 5 &amp; Prio 1 ändern
                  </button>

                  <script type=“text/javascript“>
                  document.getElementById(‚CustomPrioQueueBtn‘).addEventListener(‚click‘, function(event) {
                  event.stopPropagation();

                  // Button optisch deaktivieren gegen Doppelklicks
                  var btn = this;
                  btn.disabled = true;
                  btn.textContent = ‚⏳ Wird verarbeitet…‘;

                  // AJAX-URL mit DestQueueID=5 und NewPriorityID=1
                  var targetUrl = ‚[% Env(„Baselink“) %]Action=AgentTicketMove;Subaction=Store;TicketID=[% Data.TicketID | html %];DestQueueID=5;NewPriorityID=1;ChallengeToken=[% Env(„UserChallengeToken“) %]‘;

                  // Hintergrund-Request abschicken
                  if (typeof jQuery !== ‚undefined‘) {
                  jQuery.ajax({
                  url: targetUrl,
                  type: ‚POST‘,
                  success: function() {
                  btn.textContent = ‚✅ Erledigt!‘;
                  window.location.reload();
                  },
                  error: function() {
                  alert(‚Fehler beim schnellen Verschieben des Tickets.‘);
                  btn.disabled = false;
                  btn.textContent = ‚🔄 Sofort in Queue 5 & Prio 1 ändern‘;
                  }
                  });
                  } else {
                  // Fallback ohne jQuery
                  fetch(targetUrl, { method: ‚POST‘ })
                  .then(function() { window.location.reload(); })
                  .catch(function() {
                  alert(‚Fehler beim Verschieben.‘);
                  btn.disabled = false;
                  btn.textContent = ‚🔄 Sofort in Queue 5 & Prio 1 ändern‘;
                  });
                  }
                  });
                  </script>
                  <!– End: Custom Prio & Queue Button –>

                  </h1>

                  Änderung abspeichern und den cache leeren.

                  ./bin/otobo.Console.pl Maint::Config::Rebuild –cleanup
                  ./bin/otobo.Console.pl Maint::Cache::Delete

                   

                  Im Script selbst muss noch die DestQueueID=5;NewPriorityID=1 angepasst werden. Falls Prio nicht benötigt wird, einfach aus dem Script löschen und die Beschriftung des Buttons kann nach belieben angepasst werden.

                  Gruß Marcel

                • #42165
                  marcel-graf
                  Teilnehmer

                    Anbei nochmal eine Änderung.

                    Die Ticket Prio kann jetzt ausgewählt werden und es ändert sich die Farbe vom Rahmen, je nach Prio.

                    #—Script—

                    <!– 2 Start: Custom Prio & Queue Button + GUI Prio Auswahl (Otobo Farben & Auto-Vorauswahl) –>
                    <div style=“display: inline-flex; align-items: center; vertical-align: middle; margin-left: 10px; background: #f4f4f4; border: 2px solid #cccccc; border-radius: 4px; padding: 2px 4px; box-shadow: inset 0 1px 2px rgba(0,0,0,0.05); transition: border-color 0.2s ease;“
                    onclick=“event.stopPropagation();“>

                    <!– Native Prio-Auswahl –>
                    <select style=“border: none; background: transparent; font-size: 11px; height: 22px; padding: 0 4px; cursor: pointer; color: #333; font-weight: bold; outline: none; margin-right: 4px;“
                    onclick=“event.stopPropagation();“
                    onchange=“
                    var container = this.parentNode;
                    if (this.value == ‚1‘) container.style.borderColor = ‚#337ab7‘; /* Otobo Blau */
                    else if (this.value == ‚2‘) container.style.borderColor = ‚#5cb85c‘; /* Otobo Grün */
                    else if (this.value == ‚3‘) container.style.borderColor = ‚#cccccc‘; /* Otobo Grau */
                    else if (this.value == ‚4‘) container.style.borderColor = ‚#f06292‘; /* Otobo Pink */
                    else if (this.value == ‚5‘) container.style.borderColor = ‚#d9534f‘; /* Otobo Rot */
                    „>
                    <option value=“1″>Prio 1 (sehr niedrig)</option>
                    <option value=“2″>Prio 2 (niedrig)</option>
                    <option value=“3″>Prio 3 (normal)</option>
                    <option value=“4″>Prio 4 (hoch)</option>
                    <option value=“5“>Prio 5 (sehr hoch)</option>
                    </select>

                    <!– Trennlinie in der GUI –>

                    <!– Der funktionierende Aktions-Button –>
                    <button type=“button“
                    style=“border: none; background: transparent; font-size: 11px; height: 22px; padding: 0 8px; cursor: pointer; color: #000; font-weight: bold; outline: none;“
                    onclick=“
                    event.preventDefault();
                    event.stopPropagation();

                    var btn = this;
                    var container = btn.parentNode;
                    var selectEl = container.querySelector(’select‘);
                    var prioId = selectEl.value;

                    // Aktuelle Werte des Tickets aus Otobo auslesen
                    var currentQueueId = ‚[% Data.QueueID | html %]‘;
                    var currentPrioId = ‚[% Data.PriorityID | html %]‘;

                    // VALIDIERUNG
                    // Fall 1: Queue stimmt bereits UND Prio stimmt bereits
                    if (currentQueueId == ‚5‘ && currentPrioId == prioId) {
                    alert(‚Das Ticket befindet sich bereits in Queue 5 mit dieser Priorität.‘);
                    return;
                    }

                    btn.disabled = true;
                    selectEl.disabled = true;

                    // Fall 2: Nur die Prio muss geändert werden (Queue ist bereits ID 5)
                    var targetUrl = ‚[% Env(‚Baselink‘) %]Action=AgentTicketMove;Subaction=Store;TicketID=[% Data.TicketID | html %];ChallengeToken=[% Env(‚UserChallengeToken‘) %]‘;
                    if (currentQueueId == ‚5‘) {
                    btn.textContent = ‚⏳ Prio wird geändert…‘;
                    targetUrl += ‚;DestQueueID=5;NewPriorityID=‘ + prioId;
                    } else {
                    // Fall 3: Queue (und evtl. Prio) wird geändert
                    btn.textContent = ‚⏳ Verschiebe…‘;
                    targetUrl += ‚;DestQueueID=5;NewPriorityID=‘ + prioId;
                    }

                    var xhr = new XMLHttpRequest();
                    xhr.open(‚POST‘, targetUrl, true);
                    xhr.onload = function() {
                    btn.textContent = ‚✅ Erledigt!‘;
                    window.location.reload();
                    };
                    xhr.onerror = function() {
                    alert(‚Fehler beim Verarbeiten.‘);
                    btn.disabled = false;
                    selectEl.disabled = false;
                    btn.textContent = ‚🔄 In Queue 5 verschieben‘;
                    };
                    xhr.send();
                    „>
                    🔄 In Queue 5 verschieben
                    </button>

                    <!– Initialisierungsskript zur automatischen Vorauswahl der aktuellen Ticket-Priorität –>
                    <script type=“text/javascript“>
                    (function() {
                    var ticketPrio = ‚[% Data.PriorityID | html %]‘;
                    // Suchen das letzte Select-Element, um Otobo-Konflikte zu vermeiden
                    var selects = document.getElementsByTagName(’select‘);
                    for (var i = selects.length – 1; i >= 0; i–) {
                    if (selects[i].parentNode && selects[i].parentNode.style.display === ‚inline-flex‘) {
                    var selectEl = selects[i];
                    if (ticketPrio) {
                    selectEl.value = ticketPrio;
                    // Triggere das onchange Event manuell für die richtige Rahmenfarbe beim Laden
                    if (typeof selectEl.onchange === ‚function‘) {
                    selectEl.onchange();
                    }
                    }
                    break;
                    }
                    }
                    })();
                    </script>
                    <!– End: Custom Prio & Queue Button –>

                    In meinem Test hat es super funktioniert.

                    Gruß Marcel

                     

                     

                  • #42362
                    Tobias Bück
                    Teilnehmer

                      Servus,

                      Marcel’s Button-Lösung geht natürlich, für deinen Workflow (Prio-Dialog, Queue soll gleich 1st Level vorbelegt sein) würde ich zuerst ACL probieren.

                      Im Prio-Dialog kannst du per ACL die Queue setzen oder fest vorgeben, z.B. Match auf Action AgentTicketPriority und optional auf Priority (oder nur Screen). Dann Queue auf eure 1st Level-Queue. So sparst du den Klick ohne Custom-.tt im Zoom.

                      Kurz gesagt: wenn Screen = Prio-Dialog → Queue X, oder wenn Prio = … → Queue Y, je nachdem was ihr braucht.

                      Ticket::Frontend::AgentTicketPriority###QueueDefault gibt’s tatsächlich nicht (nur PriorityDefault usw.), aber ACL ist oft der sauberere Weg als Postmaster direkt in 1st Level (Raw + Eskalation wollt ihr ja behalten).

                    • #42369
                      Sascha Behnsen
                      Teilnehmer

                        Guten Morgen!

                        Danke für die Tipps. Das mit der ACL funktioniert tatsächlich. Hat allerdings die Einschränkung, dass dann die Queue nicht mehr wählbar ist, sondern eben auf diese eine eingeschränkt wird.

                        Außerdem ist für die automatische Selektion auch noch eine Einstellung in der Sysconfig nötig und zwar
                        TicketACL::Autoselect. Hier muss die ganze Sektion aktiviert werden und Dest auf 1 oder 2 gesetzt werden. Nur dann wird auch automatisch auf die durch die ACL einzig verbleibende Auswahl automatisch selektiert.

                        Zumindest habe ich keine andere Möglichkeit gefunden, die Auswahlliste grundsätzlich beizubehalten, aber eine Vorauswahl zu treffen.

                    Ansicht von 8 Antwort-Threads
                    • Du musst angemeldet sein, um auf dieses Thema antworten zu können.