Okt 06

Saalplaner mit Platzierungsfunktion auf Salesforce

Bei einem unserer Projekte haben wir vor kurzem einen Saalplaner mit Platzierungsfunktion auf force.com gebaut. Das zeigt ganz schön die Power, die einem mit der Salesforce Plattform zur Verfügung steht.

Der Benutzer startet in den Saalplaner mittels eines Buttons auf der Kampagne:

kampagnen buttons fuer saalplaner

Buttons an der Kampagne um den Saalplaner aufzurufen.

Nun können die Kampagnen-Mitglieder ganz einfach per drag and drop einem Platz zugewiesen werden. Auch eine Neu-Anordnung ist möglich.

Der Saalplaner in Aktion. In blau: Anmerkungen

Der Saalplaner in Aktion. In blau: Anmerkungen

Die erfolgte Platzierung wird auf dem Kampagnen-Mitglied gespeichert. So lässt es sich direkt weiter für die Event-Planung in Salesforce verwenden. Z.B. kann dem Kontakt eine E-Mail mit seinem zugewiesenen Platz geschickt werden, Tickets oder Listen für die Organisatoren gedruckt werden. Hier greift erneut die Flexibilität der Force.com Plattform. Viele Folge-Aktionen lassen sich nämlich mit einfachen Workflows oder Berichten abbilden.

kampagnen mitglieder mit platzierungs information

Ansicht von Kampagnenmitgliedern.

Selbstverständlich kann die Information auch über die API mit anderen Systemen (Booking, Event, ERP, Abrechnung, …) geteilt werden.

Eine besondere Herausforderung war es, den vorgegebenen Saalplan möglichst elegant und flexibel im Salesforce Setup zu hinterlegen. Hierfür haben wir die Vorlage des Kunden zuerst in ein rechteckiges Schema umgewandelt und dann ein X/Y-Raster gebildet. Für den Saalplaner hat der Saal dann eine Gesamtdimension erhalten und die Sitzplätze werden in einem custom setting abgelegt. So kann die Applikation auch später ganz einfach angepasst werden –  z.B. wenn Sitze entfallen oder hinzukommen. Auch wäre es möglich, pro Kampagne eine andere Bestuhlung zu definieren.

saalplaner konfiguration

Blick auf das Custom Setting.

Für uns war es ein spannendes Projekt und der Kunde ist sehr glücklich mit der Lösung.

Haben Sie dieselbe oder eine ähnliche Anforderung? Gerne stehe ich Ihnen für ein Gespräch zur Verfügung.

Jan 21

E-Mail Erweiterungen für Kampagnen

Diese kleine Erweiterung habe ich vor einiger Zeit bei CoreMedia entwickelt. Freundlicherweise darf ich die App hier kostenlos veröffentlichen und damit der Community zur Verfügung stellen. Schon vor einiger Zeit hatte ich einen Screencast hierzu erstellt, anschließend aber keinen Blog-post folgen lassen.

Funktionalität

Das Package umfasst zwei Funktionen:

  1. Eine ausgehende E-Mail an jedes neue Kampagnen-Mitglied verschicken. Dazu wird zunächst eine template ID hinterlegt. Ist die Funktion aktiv, wird jedem Lead oder Kontakt, der mit dem Status „Sent“ oder „Gesendet“ der Kampagne hinzugefügt wird, eine E-Mail mit dem hinterlegten Template geschickt. Sollte mehr als ein Kampagnen-Mitglied hinzugefügt werden, wird automatisch ein Mass-Mailing erstellt. Das tägliche Limit an zu versendenden E-Mails pro Org. gilt natürlich weiterhin. Sollte dieses Limit erreicht werden, wird einfach keine Aktion ausgeführt und eine „MASS_MAIL_LIMIT_EXCEEDED“ Exception angezeigt.
  2. Benachrichtigung bei neuen Kampagnen-Mitgliedern. An die hinterlegte E-Mail-Adresse wird eine Benachrichtigung verschickt, wenn neue Kampagnen-Mitglieder hinzugefügt werden. Sollten wiederum mehrere Kampagnen-Mitglieder hinzugefügt werden, so werden diese in einer Benachrichtigung als  Liste zusammengefasst.

Die App ist mit vollen Unit-Tests abgedeckt, von mir manuell durchgetestet und im Live-Betrieb bereits sehr erprobt. Für CoreMedia ist die Funktionalität so wie sie ist gut und ausreichend. Sollte mich Feedback von anderen Usern erreichen, so bin ich bereit, ein bisschen Freizeit in die Weiterentwicklung zu investieren (z.B. die Exceptions abfangen und hübsche(-re) Fehler-Meldungen anzeigen 😉 ).

Hier das Ganze in Aktion:

Installation

Wichtig: Die Bereitstellung erfolgt ohne Anspruch auf Gewährleistung, Funktion, Support oder ähnliches. Nach der Installation müssen die Felder in das Page-Layout aufgenommen und die apex Klassen für die gewünschten Profile freigeschaltet werden.

Das Package funktioniert nicht automatisch mit DE Orgs, da ein freischaltungspflichtiges Feature (Mass Mail Permission) benötigt wird. Wenn Sie in eine DE Org. installieren wollen, müssen sie zunächst also dieses Feature beim Support freischalten lassen. Ich empfehle daher eine Installation in die Sandbox, um dort zu testen.

Installation in eine Live-Org.

Installation in die Sandbox.

Viel Spaß damit und wie immer freue ich mich über Feedback. Besonders gespannt bin ich auf Eure / Ihre Anwendungsfälle.

//Hannes

Nov 27

Aufrufen von APEX-Code per Button

Ich möchte hier beschreiben, wie man ganz simpel Apex-Code durch einen ‚Knopfdruck‘ ausführen kann. Mit Hilfe solcher Buttons („Benutzerdefinierte Schaltfläche“) können dem User lästige Aufgaben, die sich automatisieren lassen, abgenommen werden. Ein oft genutztes Einsatzgebiet ist das Anlegen von Datensätzen, Versenden von E-Mails oder Anstoßen eines Workflows.

Das Vorgehen als Checkliste

  • Apex-Klasse und Methode(n) schreiben
  • Button anlegen
  • Button zunächst in ein Test Page Layout aufnehmen und testen
  • Sicherheitseinstellungen des Buttons anpassen (für Profile freischalten)
  • Button in alle gewünschten Page Layouts aufnehmen

Im Detail

Der Button sollte mit den folgenden Einstellungen angelegt werden:

Mit den hier gezeigten Einstellungen kann man den Button später an der Detailansicht des Datensatzes positionieren, also z.B. neben „Bearbeiten“ und „Löschen“. Möchte man einen Button an einer Related List haben, so muss der „List Button“ („Schaltfläche für Liste“) ausgewählt werden und der Button muss bei dem entsprechenden Unterobjekt angelegt werden. Soll beispielsweise ein Button an der Related List für Aktivitäten am Account eingebunden werden, so muss der Button auch am Aktivitäten-Objekt angelegt werden;

[Zum vergrößern Bild anklicken]

Als Aufruf für den Button wird nun folgender Javascript code in das große Feld eingefügt:

{!requireScript("/soap/ajax/18.0/connection.js")}
{!requireScript("/soap/ajax/18.0/apex.js")}

if(confirm('Dies ist eine beliebige Sicherheitsabfrage.'))
sforce.apex.execute(
	'KlassenName',
	'MethodenName',
	{Id:'{!Account.Id}', ParameterZwei:'bla'});

Der Code Zeile für Zeile erklärt:

Die ersten beiden Zeilen stellen sicher, dass die benötigten Javascript-Bibliotheken geladen sind.

Anschließend wird eine einfache Sicherheitsabfrage mittels „Ok / Abbrechen“ Dialog durchgeführt. Diese ist natürlich optional und kann auch weggelassen werden. Ich benutze sie gerne, um ein versehentliches Auslösen der Aktion zu unterbinden.

Nun wird die eigentliche APEX Klasse aufgerufen. KlassenName und MethodenName sind dabei natürlich entsprechend dem eigenen Code anzupassen. Die zu übergebenen Parameter richten sich auch nach der aufgerufenen Methode.

Die APEX Klasse dazu sieht wie folgt aus:

global class KlassenName{
  Webservice static void MethodenName(String Id, String ParameterZwei) {
   //Programm-Logik....
  }
}

Wichtig ist, die Klasse als global und die Methode als Webservice zu deklarieren.

Bezieht sich die Programm-Logik auf ein konkretes sObject, so muss dieses ggf. erst per SOQL bereit gestellt werden.

Bevor nun der Button in das Page-Layout aufgenommen wird, ganz wichtig, nicht vergessen: Die Security-Einstellungen für die Klasse anpassen. D.h. alle User, die den Button benutzen möchten, müssen dafür freigeschaltet werden. Hierzu navigiert man im Setup zu „Develop“ -> „Apex Classes“ -> „Security“ und schiebt alle gewünschten Profile von links nach rechts;

Ein Anwendungsfall

Was z.B. mit einem solchen Button möglich ist: Eine Task mit vordefiniertem Inhalt anlegen. Hier genutzt um Anrufe zu protokollieren, bei denen der Agent auf der Mailbox gelandet ist. Der Button kann sowohl an einem Lead, Kontakt als auch Account angelegt werden. Es muss entsprechend mindestens eine whoID oder whatID oder auch beides übergeben werden.

Button Beispiel an einem Lead:

{!REQUIRESCRIPT("/soap/ajax/18.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/18.0/apex.js")} 

if(confirm('Called and left VM?')){ 

sforce.apex.execute(
'TaskHandling',
'addTask',
{Status:'Completed',whoId:'{!Lead.Id}', Subject:'Called, left VM', Type:'Call'});

location.reload();}

Und die dazugehörige Apex-Klasse:

global class TaskHandling {

    Webservice static void addTask(String status, String whoId, String subject, String tipe, String whatId) {
        /*
        Creates a task for given lead or contact
        */

        // Build a new Task and insert it
        Task task = new Task(
            Status = status,
            Subject = subject,
            Type = tipe,
            ActivityDate = System.today()

        );
        if (whatId != '' && whatId != null) {
          task.WhatId = whatId;
        }
        if (whoId != '' && whoId != null) {
          task.WhoId = whoId;
        }
        insert task;

    }

}

Abschluss

Viel Spaß beim Ausprobieren! Ich freue mich über Erfahrungsberichte und Beispiele für weitere Anwendungsfälle

//Hannes

Mrz 20

Validierung einer Bedingung: Formel vs. Query

Immer wieder stößt man in der Programmierung auf Bedingungen. Nur wenn diese Bedingungen zutreffen, findet eine bestimmte Verarbeitung statt. Ich möchte in diesem Artikel vorstellen, auf welche Arten Ausführungen in Salesforce an Bedingungen geknüpft werden können und anschließend untersuchen welche Methoden dabei am effektivsten sind. Im Besonderen gehe ich dabei auf die Benutzung von Formeln ein. Continue reading

Mrz 14

Erweiterung von / Anwendungsentwicklung auf Salesforce

Das, was Salesforce.com deutlich von seinen Mitbewerbern absetzt, ist die Möglichkeit, eigens entwickelten Programmcode auf den Servern von Salesforce auszuführen. So lässt sich die CRM-Funktionalität nach Belieben erweitern oder sogar ganze Applikationen und Websites auf ‚force.com‚ betreiben. Dieser Artikel soll einen Einblick in die Möglichkeiten geben, die einem damit zur Verfügung stehen. Er richtet sich damit an Administratoren und Entwickler.

Continue reading