Voorwoord Deze scriptie wordt voorgedragen tot het behalen van het diploma “master in de industri¨ele wetenschappen informatica” aan de Hogeschool Gent. In deze scriptie vindt u alle informatie betreffende het werk en onderzoek verricht met het oog op het positief be¨eindigen van deze masterproef. Het voorstel voor deze masterproef beschrijft de ontwikkeling van twee uitbreidingsmodules voor een contact center scripting applicatie. Enerzijds beschrijft het voorstel een component om aan agendaplanning te doen. Anderzijds een module om aan telesales te doen. Deze modules worden in deze scriptie grondig uitgewerkt. Het voorstel werd ingediend door MI4C. Het bedrijf biedt een totaalpakket voor diverse contact centers. Deze masterproef werd uitgewerkt door Frederik De Jaegher. Om tot een goed resultaat te komen werd van begin februari tot begin juni stage gelopen in het bedrijf MI4C te Merelbeke. Hierbij werd hij begeleid door mevr. Veerle Ongenae (docent Hogeschool Gent) en dhr. Filip Hoste. Hij werd ook bijgestaan met raad en daad door dhr. Bert Reyntjens en de andere werknemers van MI4C. Dit is ook de uitgelezen kans om alle begeleiders van harte te bedanken voor de goede begeleiding, tips en ondersteuning. In deze scriptie worden volgende hoofdzaken in volgorde besproken: 1. Situatieschets 2. Component agendaplanning 3. Component verkoop 4. Debugging CTScript 5. Resultaat
iv
Hoofdstuk 1
Situatieschets Om deze masterproef te kunnen situeren is het handig een goed zicht te hebben op de hele situatie. Dit hoofdstuk zal u dit inzicht geven. Daarom krijgt u eerst een globaal overzicht wat MI4C doet. Verder in dit hoofdstuk komen de belangrijkste producten van MI4C even aan bod. Naast deze producten komt binnenkort ook CTScript op de markt. Deze applicatie is heel belangrijk voor deze masterproef. Daarom zal u verder in dit hoofdstuk wat meer informatie krijgen over CTScript. Het tweede deel schetst het doel van deze masterproef.
1.1 1.1.1
MI4C Het bedrijf
MI4C1 is een relatief klein bedrijf, gevestigd in Merelbeke. MI4C is een groeiend bedrijf, het telt momenteel zeven werknemers. Ik had de eer enkele maanden te mogen meewerken in dit team van vrij jonge, gedreven mensen. Het bedrijf maakt oplossingen voor call centers en contact centers. Momenteel bieden zij een vrij groot pakket aan oplossingen. Het pakket bestaat uit enkele producten die los van elkaar kunnen staan maar toch sterk verweven zijn. MI4C biedt oplossingen zowel op hardwareniveau (servers, ISDN-verbindingen, VoIP-verbindingen,..) als op middlewareniveau. Het hele systeem staat in voor de centralisatie van het belwerk. Om dit te verwezenlijken zien we drie types applicaties: Inbound: MI4C biedt een volledig geautomatiseerde oplossing voor inkomend telefonieverkeer. Een goed voorbeeld hiervan zijn de gekende helpdesks. De IVR-module 2 zorgt ervoor dat mensen automatisch bij een call agent 3 met de juiste competenties terechtkomt (het klassieke scenario “Druk 1 voor Nederlands. Druk 2 voor Frans”). Outbound: Het telefonieplatform is ontwikkeld om centraal mensen op te bellen. Concreet is het zo dat de telefooncentrale vanuit een database tele1 MI4C
wordt uitgesproken als “My Force” maar is hier niet van afgeleid. De echte herkomst heb ik helaas nog niet kunnen achterhalen. 2 IVR: Interactive Voice Response, een telefonische toepassing om opdrachten via telefoontoetsen of de stem door een computer uit te laten voeren. 3 Operator of Call agent: Personen die instaan voor de eigenlijke telefoongesprekken.
1
HOOFDSTUK 1. SITUATIESCHETS
2
foonnummers kiest en die zelf opbelt. Van zodra iemand aan de andere kant van de lijn antwoordt, schakelt de centrale het gesprek door met een agent. Call agents moet dus niet langer zelf een lijst nummer aflopen en intoetsen. Dit proces kan versneld worden door verschillende technieken zoals predictive dialling 4 Monitoring: Het systeem van MI4C wordt ge¨ınstalleerd bij contact centers met een capaciteit van 10 tot 300 call agents. Al deze mensen moeten opgevolgd worden. Hiervoor is er ook een uitgebreide oplossing. Zo kan een supervisor 5 vanop afstand meeluisteren met elk gesprek, of kan er zelfs vanop afstand meegekeken worden op het scherm van de agent. Tenslotte kunnen gesprekken worden opgenomen en worden via rapporteringsmodules uitgebreide statistieken over elk gesprek verzameld. MI4C biedt momenteel dus oplossingen aan voor telemarketing en call centers (bv: helpdesks). Tot voor kort ontbrak er nog ´e´en module in het hele pakket, nl. een module voor telesales 6 . Er was tot op heden nog geen module voor het telefoongesprek zelf ontwikkeld. Hierin zal CTScript verandering brengen. Over deze module volgt verderop meer informatie (1.1.3). Naast de eigen producten is MI4C ook exclusieve verdeler van ASKIAproducten. ASKIA is een Frans bedrijf dat gespecialiseerd is in surveyoplossingen. De focus ligt bij ASKIA meer op enquˆetering7 terwijl MI4C eerder de focus legt op zijn telefonie-engine en call centers. De producten van beide bedrijven staan in feite los van elkaar. Toch worden ze heel vaak samen ge¨ıntegreerd bij klanten. De reden hiervoor is vrij eenvoudig, de producten zijn ontwikkeld voor verschillende doeleinden. In plaats van elkaars producten te kopi¨eren werd er gekozen om een samenwerking tot stand te brengen. Op deze manier kunnen MI4C en ASKIA een completer pakket aanbieden aan hun potenti¨ele klanten.
1.1.2
De producten
Vooraleer dieper in te gaan op de producten zelf wordt hier een overzicht gegeven hoe alles precies werkt. Een gesprek is pas mogelijk als enkele zaken aan elkaar gekoppeld zijn. Deze structuur wordt hierna in grote lijnen geschetst. Elke call agent zit in een groep. Taken (opdrachten) kunnen aan elkaar gekoppeld worden. Aan elke taak hangen dan weer de nodige telefoonlijsten. Het systeem zal er voor zorgen dat er steeds iemand opgebeld wordt zodat de call agent dit niet zelf hoeft te doen. De operator verliest hier dus geen tijd mee. Iedere klant wordt verder afgewerkt a.d.h.v. een VB-script of een ASKIA-clientscript. CTScript zal ook instaan voor de afhandeling van klanten. Gegevens die verkregen werden uit het gesprek worden bijgehouden in een centrale databank. Om nuttige informatie te verkrijgen worden deze gegevens in rapporten gegoten. Dit was ´e´en mogelijk scenario, nl. outbound. Een ander mogelijk scenario is dat van een helpdesk. Hierbij krijgt de helpdesk een oproep (inbound). Dankzij 4 Predictive dialling: Het systeem gaat op basis van enkele parameters personen opbellen nog voor er een operator beschikbaar is. Op die manier kan tijd van een call agent optimaal benut worden. 5 Supervisor: Deze persoon is verantwoordelijk voor een groep call-agents. 6 Telesales: Verkoop van producten in een telefoongesprek. 7 Enquˆ etes worden ook wel surveys genoemd
HOOFDSTUK 1. SITUATIESCHETS
3
technieken als “IVR” kan al op voorhand beslist worden wie het gesprek zal afhandelen. Het systeem kiest a.d.h.v de input van de klant de meest geschikte beschikbare operator. Zo kan sneller gespecialiseerde hulp geboden worden. De oplossingen van MI4C (samen met ASKIA) maken dit alles mogelijk. Hieronder worden de belangrijkste producten van MI4C besproken. De producten geven u misschien een beter beeld op de werking van een call center. In deze lijst werden enkele producten opgenomen die de meest courante bewerkingen moeten voorzien voor een call center. CCA Dit acroniem staat voor Contact Center Administrator, meestal kortweg “CCA” genoemd. Deze applicatie omvat meerdere modules. Elke module staat in voor het beheer van een of ander onderdeel. Elk van de hierboven beschreven onderdelen zoals call agents, groepen, taken enz. kunnen vanuit CCA beheerd worden. Daarnaast kan CCA bijvoorbeeld rapporten aanmaken, Call back rules instellen, enzovoort. CTArchitect Deze applicatie beheert de telefoonlijnen van een call center. CTArchitect zorgt ervoor dat mensen automatisch opgebeld worden. Het hele proces kan drastisch verbeterd worden dankzij deze applicatie door preview-, progressive- en predictive dialling. Deze technieken zorgen er voor dat de call agent zo min mogelijk tijd verliest tussen twee gesprekken. CTArchitect detecteert ook verkeerde nummers en herkend een voice mail aan de andere kant van de lijn. Deze mislukte gesprekken worden eveneens bewaard. Later kan dan een nieuwe poging gedaan worden dankzij automated call back rules. Kortom deze module verhoogt de effici¨entie van een call center enorm. CATI Deze applicatie is het werkpaneel voor de call agents. Dit is een eenvoudige interface waarmee de operators kunnen aangeven of ze al dan niet aan het werk zijn. Zo kunnen ze bijvoorbeeld pauzes aangeven (zodat er geen nieuwe gesprekken meer naar hen doorgestuurd worden). CATI zorgt er ook voor dat de nodige commando’s uitgevoerd worden bij het opstarten van een gesprek. Hierbij kan het gaan om een VB-script dat moet uitgevoerd worden of een ASKIA-client-script dat opgestart moet worden. Kortom, dit is de werkomgeving van de operators. CTDesign Deze module maakt het mogelijk om op een makkelijke manier een IVR-schema te maken. Op deze manier kunnen call centers de meest geschikte call agent kiezen voor een bepaalde oproep nog voor iemand aan de lijn kwam. Dankzij een makkelijke grafische interface kan een stroomschema opgesteld worden. Aan de hand van dit schema krijgen klanten dan enkele vragen voorgeschoteld waarop ze kunnen antwoorden via de toetsen van hun toestel.
1.1.3
De applicatie CTScript
Het pakket van MI4C en ASKIA biedt al heel wat oplossingen maar voor telesales is momenteel nog geen oplossing ontwikkeld. MI4C zou deze markt immers wel graag aanspreken met hun nieuwste product, CTScript. CTScript loodst de operator als het ware door het gesprek a.d.h.v. een belscript.
HOOFDSTUK 1. SITUATIESCHETS
4
In wat volgt komt u te weten wat CTScript te bieden heeft. Eerst zullen we zien hoe een call agent een belscript kan uitvoeren met CTScript. Daarna wordt er beschreven hoe een supervisor een belscript kan maken en welke mogelijkheden hij hiervoor heeft. Als laatste zullen we iets dieper ingaan op de technologie achter CTScript.
Figuur 1.1: CTScript - Leeg werkscherm met toolbox en properties zichtbaar.
Een belscript uitvoeren Een belscript kan gebruikt worden om een call agent door een gesprek te leiden. Dankzij een belscript worden vragen op het scherm getoond. Hierdoor kan de operator op het juiste ogenblik de juiste vragen stellen en de antwoorden hierop invullen. Dit is de hoofdwerking van CTScript voor een operator.
Figuur 1.2: CTScript - Opgestart belscript met een tekst- en numeriek veld. Als CTScript een belscript opstart ziet de operator het eerste scherm van een belscript verschijnen. Op dit scherm staan enkele vragen, zie figuur 1.2. Afhankelijk van de vraag kan er dan een antwoord aangeduid of ingevuld worden.
HOOFDSTUK 1. SITUATIESCHETS
5
De operator kan dan navigeren naar een ander scherm. Op dit nieuwe scherm staan dan weer enkele vragen of keuzemogelijkheden. Als alle schermen afgewerkt zijn wordt een resultaat van het gesprek bekomen. Dit resultaat wordt dan bijgehouden in de centrale databank. De werking van deze applicatie is voor operators vrij eenvoudig gehouden. Zij hoeven niets aan te passen of in te stellen om een dergelijk belscript te doorlopen. Een operator kan wel de taal van de schermen kiezen of veranderen tijdens uitvoering. Elk belscript is immers voorzien van een of meerdere talen. Voor sommige taken kan dit heel handig zijn. Het veranderen van de taal zal er dan voor zorgen dat alle velden (die vertaald werden) zullen aangepast worden. Een belscript maken of aanpassen Een belscript kan uiteraard pas uitgevoerd worden als het bestaat. Zo’n belscript maken is het werk van de supervisor. Hij kan CTScript gebruiken om dit belscript te maken. Hiervoor zijn meer mogelijkheden beschikbaar dan voor een operator. Deze mogelijkheden worden besproken in wat volgt. Om te beginnen moet er een nieuw project aangemaakt worden. Elk project bestaat uit schermen en ieder scherm kan dan weer bestaan uit enkele componenten. Deze boomstructuur wordt getoond in de “Solution Explorer”. Om een nieuw scherm te maken kan men starten van een leeg scherm of beginnen met een webpagina. Als er gekozen wordt voor een webpagina wordt deze eerst helemaal ingeladen. Op een scherm kunnen componenten gesleept worden vanuit de toolbox. De componenten in de toolbox zijn meestal eenvoudige controls zoals een knop of een tekstveld. Ze zijn perfect vergelijkbaar met die van webformulieren want eigenlijk zijn het dezelfde componenten (verder meer hierover). Een component kan ook iets uitgebreider zijn. Zo bestaat een “check box group” uit enkele check boxes die automatisch aan elkaar gelinkt zijn als 1 variabele. Andere componenten hebben dan weer een aangepaste werking. Zo is een numeriek veld eigenlijk een tekstveld dat enkel numerieke waarden aanvaardt. Iedere component heeft zijn eigen specifieke parameters en/of eigenschappen. De eigenschappen8 kunnen aangepast worden in het “Properties”-paneel. Dit paneel staat standaard aan de rechter zijde van het scherm. Hier kunnen zaken aangepast worden zoals de inhoud van een knop of de naam van een variabele. De actie die uitgevoerd wordt bij het klikken van een knop kan op dezelfde wijze ingesteld worden. Naast eigenschappen heeft elk scherm ook enkele taalafhankelijke variabelen. Om deze aan te passen is er de “Multi-Language Setup” voorzien. Standaard wordt dit paneel onderaan het scherm getoond. Hier kunnen alle variabele teksten ingesteld worden per taal. Iedere kolom staat voor een taal. Analoog aan deze taalinstellingen kunnen ook variabelen beheerd worden in het paneel “Variable List”. Dit paneel wordt ook onderaan weergegeven. Deze variabelen kunnen dan in andere schermen gebruikt worden om specifieke output te genereren of gerichte vragen te kunnen stellen. Tussen al deze panelen staat het belangrijkste deel. De eigenlijke weergave van de geopende schermen. Het is mogelijk meerdere schermen te openen. Deze worden dan getoond als tabbladen. Onderaan dit editeervenster staan drie tabs 8 ook
properties genoemd
HOOFDSTUK 1. SITUATIESCHETS
6
nl. “Edit”, “Source” en “View”. In de tab “Edit” kunnen de componenten op een grafische manier herschikt worden. Door een component hier aan te klikken kunnen ook de nodige properties ingesteld worden. In de tweede tab, “Source”, kan we de HTML-code van het scherm bekeken en aangepast worden. De laatste tab, “View”, geeft dezelfde uitvoer als de tab “Edit” maar dan zonder aanpassingsmogelijkheden. Zoals daarnet vermeld werd, kunt u in de “Solution Explorer” het hele project en zijn boomstructuur zien. Als u een scherm wil toevoegen aan een project kan dit hier ook gebeuren. U kan er ook de volgorde van de schermen aanpassen. Er werden ook functies zoals plakken, kopi¨eren en knippen voorzien om met de schermen te werken. Een supervisor kan een project starten zodat hij het hele belscript kan testen. Bij het starten van een scherm krijgt hij hetzelfde te zien als een operator die een belscript gestart heeft. Op deze manier is het makkelijk een project te testen op fouten. Achter de schermen Omdat binnenshuis niet genoeg tijd kon ge¨ınvesteerd worden om dit project uit te werken, werd een masterproefvoorstel gedaan voor dit project. Er boodt zich helaas geen enkele student aan om dit project in handen te nemen. Daarom werd besloten om het project te outsourcen naar Roemeni¨e. Uiteindelijk werd CTScript half februari opgeleverd. Tot nu toe werden alle huidige applicaties van MI4C ontwikkeld in C++. Voor CTScript wou men het immers over een andere boeg gooien. Daarom werd CTScript ontwikkeld in C#. Hierbij werd gekozen voor het .NET 2.0 framework. Daarnet is de structuur van een project even kort besproken. Zo zagen we dat een project schermen bevat en elk scherm enkele componenten bevat. Eigenlijk komt elke component overeen met specifieke HTML-code. Als voorbeeld ziet u hieronder de gegenereerde HTML-code van een eenvoudige knop.
Elk scherm komt m.a.w. overeen met een HTML-pagina. Aan het begin van deze standaardpagina worden reeds enkele javascript- en CSS-bestanden ingeladen. Deze zorgen voor de specifieke opmaak en acties van de verschillende componenten. De supervisor kan hier eventueel ook nieuwe bestanden aan toevoegen. Het belscript zal deze dan ook laden. Dit zorgt er voor dat er specifieke interactie met de operator kan ge¨ımplementeerd worden. Mits de juiste kennis van zaken kan er heel wat aangepast worden. Om webpagina’s weer te geven werd er gebruik gemaakt van een web engine nl. die van Internet Explorer. De engine van IE79 wordt automatisch gebruikt om HTML weer te geven. Hierdoor is het dus ook belangrijk rekening te houden met verschillende versies van Internet Explorer. 9 De
IE7 browser engine is eigen aan .NET framework 2.0
HOOFDSTUK 1. SITUATIESCHETS
7
Omdat javascript alleen niet volstaat om bepaalde zaken uit te voeren moet er ook interactie voorzien worden tussen javascript van de getoonde pagina en de programmacode van CTScript zelf. Op deze manier is het mogelijk om een event op te vangen in javascript en erna ook in programmacode de nodige verwerking toe te laten. In de andere richting is het ook mogelijk om bv. eerst nieuwe HTML te genereren en deze erna te verwerken met javascript. Analoog hieraan is de drag-and-drop van componenten ge¨ımplementeerd. Overzicht Een belscript kan gebruikt worden om telefoongesprekken te leiden. Deze belscripts kunnen gemaakt ´en uitgevoerd worden in CTScript. Om een belscript te maken heeft een supervisor enkele mogelijkheden zoals aanpassen van parameters, instellen van meerdere talen enz. Mits wat kennis van HTML, javascript en CSS kan de supervisor nog meer specifieke aanpassingen doen.
1.2
Doel van de masterproef
In deze paragraaf krijgt u een overzicht wat de masterproef inhoudt. Nu we een duidelijk beeld hebben op wat er al bestaat en beschikbaar is, zullen we verder ingaan op de uitbreidingen voorzien tijdens deze masterproef. Zoals reeds eerder vermeld zijn de meeste componenten vrij eenvoudig opgebouwd. Het is ook mogelijk om samengestelde componenten te voorzien binnen CTScript. De hoofdbedoeling van deze masterproef is eigenlijk het maken van enkele samengestelde componenten voor specifieke taken. De eerste gewenste component is er ´e´en om de agenda van vertegenwoordigers te plannen. De tweede component zal helpen bij de verkoop van producten. Naast de ontwikkeling van deze componenten is er ook rapportering voorzien. Als laatste maar niet minder belangrijk - onderdeel van deze masterproef werden hier en daar bugs opgelost in CTScript. De eerste component die ontwikkeld werd, is die voor het plannen van de agenda van vertegenwoordigers. Een call center krijgt de opdracht van hun klant om de agenda van enkele vertegenwoordigers in te vullen. Hiervoor zal het call center naar mogelijke klanten telefoneren en een afspraak proberen maken. Bij het kiezen van een vertegenwoordiger moet gestreefd worden naar zo’n effici¨ent mogelijke verdeling van de afspraken. Het is mogelijk om de nieuwe agendaitems op een makkelijke manier tot bij de vertegenwoordigers zelf te krijgen. Automatische synchronisatie was zeer gewenst en is mogelijk gemaakt. Binnen CTScript krijgt een operator een agenda voorgesteld waarin dan een afspraak kan gemaakt worden. Het is mogelijk dat de voorgestelde agenda toch geen goede mogelijkheid biedt. Dan is het mogelijk voor de operator om een andere agenda te (laten) selecteren. De tweede component die ontwikkeld is, zal gebruikt worden voor het verkopen van producten. Het call center krijgt de opdracht een reeks producten aan de man te brengen. Het kan hierbij gaan over de effectieve verkoop van producten of het wekken van interesse in producten. De eigenlijke verkoop is hierbij het belangrijkste. Om de operator toe te laten effici¨ent te werken, is het nodig de productgegevens op een overzichtelijke manier weer te geven. Dankzij enkele gerichte vragen kan het eventueel mogelijk zijn om bepaalde producten
HOOFDSTUK 1. SITUATIESCHETS
8
te selecteren of te elimineren. Dit kan de verkoop van deze producten sterk bevorderen. Hierbij denken we bijvoorbeeld aan verschillende doelgroepen met elk hun specifieke interesses. Naast het verkopen van producten zal deze component ook gebruikt worden om verkopen te beheren. Zo kan het nuttig zijn om na het verkopen deze nog te kunnen wijzigen. Hiervoor is het dus ook mogelijk om aan de hand van bepaalde gegevens de verkoopsgegevens terug op te vragen. Uit een aantal gesprekken kan een heleboel gegevens verzameld worden. Deze gegevens zeggen misschien iets maar helemaal niet alles. Daarom is het zeer nuttig om van deze gegevens gestructureerde rapporten te maken. Deze rapporten zullen de ruwe gegevens destilleren naar bruikbare, nuttige gegevens. Aangezien de rapportering nog niet is voorzien binnen CTScript valt dit ook onder de taken van deze masterproef. Naar analogie met de andere applicaties is voor de rapportering ook “CrystalReports” 10 gebruikt. Omdat CTScript een nieuw product is, had het nog last van enkele kinderziektes. Tijdens de verdere ontwikkeling was het hier en daar nodig enkele bugs te verhelpen. Dit gaf uiteraard een grote meerwaarde aan deze masterproef. Zo werd een goed inzicht verkregen in de structuur en opbouw van de applicatie. Hierdoor werd het soms makkelijker om verder te bouwen op de oorspronkelijke architectuur.
10 http://www.crystalreports.nl
Hoofdstuk 2
Component agendaplanning 2.1
Inleiding
In dit hoofdstuk vindt u alle concrete informatie over de component “agendaplanning”. In grote lijnen zal de uitwerking van de hele component in chronologische volgorde besproken worden. Zo komen de vereisten en het onderzoek als eerste aan bod. Daarna wordt de uitwerking van de component uit de doeken gedaan. Tijdens de uitwerking zijn er enkele problemen opgedoken. Deze worden besproken in het onderdeel “Hindernissen”. Hierna wordt de hele functionaliteit van de component aan u voorgesteld. Helemaal op het einde vindt u nog het besluit.
2.2
Wat vooraf ging
2.2.1
Concrete vereisten
Het eerste wat vorm krijgt bij een project zijn meestal de vereisten. Deze vereisten zitten meestal vervat in een globaal beeld van het eindproduct. In dit deel worden de verschillende vereisten, ´e´en voor ´e´en, grondiger geschetst. De methode hoe elke vereiste opgelost werd komt later aan bod in hoofdstuk 2.3.2. Ophalen externe agenda’s Het was van bij het begin de bedoeling dat de agenda’s van verschillende vertegenwoordigers opgehaald moesten worden. Dit was noodzakelijk om achteraf met deze gegevens nieuwe afspraken al dan niet manueel te kunnen vastleggen. Hiervoor moest dus gezocht worden naar een agendasysteem waarbij het mogelijk is agenda’s op te halen en bij te werken. Binnen MI4C had men al enige ervaring met Google Calendar. Men neigde dus ook om met deze agenda aan de slag te gaan binnen CTScript. Bepalen nieuwe afspraken De eigenlijke bedoeling van deze component is het plannen van nieuwe afspraken. Deze nieuwe afspraken moeten gemaakt worden tussen de bestaande afspraken van een agenda. Het kan hierbij gaan om een handvol agenda’s of tientallen 9
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
10
agenda’s. Als er tientallen agenda’s moeten bekeken en vergeleken worden is dit zeer arbeidsintensief. Het is dan ook de bedoeling dat de CTScript deze vergelijkingen voor zijn rekening neemt. Eenmaal alle agenda’s opgehaald zijn, moet het mogelijk zijn nieuwe afspraken te berekenen. Hierbij moet rekening gehouden worden met de huidige afspraken en enkele andere factoren. Hierbij denken we aan de nodige tijd voor de afspraak zelf en de nodige tijd om naar de afspraak te rijden. Naast deze factoren is het ook belangrijk dat de planning zo efficint mogelijk gebeurd. Hiervoor moet dan weer rekening gehouden worden met factoren als de afstand tussen twee afspraken. Op die manier kan ook de aanrijtijd geminimaliseerd worden voor elke nieuwe afspraak. Een laatste factor die belangrijk kan zijn bij het bepalen van nieuwe afspraken is de overige tijd tussen twee afspraken. Als er meer ruimtes ontstaan tussen de afspraken wordt het steeds moeilijker om nog afspraken tussen te voegen. Kortom, voorzichtigheid is geboden bij het voorstellen van nieuwe afspraken. Navigeren tussen voorgestelde afspraken Eens de berekeningen uitgevoerd zijn kan een voorstel aangeboden worden. De kans bestaat dat de klant zich op dat moment niet kan vrijmaken. Hiervoor moet het mogelijk zijn om te navigeren door de verschillende voorstellen. Nieuwe afspraken manueel bepalen Als de voorgestelde afspraken niet voldoen aan de eisen van de klant kan het handig zijn om hiervan af te wijken. In dit geval lijkt het ook handig om manueel een afspraak te kunnen tekenen op de kalender. Deze manueel toegevoegde afspraken kunnen op dezelfde manier opgeslagen worden. Gegevens uit belscript bewaren in nieuwe afspraken Een afspraak bestaat niet enkel uit een begin- en eindtijd. Zo bevat een afspraak ook liefst een titel, een locatie en eventueel een omschrijving. Deze gegevens zijn niet altijd dezelfde voor elke afspraak. Het moet dus mogelijk zijn om gegevens uit het belscript op te halen en deze te verwerken in de nieuwe afspraken. Werkuren instellen Een dag in een agenda of op een kalender loopt meestal van 00h00 tot 23h59. Dat strookt niet echt met de re¨ele werkuren van vertegenwoordigers. Het moet dan ook mogelijk zijn om de weergegeven kalender aan te passen aan de werkuren van werknemers. Periode voor planning instellen De periode waarin agenda’s kunnen gepland worden moet afgebakend kunnen worden. Daarom moet het mogelijk zijn met enkele eenvoudige instellingen voldoende controle te krijgen over de dagen waarin een call agent afspraken kan inplannen voor vertegenwoordigers.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
11
Intu¨ıtieve gui Tijdens een telefoongesprek moet elke invoer van gegevens of opzoeking effici¨ent kunnen gebeuren. Het is dus belangrijk een intu¨ıtieve interface te voorzien om alle nodige handelingen te kunnen doen. Hierbij denken we aan een overzichtelijk geheel met niet te veel onnodige knopjes en/of velden. Externe afhankelijkheden Bij het gebruik en instellen van deze component is het belangrijk dat er zo min mogelijk externe bronnen aangesproken moeten worden. Waarschijnlijk zal toch een of andere bron aangesproken moeten worden, hier kunnen we niet echt onderuit. Toch moet er gestreefd worden naar een zo laag mogelijke afhankelijkheid met externe bronnen. Veiligheid gegevens Vandaag de dag is het zeer belangrijk om even stil te staan bij de veiligheid van het hele proces. Deze component mag bijvoorbeeld geen login-gegevens blootstellen.
2.2.2
Onderzoek
Vooraleer met de eigenlijke uitwerking van de hele component kon begonnen worden was het noodzakelijk enkele zaken op te zoeken. Het was van bij het begin duidelijk dat er twee zaken vrij belangrijk zouden worden tijdens de onderzoeksfase. Enerzijds bleken de externe agenda’s heel belangrijk voor deze masterproef. Er werden enkele mogelijkheden onderzocht om te bepalen welke de beste mogelijkheden biedt voor de component agendaplanning. Dit deel van het onderzoek vindt u na deze inleiding. Anderzijds bleek ook de locatiebepaling van adressen een belangrijk punt om afspraken effici¨ent te kunnen plannen. Dit kan op meerdere manieren. Verder in dit hoofdstuk leest u hierover meer. Externe agenda’s Om de werking van deze component te ondersteunen moest de externe agenda aan enkele vereisten voldoen. Hieronder volgt een opsomming van deze vereisten: • De oplossing is bij voorkeur zo goedkoop mogelijk of zelfs gratis. • Data (zoals afspraken) wordt liefst online bijgehouden. • Data moet bereikbaar zijn vanuit CTScript. • Er moeten nieuwe afspraken kunnen gemaakt worden vanuit CTScript. • Er moet een makkelijke manier bestaan om meerdere accounts (voor meerdere vertegenwoordiges) te beheren. • Bij voorkeur wordt er reeds synchronisatie voorzien naar externe apparaten.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
12
Bij het begin van deze masterproef hadden de mensen van MI4C reeds de voorkeur voor Google Calendar. Men had deze voorkeur omdat er al gewerkt werd met Google Calendar en omdat men het vermoeden had dat Google een vrij goede API beschikbaar zou hebben. Concrete informatie was hierover immers nog niet bekend. Aan het begin van dit onderzoek was dus al duidelijk dat met enkele zaken strikt rekening moest gehouden worden. Enerzijds de algemene vereisten en anderzijds de voorkennis van MI4C. De denkpiste in de richting van Google Calendar was dan wel al geopend, toch werd hiermee initi¨eel geen rekening gehouden bij het onderzoek. Er werd hier bewust voor gekozen omdat goede mogelijkheden niet zomaar uitgesloten mochten worden. Aan het begin van deze onderzoeksfase werd dus begonnen met een schone lei. Er kwamen al snel enkele mogelijke oplossingen naar voor. Hieronder vindt u staan ze opgesomd: SyncMyCal De agenda werkt enkel samen met Outlook. Er is blijkbaar geen API voorzien. Dit maakt het heel erg moeilijk om vanuit CTScript de gegevens op te halen en te bewerken. Deze oplossing is betalend. Er is daarentegen wel een gratis “Lite” versie met beperkte functionaliteit. 1 KeenandShare Deze mogelijke oplossing voorziet wel in online opslag van document, afbeeldingen en agenda’s. Er zijn meerdere toegangsmogelijkheden. Zo is het niet noodzakelijk dat iemand ingelogd is om een agenda te bekijken. Ook hier is geen API voorzien om aan de slag te kunnen. Gegevens extern opvragen en/of updaten is dus helaas niet mogelijk. Deze dienst biedt vooral oplossingen voor het delen van diverse bestanden. 2 DidItBetter - Add 2 Exchange Deze oplossing heeft tot hier toe de meest uitgebreide functionaliteit wat betreft agenda’s, contacten etc. Er wordt ook voorzien in automatische synchronisatie met externe toestellen zoals smartphones, iPads e.d. De mogelijkheid om een eigen integratie te maken zou wel mogelijk zijn. Helaas is deze oplossing ook betalend, de basispakket kost 195 dollar per account. 3 Plaxo Dit is eigenlijk een laag bovenop Google Calendar, zo blijkt. Zo is er standaard wel beheer van contacten mogelijk maar enkel via Google is er ook een kalender mogelijk. Men voorziet wel in synchronisatie maar dit verloopt ook via Google Sync. 4 Google Calendar Uiteindelijk komen we dan bij Google Calendar terecht. Deze biedt zowel betaalde als gratis diensten. De gratis diensten zijn vrij uitgebreid waardoor het niet nodig lijkt om voor de betalende oplossing te moeten kiezen. Er is ook een uitgebreide API voorzien. De mogelijkheden van Google Calendar worden verder in deze tekst besproken. 5 Yahoo! Calendar Yahoo! biedt ook een goed alternatief aan voor de Google Calendar. Qua functionaliteit zijn beide heel vergelijkbaar. Er is helaas 1 http://www.syncmycal.com/ 2 http://www.keepandshare.com/ 3 http://www.diditbetter.com/ 4 http://www.plaxo.com/ 5 http://www.google.com/calendar
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
13
niet direct een API beschikbaar om vanuit C#.Net de kalenders van Yahoo! aan te spreken. Er kan wel gewerkt worden met AJAX-calls. Yahoo! voorziet ook in diverse synchronisatiemogelijkheden.6 Zoals u hierboven wellicht heeft gemerkt biedt Google zowat de beste oplossing voor deze component. Het feit dat Google-oplossingen meer en meer gebruikt worden binnen bedrijven versterkte de keuze voor Google Calendar. De beslissing om CTScript te gaan gebruiken hoeft op die manier niet noodzakelijk veel gevolgen te hebben voor de bedrijven. In wat nu volgt vindt u meer concrete informatie over de mogelijkheden van Google Calendar en diens API. In hoofdstuk 2.3.3 wordt dieper ingegaan op de concrete uitwerking van Google Calendar in de component agendaplanning. Een heel groot voordeel aan de Google Calendar is uiteraard dat het gratis te gebruiken is. Hierbij werden zelfs geen restricties opgelegd wat betreft het aantal aanvragen per dag. Iedereen die een Google Calendar wil gaan gebruiken kan op enkele minuten tijd een nieuwe account aanmaken (indien dit nog nodig is) en onmiddellijk aan de slag gaan met de kalendermogelijkheden. Een gebruiker kan ook meerdere kalenders binnen ´e´en account aanmaken. Er zijn ook diverse mogelijkheden om toegang tot ´e´en van je kalenders te regelen. Zo kunnen kalenders van andere personen makkelijk weergegeven en/of beheerd worden. Deze instellingen kunnen door de gebruiker zelf makkelijk aangepast worden. Op die manier verliest de eigenaar van een kalender nooit het gevoel van veiligheid. Hij heeft tenslotte nog steeds de touwtjes in handen. We kunnen andere gebruikers ook kennis geven van een enkele afspraak in de agenda door hen hierop “uit te nodigen”. Voor deze ene afspraak kan ook gekozen worden welke rechten de andere gebruikers krijgen. Zo kan de andere gebruiker de afspraak eventueel aanpassen en/of andere mensen uitnodigen. Er bestaat achter de schermen een systeem van “Access Control Entries” die gebundeld worden in een “Access Control List”. Deze toegangscontrole kan ook via de API beheerd worden. Al is dit niet van toepassing op deze component. Binnen deze structuur bestaan er enkele rechten: None De gebruiker heeft geen enkel recht over de kalender. Op deze manier kan men iemand uit een groep bijvoorbeeld expliciet uitsluiten. Freebusy De gebruiker kan zien of de persoon in kwestie al dan niet vrij is op een bepaald moment. Hij kan geen verdere informatie verkrijgen over eventuele afspraken. Read De gebruiker kan de gegevens van afspraken zien. Hij kan geen aanpassingen doen. Owner De gebruiker wordt mede-eigenaar van een kalender. Hij krijgt daarbij de rechten om afspraken aan te maken, aan te passen of te verwijderen. Het enige wat hij niet kan is de rechten van deze kalender aanpassen. Dit blijft een exclusief recht van de oorspronkelijke eigenaar. Naast dit alles biedt Google ook een vrij uitgebreide API om agenda’s vanuit diverse applicaties beheerbaar te maken. De nieuwste versie (2.0) van de API is beschikbaar voor .Net, Java en Python. De oudere versie (1.0) is daarnaast 6 http://calendar.yahoo.com
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
14
ook nog beschikbaar voor PHP en Javascript. We kunnen dankzij de API voor .Net (versie 2.0) volgende zaken met een agenda doen: • Kalenders ophalen van ´e´en account. • Beheren van kalenders: aanmaken, aanpassen en verwijderen. • Afspraken ophalen • Afspraken beheren: aanmaken, aanpassen en verwijderen. • Verschillende types afspraken maken: eenmalig of herhaalde events. • Toegangsrechten van kalenders beheren: opvragen, aanmaken nieuwe rechten, aanpassen rechten en verwijderen van bepaalde rechten. Om deze API te leren kennen stelt Google enkele voorbeeldapplicaties ter beschikking. Bij het downloaden en installeren van de “Google Data API SDK” krijg je deze er bij. Het leek me dan ook interessant om hiermee aan de slag te gaan. Op die manier kon ik vrij makkelijk achterhalen of alle noodzakelijke handelingen konden uitgevoerd worden. Op die manier kon snel een proof of concept bekomen worden waarin alle deelaspecten konden getest worden. Zo kan de applicaties alle kalenders van ´e´en account ophalen en weergeven. Het is ook mogelijk nieuwe agendapunten toe te voegen binnen de verschillende kalenders. Daarnaast is ook alles voorzien om de Access Control Lists aan te passen. Google voorziet ook in synchronisatie naar diverse apparaten of externe agenda’s. Er zijn mogelijkheden voor iPhone (iOS 3.0 of hoger), Blackberry, Nokia, Windows Mobile en Android-toestellen. Voor synchronisatie met Outlook is er een kleine applicatie beschikbaar. Deze applicatie kreeg de naam “Google Calendar Sync” en is volledig gratis te downloaden. Op die manier is het mogelijk om (bijna) onmiddellijk op de hoogte te zijn van wijzigingen in een kalender. Dit was een vereiste die van bij het begin werd opgelegd. Het is van groot belang dat een vertegenwoordiger zijn eigen agenda kan blijven controleren en dat hij hierop een goed zicht blijft behouden. Er werden enkele tests gedaan om de synchronisatie te testen in de praktijk. Zo werd getest voor Outlook, iCal, Android en iOS. Een kalender publiceren is ook makkelijk voor mekaar te krijgen dankzij Google. Zo voorzien ze in enkele mogelijkheden om een kalender op een ge¨eikte manier online beschikbaar te maken. Dit heeft binnen deze masterproef niet direct een meerwaarde, al werd dit initi¨eel wel gedacht. Op het eerste zicht leek het mogelijk om de HTML-code van Google te gebruiken binnen CTScript. Het werd helaas snel duidelijk dat de mogelijkheden hiervan te beperkt waren. Locatie- en/of afstandbepaling Een tweede onderdeel dat de nodige aandacht verdiende bij het onderzoek was locatiebepaling van afspraken. Op die manier zou de component beter in staat moeten zijn op een intelligente manier nieuwe afspraken voor de stellen. Aan de hand van de locaties van verschillende aanwezige afspraken kan bepaald worden voor welke vertegenwoordiger een nieuwe afspraak het best bereikbaar is. Voor deze dienst werden ook enkele vereisten opgelegd. Deze worden hierna beschreven.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
15
• Bij voorkeur is deze dienst zo goedkoop mogelijk of zelfs gratis. • Het kan gaan om een online of offline dienst. • Data moet bereikbaar zijn vanuit CTScript. • Er moet een groot aantal berekening kunnen gebeuren. • De gegevens moeten up-to-date zijn. • Locatiebepaling moet accuraat zijn. Binnen MI4C was nog geen kennis wat betreft locatiebepaling. Het werk in dit onderzoek zou dus tevens ook de eerste kennis binnen MI4C moeten verzorgen. Een ruime blik op de zaken was dus handig meegenomen. Dankzij het web werden al snel enkele mogelijkheden gevonden. Deze worden hieronder kort opgesomd: Yahoo! Placefinder biedt de mogelijkheid om aan geocoding 7 te doen in beide richtingen. Deze diensten worden vrij aangeboden in de vorm van een webservice. Er is een limiet van 50.000 requests per dag per applicatieid. 8 Google Maps API biedt ongeveer vergelijkbare diensten als Yahoo! Placefinder. De vereisten zijn immers strikter. Zo kan je gratis maar 2.500 requests per dag uitvoeren. Indien een premier account aangekocht wordt kan dit aantal opgetrokken worden naar 100.000. We spreken hier dan al snel over een kost van enkele duizenden euro ($ 10.000 per jaar). Google vereist ook dat deze gegevens enkel gebruikt worden in combinatie met hun kaartweergaves. Deze dienst is beschikbaar in de vorm van een webservice (keuze tussen JSON en XML als output). 9 Google Directions API biedt uitgebreidere mogelijkheden dan de Maps API. Met behulp van deze API kunnen we bijvoorbeeld ook routes tussen twee adressen bekomen. Deze dienst is naar analogie met het voorgaande ook beschikbaar als webservice met eveneens keuze tussen JSON en XML als output. De restricties van Google Maps API gelden ook voor de Google Directions API. 10 Bing Maps biedt een vrij compleet pakket. Zo bieden zij naast een AJAXcontrol, een silverlight-control en spatial data services ook enkele webservices aan. Er zijn zowel SOAP- als REST-services. Onder de SOAP-services vinden we onder andere een geocoding service en een route service. Met de gratis diensten kunnen we 125.000 aanvragen verwerken per jaar. Dit kan op termijn niet voldoende blijken. Er is ook een betalend alternatief dat meer aanvragen toestaat. 11 7 Het
proces om co¨ ordinaten te bekomen a.d.h.v. een adres of in de andere richting. http://developer.yahoo.com/geo/placefinder/ 9 http://code.google.com/intl/nl-NL/apis/maps/documentation/geocoding/ 10 http://code.google.com/intl/nl-NL/apis/maps/documentation/directions/ 11 http://msdn.microsoft.com/en-us/library/cc980922.aspx 8
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
16
MapPoint van Microsoft is een software-pakket dat ook aan routebepaling kan doen. Helaas waren er problemen met de MSDN-pagina’s die meer informatie bevatten. Daardoor kon er geen verdere concrete gegevens verkregen worden i.v.m. de beschikbare SDK. Er zijn twee belangrijke mogelijkheden om het algoritme meer informatie te geven. Ten eerste is het goed mogelijk om de co¨ordinaten van een adres te bekomen en die dan te vergelijken. Anderzijds bestaan er mogelijkheden om routes tussen twee adressen te berekenen. Bij beide methodes moeten we de bedenking maken dat de afstand op zich niet de meest nuttige informatie biedt. De tijd nodig om van het ene adres naar het andere te rijden is nuttiger voor het algoritme. Om een afspraak in te plannen moeten we immers een begin- en einduur kunnen bepalen. Laten we iets dieper ingaan op de afstandbepaling a.d.h.v. co¨ordinaten. De oplossing van Yahoo!, nl. Placefinder, lijkt de beste oplossing omwille van de beperkte restricties. Om de co¨ordinaten te bepalen kunnen we dus gebruik maken van hun REST webservice. Het adres in kwestie wordt meegegeven in de URL alsook de aangemaakte application-id. De output van deze webservice is XML. De lengte- en breedtegraad zijn vrij makkelijk uit de XML te halen. Nu we twee keer een paar co¨ordinaten hebben willen we de afstand hiertussen bepalen. De afstand berekenen tussen twee geografische punten kan a.d.h.v. de Haversine-formules. Deze wiskundige formule is op zich niet zo ingewikkeld en kan vrij snel ge¨ımplementeerd worden. Deze berekende afstand omzetten in een aanrijtijd blijkt echter niet makkelijk. De afstand in vogelvlucht kan immers nogal veel afwijken van de afstand over de weg. Er werd gezocht naar een functie die de afstand kan omzetten in een benaderende reistijd. Er werd al snel een functie gevonden maar deze voldeed niet aan de eisen. Hier en daar werden grote afwijkingen gevonden in de testdata. Het ander alternatief is werken met routegegevens. Uit de gegevens van zo’n route kunnen we dan de effectieve reistijden halen. Dit is moeilijker te bekomen maar biedt correcte gegevens. De foutmarge is op deze manier veel kleiner. De beste mogelijkheid bleek de Google Directions API te zijn. Hiermee kan, in beperkte mate, gratis gewerkt worden. De grootste beperking is het aantal requests dat per dag kan gedaan worden. Zo kan je per dag maar 2.500 gratis aanvragen doen. Dit lijkt misschien op het eerste zicht vrij veel maar voor een applicatie die dagelijks vele berekeningen moet maken kan dit toch een beperking blijken. Er werd hier gekozen voor de XML-output van Google Directions. Dit naar analogie van Yahoo! Placefinder. Resultaat onderzoek Het eerste deel van het onderzoek ging over externe agenda’s. We vonden al snel dat Google Calendar een zeer complete oplossing biedt voor onze component agendaplanning. Zo biedt Google Calendar automatische synchronisatie. Google biedt ook een mooie en complete API aan. Met deze API kunnen de nodige gegevens opgehaald worden en aangepast worden. Het is ook mogelijk om een goede structuur te maken binnen Google Calendar waardoor veiligheid en beheer voor de externe klant behouden blijft. Het tweede deel ging na wat de mogelijkheden zijn om vanuit de component locaties en/of routes te bepalen. Er zijn vrij veel diensten beschikbaar maar
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
17
meestal gelden hiervoor wat restricties. Zo vonden we ook dat Yahoo! Placefinder het best toegankelijk is via een webservice. Hiermee kan aan geocoding gedaan worden. Google Directions biedt ook een snelle en betrouwbare webservice waarmee routes kunenn berekent worden. Bij Google Directions kunnen maar een beperkt aantal aanvragen per dag gedaan worden tenzij voor de dienst betaald wordt.
2.3 2.3.1
Uitwerking Ontwerp
Aan het begin van deze masterproef werden voor beide componenten use cases opgesteld om een goed beeld te krijgen van de verwachtingen voor beide componenten. U kan deze use cases terug vinden in de bijlage achteraan deze scriptie. Er wordt hierop verder niet ingegaan omdat dit een eerste idee was. Het doel en de vereisten zijn dermate veranderd dat deze niet meer volledig relevant zijn. Hoe de component ge¨evolueerd is kan u wel merken indien u de use cases vergelijkt met de het resultaat dat beschreven staat in deze scriptie. Voor we dieper ingaan op het ontwerp van de agendacomponent zelf, bekijken we eerst even het algemene ontwerp voor de componenten binnen CTScript. Hierna komt dan het ontwerp aan bod gerelateerd met de agendacomponent. Alle klassen die hierna besproken zullen worden bevinden zich allen in het deelproject “CTScript.ControlsLib”. De klassen gerelateerd aan de agendacomponent zitten in de map “CTXCalendarClasses” en “CTXHeuristics”. Deze mappen bevinden zich in de map “CTXMLsClasses”12 . Controls CTScript Voor er iets concreet kon uitgewerkt worden was het noodzakelijk om het ontwerp van CTScript te doorgronden. Aangezien het grootste doel van deze masterproef bestaat uit het ontwikkelen van enkele nieuwe componenten is het deel van de klassen dat de verschillende componenten beschrijft heel belangrijk. Daarom werd een eerste klassendiagram opgesteld (fig. 2.1). Een component eigenlijk uit twee delen. Het eerste deel erft over van CTControl. Deze klasse erft dan weer over van ICTControl. Er wordt ´e´en methode omschreven nl. “GetToolBoxItem()”. Deze methode geeft een object terug van de klasse CTDescription. Dit object bevat enkele zaken die belangrijk zijn voor de weergave van de component binnen CTScript. Bijvoorbeeld de tekst die moet verschijnen in de toolbox en het icoontje hierbij. Verder hebben objecten van deze CTControl-klassen geen andere werking. Anderzijds bestaat elke component ook uit een object dat overerft van CTXBase. Algemeen omschreven bevatten deze klassen de eigenlijk interactie met de interface. Zo beschrijven ze o.a. de HTML-code die weergegeven moet worden voor de component in kwestie. Er is een link tussen CTXBase en CTControl door de methode “GetControlType()”. Deze methode geeft een “Type” terug van de CTControl-subklassen overeenkomstig met de CTXBasesubklasse. 12 De map “CTXMLsClasses” bevat alle effectieve componenten alsook klassen als CTXScreen en CTXProject.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
18
Figuur 2.1: Ontwerp - Klassendiagram Controls oorspronkelijk
Om de nieuwe componenten te integreren leek het interessant om een beperkte uitbreiding te doen op dit schema (fig. 2.2). Zo werd een klasse tussen CTXBase en de nieuwe componenten toegevoegd. De klasse kreeg de naam CTXComposed. Ze bevat vooral methodes voor het inlezen van een resourcebestand en verwerken van bijgehouden velden in de HTML-code. De reden om deze zaken te voorzien wordt verder uitgewerkt in hoofdstuk 2.4.2
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
19
Figuur 2.2: Ontwerp - Klassendiagram Uitgebreide Controls
Agendacomponent We zullen nu het ontwerp dat specifiek is voor de agendacomponent van iets nader bekijken. In figuur 2.3 ziet u het hele ontwerp. Aan de linkers zijde staan de basisklasses die we daarnet al even zagen alsook de volledige klasse CTXCalendar. Op die manier is het volgende schema dus gekoppeld aan voorgaande schema’s. De figuur zegt op zich niet zo veel. Daarom vindt u hieronder een korte uitleg bij elke klasse. Hiermee wordt waarschijnlijk het ´e´en en ander duidelijk. CTXBase is de basisklasse voor elke component. Deze omvat de standaard werking van een component. CTXComposed is een laag die extra mogelijkheden toevoegt. Elke component die overerft van deze klasse is een uitgebreide component met meer complexe interactiemogelijkheden. CTXCalendar is de basis voor de hele agendacomponent. Binnen deze klasse komen alle aanvragen van de rest van de applicatie toe. Ze worden dan ook vaak doorgestuurd naar diverse klassen. RSAEncryption is een statische klasse. Het is een vrij kleine klasse die instaat voor het versleuten van bijvoorbeeld wachtwoorden. Deze klasse gebruikt
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
20
Figuur 2.3: Ontwerp - Klassendiagram agendacomponent
een vast sleutelpaar waardoor gegevens kunnen overgedragen worden naar een andere instantie van CTScript. Ook decrypteren is mogelijk. CTXGoogleAccountController is ook een statische klasse. Ze maakt de verbinding tussen de agendacomponent en de services van Google. Zo worden van hieruit alle kalendar opgehaald en bijgehouden in verschillende instanties van CTXDiary. Instanties van CTXCalendar kunnen aan deze klasse ook de huidige weergave van de kalender vragen. Deze weergave hangt bijvoorbeeld af van de getoonde dagen en het interval waarbinnen men kan plannen. CTXDiary is een klasse die overeenstemt met een kalender van Google. Daarenboven heeft deze klasse ook logica aan boord om nieuwe afspraken voor te stellen en bij te houden. Elke instantie van CTXDiary heeft een (beste) voorstel klaar. Door alle instanties te sorteren kunnen we h´et beste voorstel bekomen. Hiervoor is een eigen “CompareTo”-methode uitgewerkt. Deze methode kan aan de hand van enkele Heuristieken(zie ook 2.3.4) de
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
21
verschillende CTXDiary-instanties vergelijken13 . CTXAppointment simuleert eigenlijk instanties van EvenEnty (Google Data API klasse). Deze klasse kan ook ingestelde variabelen parsen naar de eigenlijke waarde a.d.h.v. casedata. Casedata omvat alle variabelen en hun antwoorden uit het belscript. De gekozen CTXAppointment kan opgeslaan worden. Gegevens worden dan pas omgezet naar hun effectieve waarde. Op die manier kunnen we variabelen combineren met delen tekst. CTXLocation stelt een geografisch punt op de wereldbol voor. Daarom bevat deze klasse een lengte- en een breedtegraad. CTXLocator is een statische klasse. Ze staat in voor het bepalen van co¨ ordinaten, ophalen van routes en berekening van reistijden en afstanden. Deze klasse wordt frequent gebruikt bij het bepalen van nieuwe afspraken. Ook tijdens het sorteren wordt deze klasse gebruikt. U heeft nu al een goed globaal beeld over de interactie tussen de verschillende klasses. De verschillende attributen van elke klasse bespreken gaat iets te ver. In wat volgt komen enkele aspecten zeker nog aan bod.
2.3.2
Opgeloste vereisten
Zoals hierboven reeds vermeld waren er enkele specifieke vereisten opgelegd aan deze component. De oplossingen die gevonden en ge¨ımplementeerd werden, worden hieronder besproken. Ophalen externe agenda’s Dankzij de Google Data API is het perfect mogelijk connectie te maken met externe agenda’s van Google. Eenmaal verbonden met een agenda kunnen we alle kalenders binnen deze agenda ophalen. Elke kalender bevat dan weer afspraken14 . Het is dus perfect mogelijk om de huidige staat van een agenda volledig te achterhalen. Dit kan vertrekkend van een gebruikersnaam en een wachtwoord. In hoofdstuk 2.3.3 gaan we dieper in op de concrete uitwerking van deze oplossing. Bepalen nieuwe afspraken Het is mogelijk om voorstellen te verkrijgen van de agendacomponent. Aan de hand van de verkregen afspraken kan berekend worden waar een nieuwe afspraak mogelijk is. Afhankelijk van enkele waarden wordt de beste gekozen uit alle voorstellen. Het beste voorstel wordt als eerste getoond op de kalenderweergave. Navigeren tussen voorgestelde afspraken Hierboven werd reeds vermeld dat de beste voorgestelde afspraak als eerste getoond wordt op de kalender. Het is niet altijd mogelijk om deze afspraak ook effectief in te plannen. Als de klant op dat ogenblik niet vrij is, heeft het geen 13 Bij het vergelijken van instanties van CTXDiary worden eigenlijk hun beste voorstellen met elkaar vergeleken. 14 Een afspraak wordt ook wel een event genoemd.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
22
zin om een afspraak in te plannen op dat moment. Om in deze situaties toch een goede afspraak te kunnen bepalen is het mogelijk te navigeren in de voorstellen. Zo kan een operator het systeem vragen een volgende voorstel weer te geven. Het is op dezelfde manier ook mogelijk om een vorig voortel weer te geven. Nieuwe afspraken manueel bepalen Een call agent kan de voorgestelde afspraken naast zich neer leggen en zelf een nieuwe afspraken tekenen op de kalender. Deze benadering biedt meer vrijheid maar verliest daarentegen ook de veiligheid van het algoritme. Het algoritme voorziet voldoende tijd tussen twee afspraken. Dit is niet gegarandeerd als de call agent zelf een afspraak bepaald. Ook de verdeling over de hele dag kan verstoord worden waardoor bijvoorbeeld grotere pauzes ontstaan voor de vertegenwoordiger. Dit is meestal niet het gewenste resultaat. Het is dus wel mogelijk zelf een afspraak te bepalen maar we moeten toch voorzichtig omspringen met deze vrijheid. Het intelligent planningsalgoritme wordt besproken in hoofdstuk 2.3.4. Gegevens uit belscript bewaren in nieuwe afspraken Een belscript bestaat niet alleen uit de agendaplanning. Er zijn meestal al enkele schermen aan vooraf gegaan en er kunnen nog schermen volgen. Het zou dus heel handig kunnen zijn om in de afspraken gegevens van de klanten bij te houden. Dit is mogelijk gemaakt dankzij een soort tags. De tags zien er uit als volgt: “??naam??”. De vraagtekens zijn niet toevallig gekozen. Binnen de ASKIAoplossingen wordt dezelfde manier van tagging al gebruikt. Voor gebruikers is deze manier van werken dus niet nieuw. De variabele velden van een afspraak zijn die voor de titel van de afspraak, de beschrijving en de locatie. Naast tags kan er in een variabele ook nog gewone tekst staan. De variabele beschrijving kan dan bijvoorbeeld de volgende zijn: “Bespreking ??product?? bij deh./mevr. ??voornaam?? ??familienaam??”. Op het moment dat de afspraak opgeslagen wordt, worden deze tags omgezet in de effectieve waarde. Hiervoor wordt de caseData15 meegegeven naar de nieuwe afspraak. Deze nieuwe afspraak is een object van “CTXAppointment”. Deze klasse voorziet in een methode om deze tags om te zetten in gegevens uit de caseData. Pas na het parsen wordt de afspraak opgeslagen in de Google Calendar. Werkuren instellen Het is mogelijk een interval in te stellen waarbinnen de vertegenwoordigers werken. Dit interval wordt bepaald door een begin- en einduur. Het is dus wel zo dat alle vertegenwoordigers binnen hetzelfde interval moeten werken. Voorlopig is het dus nog niet mogelijk om per vertegenwoordiger dat interval in te stellen. Er werd wel stilgestaan bij dit probleem. Om externe afhankelijkheden voorlopig beperkt te houden tot het internet voor deze component werd beslist om niet met extra bestanden te werken om dit op te lossen. Dit is echter wel perfect implementeerbaar. Een ander nadeel van externe bestanden is dat ze 15 Dit
zijn alle vragen en hun antwoorden uit het belscript
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
23
up-to-date moeten gehouden worden. Zonder deze garantie heeft het weinig zin om gegevens op die manier bij te houden. We zouden deze instelling eigenlijk wel kunnen simuleren door dummyafspraken te voorzien in de agenda. Hierdoor kan die tijd niet meer gebruikt worden voor een nieuwe afspraak. Maar dat is uiteraard ook niet de ideale oplossing. Periode voor planning instellen De supervisor kan bij het aanmaken van een belscript een periode instellen waarbinnen afspraken kunnen gepland worden. Deze periode zorgt er voor dat een operator enkel de dagen binnen het interval kan opvragen. Hier kunnen dan eventueel nieuwe afspraken ingepland worden. Een interval kan ook beginnen voor de huidige datum16 , hierdoor kan een belscript ook gebruikt worden om een agenda te raadplegen. Hij kan dit doen op twee manieren. Enerzijds met vastgestelde data, anderzijds met relatieve intervallen. De eerste methode zorgt er voor dat de operators de kalender kunnen zien en aanpassen binnen vast ingestelde data. Dit betekent dat de datum voor het begin van de planning en het einde van de planning op voorhand vast staan. Deze zijn dus niet afhankelijk van de huidige datum. Bijvoorbeeld: Begin op 1 september 2011, einde op 30 september 2011. De tweede methode zorgt daarentegen voor een interval dat meeschuift met de dag van uitvoering. Zo kan de supervisor dus een getal invoeren, dit wordt gezien als een aantal dagen verschillend van de huidige datum. Hij kan dit doen voor zowel het begin als het einde van een interval. Bijvoorbeeld: Begin 7 dagen geleden, einde over 21 dagen. Intu¨ıtieve gui Om het geheel makkelijk bruikbaar te maken zonder extensieve opleidingen was het noodzakelijk een intu¨ıtieve gui te voorzien. De weergave van de kalender is gebaseerd op de weergave van Google zelf. Google stelt code beschikbaar om een kalender op een webpagina te plaatsen. Met deze code kunnen we helaas niet veel aanvangen omdat we er niets kunnen aan veranderen. Er werd uitgegaan van deze weergave om een eigen gui te maken. Zo werd eigen HTML-code met de bijhorende CSS geschreven met de Google weergave als basis. In deze weergave werden dan drie zaken toegevoegd. De eerste is een datepicker ge¨ımplementeerd om met te navigeren naar een andere datum. Deze datepicker staat naast de knoppen “volgende” en “vorige”. Een tweede extraatje is de voorziening om te navigeren tussen de verschillende voorgestelde afspraken. Deze knoppen zien er uit als de andere navigatieknoppen maar hier dan met een dubbele pijl. Deze twee extra knoppen kregen ook dezelfde kleur als een nieuwe afspraak. Op die manier wordt de correlatie tussen beide ook visueel aangeduid. Daarnaast staat ook de titel van een kalender weergegeven. Deze titel kan ingesteld worden door de vertegenwoordiger zelf. De titel heeft geen extra functionaliteit maar op deze manier weet een operator wel in welke kalender hij aan het werken is. 16 Huidige
datum = dag waarop belscript wordt uitgevoerd.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
24
Externe afhankelijkheden Zoals reeds vermeld bij de vereisten was het niet te vermijden dat gegevens uit een externe bron moesten geladen worden. Deze bron is Google Calendar geworden. Dit betekent dus dat de pc waarop het belscript is gestart een verbinding met het internet moet kunnen maken. Om up-to-date gegevens te kunnen garanderen bleek dit al snel de enige mogelijkheid. Momenteel is het zo dat CTScript zelf steeds een verbinding met het internet zal leggen. Er werd ook nagedacht over een manier waarbij niet CTScript zelf de gegevens zal ophalen. Hierbij zou CCA 17 de gegevens ophalen en up-to-date houden. Op deze manier moet de pc in kwestie geen verbinding met het internet meer leggen maar wel een verbinding op het intern netwerk hebben. Dit kan om veiligheidsredenen ook beter blijken. Dit is momenteel nog niet mogelijk omdat de integratie van CTScript en CCA nog niet is afgewerkt. Veiligheid gegevens Er werd bij de ontwikkeling van deze component ook aandacht besteed aan de veiligheid van de gegevens. Voor we data kunnen ophalen van Google moet er een CalendarService aangemaakt worden. Deze instantie zorgt voor de authenticatie van CTScript a.d.h.v. de nodige credentials. Zo worden gebruikersnaam en wachtwoord meegegeven aan het object als het aangemaakt wordt. Hierbij wordt gebruik gemaakt van de “ClientLogin username/password authentication” van de Google Data API. Een belscript wordt bijgehouden als .CTX-bestand. Hierin staat het volledige belscript beschreven dus ook het wachtwoord voor de agendacomponent. Het wachtwoord bijhouden in gewone tekst zou dus niet heel verstandig zijn. Daarom werd gekozen om dit wachtwoord te versleutel met RSA-encodering. Binnen CTScript zitten zowel de publieke als private sleutel opgeslagen. Op deze manier kan CTScript de eigen versleuteling terug ongedaan maken om toch het wachtwoord goed te kunnen meegeven aan de Google-CalendarService.
2.3.3
Google Data API
Hierboven werd reeds uitvoerig gesproken over de mogelijkheden van de Google Data API. Hier zal iets concreter ingegaan worden op de eigenlijk uitwerking binnen CTScript. Eerst worden de voorbereidingen uit de doeken gedaan. Daarna komt de concrete verwerking in CTScript aan bod. Voor we de component kunnen gebruiken is het noodzakelijk enkele zaken in orde te maken. Deze voorbereidingen houden op zich niet zo veel in maar mogen niet uit het oog verloren worden om de component zijn werk te laten doen. 1. Er moet een hoofdaccount gemaakt worden die zal instaan voor het beheer van de verschillende agenda’s van de vertegenwoordigers. De credentials van deze account zullen nodig zijn bij het instellen van de component. Een account aanmaken is volledig gratis en duurt minder dan 5 minuten. 17 De globale serverapplicatie van MI4C, deze doet een belscript opstarten indien dit nodig blijkt.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
25
2. Daarnaast moeten alle kalenders van de vertegenwoordigers gelinkt worden met de hoofdaccount. Hierbij moet elke vertegenwoordiger toegang en beheersrechten geven aan de hoofdaccount. Deze instelling kan gebeuren met behulp van de webinterface van Google Calendar. Als bovenstaande zaken in orde zijn, is het grootste deel van het schema in figuur 2.4 alvast in orde. In wat volgt wordt besproken hoe de communicatie tussen CTScript en de hoofdaccount verzorgd wordt.
Figuur 2.4: Samenwerking CTScript - Google Calendar Nu we binnen Google Calendar de juiste relaties hebben tussen de verschillende kalenders kunnen we via de hoofdaccount de nodige aanvragen en aanpassingen doen. Dit proces wordt hieronder uitgelegd. Verbinding leggen met een Google Calendar dient te gebeuren in enkele stappen. Zo moeten we eerst alle beschikbare agenda’s ophalen. Dit gebeurt als volgt: 1. Maak een object van de klasse “CalendarService” met als enige parameter de naam van de applicatie. Zet de credentials “gebruikersnaam” en “wachtwoord” voor dit object. 2. Maak een object van de klasse “CalendarQuery” zonder parameters. 3. Zet de Uri van de query. vb: https://www.google.com/calendar/feeds/default /allcalendars/full 4. Door de query uit te voeren op de aangemaakte “CalendarService” krijgen we een “CalendarFeed”. 5. In deze “CalendarFeed” zitten dan “CalendarEntries”. 6. Deze objecten worden omgezet naar een object van de klasse CTXDiary. 7. Vanaf nu hebben we per kalender een object binnen de applicatie die ermee overeen stemt. Eens de agenda’s opgehaald zijn, zijn we nog maar halfweg. Nu moeten uit elke agenda nog de afspraken opgehaald worden. Dit kan gebeuren op de volgende manier:
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
26
1. Bij het aanmaken van het CTXDiary-object werd reeds de calendar service en de specifieke query ingesteld. Deze query moet nu uitgevoerd worden. 2. We krijgen nu een “ResultFeed”. 3. Uit de “ResultFeed” kunnen we de verschillende events ophalen. Dit zijn objecten van de klasse “EventEntry”. 4. Deze events worden allemaal bijgehouden om achteraf de nodige berekeningen te kunnen doen. Momenteel is het dus zo dat de klasse “CTXGoogleAccountController” onrechtstreeks alle afspraken van de verschillende kalenders bijhoudt. Dit is een statische klasse. Er werd hiervoor gekozen omdat op die manier de gegevens beschikbaar zijn zonder hiervoor een instantie te moeten bijhouden. Je kan de gegevens dan ook makkelijker benaderen. Hierdoor werden gelijk ook problemen voorkomen bij het kopiren van de agendacomponent. Met de kalenders en afspraken kunnen we op zich nog niet zo veel aanvangen. Deze gegevens dienen nog verwerkt te worden tot bruikbare data. Onder bruikbare data verstaan we voorstellen voor nieuwe afspraken. De verwerking van de gegevens hangt ook nauw samen met de klassen “CTXDiary” en “CTXGoogleAccountController”. Hoe alles precies berekend wordt staat beschreven in hoofdstuk 2.3.4. Momenteel houdt CTScript zelf de afspraken en kalenders bij. Alle bewerking met deze gegevens moeten dan ook uitgevoerd worden vanuit CTScript. Om de bewerkingen te doen is toch wat rekenkracht noodzakelijk. Het lijkt dan ook handig om op termijn deze berekeningen onder te brengen in een serverapplicatie (eventueel CCA). Hierdoor zouden de gegevens beschikbaar zijn binnen het pakket van MI4C en moet er niets opgehaald worden vanuit CTScript. Enkel CCA zou dan nog data moeten ophalen bij Google. Het up-to-date houden van de gegevens kan dan ook gecentraliseerd worden. Op deze manier zal het aantal requests via de Google Data API ook sterk verminderen. Deze methode kan tot op heden helaas nog niet ge¨ımplementeerd worden omdat de integratie van CTScript met CCA nog niet is afgewerkt.
2.3.4
Intelligent planningsalgoritme
Nu we alle gegevens uit Google Calendar hebben verkregen dankzij de Google Data API willen we deze graag omzetten naar bruikbare gegevens. De bruikbare gegevens zijn liefst voorgestelde nieuwe afspraken. Om deze nieuwe afspraken te bepalen aan de hand van de verkregen gegevens werd een intelligent algoritme ontwikkeld. In figuur 2.5 vindt u een overzicht van de algemene werking van dit algoritme. De 2 blauwe fasen worden hierna in detail besproken. De groene fasen duiden respectievelijk op de in- en output van het algoritme. De eerste fase is die voor het bepalen van mogelijke nieuwe afspraken. Of deze afspraken al dan niet zullen voorgesteld worden blijft hier nog even buiten beschouwing. Dit deel van het algoritme zal in iedere kalender op zoek gaan naar open ruimtes tussen afspraken waar eventueel nog een nieuwe afspraak tussen kan. Indien zo’n ruimte gevonden wordt zal het algoritme nakijken of er voldoende tijd is. Hierbij wordt ook rekening gehouden met de tijd die nodig is om ter
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
27
Figuur 2.5: Intelligent planningsalgoritme
plaatse te raken. Daarnaast is het ook mogelijk om een extra ruimte te voorzien tussen twee afspraken. Dit kan ingesteld worden bij het configureren van de component. Indien er voldoende ruimte is, zal de nieuwe afspraak bijgehouden worden naast de kalender waarop de afspraak kan geplaatst worden. Op deze manier worden alle kalenders overlopen. De tijd nodig om naar een andere afspraak te rijden kan berekend worden op twee verschillende manieren. De eerste manier werkt met co¨ordinaten. Deze worden bekomen dankzij Yahoo! Placefinder (zoals besproken in hoofdstuk 2.2.2). De co¨ ordinaten worden hierbij bekomen uit de XML van de webservice. Aan de hand van twee geografische locaties kan dan snel een afstand18 berekend worden dankzij de formule van Haversine. De afstand is nog niet helemaal wat we willen. Om deze om te rekenen naar een reistijd werd een benaderend formule bepaald. Deze formule rekent de afstand om in twee delen. Bij langere afstanden worden de reistijden immers relatief minder dan bij kortere afstanden. Zo wordt het eerste deel (5km.) berekend aan een gemiddelde snelheid van 20 km/h. Het tweede deel (totale afstand - 5km.) wordt berekend aan een gemiddelde snelheid van 75 km/h. Om dit alles te testen werd een testapplicatie geschreven die 16 scenario’s test. Deze scenario’s vari¨eren van vrij korte routes tot vrij lange routes. Hierbij wordt telkens de berekende tijd vergeleken met de reistijd volgens Google Directions. Deze berekening geeft in de meeste gevallen een goede benadering van de effectieve reistijd. Hier en daar zijn er immers wel grote uitschieters op te merken. De grootste fouten worden gevonden bij routes waarbij voornamelijk secundaire wegen worden gebruikt. De tweede methode gebruikt de diensten van Google Directions. Het gaat hier dus niet om een benadering van de reistijden maar om de effectieve reistijden over de weg. Deze tijden worden volledig berekent door het routingalgoritme van Google. Bij het ophalen van deze tijd sturen we de twee betrokken adressen naar de webservice van Google. We krijgen hierna XML-data terug waar we de effectieve reistijd (in minuten) uit kunnen ophalen. Deze methode biedt dus veel correctere gegevens. Er is immers wel een “maar”. Er kunnen maar 2.500 requests per dag gedaan worden. Het is wel mogelijk om (tegen betaling) meer aanvragen te kunnen doen. Omdat deze dienst toch een grote meerwaarde biedt voor het algoritme werd er gekozen om deze dienst optioneel aan te bieden. Het is dus mogelijk om bij het configureren van de agendacomponent in te stellen welke dienst gebruikt dient te worden. Als de Google Directions API niet bruikbaar blijkt te zijn (bv. door te veel requests) wordt ook automatisch de benaderende methode als alternatief genomen. Zo bekomt het algoritme wel steeds een goed resultaat. 18 Het
gaat hier om een afstand in vogelvlucht.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
28
Bij het opzoeken van alle mogelijke plaatsen waar een nieuwe afspraak tussen past springt het algoritme zo snel mogelijk vooruit. De sprongen die het hiervoor neemt zijn afhankelijk van de gegevens die het op dat moment bekijkt. Indien we bijvoorbeeld voor een andere afspraak staan zal het algoritme onmiddellijk naar de eindtijd van deze afspraak springen. Als we bijvoorbeeld een afspraak hebben voorgesteld en er volgen geen andere afspraken meer die dag zullen we direct naar de volgende dag springen. Dit om geen onnodige ruimtes in de agenda te cre¨eren. Dankzij de grote sprongen is het algoritme toch in staat om vrij snel alle mogelijke voorstellen te doen. Indien we een lege kalender zouden aanbieden, zouden er zonder deze sprongen enorm veel voorstellen mogelijk zijn. Dankzij de sprongen wordt het aantal in dit geval beperkt tot ´e´en afspraak per dag. De tweede fase van het algoritme zal alle kalenders sorteren 19 . Hiervoor werd een systeem ontwikkeld met heuristieken. Elke heuristiek wordt afzonderlijk berekend en krijgt ook een eigen gewicht toegewezen. Dit principe met heuristieken heeft enkele grote voordelen. Zo is het bijvoorbeeld makkelijk om het sorteren aan te passen naar de wensen van een specifieke klant. Het is ook perfect mogelijk om nieuwe heuristieken aan te maken en bij te voegen bij de sortering met hun eigen gewicht. Iets meer over de concrete uitwerking binnen CTScript nu. De klasse “CTXDiary” bevat al haar voorstellen en een methode “CompareTo”. Deze methode is vereist om een lijst van CTXDiary-objecten te laten sorteren. In deze methode worden twee objecten met elkaar vergeleken. Hiervoor wordt voor elke heuristiek de overeenkomstige waarde berekent. Deze waarden worden opgeteld. Deze som wordt de return-waarde van deze methode. Aan de hand hiervan kunnen de objecten van “CTXDiary” vergeleken worden. Alle heuristieken zijn afgeleid van de klasse “CTXHeuristic”. Deze abstracte klasse legt op dat iedere heuristiek een gewicht (van het type double) moet vastleggen. Daarnaast moet er ook een methode “CalculateValue(CTXDiary diary1, CTXDiary diary2)” gespecifi¨eerd worden. Deze zal de eigenlijk waarde berekenen. Momenteel wordt er gesorteerd aan de hand van twee heuristieken. De eerste hiervan houdt enkel rekening met de dag van de afspraak. De afspraak die het vroegst ligt krijgt de voorkeur. Deze heuristiek berekent de het verschil tussen de starttijden van de nieuwe afspraken. Deze waarden wordt dan vermenigvuldigd met het gewicht (0,01). Deze heuristiek heeft pas invloed als de tweede heuristiek bijna gelijke waarden opleverd. De tweede heuristiek vergelijkt de afstand tussen de nieuwe afspraak en de afspraak ervoor. Hiervoor wordt gebruik gemaakt van de diensten van Yahoo! Placefinder. Deze methode werd gekozen omdat we zo requests aan de Google Directions API kunnen uitsparen. Aangezien dit een vrij goede benadering is bekomen we toch een goede heuristiek. Deze heuristiek heeft als gewicht de waarde 1. Het verschil tussen de twee afstanden wordt dus integraal in rekening gebracht om te vergelijken. Tot hiertoe werd het hele proces van opgehaalde gegevens tot berekende nieuwe afspraken uitgelegd. Nu rest enkel nog het opvragen van het beste voorstel. Aangezien de kalenders nu gesorteerd bijgehouden zijn binnen “CTXGoogleAccountController” kunnen we hier het eerste element van opvragen. Indien we willen navigeren in de voorstellen wordt er gewerkt met een stack. Op die 19 Impliciet
worden dus de voorstellen gesorteerd.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
29
manier komen kalenders (met hun voorgestelde afspraak) in volgorde op de stack te staan. Eenmaal de kalender op de stack zit laten we deze naar zijn volgende voorstel springen. Als we nu opnieuw sorteren krijgen we het volgende beste voorstel. Om terug te keren kunnen we een kalender terug van de stack halen en zo de vorige afspraak te zien krijgen. Dit algoritme bestaat dus uit twee belangrijke delen. Enerzijds het berekenen van nieuwe voorgestelde afspraken en anderzijds het sorteren van alle voorstellen. Bij het berekenen is er de mogelijk om benaderend of precies te berekenen d.m.v. respectievelijk Yahoo! Placefinder of Google Directions. Om te sorteren wordt gewerkt met een bundel heuristieken die elk hun gewogen bijdrage leveren om te sorteren. Navigeren tussen verschillende voorstellen is mogelijk gemaakt dankzij een stack die bijhoudt welke voorstellen we al gehad hebben.
2.4
Hindernissen
De ontwikkeling van de agendacomponent verliep niet altijd zonder slag of stoot. Zo waren er enkele hindernissen die overwonnen moesten worden. Hieronder vindt u enkele van de belangrijkste hindernissen die met succes werden genomen.
2.4.1
XML-serialisatie
Binnen CTScript wordt er gebruik gemaakt van XML-serialisatie om de gegevens van een belscript op te slaan in een XML-bestand. Deze bestanden krijgen de extensie “.CTX”. Daarnaast wordt dezelfde serialisatie gebruikt om componenten te kopi¨eren. Zo wordt er in dat geval een geserialiseerde versie naar een “MemoryStream” geschreven en later terug geladen in een nieuw object. Op die manier krijgen we zeker geen referentie naar een bestaand object. Of dit de beste methode is om deze actie te doen is maar de vraag. De code die aan het begin van deze masterproef beschikbaar was deed het immers op deze manier. Er werd dus ook op deze manier verder gewerkt. Er moest dus gezorgd worden dat nieuwe, complexere, componenten ook serialiseerbaar waren. Op zich lijkt dit niet zeer ingewikkeld. Aangezien deze techniek vrij nieuw was zorgde het hier en daar wel voor de nodige kopzorgen. Het kwam al eens voor dat een object niet serialiseerbaar bleek omdat bepaalde instellingen niet helemaal stroken met het type van de property. Na een tijdje kwamen deze fouten gelukkig minder en minder voor. De klasse “CTXGoogleAccountController” is momenteel een statische klasse. Dit heeft ook deels te maken met de serialisatie. Het heeft geen nut om deze klasse te proberen serialiseren samen met een agendacomponent. Dit bleek ook vrij moeilijk te zijn omdat we hierbij te maken hebben met objecten van diverse klassen zoals “CalendarService” die zich niet zomaar laten serialiseren.
2.4.2
Kopi¨ eren van objecten
Bij ongeveer elke actie die ondernomen wordt met een bestaande component in het belscript wordt de component ge¨extraheerd uit de corresponderende HTMLcode. Deze code wordt dan omgezet naar een object van de desbetreffende
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
30
klasse. Zo worden standaarvelden als “Value” wel meegenomen bij het maken van een component maar extra velden konden op die manier niet zomaar opgenomen worden. Aangezien het wel heel erg belangrijk is om aanpassingen aan componenten bij te houden in de component moest hiervoor een oplossing gezocht worden. De oplossing is werd gevonden met de methode “ParseContent(HtmlElement element)”. Deze methode zet dus de HTML-code om in een bruikbaar object van de klasse. Deze methode is standaard aanwezig in elke klasse die afgeleid wordt van CTXBase dus ook in alle complexe componenten. Bij het bestuderen van deze hindernis kwam het idee naar boven om de extra velden bij te houden in een verborgen “¡DIV¿” onderaan de code van de component. Op die manier zitten de velden toch in de HTML-code. In de methode “ParseContent” moeten dan de nodige zoekopdrachten gespecifieerd worden. Hierdoor komen de gegevens uit de HTML-code toch in de respectievelijke properties van het nieuwe object terecht. Deze manier van werken is wellicht niet de meest aangewezen methode maar het kon op het eerste zicht niet echt anders. Het deels herontwerpen van CTScript om dit beter te doen leek iets te ver af te wijken van het eigenlijke doel van deze masterproef.
2.4.3
Performantieprobleem CTScript
Bij het laden van de agendacomponent, wordt er een vrij ingewikkelde HTMLstructuur ingeladen. Het gaat hier om 720 “span”-elementen die de hele kalenderweergave vormen. Er werd eerst geprobeerd om te werken met een “table” maar dan is het een pak moeilijker om de events als “onmouseover” op te vangen. De events worden niet enkel getriggered op de “td”-elementen maar ook op hun omvattende “tr”. Hierdoor kregen we schokkerige interactie. Verschillende “span”-elementen boden hiervoor de oplossing. Het aantal “span”-elementen is immers niet groter dan het aantal interne “td”-elementen. Waardoor het laden niet vertraagt. Het laden van deze uitgebreide structuur is heel erg zwaar. In eerste instantie werd de volledige HTML-code real-time in C# gegenereerd. Dit bleek achteraf de traagste optie te zijn. De tweede poging werkte met de volledige HTML-code in een bestand. Dit bestand moest dan volledig ingeladen worden. In dit bestand moesten wat velden aangepast worden maar dit gebeurde allemaal vrij snel. Toch was de vertraging bij het aanmaken of updaten van een agendacomponent nog steeds onaanvaardbaar. Bij de derde methode werd een soort hybride werking bedacht. Zo wordt momenteel enkel een kale versie van de HTML-code uitgelezen uit een bestand. De 720 spans worden pas later gegenereerd, bij het tonen van de code in CTScript. Het genereren van de spans gebeurt niet in C# maar in javascript. Dit blijkt een pak sneller te gaan dan de vorige twee pogingen. Daarnaast is het ook mogelijk om niet de hele tabel van 00h00 ’s ochtends tot 00h00 ’s nachts te tonen maar om aan de hand van de instellingen enkel de werkuren te tonen. Nadat alle spans gezet zijn worden ook eventuele afspraken en nieuwe voorstellen op hun plaats gezet. Deze aanpassingen zorgden op hun beurt voor een extra versnelling van de weergave. Dankzij deze aanpassingen kon het performantieprobleem herleid worden tot een kleine vertraging bij het configureren van de agendacomponent. De werking
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
31
van deze component werd enorm verbeterd. De klein vertraging die nu nog rest is zeker aanvaardbaar geworden.
2.4.4
Laden elementen in javascript
Bij het laden van de agendacomponent dient er nog heel wat geladen te worden. Zo moeten alle vakjes van de kalender nog geplaatst worden. Alle huidige afspraken en een nieuw voorstel moeten ook nog geplaatst worden bovenop de kalender. Daarnaast moeten ook de gegevens voor de datepicker nog geladen worden. Er is dus nog wat verwerking nodig eens de component weergegeven wordt. Toen de performantie nog niet op punt stond waren er dikwijls problemen met de javascript-code. Zo werden de events bij het laden van de pagina soms te vroeg geladen. Op die manier konden de nodige elementen uiteraard niet gevonden worden. Dit zorgde dan ook voor een slechte weergave van de kalender. Om dit te verbeteren werd gewerkt met timers. Op die manier werden de verschillende methodes even in wacht gezet. Zo kon CTScript eerst alles toch goed weergeven voor de methodes effectief uitgevoerd werden. Eens de performantie verbeterd was, kwam dit probleem haast niet meer voor.
2.5
Werking van de component
In dit hoofdstuk vindt u een overzicht van de werking van deze agendacomponent. De functionaliteit wordt bekeken uit het standpunt van een supervisor en daarna uit het standpunt van een call agent.
2.5.1
Instellen - Supervisor
Voor een component ingesteld kan worden moet hij eerst op een scherm geplaatst worden. Een scherm is een onderdeel van een project. Een supervisor kan een nieuw project opstarten of een ander project verder uitbreiden. Hieronder vind u eerst hoe een component op het scherm geplaatst kan worden. Daarna volgen de verschillende instellingen die een supervisor kan/moet instellen. Er zijn twee manieren om een component op een scherm te plaatsen. Enerzijds kan dit door op een component te dubbelklikken in de toolbox. Anderzijds kan een component geplaatst worden door hem naar het scherm te slepen vanuit de toolbox. De toolbox staat standaard aan de rechter zijde van het scherm. Hieronder vindt u alle instellingen die van toepassing zijn op de agendacomponent: Google Calendar Met deze instellingen wordt de hoofdaccount ge¨ıdentificeerd. Deze credentials zijn noodzakelijk om de CalendarService te kunnen aanmaken en gebruiken. Deze velden zijn dus verplicht in te stellen. Username duidt op de username [email protected]
voor
de
hoofdaccount.
Vb:
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
32
Password duidt op het wachtwoord dat bij dezelfde account hoort. Dit veld wordt gemaskeerd. Achter de schermen wordt dit veld niet als plain text bijgehouden. Het wordt met een vast RSA-sleutelpaar ge¨encrypteerd. Zo wordt ook de ge¨encrypteerde versie in de CTX-bestanden bijgehouden. In de testversie is de account reeds ingevuld, op die manier kan er sneller getest worden. In de offici¨ele release zal dit uiteraard niet het geval zijn. Vb: “Welcome” wordt “*******” Presentation Hoe en wat precies weergegeven wordt, kan ingesteld worden met onderstaande velden. Voor elke waarde is er een standaard waarde voorzien. Dit maakt de configuratie makkelijker. Width geeft aan hoe breed de component moet zijn op het scherm. Vb: 800 Height geeft aan hoe hoog de component zal zijn op het scherm. Vb: 500 First shown weekday geeft de supervisor de mogelijkheid om te kiezen op welke dag een week begint. Althans, hij kan kiezen welke dag eerst wordt weergegeven. Dit kan een handige instelling zijn als men wil beginnen plannen op een andere dag dan maandag. De waarde kan gekozen worden uit een drop-down list. Onderaan de lijst staat ook de optie “Today’s week day”. Deze waarde zorgt er dan voor dat de huidige weekdag altijd als eerste staat. De kalender kan dan nog efficienter gepland worden, al vergt dit wel een aanpassing van de call agent. Deze waarde wordt achter de schermen omgezet naar een aantal dagen, relatief t.o.v. vandaag, dat de weergave moet aangepast worden. Vb: Monday Change proposed appointment is een true/false veld. Met deze optie kan de mogelijkheid uitgezet worden om zelf afspraken te tekenen op de kalender. “True” betekent dat de call agent zelf nieuwe afspraken kan tekenen. Vb: True Time window start geeft aan vanaf welke dag er kan gepland worden. Dit veld kan ingesteld worden op twee verschillende manier. Enerzijds met een getalwaarde. Anderzijds met een datum. Een getal duidt op een aantal dagen t.o.v. vandaag. Een datum stelt een vaste datum in waarop de planning zal beginnnen. Op die manier kan het interval voor planning (samen met de volgende waarde) relatief of vast ingesteld worden. Vb: “1” = morgen, “-14” = twee weken geleden, “01/01/2012” = 1 januari 2012 Time window end geeft aan tot welke dag er kan gepland worden. Deze waarde wordt ingesteld zoals de waarde van “Time window start”. Vb: “21” = over 21 dagen, “-7” = een week geleden, “31/01/2012” = 31 januari 2012 Working time start is de waarde die aangeeft wanneer een werkdag begint. Hier kan de supervisor een uur ingeven waarop de eerste afspraken mogen gepland worden. Vb: 07:00
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
33
Working time end hangt samen met voorgaande parameter. Deze waarde bepaalt het einde van de werkdag van vertegenwoordigers. Aan de hand van deze en voorgaande waarde wordt ook bepaald welk deel van de dag moet weergegeven worden in de kalender. Afspraken buiten dit interval hebben geen invloed op de werking van deze component. Afspraken die deels binnen het interval vallen worden bijgeknipt zodat ze toch binnen het interval weergegeven worden. Vb: 16:00 Spacing appointments maakt het mogelijk om een vaste ruimte tussen twee afspraken te voorzien. De voorgestelde afspraken zullen dan minstens dit aantal minuten van de voorgaande afspraak staan. De ruimte kan ook groter zijn omdat de ruimte er tussen momenteel afgerond wordt op het grotere kwartier. Vb: 15 = 15 minuten Location service is een keuzeveld. Hier kan je kiezen tussen de waarde “Google Directions” en “Yahoo! placefinder”. Met deze waarde kunnen we de mogelijkheid om Google Directions te gebruiken benutten. Yahoo! Placefinder wordt automatisch gebruikt als het bepalen van de reistijd niet lukt met Google Directions. Vb: Google Directions Appointments Met de volgende instellingen kunnen we bepalen welke gegevens in de afspraak in Google Calendar zullen komen. Alle velden die hieronder beschreven worden kunnen tags bevatten. Deze tags zien er uit als “??amount??”. Als we gebruik maken van deze tags kunnen gegevens uit het belscript gebruikt worden om in de afspraken opgeslagen te worden. Rond de tags kan ook vaste tekst geschreven worden. Vb: Bespreking ??product?? bij deheer/mevrouw ??voornaam?? ??familienaam?? Description is het veld dat bij Google Calendar eveneens “Beschrijving” noemt. Het algemeen voorbeeld is hier een heel goed voorbeeld van. Location duidt op het adres van de afspraak. Het is dan ook de bedoeling dat hier een adres in komt te staan. Dit adres is nodig om de reistijd tussen twee afspraken te bepalen. Vb: ??adresKlant?? Title wordt de titel van een afspraak. Dit is ook de waarde die weergegeven wordt op het blokje van een afspraak in Google Calendar. De titel wordt in elke agendaweergave getoond als tekst bij een afspraak. Vb: Bespreking ??product?? Duration of appointment is de waarde die aangeeft hoe lang een afspraak duurt. Dit kan een vaste waarde zijn en ook ingesteld worden door een tag. Deze waarde moet dus omgezet kunnen worden naar een numerieke waarde die de duurtijd aangeeft in minuten. Deze waarde komt niet rechtstreeks in een veld van Google Calendar terecht maar duidt op het interval tussen het begin en het einde van een afspraak. Deze waarde is dus nodig voor het bepalen van de voorgestelde afspraken. Zonder deze waarde kan niet nagekeken worden of er voldoende ruimte is tussen twee afspraken. Vb: ??duurtijd??
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
34
Content Hierna volgen enkele parameters met betrekking tot de tekst die getoond wordt in de agendacomponent. Ze kunnen hier ingesteld worden maar zijn ook instelbaar a.d.h.v. multilanguage instellingen. Title Calendar , deze tekstwaarde komt linksboven de kalender te staan. Vb: Agendaplanning NUON Text button start stelt de tekst in die op de “start”-knop komt. Met een druk op deze knop kan je eenvoudig vandaag of naar de eerste dag van de weergave navigeren. Vb: Start Title week stelt de tekst in die op de tab voor de weekweergave verschijnt. Vb: Week Title month stelt de tekst in die op de tab voor de maandweergave verschijnt. 20 Vb: Maand Overig De velden die hierna besproken worden zijn eigen aan elke component. Deze velden zijn overge¨erfd van de klasse CTXBase. Ze zijn standaard wel aanwezig maar het is niet noodzakelijk om deze aan te passen. id is standaard de naam “Calendar” met een volgnummer achteraan. Met deze id is het soms makkelijk om een component te herkennen. Deze waarde is vooral handig als er meerdere kalenders gebruikt worden. Vb: Calendar1 ClassName is ook een standaardwaarde. Het heeft momenteel niet echt nut deze waarde aan te passen. Vb: CTCalendar Style biedt de mogelijkheid om de CSS-stijl van de component aan te passen. Het is niet de bedoeling dat hiermee width en height ingesteld worden omdat deze een eigen parameter hebben gekregen. Andere zaken zoals “margin” kunnen hiermee wel ingesteld worden. Vb: margin:10px; Variable geeft een naam aan de variabele die overeenkomt met deze component. Bij de agendacomponent heeft deze momenteel niet veel extra nut. Bij andere componenten zoals een tekstveld worden de namen van deze waarde gebruikt om de variabelen te identificeren. Het zijn dan ook deze namen die gebruikt dienen te worden tussen de tags als “??naam??”. Vb: afspraakCalendar1 Het is dus vrij gemakkelijk om deze component te gebruiken. Er worden heel wat waarden ingesteld op een standaardwaarde zodat de component snel kan getest worden. Door deze standaardwaarden aan te passen kunnen we toch een duidelijk andere werking van de component bekomen. 20 Momenteel is de maandweergave nog niet beschikbaar. De vraag van klanten zal moeten wijzen op de noodzaak hiervan. Een weergave van ´ e´ en dag kan eventueel ook een goede optie zijn.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
2.5.2
35
Gebruiken - Call agent
Nu we weten hoe deze component te configureren is lijkt het ook handig om even te bespreken hoe een call agent nu precies kan werken met deze component. In dit hoofdstuk wordt hier dieper op ingegaan. In figuur 2.6 ziet u een weergave van de agendacomponent.
Figuur 2.6: CTScript - Lopend project waarin scherm met kalender is geladen.
Laden Als een scherm geladen wordt met daarop een agendacomponent, wordt de component automatisch gegenereerd. De HTML-code wordt deels geladen uit een bestand en deels gegenereerd door de javascript-code. Eerst ziet de call-agent een globaal beeld van de component. De kalender krijgt eerst een grijze overlay met in het midden de aanduiding dat bepaalde zaken nog geladen worden. Van zodra alles geladen is verdwijnt de grijze overlay en kan de component gebruikt worden. Navigeren in de tijd Binnen deze component kan er genavigeerd worden in de tijd en tussen de verschillende voorstellen. Hier wordt eerst het navigeren in tijd besproken. Onder de titel bevindt zich een knop met het opschrift “start”. Dit opschrift kan aangepast worden bij de configuratie. Met deze knop is het mogelijk terug naar de eerste getoonde datum terug te keren. Die eerste datum kan de dag van vandaag zijn maar ook de eerste dag van een interval als het interval volledig in de toekomst ligt.
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
36
Naast de “start”-knop bevinden zich twee blauwe knoppen. E´en ervan met een pijl naar links en de ander met een pijl naar rechts. Met deze knoppen kunnen respectievelijk een week achteruit of een week vooruit navigeren. Na een druk op een van beide knoppen wordt de kalender herladen, nieuwe gegevens worden opgehaald en weergegeven. Er is ook een derde methode voorzien om te navigeren. Deze methode maakt gebruik van een datepicker. Deze is te zien als een tekstveld met daarin het zichtbare interval met ernaast een blauw icoontje voor de datapicker zelf. Als we op dit blauwe icoontje klikken komt een kalendertje tevoorschijn. Op dit kalendertje zijn enkel de dagen binnen het te plannen interval beschikbaar. Als we een op een dag klikken wordt de kalender herladen voor de gekozen dag (en de dagen er rond). Kortom, er zijn drie manieren om te navigeren in de tijd. De eerste methode springt naar de oorspronkelijke dag. De twee methode schuift ´e´en week voor- of achteruit. Met de derde manier kan je naar een datum naar keuze navigeren. Navigeren tussen voorstellen Daarnet zagen we al hoe een call agent kan navigeren door de tijd. In wat nu volgt wordt uitgelegd hoe hij kan navigeren tussen de verschillende voorgestelde afspraken. Naast de datapicker staat “Proposals:” met ernaast opnieuw twee knoppen. Deze keer zijn de knoppen rood en bevatten ze een dubbele pijl. De kleur van deze knoppen is dezelfde als de voorgestelde afspraak die getoond wordt. Hierdoor wordt de relatie tussen het voorstel en deze knoppen aangeduid. Als op een van beide knoppen gedrukt wordt gaat het systeem op zoek naar een volgend/vorig voorstel. Hiervoor wordt gebruik gemaakt van de stack in CTXGoogleAccountController. Iedere CTXDiary heeft een nieuwe appointment klaar. De geselecteerde CTXDiary (voor de druk op de knop) zal naar zijn volgende voorstel springen. Hierdoor wordt het beste voorstel een andere afspraak na het sorteren van alle CTXDiaries. De kalender wordt opnieuw herladen. Nu wordt een ander voorstel getoond. De geselecteerde CTXDiary wordt aangegeven door het veld tussen de twee navigatieknoppen en de tabs aan de rechter zijde. Hier wordt de titel van de CTXDiary getoond. Deze titel is in te stellen voor elke kalendar binnen Google Calendar. Zelf een afspraak tekenen Enerzijds is het dus mogelijk om voorgestelde afspraken te bekijken en deze eventueel op te slaan. Het is anderzijds ook mogelijk zelf een afspraak te tekenen op de kalender. Deze mogelijkheid biedt meer vrijheden. Zo kan de call agent zelf kiezen hoe groot een afspraak moet zijn. Hij kan ook zelf bepalen wanneer de afspraak precies begint. Bij het gebruik van deze functie moeten we steeds in het achterhoofd houden dat op deze manier ook onmogelijke afspraken gepland kunnen worden. Dit is dan de verantwoordelijkheid van de call-agent. Om een afspraak te tekenen kunnen we gewoon klikken en slepen. Bij het tekenen wordt van boven naar onder een afspraak getekend. Dankzij javascript worden begin en einduren automatisch aangepast tijdens het tekenen. Zo heeft de call agent extra controle over de afspraak die hij tekent. De afspraak moet
HOOFDSTUK 2. COMPONENT AGENDAPLANNING
37
binnen ´e´en dag blijven. Momenteel is het niet mogelijk om afspraken gespreid over meerdere dagen te maken.
2.6
Besluit
Om met de ontwikkeling van de agendacomponent te kunnen beginnen werden eerst enkele vereisten opgesteld. Deze vereisten gaven een duidelijk beeld over het noodzakelijke onderzoek. Zo bleek al snel dat het onderzoeken van externe agenda’s een heel belangrijk onderdeel zou worden. Daarnaast diende er ook onderzoek te gebeuren naar methoden om aan locatiebepaling en/of routebepaling te doen. Tijdens het onderzoek naar externe agenda’s werd vrij snel duidelijk dat Google een heel complete oplossing biedt met zijn “Google Calendar” diensten. Zo is het mogelijk om met C# (.NET) de gegevens van een kalender op te halen en aan te passen. Er wordt ook voorzien in kant-en-klare mogelijkheden tot synchronisatie met externe toestellen en agenda’s. Het onderzoek naar locatiebepaling en/of routebepaling verliep iets minder vlot. Enerzijds werd wel snel de dienst van Yahoo! nl. “Placefinder” gevonden maar een routing service bleek andere koek te zijn. De meeste diensten hebben vrij veel restricties waar we niet direct omheen konden. Na een tijdje puzzelen werd toch (deels) een oplossing voorzien dankzij de Google Directions API. Het eindresultaat is een hybride tussen Yahoo! Placefinder en Google Directions geworden. Na het noodzakelijke onderzoek werd begonnen aan het ontwerpen en uitwerken van de eigenlijke component. Een kleine uitbreiding op de architectuur van CTScript maakt het makkelijker samengestelde componenten te maken. Mits enkele hindernissen verliep de ontwikkeling vrij vlot. Na enkele weken was er al een vrij complete oplossing waarin de meeste vereisten goed opgelost waren.
Hoofdstuk 3
Component verkoop 3.1
Inleiding
Het vorige hoofdstuk handelde over de agendacomponent. In dit hoofdstuk zullen we dieper ingaan op het tweede grote luik van deze masterproef nl. de verkoopcomponent. We zullen hier ongeveer dezelfde structuur hanteren. We beginnen dus opnieuw met het opstellen van enkele vereisten gevolgd door het onderzoek betreffende deze component. Daarna gaan we ook wat dieper in op de concrete uitwerking van dit deel. We sluiten uiteraard ook af met een besluit.
3.2
Wat vooraf ging
3.2.1
Concrete vereisten
Ook bij deze component waren enkele vereisten het eerste wat vorm kreeg. Het beeld dat geschetst werd in het masterproefvoorstel wordt hieronder in enkele concrete vereisten gegoten. Later, in hoofdstuk 3.3.3, vindt u hoe elke vereiste werd opgelost. Verkopen van ´ e´ en product Het moet met deze component mogelijk zijn om ´e´en product te verkopen. Hierbij moeten gegevens als naam, prijs, beschrijving en taxen ingesteld kunnen worden. Verkopen van meerdere producten Het moet met deze component ook mogelijk zijn meerdere producten tegelijk aan te bieden. De gegevens van deze producten - zoals naam, beschrijving, prijs en taxen - kunnen opgehaald worden uit een externe bron. Het aantal producten dat verkocht wordt moet per product afzonderlijk in te stellen zijn. Overzicht van winkelmandje geven Producten verkopen is ´e´en ding, een goed overzicht houden op het hele pakket een ander. Het is dan ook nodig dat we op een overzichtelijke manier te zien kun-
38
HOOFDSTUK 3. COMPONENT VERKOOP
39
nen krijgen wat de toestand is van het winkelmandje. Hierbij kan bijvoorbeeld ook de totaalsom een belangrijk element zijn. Makkelijk verwijderen of aanpassen van producten Het moet makkelijk zijn om met de component het aantal verkochte producten aan te passen. Het verwijderen van een product uit het winkelmandje moet ook mogelijk zijn. Op die manier werkt de component de dynamiek van een telefoongesprek niet tegen. Status weergeven van winkelmandje Het kan handig zijn om snel een blik te kunnen werpen op de huidige toestand van het winkelmandje. Hierbij denken we aan het aantal producten dat reeds verkocht werd en totaalprijs van het winkelmandje op dat moment. Interesse in een product wekken Indien een gesprek niet echt als doel heeft een product te verkopen kan het ook handig zijn deze component te gebruiken om uitleg te geven bij een product. Hierdoor kan de interesse bij de klant gewekt worden. Intu¨ıtieve gui Net zoals bij de agendacomponent is het vereist dat er een intu¨ıtieve gui wordt ontwikkeld om elke handig makkelijk en vlot te laten verlopen. Externe afhankelijkheden Deze component is liefst zo min mogelijk afhankelijk van externe bronnen. Het kan in specifieke gevallen wel mogelijk gemaakt worden maar mag niet noodzakelijk zijn. Veiligheid gegevens De veiligheid van gegevens die betrokken zijn bij de verkoop van producten mag niet in gevaar komen. Er moet hier voldoende aandacht aan besteed worden.
3.2.2
Onderzoek
Er zijn niet echt concrete zaken te onderzoeken voor deze component. Er kon wel inspiratie gehaald worden uit de manier waarop andere verkoopsystemen te werk gaan. Daarom werd toch een deeltje onderzoek verricht naar de werking van online sales systemen. Anderzijds werd er ook op zoek gegaan naar systemen die eventueel integreerbaar waren binnen CTScript. Bekijken online sales systemen Om een idee te krijgen wat de beste werking is voor een verkoopsysteem werden enkele online winkels bekeken. De voorbeelden die hieronder besproken
HOOFDSTUK 3. COMPONENT VERKOOP
40
worden komen uit Amazon1 , Neckermann2 en PIXmania3 , drie toonaangevende webwinkels. Bij het aankopen van producten ga je op de drie sites eerst op zoek naar het gewenste product. Hier zie je dan uitgebreide informatie over het product. Hier worden meestal ook enkele afbeeldingen getoond om het product te promoten. Het tonen van afbeeldingen lijkt op het eerste zicht niet echt nuttig binnen CTScript omdat de producten verkocht zullen worden via de telefoon. Afbeeldingen doen in die context niet echt terzake. Tussen de productinformatie is ook telkens een knop te zien om het product in je winkelmandje te plaatsen. In figuren 3.1, 3.2 en 3.3 zie je de drie verschillende knoppen. Ze hebben allen dezelfde functionaliteit nl. een product toevoegen aan je winkelmandje. Enkel bij Amazon zie je daarnaast ook nog een keuzeveld waarmee je kan kiezen hoeveel je van het product in je winkelmandje wil leggen. Dit lijkt nochtans een handige optie, ook al bieden de anderen het niet direct aan.
Figuur 3.1: Amazon - knop “Add to Cart”
Figuur 3.2: Neckermann - knop “Leg in winkelmand”
Figuur 3.3: PIXmania - knop “In winkelmandje”
In drie webwinkels kunnen we naar de toestand van ons winkelmandje kijken. Hier is meestal een link voor voorzien naar het winkelmandje. Bij Pixmania verschijnt een overzicht van het winkelmandje ook aan de rechter zijde van het scherm. In figuren 3.4, 3.5 en 3.6 zie je de verschillende weergaves. Het valt op dat iedere weergave van het winkelmandje een link voorziet naar het uitchecken en/of effectief bestellen van de producten. Deze optie valt buiten 1 http://www.amazon.com/ 2 http://www.nl.neck.be 3 http://www.pixmania.be
HOOFDSTUK 3. COMPONENT VERKOOP
41
Figuur 3.4: Amazon - winkelmandje
Figuur 3.5: Neckermann - winkelmandje
Figuur 3.6: PIXmania - winkelmandje aan de rechter zijde
de scope van deze component. Er is ook bij elk winkelmandje een optie voorzien om aanpassingen te doen. Amazon en Neckermann opteren hier voor een link waarmee je de het winkelmandje kan aanpassen. PIXmania voorziet enkele mogelijkheden direct in het winkelmandje zelf. Zo staan er knoppen naast ieder product om er ´e´en aan toe te voegen of er een van af te trekken. Er is ook
HOOFDSTUK 3. COMPONENT VERKOOP
42
een icoontje (een vuilnisemmer) voorzien waarmee een product kan verwijderd worden. De mogelijkheden van PIXmania lijken wel erg handig te zijn. Er werden nu twee concrete zaken bekeken die de drie webwinkels gemeen hebben. Hier houdt het dan ook ongeveer op. De overige functionaliteit maakt het vooral mogelijk producten te zoeken en weer te geven. Dit is bij iedere webwinkel wel een beetje anders. Toch werd bij PIXmania nog iets handigs gevonden. Van zodra er iets in je winkelmandje zit zie je in de rechter bovenhoek een veld met de status van je winkelmandje. Hierin staat enkel hoeveel producten er in je winkelmandje zitten samen met de totaalprijs. Figuur 3.7 toont dit veld. Het lijkt wel handig om deze status ook aan call agents te kunnen tonen.
Figuur 3.7: PIXmania - status van het winkelmandje
Opzoeken bestaande systemen voor integratie Als twee deel van het onderzoek werd gezocht naar systemen die deels of geheel integreerbaar zijn binnen CTScript. Deze zouden kunnen dienen als basis voor de componenten. Er werden op voorhand geen concrete eisen gesteld aan deze systemen. Er werden al snel enkele systemen gevonden als “Boss Cart”4 , “CS Cart”5 en “Shoptrader”6 . Deze systemen zijn stuk voor stuk volledige e-commerce systemen. De koper van zo’n product kan hiermee aan de slag en binnen de kortste keren is er een nieuwe webwinkel online. Dit is niet echt waar wij naar op zoek zijn. Dergelijke producten vallen grotendeels buiten de scope van deze masterproef. Ze bevatten een pak meer functionaliteit dan nodig. Door deze vaststelling werd het ook duidelijk dat het misschien makkelijker is om zelf de nodige weergave te maken. Het beheer van de producten dient toch in C# zelf te gebeuren en niet extern. Dit heeft tegelijk ook het voordeel dat er geen extra afhankelijkheid ontstaat. Resultaat onderzoek Dankzij het eerste deel van het onderzoek leek het aangewezen om niet ´e´en component te maken binnen CTScript. Er zouden drie deelcomponenten kunnen gemaakt worden die nauw samenwerken. Ten eerste hebben we dan de knop om een product in het winkelmandje te leggen. Ten tweede is er dan de weergave van het hele winkelmandje, liefst met aanpassingsmogelijkheden. De derde en (voorlopig) laatste component zou een status van het winkelmandje weergeven. 4 http://www.bosscart.com/ 5 http://www.cs-cart.com 6 http://www.shoptrader.nl
HOOFDSTUK 3. COMPONENT VERKOOP
43
Het tweede deel van het onderzoek had niet evenveel resultaat. Na afloop werd beslist om toch eigen componenten te maken. Het beheer van producten valt dan volledig binnen de code van CTScript, dit heeft op zich ook voordelen.
3.3 3.3.1
Uitwerking Ontwerp
Aan het begin van deze masterproef werden voor beide componenten use cases opgesteld om een goed beeld te krijgen van de verwachtingen voor beide componenten. U kan deze use cases terug vinden in de bijlage achteraan deze scriptie. Er wordt hierop verder niet ingegaan omdat dit een eerste idee was. Het doel en de vereisten zijn dermate veranderd dat deze niet meer volledig relevant zijn. Hoe de component ge¨evolueerd is kan u wel merken indien u de use cases vergelijkt met de het resultaat dat beschreven staat in deze scriptie. In fig. 2.1 en fig. 2.2 werd het algemeen ontwerp rond componenten reeds geschetst. Hier gaan we direct dieper in op het ontwerp van de verkoopcomponent. Alle klassen die hierna besproken zullen worden bevinden zich allen in het deelproject “CTScript.ControlsLib”. Klassen gerelateerd aan de verkoopscomponent zitten in de map “CTXSalesClasses”. Deze map bevindt zich in de map “CTXMLsClasses”7 . In het onderzoek bleek reeds dat de verkoopcomponent eventueel kon bestaan uit meerdere kleinere componenten. Tijdens uitvoerige gesprekken i.v.m. deze component werd ook meer en meer duidelijk dat dit noodzakelijk was. Er werd geconcludeerd dat de component zou bestaan uit 4 deelcomponenten nl. “Shopping Basket”, “Add to Basket”, “Shopping List”, “Shopping Status”. Deze worden hieronder even kort aangehaald. In hoofdstuk 3.5 volgt een uitgebreide uitleg van de componenten. In figuur 3.8 vindt u een schema van het hele ontwerp. Bovenaan het schema ziet u opnieuw de klassen CTXComposed en CTXBase waarlangs het schema ge¨ent kan worden op het schema uit figuur 2.2. Hieronder wordt de functionaliteit van elke klasse kort uitgelegd. CTXBase en CTXComposed werden reeds besproken in hoofdstuk 2.3.1. CTXShoppingBasket toont de inhoud van het winkelmandje. Het is de ideale component om na een gesprek de toestand nog even te bespreken. Hier werden ook mogelijkheden voorzien om de aantallen per product aan te passen of een product geheel te verwijderen uit het winkelmandje. CTXAddToBasket is de tweede component is een knop waarmee een vastgesteld product kan toegevoegd worden aan het winkelmandje. Dit product kan ingesteld worden met vaste waarden of met variabelen. CTXShoppingList is een component waarmee een lijst producten aangeboden kunnen worden op een uniforme wijze. Zo kan een call agent snel een overzicht krijgen over een aantal producten. Per product kan een aantal aankopen geregistreerd worden. 7 De map “CTXMLsClasses” bevat alle effectieve componenten alsook klassen als CTXScreen en CTXProject.
HOOFDSTUK 3. COMPONENT VERKOOP
44
Figuur 3.8: Ontwerp - Klassendiagram verkoopcomponent
CTXCurrentShoppingStatus geeft de call agent een zicht op de totaalsom van het winkelmandje en het totaal aantal producten. Deze component kan overal geplaatst worden. Hij heeft zelf geen echte functionaliteit. Deze component wordt altijd ge¨ updatet bij een verandering aan het winkelmandje. CTXShoppingBasketController beheert alle informatie i.v.m. verkochte artikelen. Er worden o.a. lijsten bijgehouden die per product het aantal verkochte items bijhoudt. Er wordt ook bijgehouden welk product bij welke “Shopping List” hoort. De vier componenten communiceren met deze statische klasse om hun gegevens te updaten of om de up-to-date HTML-code te verkrijgen. CTXProduct is de klasse die een product voorstelt. Elke product wordt beschreven door de velden naam, beschrijving, prijs, tax en minimaal te kopen hoeveelheid. Een product kan, in het geval van de “Add to basket”-
HOOFDSTUK 3. COMPONENT VERKOOP
45
component ook aan die component gekoppeld worden. Producten worden vooral beheerd vanuit CTXShoppingBasketController. CTXProductSource is een abstracte klasse. Deze klasse is de basis van elke databron gebruikt voor CTXShoppingList. Deze databronnen moeten op zijn minst de methoden “RetrieveProducts” en “IsReady” bevatten. CTXProductSourceCSV erft van CTXProductSource. Deze klasse beschrijft de werking om een CSV-bestand 8 uit te lezen. Deze klasse specifi¨eerd o.a. welk veld uit het bestand overeen komt met een de velden van een product. CTXProductSourceCSVConverter is nodig om het veld “CSV Source” te kunnen samenklappen. Mocht deze functie niet voorzien zijn zouden de eigenschappen van een Shopping List snel onoverzichtelijk worden. CTXProductSourceXML is een ander voorbeeld van een databron. Hierbinnen moeten dan de verschillende XML-tags gekoppeld worden aan de velden van een product. Nu heeft u een goed beeld op de algemene werking van elke klasse. Hier wordt niet dieper ingegaan op elke klasse. De belangrijkste werking van iedere klasse komt verder nog aan bod in hoofdstuk 3.3.2 en 3.5.
3.3.2
Samenwerking verschillende componenten
Het zal al lang geen verrassing meer zijn dat we hier te maken hebben met vier componenten. Deze vier componenten vormen samen ´e´en geheel. Samen kunnen ze instaan voor het verkopen van verschillende producten en het beheren van deze verkopen. In dit deel wordt grondiger besproken hoe de verschillende componenten samenwerken om tot die resultaat te komen. De vier componenten worden elk beschreven in een aparte klasse. Deze klasses spreken allen met de klasse CTXShoppingBasketController. Die laatste klasse is de plaats waar alle gegevens i.v.m. de producten en verkopen worden opgeslagen. Deze klasse produceert ook de nodige HTML-code voor de componenten “Shopping List”, “Shopping Basket” en “Current Shopping Status”. De klasse is hiervoor perfect geplaatst omdat ze beschikt over alle gegevens i.v.m. de producten en de verkochte artikelen. Nu we weten waar alle gegevens bijgehouden worden is het snel uitgelegd dat de “Current Shopping Status” en “Shopping Basket” hier rechtstreeks hun gegevens halen. Ze geven beide eigenlijk een blik op de stand van zaken. De status doet dit heel beperkt door enkel het totaal aantal verkochte artikelen en de totaalprijs weer te geven. Het winkelmandje daarentegen geeft per product een lijn met gegevens weer. Zo staat de eenheidsprijs, tax en totaalprijs per product op elke lijn. Onderaan vind je dan een veld met de algemene totaalprijs. In de “Shopping Basket” kan je ook de aantallen nog verhogen of verlagen met de voorziene knopjes naast het aantal. Je kan een product ook volledig uit het winkelmandje verwijderen. Deze acties worden achter de schermen doorgegeven 8 CSV staat voor “Comma-separated Values”. Een CSV-bestand kan makkelijk verkregen worden door een Excel-sheet te exporteren als CSV.
HOOFDSTUK 3. COMPONENT VERKOOP
46
aan CTXShoppingBasketController zodat er altijd een up-to-date weergave kan bekomen worden. De component “Shopping List” geeft een aantal producten weer. De gegevens worden inti¨eel uit een databron opgehaald. De Shopping List geeft de geselecteerde databron door aan de controller. Deze zal dan, indien nodig, de gegevens laden uit de bron. Eenmaal ze geladen zijn worden ze bijgehouden om achteraf meermaals opgevraagd te kunnen worden. Bij elk product wordt ook bijgehouden hoeveel exemplaren er van verkocht werden. Hierdoor krijgt de gebruiker in een Shopping List ook telkens het meest recente aantal te zien. De laatste component is de eenvoudigste “voeg toe”-knop. Met deze knop kan je een vast ingesteld product toevoegen aan het winkelmandje. Het instellen van een dergelijk product vergt iets meer werk omdat elk veld afzonderlijk ingesteld moet worden. Hier kunnen dan weer wel variabelen uit andere velden gebruikt worden om de data te voorzien. Op die manier kan heel dynamisch gebruik gemaakt worden van deze knop. De gegevens die hieruit voortvloeien worden ook bijgehouden in de Controller-klasse. De vier componenten draaien dus volledig rondom de CTXShoppingBasketController. Deze klasse verdiende ook de nodige aandacht omdat hier zeker niets mag mislopen. Indien hier een fout zo optreden kan dit invloed hebben op het hele gesprek, een scenario dat zeker voorkomen moet worden.
3.3.3
Opgeloste vereisten
Hieronder vindt u alle vereisten terug die daarnet reeds werden aangehaald. Bij elke vereiste staat beschreven op welke manier de vereiste werd verwerkt binnen de verschillende componenten. Verkopen van ´ e´ en product De component “Add-to-Basket” is een knop waarmee we een product kunnen toevoegen aan het winkelmandje. Als we deze component willen gebruiken moet het product volledig beschreven worden. Om deze knop vele keren te gebruiken is vrij veel werk vereist. Het is dan ook niet de bedoeling dit te doen. Deze knop is vooral voorzien om ´e´en vast product te verkopen. Tijdens het instellen van deze component is het mogelijke variabelen uit andere componenten hiervoor te gebruiken. Verkopen van meerdere producten We zagen net dat ´e´en van de componenten instaat voor het verkopen van een vast product. Het is ook mogelijk gemaakt, met een andere component, om meerdere producten aan te bieden met ´e´en component. “Shopping List” zorgt voor deze functionaliteit. Om producten in te laden in de lijst kan je kiezen tussen verschillende databronnen. Momenteel zijn enkel CSV en XML beschikbaar als databronnen. Het is kan perfect mogelijk gemaakt worden om andere databronnen zoals een webservices of externe databanken te koppelen. Hiervoor werd een interface geschreven die elke databron moet implementeren. Hierna kan de databron binnen de Shopping List beschikbaar gemaakt worden. Na het instellen van een Shopping List worden de gegevens automatisch geladen uit de databron. Pas na het laden kunnen de producten goed weergegeven worden.
HOOFDSTUK 3. COMPONENT VERKOOP
47
Overzicht van winkelmandje geven Het is ook perfect mogelijk een overzicht te krijgen van het winkelmandje met de component “Shopping Basket”. Deze component geeft per product een aantal gegevens weer. Bij elk product wordt de naam, de eenheidsprijs, eventuele taxen en totaalprijs vermeld. Onderaan staat een veld met daarin de globale totaalprijs van het hele winkelmandje. Makkelijk verwijderen of aanpassen van producten Met de componenten “Shopping List” en “Add-to-Basket” is het mogelijk de gegevens te updaten. De nieuwe aantallen worden dan opgeslagen in het winkelmandje. Een nieuw aantal kan ook nul zijn. Een product nul keer in het winkelmandje leggen komt impliciet overeen met het verwijderen van dit product. De component “Shopping Basket” voorziet expliciet in de mogelijkheden om producten nog aan te passen. Er staan twee knoppen naast het veld aantal. Eentje voor verminderen van een aantal en eentje voor het verhogen van een aantal. Helemaal rechts staat nog een knop om een product volledig te verwijderen uit het winkelmandje. Deze functies kunnen goed van pas komen als een klant zich op het einde van een gesprek toch nog zo bedenken. Status weergeven van winkelmandje In de vorige vereisten kwamen bijna alle componenten aan bod. Enkel de “Current Shopping Status”-component werd nog niet aangehaald. Die component komt immers tegemoet aan deze vereiste. Deze eenvoudige weergave van de huidige status van het winkelmandje omvat het aantal artikelen en de totaalprijs. Deze component kan snel overal geplaatst worden. Er hoeft niet veel ingesteld te worden. Op deze manier kan een call agent op elk moment in een gesprek op de hoogte zijn van de huidige status. Interesse in een product wekken Wat er precies gebeurt met de gegevens bekomen uit deze componenten kan vrij bepaald worden door het call center. Het is dus evengoed mogelijk om effectieve verkopen te doen met deze componenten als interesse te wekken bij klanten met deze component. Het is ook perfect mogelijk een product aan te prijzen en dan achteraf de klant te benaderen voor verdere uitleg en een eventuele aankoop. Hiervoor kan bijvoorbeeld ook de agendacomponent gebruikt worden in combinatie met deze verkoopscomponenten. Intu¨ıtieve gui Net als bij de agendacomponent werd gekozen voor eenvoudig ogende componenten. De functionaliteit spreekt voor zich. Er wordt hiervoor gezorgd door goedgekozen pictogrammen en icoontjes te voorzien. Op deze manier wordt ook het leerproces voor deze componenten zo laag mogelijk gehouden.
HOOFDSTUK 3. COMPONENT VERKOOP
48
Externe afhankelijkheden De componenten zijn enkel afhankelijk van de klasse CTXShoppingBasketController. Het was dan ook heel belangrijk om deze klasse de nodige aandacht te geven. Buiten deze klasse zijn er geen andere afhankelijkheden. Het is bijvoorbeeld niet nodig verbinding met het internet te leggen om deze componenten te kunnen gebruiken. Het is daarentegen wel mogelijk om bij de “Shopping List” een externe databank te gaan gebruiken. Het gaat hier dan wel om een bewuste keuze. Bij het kiezen van een dergelijke databron moet dan ook stilgestaan worden bij deze vereiste. Al heeft deze keuze natuurlijk wel het voordeel dat er steeds up-date-gegevens beschikbaar zijn. Veiligheid gegevens Hierboven werd reeds de werking van de databronnen toegelicht. Dit lijkt het enige punt waarbij de veiligheid enigszins in het gedrang kon komen. Bij het kiezen voor een externe databron moet hierbij ook altijd de nodige aandacht aan besteed worden. Hoe het verkeer tussen een werkstation en een server verloopt kan moeilijk geregeld worden vanuit CTScript. Het is niet zo dat CTScript enige encryptie vereist. Indien gekozen wordt voor CSV of XML als bron dan is er geen probleem wat veiligheid betreft. De bestanden worden gekopi¨eerd naar de werkmap van het belscript. Bij het opslaan van een bescript zit het bestand vervat in het .ctxbestand. Hierbij wordt het bestand omgezet naar zijn base64-representatie. De gegevens zijn dus niet zomaar leesbaar. Base64-text kan immers wel snel omgezet worden naar plain text. Als het nodig blijkt dat hierop encryptie vereist is kan dit perfect ge¨ımplementeerd worden. Voorlopig is deze vereiste immers nog niet aan de orde.
3.4 3.4.1
Hindernissen Verschillende databronnen
Voor de component “Shopping list” was het noodzakelijk om te voorzien in externe bronnen. Uit deze bronnen kan een lijst met producten opgehaald worden. Op welke manier de producten aangeboden worden kan niet op voorhand voorspeld worden. Om die reden leek het handig om meerdere databronnen mogelijk te maken. Enkele voorbeelden zijn CSV-bestanden, XML-bestanden, webservices en databanken. Elke bron heeft een eigen manier om gegevens aan te bieden. Deze verschillende delen code moesten zonder enig probleem kunnen samenwerken met de CTXShoppingList-klasse. Hierdoor leek het al snel handig om een interface te schrijven voor alle databronnen. Deze interface kreeg de naam “CTXProductSource”. De interface voorziet in twee methoden. Enerzijds een methode die nakijkt of alles in orde is om producten op te halen nl. “IsReady()”. Anderzijds een methode om de producten effectief op te halen nl. “RetrieveProducts”. De klasse CTXShoppingList kan nu objecten van de klasse CTXProductSource beschikbaar stellen. De verschillende klassen hebben uiteraard hun eigen attributen en methodes om een goede werking te garanderen.
HOOFDSTUK 3. COMPONENT VERKOOP
49
De eerste databron die ge¨ımplementeerd werd zijn CSV-bestanden. Binnen de klasse zijn attributen die aanduiden welk veld uit de CSV hoort bij welk attribuut van een product. Hierdoor kunnen de velden toegewezen worden aan de correcte attributen. Indien enkele databronnen onder elkaar zouden staan in het propertiespaneel zou dit al vrij snel een hele hoop veldjes zijn. Daarom was het noodzakelijk om deze bronnen samengeklapt aan te bieden. De gebruiker kan deze dan open klappen en de nodige velden invullen. Om dit te bekomen moest er een “Converter” geschreven worden. Deze converter staat in voor het weergeven van een soort korte inhoud in het samengeklapte veld. De klasse “CTXProductSourceCSVConverter” verzorgt deze functionaliteiten. Bij het schrijven van een converter moeten minsten twee methodes herschreven worden. Dit zijn de methodes “CanConvertTo” en “ConverTo”. De eerste methode geeft een boolean terug die aanduidt of deze klasse het gevraagde element kan converteren. Als op deze vraag een positief antwoord volgt kan de andere methode, “ConvertTo”, aangeroepen worden om de gegevens om te zetten in een ander object. In dit geval is dit object een string. Er wordt een boodschap weergegeven die aanduidt of er een bestand is geladen of niet. Niet alleen het samenklappen van de velden was nieuw, ook het gebruiken van een extern bestand was nieuw. Er moet een bestand gekozen kunnen worden en dit moet bijgehouden en ingelezen kunnen worden. Hiervoor werd even gekeken hoe dit gebeurd bij het importeren en exporteren van data voor een project. Er wordt gebruik gemaakt van de klasse “CTXBinaryData”. Er werd binnen de databron ook een object van het type “CTXBinaryData” voorzien. Deze klasse voorziet de conversie van de content naar Base64. Naast deze klasse wordt er ook een “BinaryDataEditor” beschreven. Deze laatste zorgt de knoppen “import” en “export”. Op die manier kunnen bestanden gekozen worden met een “FileDialog”. Naast het gebruik van de klasse “CTXBinaryData” diende er enkel een methode bijgemaakt te worden die bij het laden van een bestand het event verwerkt. Om de gegevens in de juiste map bij te houden diende hiervoor ook een methode geschreven te worden. Het bestand dat in de tijdelijke map wordt bijgehouden krijgt als naam de ID van de “Shopping List”-component9 met extensie “.csv”. Op die manier kunnen achteraf makkelijk de juiste bestanden opgehaald worden zonder de naam van het bestand bij te moeten houden. Analoog aan de algemene werking van de CSV-databron kunnen ook andere bronnen ge¨ımplementeerd worden. Bij een XML-databron moeten dan de verschillende tags (en/of attributen) gekoppeld worden aan de verschillende velden van een product. Andere databronnen krijgen dan bijvoorbeeld ook velden om een URI in te stellen e.d. Dit is echter kwestie van implementatie van andere velden om de werking van een databron te garanderen. Het implementeren van diverse databronnen kan dus vrij vlot gebeuren.
3.4.2
Onderscheid gegevens
Daarnet werd de klasse “CTXShoppingBasketController” al besproken. Binnen deze klasse is het noodzakelijk om de gegevens uit een “Add-to-Basket”-button of uit een Shopping List gescheiden te houden. Deze klasse staat enerzijds in 9 De
ID’s gebruikt binnen CTScript zijn GUID’s.
HOOFDSTUK 3. COMPONENT VERKOOP
50
voor het weergeven van alle bestelde producten en anderzijds voor het weergeven van een shopping list. Om alle bestelde producten weer te geven werden deze bijgehouden in een Dictionary die producten koppelt aan een aantal. Op dezelfde manier werden ook voor elke lijst de verschillende producten bijgehouden (ook met bijhorend aantal). Dankzij het bijhouden van deze aantallen is het makkelijk om de juiste getallen te vermelden in een vernieuwde weergave van deze component 10 . Bij elke update van een product, bijvoorbeeld een product verwijderen uit het winkelmandje, moeten deze gegevens ook correct aangepast worden. Het bijhouden op zich is inderdaad maar een kwestie van de juiste gegevensstructuren te gebruiken. Het gebruik van Dictionaries om een aantal te koppelen aan een product leek nogal voor de hand te liggen. Het blijkt immers nog niet zo makkelijk om een waarde uit de “Values” te verkrijgen. Dit kan immers wel met de methode “TryGetValue(key, out value)”. Deze methode geeft een boolean terug en stopt de overeenkomende value in het meegegeven output-veld. De key-waarde indexeren blijkt ook niet zomaar te lukken. Hiervoor kunnen we eerst de sleutels kopi¨eren naar een andere array en daarna indexeren. Deze twee handelingen waren noodzakelijk om makkelijk met de gegevens aan de slag te kunnen.
3.5
Werking van de componenten
In dit hoofdstuk vindt u vier delen. Elk deel bespreekt de werking van ´e´en van de deelcomponenten. Bij elke bespreking wordt begonnen met de mogelijke instellingen. Deze instellingen zijn vooral van belang voor een supervisor die een belscript zal maken. Na de instellingen komt het gebruik van een component aan bod. Hoe een component gebruikt wordt is zowel voor supervisor als call agents van beland. Een supervisor moet de component kunnen testen (of alles goed ingesteld is). Een call agent zal de componenten in de praktijk moeten gebruiken. Hoe een component op het scherm moet geplaatst worden zal hier niet opnieuw besproken worden. Hier werd reeds dieper op ingegaan in hoofdstuk 2.5. Instellingen als “id”, “ClassName”, “Style” en “Variable” worden hier niet nogmaals besproken. De werking van deze instellingen kwam ook reeds aan bod in hoofdstuk 2.5.
3.5.1
Shopping basket
In figuur 3.9 ziet u de weergave van het winkelmandje. Deze component is vooral geschikt voor het weergeven van het eindresultaat van een gesprek. Deze component zal dan ook meestal aan het einde van een gesprek getoond worden. Instellen Text Deze tekst wordt de titel van het winkelmandje. Vb: Shopping Basket Width Met deze waarde kan de breedte van de hele component ingesteld worden. Vb: 500 10 Het kan in een belscript handig zijn dat een call agent terug kan keren op zijn stappen. Er moeten steeds up-to-date weergaves van de componenten voorzien worden.
HOOFDSTUK 3. COMPONENT VERKOOP
51
Figuur 3.9: CTScript - Shopping basket
Show taxes Dit is een boolean. Indien de waarde op “false” staat wordt enkel het aantal gekochte producten en de totaalprijs getoond. Indien deze waarde op “true” staat wordt per product ook de eenheidsprijs exclusief taxen getoond en het percentage taxen dat geheven wordt. Als de waarde op “true” staat krijg de gebruiker dus eigenlijk een vereenvoudigde weergave te zien. Vb: True Valuta Met dit veld kan het valutasymbool voor de prijzen gekozen worden. Met dit veld worden enkele mogelijkheden voorzien. Zo kan het symbool voor of achter de numerieke waarde getoond worden. Om een symbool na de waarde te plaatsen volstaat het om een “-” voor het symbool te plaatsen. Deze manier van werken werd gekozen omdat de meest gebruikte valutatekens nl. “e” en “$” voor de waarde horen te staan. Vb: “e” = e10,00 of “-euro” = 10,00 euro Gebruiken De call agent krijgt met deze component in de eerste plaats een zicht op de huidige toestand van het winkelmandje. Op deze manier kunnen alvast mogelijke slechte ingaves opgespoord worden. Deze weergave geeft ook een zicht op de totaalprijs van de hele bestellign. Anderzijds krijgt de call agent ook de mogelijkheid om dankzij deze component kleine veranderingen te doen aan de bestelling. Het is mogelijk een product te verwijderen uit de bestelling. Om een product te verwijderen is een rode “X” voorzien na elke lijn. Eenmaal op deze knop gedrukt zal het product direct verdwijnen uit het winkelmandje. Er is geen functie “Ongedaan maken” binnen CTScript, dus weg is weg. Het is ook mogelijk het aantal bestelde producten aan te passen. Hiervoor zijn twee knopjes voorzien. De ene knop staat voor “-”. Met deze knop is het mogelijk ´e´en exemplaar van het product te verwijderen. Als het minimum te bestellen producten bereikt is wordt dit knopje grijs en kan er niet meer op geklikt worden. De andere knop staat voor “+”. Met deze knop kan je dan weer ´e´en exemplaar meer bestellen van het product in kwestie.
3.5.2
“Add to basket”-knop
In figuur 3.10 ziet u deze knop. De knop krijgt standaard “Update shopping basket” als inhoud. Deze tekst geeft ook perfect weer waarvoor deze knop
HOOFDSTUK 3. COMPONENT VERKOOP
52
dient. Met deze knop kan een vast product toegevoegd en ge¨ update worden in het winkelmandje.
Figuur 3.10: CTScript - “Add to basket” knop
Instellen De instellingen van deze component zijn opgedeeld in twee delen. Het eerste deel gaat over de component zelf, het ander over het product dat vasthangt aan deze component. Hieronder vind u eerste de instellingen met betrekking tot de component zelf. Text Dit is de string-waarde die getoond zal worden op de knop. Op deze manier kan een eigen tekst (eventueel aangepast aan het product) op de knop geplaatst worden.Vb: “Update shopping basket” Width Met deze numerieke waarde kan de breedte van de knop ingesteld worden. Vb: 230 Het instellen van de knop zelf houdt niet zo veel in. Daarnaast is het instellen van het product ook zeer belangrijk. Het gaat hier immers om de eigenlijke werking van deze component. De component heeft de productgegevens nodig om het product aan het winkelmandje toe te voegen. Name Deze waarde beschrijft de naam van het product. Vb: Testproduct Description Hiermee kan een beschrijving van het product ingesteld worden. Vb: “Hiermee lost u zo het fileprobleem op.” Prize Elk product heeft een prijs. De prijs van het product kan hier ingesteld worden. Vb: 10,00 Tax Hier kan een waarden (in procent) opgegeven worden. Deze waarde kan dus niet negatief ingesteld worden. Vb: 21 Minimal Quantity Als het product minimaal een aantal keer moet verkocht worden kan dit aantal hier worden opgegeven. Vb: 5 Amount Deze waarde slaat op het aantal dat van dit product verkocht wordt. Meestal zal hier een verwijzing staan naar een andere variabele. Het is ook mogelijk om hier eenvoudige bewerkingen te gebruiken. Zo kan, voor wijn bijvoorbeeld, het aantal dozen omgezet worden naar het aantal flessen achter de schermen. Vb: ??amount?? * 6 Er werd enkel bij het veld “Amount” notie gemaakt van het gebruik van variabelen. Dit kan immers ook in de andere velden. Vooraleer het product in het winkelmandje wordt opgeslagen worden alle variabelen eerst omgezet naar hun actuele waarde. Die waarden worden dan gebruikt om het product effectief te beschrijven.
HOOFDSTUK 3. COMPONENT VERKOOP
53
Gebruiken Voor de call agent lijkt deze component op het eerste zicht vrij eenvoudig. Er kan dan ook enkel geklikt worden op deze knop. Toch zijn enkele zaken de vermelding waard. Indien het aantal producten dat verkocht wordt gekoppeld is aan een numeriek veld, is het ook noodzakelijk dat deze waarde ingevuld is. Anders kan de component geen producten toevoegen aan het winkelmandje. De waarde van dit veld moet ook hoger zijn dan het minimaal toegelaten aantal. Deze twee zaken worden gecontroleerd op het ogenblik dat iemand de knop indrukt. Indien er fouten gevonden worden tegen deze twee zaken zal een melding getoond worden en kan de operator de waarden nog invullen of aanpassen. Als de gebruiker naar een ander scherm wil navigeren zal nagekeken worden of alle waarde up-to-date zijn. Als blijkt dat de waarde in het “amount”-veld en in het winkelmandje niet gelijk zijn krijgt de call agent hiervan ook een melding. Hij kan dan kiezen om alsnog te updaten en door te gaan (optie “Yes”). Anderzijds kan hij ook kiezen om niet te updaten maar toch door te gaan (optie “No”) met de navigatie. De derde optie laat de gebruiker toe de waarde zelf nog aan te passen en dus de navigatie te onderbreken (optie “Cancel”). Beide controles gebeuren uiteraard om fouten te vermijden en zo het belscript vlotter te maken. Eenmaal een call agent de meldingen kent kan hij snel de juiste keuze maken en toch vlot verder werken. Op het ogenblik dat de waarden in het winkelmandje ge¨ updatet worden zullen ook alle statusvelden bijgewerkt worden. Deze statusvelden kunnen zowel de statuscomponenten zijn als het veld binnen een shopping list (rechts bovenaan) die de status van het winkelmandje weergeven.
3.5.3
Shopping list
De derde component is de “Shopping list”. Deze component ziet u in figuur 3.11 afgebeeld. Deze componenten kan voornamelijk gebruikt worden om een aantal producten uit een bepaald databron te halen en deze weer te geven op een uniforme wijze. Instellen Voor de component “Shopping list” is het nodig een databron in te stellen. Hiervoor is een deel van de instellingen voorbehouden. Voor we deze instellingen bespreken gaan we iets dieper in op de algemene instellingen. Text Dit is de tekst die getoond wordt bovenaan een lijst, als titel. Vb: Shopping List Width Met deze waarde kan de algemene breedte van de component ingesteld worden. Vb: 500 Width update button Deze waarde stelt de breedte van de “update”-button in. Vb: 190 Valuta Deze instelling werkt analoog als dezelfde waarde bij de component “Shopping basket”. Het symbool kan dus ook vooraan geplaatst worden
HOOFDSTUK 3. COMPONENT VERKOOP
54
Figuur 3.11: CTScript - Shopping list
dankzij het toevoegen van “-” voor het symbool. Vb: “e” = e10,00 of “-euro” = 10,00 euro Tax included Dit is eveneens een instelling (zoals bij het winkelmandje) dat de keuze geeft om een prijs te tonen inclusief of exclusief taxen. Indien deze waarde op “True” staat worden alle prijzen weergegeven inclusief taxen. Indien de waarde op “False” staat zullen prijzen weergegeven worden exclusief taxen. Vb: True = e12,10 of False = e10,00 Dankzij deze instellingen is het mogelijk om de algemene weergave van de component aan te passen. De volgende instellingen nemen als voorbeeld het instellen van een CSV-databron. Andere databronnen kunnen analoog hieraan ingesteld worden. De eigenschappen van een databron zijn standaard samengeklapt. Dit zorgt ervoor dat de weergave van alle instellingen toch overzichtelijk blijft. Data Met deze waarde kan een bestand gekozen worden. Hiermee wordt dus het juiste CSV-bestand gekozen. Dit bestand wordt achter de schermen gekopi¨eerd naar de tijdelijke werkmap van CTScript. Het krijgt als naam de ID van deze component om het bestand achteraf makkelijk terug te vinden. Vb: een gekozen bestand “producten.csv” Field “x” De “x” moet hier vervangen worden door respectievelijk “Name”, “Description”, “Price”, “Tax” en “Minimal”. Met deze waarden kunnen
HOOFDSTUK 3. COMPONENT VERKOOP
55
de velden gekozen worden die overeen komen met de velden van producten. In het CSV-bestand krijgt het eerste veld nummer 1. Na deze instelling weet de component hoe de verschillende waarden uit het bestand moeten gehaald worden. Vb: 2 Voor deze component gebruikt kan worden is het dus ook noodzakelijk dat de supervisor een CSV-bestand beschikbaar heeft. Dit bestand kan aangemaakt worden vanuit Excel. Het is dan ook makkelijk om het daar te updaten en opnieuw in te laden in het belscript. Op deze manier kan een nieuwe versie van de productgegevens toch makkelijk verspreid worden. Het bestand wordt immers bijgehouden in het CTX-bestand dat een belscript beschrijft. Gebruiken Een call agent krijgt initi¨eel een lijst te zijn van productnamen. Naast iedere naam staat ook de eenheidsprijs (taxen inclusief of exclusief, afhankelijk van de gekozen instelling). Op het einde van elke rij staat een tekstveld waarin het aantal kan opgegeven worden. Naast elk tekstveld staat het minimaal aantal dat kan verkocht worden van het product van die lijn. Bij het ingeven van een waarde in dit numeriek veld worden enkel numerieke waarden aanvaard. De beschrijving van een product is verborgen. Deze kan weergegeven worden door op de naam van een product te klikken. De beschrijving wordt dan heel vloeiend weergegeven. De functie die hiervoor werd geschreven zal op een vast interval de beschrijving openen. Als er een andere beschrijving open staat zal deze tegelijk gesloten worden. Zo blijft het geheel toch mooi overzichtelijk. Om een schokkerig effect van het openen en sluiten te voorkomen werd gebruik gemaakt van een soort klokvormige curve. Aan het begin en op het einde is het verschil subtieler dan in het midden van de actie. In het midden opent de beschrijving sneller. Op deze manier kan een grote beschrijving elegant geopend worden terwijl een kleine beschrijving elegant gesloten wordt. Op het ogenblik dat de operator naar een ander scherm wil navigeren zal het scherm gevalideerd worden. Bij een shopping list komt het er dan op neer dat iedere waarde zal gecontroleerd worden met de huidige waarde in het winkelmandje. Als er inconsistenties gevonden worden krijgt de gebruiker hiervan een melding. Hij kan dan kiezen om alsnog te updaten en verder te gaan (optie “Yes”). De optie “No” zal de update voorkomen en toch verder gaan naar de andere pagina. Met de laatste optie, “Cancel”, kan de gebruiker zelf nog ingrijpen door de navigatie te stoppen. Als de waarden ge¨ updatet zijn naar het winkelmandje wordt ook de huidige status (in de rechter bovenhoek) bijgewerkt. Indien er andere status-componenten op de pagina staan worden die ook bijgewerkt. Bij het bijwerken van het winkelmandje wordt ook nagegaan of alle waarden wel boven het minimum liggen. Als dit niet het geval is wordt opnieuw een gepaste boodschap weergegeven. Het bijwerken zal in dat geval niet doorgaan. Deze functie zorgt opnieuw samen met de vorige functie dat gebruiker vlotter kan werken met deze component. Dankzij deze functies kan hij niet vergeten updaten en kan hij geen foutieve waarden toevoegen.
HOOFDSTUK 3. COMPONENT VERKOOP
3.5.4
56
Current shopping status
De vierde een laatste deelcomponent voor het verkopen van producten toont de status van het winkelmandje. Hierbij worden enkel twee zaken weergegeven. Ten eerste het totaal aantal verkochte producten, ten twee de totaalprijs van het pakket. De weergave van deze gegevens kan u zien in figuur 3.12.
Figuur 3.12: CTScript - Current shopping status
Instellen Deze component heeft geen nood aan uitgebreide instellingen. Dat is ook de bedoeling van dit veld. Er moet op een makkelijke manier een status getoond worden. Het enige veld dat kan ingesteld worden is “Valuta”. Je kan hier kiezen welk teken er voor of achter de prijs zal verschijnen. Door een minteken voor het symbool te plaatsen komt het valutateken achter de prijs te staan. Vb: “e” = e10,00 of “-euro” = 10,00 euro Gebruiken De instellingen van deze component zijn heel beperkt. Ook het gebruik van deze component kan vrij kort uitgelegd worden. Zo kan je met deze component eigenlijk niets doen. Voor de call agent kan het immers wel een goede manier zijn om snel een zicht te hebben op de stand van zaken. Als er op “Update shopping basket” geklikt wordt in een “Shopping list” of in een “Add to basket”button worden de waarden van een statusveld bijgewerkt. Op die manier kan de gebruiker dan ook zien dat de wijzigingen zijn doorgevoerd.
3.5.5
Besluit gebruik vier componenten
De vier componenten hebben elk hun eigen instellingen. Sommige waarden komen terug in enkele componenten (vb: valuta). Andere instellingen zijn dan weer heel specifiek (vb: databron bij “Shopping list”). Hierdoor kan een supervisor voldoende parameters wijzigen bij elke component. De gelijkende instellingen zorgen ervoor dat de supervisor sneller de verschillende componenten zal kunnen instellen. Het gebruik van de verschillende componenten is telken zo eenvoudig mogelijk gehouden. Er zijn voldoende controles voorzien zodat de call agent minder snel in de fout kan gaan. Er werd ook voorzien in mogelijkheden om op het einde van het gesprek de gegevens toch nog (beperkt) te kunnen aanpassen.
3.6
Besluit
Toen dit luik van deze masterproef vorm kreeg leek dit geheel ´e´en component. Toen er echter concreter nagedacht werd over de uitwerking van deze component
HOOFDSTUK 3. COMPONENT VERKOOP
57
bleek het meer en meer nodig om het geheel op te delen in verschillende deelcomponenten. Na enig onderzoek werd deze gedachte bevestigd. Zo kwamen we op een totaal van vier deelcomponenten nl. “Shopping basket”, “Add-tobasket”-button, “Shopping list” en “Current shopping status”. De vier componenten worden ondersteund door ´e´en centrale klasse nl. “CTXShoppingBasketController”. Deze klasse beheert de aankopen en voorziet de verschillende componenten van aangepaste HTML-code. De vier componenten worden zo gebruiksvriendelijk gehouden door o.a. voldoende controles uit te voeren bij het updaten van het winkelmandje. De weergave van elke component werd ook beperkt tot de meest noodzakelijke gegevens. Zo worden bijvoorbeeld beschrijvingen van producten initi¨eel niet getoond. Ze kunnen wel weergegeven worden door op het product te klikken. Dankzij de combinatie van de vier componenten kunnen heel diverse belscripts gebouwd worden die toch op dezelfde manier werken. Het doel van deze componenten werd dus zeker en vast bereikt.
Hoofdstuk 4
Debugging CTScript 4.1
Inleiding
Er werd gekozen om CTScript te laten ontwikkelen door een extern bedrijf, het project werd dus geoutsourcet. CTScript werd ontwikkeld door een Roemeens bedrijf. De definitieve versie werd op 18 februari 2011 opgeleverd. Vanaf dat moment kon er gestart worden met de eigenlijke ontwikkeling van de componenten. Toen we effectief aan de slag gingen met CTScript merkten we dat het hier en daar nog last had van kinderziekten. Hierbij ging het op het eerste zich over enkele kleine bugs. Deze verhelpen leek dan ook snel gebeurd. Naast de bugs viel na een tijdje ontwikkelen ook op dat de structuur misschien toch beter had gekunnen. In de volgende hoofdstukken vindt u meer details over het oplossen van deze bugs en problemen i.v.m. de structuur.
4.2
Bugs
Bij de eerste testruns van het programma kwamen enkele kleine problemen aan het licht. Deze kleine problemen werden zo goed mogelijk opgelost tijdens de eerste fase van deze masterproef. Het gaat hier niet over substanti¨ele veranderingen aan de werking van CTScript maar wel over enkele zaken die het gebruiksgemak toch sterk kunnen be¨ınvloeden. Foutieve properties getoond Bij het selecteren van een andere tab bovenaan het editeerscherm bleven de eigenschappen van de eerder geselecteerde component zichtbaar. Als we in de Solution Explorer een ander scherm selecteerden kregen we hetzelfde effect. Er werd voor gezorgd dat de eigenschappen van het geactiveerde scherm zichtbaar worden gemaakt. Op deze manier blijft steeds het recentst geselecteerde item zichtbaar in het properties-paneel. Verkeerd project gesloten Als je onder het menu “File” de keuze “close project” maakte werd het geactiveerde project afgesloten. Als je dus een project wou sluiten moest het telkens 58
HOOFDSTUK 4. DEBUGGING CTSCRIPT
59
eerst geactiveerd worden en dan pas kon het gesloten worden. Om een project te activeren moet de gebruiker er eerst op dubbelklikken. De nodige handeling om een project te sluiten was dus iets te omslachtig. Als we nu een project selecteren, zonder het te activeren, kan het wel gesloten worden. Hiervoor werd de mogelijkheid toegevoegd aan de Solution Explorer om het geselecteerde project te bepalen. Nu kan dit project makkelijk opgehaald en afgesloten worden. Schermnaam niet aangepast Als we de naam van een scherm aanpasten werd dit niet weergegeven als titel van het tabblad. Hetzelfde probleem deed zich voor als een andere taal geselecteerd werd. Dit probleem kon vrij eenvoudig opgelost worden door deze waarden in beide gevallen te updaten. Veranderen taal Er is ondersteuning voorzien om een belscript in meerdere talen te kunnen gebruiken. Bij deze voorziening zijn enkele kleine problemen in de integratie geslopen. Zo werd er in de toolbar geen enkele taal aangeduid als actief. Je kon een taal wel laten aanpassen maar indien er geen waarde is voor de geselecteerde taal werd een lege string weergegeven. Bij het ophalen van de mogelijke talen wordt nu gecontroleerd of de taal de actieve is. Als dit zo is wordt de taal als actief weergegeven. Bij het selecteren van een taal wordt deze actie doorgegeven aan het project, van het project naar de schermen om zo tot bij de componenten te raken. Het was dus kwestie van deze cascade te volgen en hier en daar de nodige controles te voorzien. Naamgeving nieuw scherm De naamgeving bij het aanmaken van een nieuw scherm was niet heel logisch. Als standaardnaam kreeg elk scherm dezelfde standaardnaam. Dit werd licht aangepast zodat de schermen een meer logische naam krijgen bij het aanmaken. Bij het maken van een nieuw scherm worden eerst de huidige schermen in dit project geteld. De naam van een nieuw scherm wordt nu “screen x”, waarbij x het volgende nummer is. Na verwijdering van een scherm kan het gebeuren dat een ander scherm reeds dezelfde naam heeft gekregen, hierop wordt dan ook gecontroleerd. Op deze manier blijft de nummering ook kloppen na het verwijderen van een scherm. Als we een scherm dupliceren vanuit het menu in de “Solution Explorer” kreeg dit nieuwe scherm dezelfde naam als het originele. Dit is vrij onoverzichtelijk. Als aanpassing werd aan de naam van het nieuwe scherm het achtervoegsel “ - Copy” bijgevoegd. Ingeven numerieke waarden met shift-toest Een van de beschikbare componenten is een numeriek invoerveld. Hier kan je dus enkele numerieke waarden opgeven. Bij de initi¨ele versie was het immers niet mogelijk waarden in te geven met een toestcombinatie met shift en een numerieke toets. Dit was natuurlijk niet heel wenselijk.
HOOFDSTUK 4. DEBUGGING CTSCRIPT
60
Na controle van de achterliggende javascript-code bleek dat deze combinaties actief geblokkeerd werden. Deze controle op de shift-toets werd verwijderd. Nu is het terug perfect mogelijk om ook met shift een numerieke waarde in te geven. Veld “required” niet bijgehouden Alle componenten hebben een attribuut “IsRequired”. Dit attribuut houdt logischerwijs bij of de component al dan niet moet ingevuld zijn. Indien we deze waarde immers aanpassen binnen CTScript bleek dit geen invloed te hebben op de validatie van het scherm. Een veld kon niet ingesteld worden als niet noodzakelijk. Het bleek al snel dat de ingestelde waarde van het attribuut geen waarde kreeg. Bijgevolg bleef deze waarde op “True” staan. De set-methode voor dit attribuut werd nochtans goed aangeroepen. Na was rondkijken werd het probleem duidelijk. De waarde van “IsRequired” werd nergens bijgehouden in de HTML. Bij het omzetten van de HTML-content naar een object werd deze waarde dus niet opgehaald. Eens het probleem gekend was kon een oplossing gevonden worden. De oplossing bestaat uit twee delen. Enerzijds diende de waarde ook, als bijkomend attribuut, bijgehouden te worden in de component. Dit gebeurde naast de andere attributen zoals “DesignID” en “variable”. Deze attributen worden allemaal gezet in de methode “InitHtmlElement” van de klasse “CTXBase”. Anderzijds werd ook de methode “parseContent” van dezelfde klasse uitgebreid. Nu wordt ook het attribuut “required” gelezen en eventueel ingesteld. Na deze twee aanpassingen doet de waarde “IsRequired” perfect zijn werk. “Move up” en “Move down” In het paneel “Solution Explorer” kan je dankzij een rechter muisklik in het menu kiezen om een scherm omhoog en omlaag te schuiven. Deze functie had soms nare gevolgen. Zo kwam een scherm (na het omhoog schuiven) altijd helemaal bovenaan te staan. Bij het bekijken van de achterliggende code bleek het te gaan om een kleine fout. Zo werd de index waar het scherm ingevoegd moest worden verkeerd ingesteld waardoor het scherm een foutieve waarde kreeg. Bijgevolg kwam het helemaal bovenaan terecht. Eenmaal deze waarde ingesteld werd op “index 1”1 was het euvel verholpen. Hernoemen van een scherm Als in de “Solution Explorer” een scherm geselecteerd is kan men in het “Properties”-paneel de naam van een scherm aanpassen. De aanpassing gebeurde niet altijd op het juiste scherm. Zo werden ook de titels van openstaande tabbladen (schermen) niet mee aangepast bij verandering. De methode die instaat voor het aanpassen van deze waarde werd zodanig herschreven dat deze methode nu wel op zoek gaat naar het juiste tabblad en de titel hiervan ook aanpast. De fout bij het aanpassen van een schermnaam in de “Solution Explorer” bleek een kleine syntaxfout te zijn. 1 Hierbij
is de index de plaats waar het scherm oorspronkelijk stond.
HOOFDSTUK 4. DEBUGGING CTSCRIPT
4.3
61
Hindernissen
In vorige paragraaf kon je enkele van de kleine bugs vinden die opgelost werden tijdens deze masterproef. In deze paragraaf vindt u enkele bedenkingen bij het ontwerp van de applicatie. Bij het oplossen van de kleinere problemen en ontwikkelen van de nieuwe componenten werd af en toe duidelijk dat niet alles even performant is. We spreken hier zo min mogelijk over problemen maar wel over hindernissen. Een hindernis kan overwonnen worden en dat was uiteraard de bedoeling. Enerzijds viel het op dat enkele events leiden naar een dubbele actie achter de schermen. Dit is uiteraard niet bevorderlijk voor de performantie van de applicatie. Anderzijds kwamen we in de problemen bij sommige verwerkingen van de uitgebreide componenten. Soms wordt een component gedupliceerd om dan met het duplicaat verder te werken. Hierbij wordt uitgegaan van de gegenereerde HTML-code. Dit zorgde ook voor de nodige problemen.
4.3.1
Waterval van events
Naast aanroepen van methodes is het natuurlijk zeer handig dat er soms automatisch events worden getriggered om bepaalde handelingen te doen. Bij de ontwikkeling van CTScript werd dit zeker niet over het hoofd gezien. Sommige interacties met het programma leiden in de achtergrond tot een ware waterval van events. Dit maakt het soms heel moeilijk om op zoek te gaan naar een specifieke fout. Hier en daar zagen we tijdens debugging ook dat bepaalde methoden vrij vaak worden aangeroepen om ´e´en verwerking te verwezenlijken. Bij sommige methodes kan dit een vrij grote impact hebben op de performantie van de hele applicatie. Een goed voorbeeld van dit probleem is de methode “GetScreen()” in de klasse “CTEditScreen”. Deze methode bevat zowel een update van de HTML-code als een duplicatie van het scherm. Deze duplicatie kopi¨eert eerst de attributen met een “duplicate”-methode om dan de HTML-code te parsen naar het nieuwe object. De “duplicate”-methode gaat het object dan weer serialiseren naar een memorystream om deze dan te deserialiseren naar een nieuw object. Dit geheel wordt soms drie keer (en meer) herhaald voor een aanpassing van een component. Als het hier dan gaat om een vrij grote component 2 zien we de performantie vrij snel dalen. Om de verwerkingstijd van vrijwel alle aanpassingen vlotter te laten verlopen is het noodzakelijk de structuur van de hele applicatie eens grondig onder de loep te nemen. Misschien kunnen we al een pak opschieten met enkele controllerklassen die bepaalde zaken beheren. Op die manier zouden we bijvoorbeeld aanpassing aan de properties naar ´e´en punt kunnen sturen. Die controller kan dan de juiste component updaten en ook de weergave aanpassen. Hierdoor kan het dupliceren van componenten vermeden worden aangezien de objecten zelf beschikbaar zijn. Het is dan ook niet meer nodig om met de verkregen HTML een nieuwe component aan te maken. Dus ook de HTML-parsing zou hiermee verdwijnen. Met deze vrij eenvoudige aanpassing zouden we dus al heel wat vertraging voorkomen. Zowel de serialisatie en deserialisatie als het parsen van HTML naar 2 Met
“een grote component” wordt een component bedoeld met veel HTML-code
HOOFDSTUK 4. DEBUGGING CTSCRIPT
62
een nieuw object worden overbodig. Toen het probleem duidelijk werd stonden we nog in de beginfase van deze masterproef. In deze vroege fase werd de keuze gemaakt om niet dieper in te gaan op dit probleem. Eventueel kon het probleem later nog onder handen genomen worden. Dankzij deze keuze kon de focus op de nieuwe componenten gelegd worden.
4.3.2
Parsen van HTML naar object
Hierboven werd het parsen van HTML naar een (nieuw) object al even aangehaald. We zullen niet dieper ingaan op het performantieprobleem dat hierdoor deels werd veroorzaakt. Er zal wel besproken worden wat er werd gedaan om de grote componenten toch goed te laten parsen. Kleinere componenten parsen is geen probleem omdat deze meestal maar ´e´en variabele hebben. Zo is bijvoorbeeld enkel de tekst van een label instelbaar. Bij het parsen van deze variabelen wordt enkel deze variabele uit de HTML-code gehaald en in het nieuw object opgeslagen. Voor grotere componenten ligt dit iets moeilijker omdat hier wat meer variabelen bijgehouden moeten worden. Hieronder vindt u een opsomming van enkele variabelen die bijgehouden dienen te worden bij de kalendercomponent: • Ingestelde breedte van de component • Ingestelde hoogte van de component • Eerst weergegeven dag in de kalender • Kan een nieuwe afspraak gemaakt worden? • Begin en einde van de toegelaten periode • Begin en einde van een werkdag • ... In de huidige architectuur is het niet mogelijk deze variabelen makkelijk mee te nemen tijdens het parsen. Hiervoor werd een oplossing gezocht. De oplossing bestaat uit twee delen. Enerzijds worden de waarden uit de HTMLcode gehaald om in de properties op te slaan en anderzijds moeten de waarden van de properties ook in de HTML-code raken. De eerste stap is het ophalen van de verschillende waarden uit de HTMLcode. Daarvoor worden de verschillende waarden bijgehouden in een verborgen veld. Deze waarden zijn dus niet zichtbaar op het scherm maar wel aanwezig in de HTML-code. Op het moment van parsing worden deze waarden allemaal uitgelezen en dankzij reflection3 worden de juiste properties gezet. Een voorbeeld van deze variabelen ziet u hieronder:
WIDTH=800; HEIGHT=500; FIRSTDAY=Monday; CHANGEABLE=True; 3 Reflection is het proces waarbij een applicatie aanpassingen kan doen aan zijn eigen structuur en gedrag.
Nu de waarden in de HTML-code zitten is het dus mogelijk om van de HTML terug een object te maken met dezelfde eigenschappen. Voor de tweede stap zijn in de template van deze component enkele tags voorzien. Deze tags zullen bij codegeneratie vervangen worden door de eigenlijke waarden van de desbetreffende property. Hieronder vindt u de code van daarnet zonder waarden maar met tags. Deze tags zijn te vinden in de template-HTML-code maar niet meer tijdens het gebruik van de kalendercomponent.
Met deze twee stappen van stringverwerking is het mogelijk om instellingen en parameters goed bij te houden. De manier waarop dit gebeurd is alles behalve ideaal. Hiervan zijn we ons ook bewust. Jammer genoeg waren we genoodzaakt tijdelijk op deze manier te werken. Het is niet echt de best mogelijke oplossing maar zo kon de ontwikkeling wel voortgezet worden. Na uitgebreide herwerking van de structuur van de hele applicatie zal dit euvel waarschijnlijk opgelost zijn. De aanwezige afspraken en nieuw voorgestelde afspraken worden ook op deze manier doorgegeven. De tag “<#APPOINTMENTS#>” wordt vervangen door een reeks “
”-tags waarin telkens 1 afspraak staat. Deze afspraken worden dan tijdens het laden van de pagina op de juiste plaats gezet op de kalender.
4.3.3
64-bit compatibiliteit
Tijdens de ontwikkeling van de nieuwe componenten werd vooral gewerkt op een 32-bit machine. Toen CTScript immers gecompileerd werd op een 64-bit toestel bleek het een en ander niet meer te werken. Het werd al snel duidelijk dat hier en daar kleine veranderingen nodig waren om dit probleem tegen te gaan. In de klasse “CTEditScreen” werden hier en daar HTML-onderdelen gecast naar de klasse “HTMLScriptElementClass”. Deze klasse gaf problemen tijdens de werking van CTScript. Het alternatief hiervoor was casten naar “IHTMLScriptElement”. Hetzelfde deed zich voor met de klasse “HTMLWindow2Clas” die moest aangepast worden naar “IHTMLWindow2”. Bij het opstarten van CTScript werd al snel duidelijk dat er ook een probleem was bij het laden van de CSS-bestanden. We zagen immers geen opmaak meer.
HOOFDSTUK 4. DEBUGGING CTSCRIPT
64
Bij het linken van CSS-bestanden aan een HTML-document vonden we het probleem. Hier bleek dat de klasse “IHTMLStyleSheet2” voor de nodige problemen zorgde. Deze klasse kon vervangen worden door “IHTMLLinkElement” waarna de problemen opgelost waren.
Hoofdstuk 5
Resultaat In dit laatste hoofdstuk vindt u een beknopt overzicht van de behaalde resultaten tijdens deze masterproef. Om dit overzichtelijk te doen wordt elk luik afzonderlijk behandeld. Hierna worden de resultaten vergeleken met de vooropgestelde vereisten. Om het geheel af te ronden leest u nog eens een globaal resultaat.
5.1
Verwezelijkingen
Alles begon met een kennismaking met de mensen bij MI4C, het onderwerp en de applicatie CTScript. Bij het onderzoek leek alles heel vlot te gaan. Pas bij de eerste implementatie kwamen kleine problemen al snel naar boven. Gelukkig kon hier steeds gepast op gereageerd worden. Hierdoor ondervond ik tijdens de vier maanden stage bij MI4C enkele ups en downs. Maar mits voldoende wilskracht en doorzettingsvermogen werden alle hindernissen met glans overwonnen. De eerste fase was een kennismaking met de applicatie CTScript (en het hele pakket dat MI4C aanbiedt). Tijdens deze kennismaking werden enkele belangrijke bugs ontdekt. Deze werden dan ook eerst aangepakt. Een betere manier om een applicatie van binnen en van buiten te leren kennen, kan ik me niet voorstellen. Na een eerste ronde van debuggen ben ik begonnen aan de ontwikkeling van de agendacomponent. Als deze component grotendeels klaar was startte ik met de ontwikkeling van de verkoopcomponent. Op het einde van de stageperiode werd er getest en dus ook aan debugging gedaan. Deze laatste debugging had zowel betrekking op de nieuwe componenten als op CTScript zelf.
5.1.1
Component agendaplanning
Om tot een goed eindresultaat te komen voor deze component was het nodig voldoende onderzoek te verrichten. Zo werden enkele mogelijk externe agenda’s vergeleken. De API en diverse mogelijkheden van Google Calendar bleken de beste kandidaat te zijn. Om de API voldoende te testen alvorens effectief aan de slag te gaan werd een testapplicatie uitgebreid naar alle noodzakelijke functionaliteit. Naast het onderzoek naar externe agenda’s werd ook onderzoek gedaan naar
65
HOOFDSTUK 5. RESULTAAT
66
services voor locatie- of routebepaling. Hierbij kwam Google Directions ook als goede kanshebber uit de bus. Al legt Google wel enkele limieten op die niet direct verenigbaar zijn met het geschreven algoritme. Een andere kandidaat, Yahoo! Placefinder, bleek deze beperkingen minder op te leggen. Daarom werd initi¨eel met Yahoo! gewerkt. Om op basis van geocoding toch een goede schatting te kunnen maken van reistijden werd hiervoor een extra testapplicatie geschreven. Met deze testapplicatie kon de configuratie vlotter getest en bijgesteld worden. In een latere fase werd het algoritme bijgewerkt zodat nu zowel Yahoo! als Google gebruikt worden. Op die manier werd een optimale oplossing bereikt mits de opgelegde beperkingen. De weergave en werking binnen CTScript werd gebaseerd op de weergave van Google Calendar (online). Om alle functionaliteit goed te laten werken is het nodige zweet gevloeid. De communicatie tussen programmacode en javascript-code op de pagina zorgde voor de nodige extra moeilijkheden. Een goed voorbeeld hiervan is de timing die soms noodzakelijk is om vertragingen op te vangen. Omdat we hier reeds deze interactie moesten voorzien was deze kennis makkelijker toe te passen bij de volgende component. Naast het weergeven van een kalender en een voorstel voor een nieuwe afspraak is het ook mogelijk om te navigeren in de tijd. Er kan ook een ander voorstel gevraagd worden aan het systeem, je kan als het ware navigeren door de mogelijke voorstellen. Vooraleer deze component kan gebruikt worden moet deze dan ook ingesteld worden door een supervisor in het call center. De voorziene instellingen zijn bekomen in overleg met het hele team bij MI4C. Dankzij de meerdere visies werd een beter, flexibeler resultaat bekomen. Deze overlegmomenten zijn dan ook heel interessant gebleken voor het uiteindelijk resultaat. Er is een zeer goed, werkbaar resultaat bekomen. Het algoritme zorgt ervoor dat een call agent zo min mogelijk zelf moet interaheren met de applicatie. Het algoritme zorgt ook voor zo’n effici¨ent mogelijke opvulling van de verschillende agenda’s. Hierbij wordt rekening gehouden met de locatie van verschillende afspraken en anderzijds worden open ruimtes in een agenda zo goed mogelijk voorkomen.
5.1.2
Component verkoop
Het onderzoek voor deze component leverde in eerste instantie weinig positief resultaat. Er werden vele kant en klare oplossingen gevonden die het mogelijk maken binnen de kortste tijd een hele website op te richten voor de verkoop van producten. Anderzijds werden op bestaande webwinkels wel idee¨en opgedaan. Deze idee¨en waren cruciaal voor het uitdenken van de verschillende deelcomponenten. Door diverse systemen te bekijken werd er al snel geconcludeerd dat de bedoeling van deze component niet kon bereikt worden met ´e´en enkele component. Er werd dan ook gekozen voor een geheel van vier componenten: Een winkelmandje, een knop om een product toe te voegen, een lijst om meerdere producten toe te voegen en een statusveld. De vier componenten kunnen op zich wel hun taak vervullen maar komen pas echt tot hun recht in combinatie met de andere componenten. Om het geheel harmonieus te laten samenwerken werd een klasse voorzien die alles kan dirigeren en beheren. Deze houd alle input bij en zorgt ook voor
HOOFDSTUK 5. RESULTAAT
67
het ophalen van diverse gegevens. De productgegevens voor de lijst van producten kunnen opgehaald worden uit diverse databronnen. Deze databronnen kunnen elk afzonderlijk ingesteld en geselecteerd worden. Het systeem werd zo opgebouwd dat het perfect mogelijk is extra databronnen te implementeren op een makkelijke wijze. Bij deze component stond flexibiliteit centraal. Dankzij de vier componenten is het mogelijk om heel diverse systemen van telesales te bouwen binnen CTScript. De vier componenten kregen hiervoor elk een heel gebruiksvriendelijk interface aangemeten.
5.1.3
Debugging
Debugging kan gezien worden als derde luik van deze masterproef. Hierbij gaat het niet om het debuggen van de eigen geschreven componenten maar wel over het debuggen van de opgeleverde applicatie, CTScript. Omdat CTScript nog maar pas werd ontwikkeld waren hier en daar nog kinderziektes te vinden. Om een goed werkende applicatie aan klanten voor te kunnen leggen was het cruciaal deze op te lossen. Daarom werd hier zowel bij het begin als bij het einde van de stageperiode aan gewerkt. Diverse fouten in de verwerking van enkele handelingen werden verbeterd. Tijdens de fase van debuggen werd ook opgemerkt dat hier en daar de performantie kan verbeterd worden. CTScript is initi¨eel gebouwd om te werken met kleine componenten. Nu we aan de slag gingen met grotere componenten zoals de agendaplanning, was het performantieprobleem toch een vrij groot struikelblok. Er werd een goede oplossing gezocht en gevonden. Om deze oplossing grondig uit te werken was helaas vrij veel tijd nodig. Om de tijd nodig voor de andere componenten niet in het gedrang te brengen werd deze oplossing dan ook nog even in de wachtrij gezet. Omdat er nog geen sluitende oplossing was voorzien voor het performantieprobleem werkte de agendacomponent dan ook niet volledig zoals het zou moeten. Na enige tijd zoeken werd dan toch een goede oplossing gevonden voor dit probleem. Javascript biedt de mogelijkheid een groot deel van de pagina aan te maken nadat deze al geladen is. Deze oplossing bleek de performantie van de component enorm te verhogen. De vertraging die nu nog te merken is, wordt vooral veroorzaakt door aanvragen aan de diverse services. Kortom, er werden niet alleen kleine en iets grotere foutjes verbeterd. Er werd ook voldoende aandacht besteed aan een groter algemeen probleem binnen CTScript. Mits de nodige inventiviteit kon hiervoor ook een oplossing gevonden worden.
5.2
Beoordeling t.o.v. doelstelling
De algemene doelstelling was om beide componenten te ontwerpen, verder uit te denken1 en uit te werken binnen CTScript. Het is toch de vermelding waard dat ik de enige was binnen MI4C die ontwikkelde in C#.2 Naast de twee componenten diende er ook voorzien te worden in reporting van beide modules. Als 1 mits
het nodige overleg applicaties worden ontwikkeld in C++.
2 Andere
HOOFDSTUK 5. RESULTAAT
68
laatste was het ook een belangrijk onderdeel van deze opdracht om CTScript deels te debuggen. Zoals u in de vorige paragrafen kon lezen is de uitwerking van beide componenten goed geslaagd. Bij de uitwerking van de verkoopcomponent is zelfs het hele plan rond deze component veranderd met als gevolg een veel flexibeler geheel. Behalve het probleem betreffende performantie verliep het debuggen vrij vlot. Er zijn een mooi aantal bugs opgelost met als gevolg dat CTScript alvast een pak stabieler is geworden. Het laatste onderdeel dat ik nog niet besproken heb in deze beoordeling is de reporting verwerkt in beide nieuwe modules. Dit komt omdat er tot op heden nog geen functionaliteit hiervoor kon ge¨ımplementeerd worden. Hiervoor was interactie met de serverapplicatie CCA noodzakelijk. Aangezien de integratiefase van CTScript wat vertraging heeft opgelopen kon nog niet begonnnen worden met de implementatie van de reporting. In ruil voor de reporting werd er beslist om twee zaken als alternatief te vervullen. Enerzijds is er in de extra tijd meer aan debugging gedaan. Daarnaast is er ook gekozen om de funtionaliteit van radio buttons te verbeteren. Het is mogelijk eigen functies in javascript te defini¨eren maar deze konden niet gekoppeld worden aan andere eenvoudige componenten. Een gewone knop heeft wel een “onclick”-event, een radio button niet. Omdat dit wel handig is om een volwaardig belscript te bouwen werd deze functionaliteit ook voorzien. E´en van de algemene doelstellingen van deze masterproef is het presteren van 625 werkuren. Helaas werd deze kaap niet gehaald. Er werden in totaal wel 570 uren gepresteerd. De reden van het niet bereiken van deze limiet is o.a. te vinden bij het laattijdige veranderen van masterproefonderwerp. Toch werden kosten noch moeite gespaard om zoveel mogelijk uren te presteren. De teller van mijn afwezigheden staat nog steeds op nul. Verder werden alle andere algemene doelstellingen volledig en goed vervuld. Hierbij denken we aan het uitgebreid voorstel, de poster, een eerste versie van de scriptie (25p.), de website en de eerste versie van de scriptie. Ook de definitieve versie van de scriptie en de daarbij horende zaken werden op tijd in orde gebracht.
5.3
Besluit
Ondanks de late verandering van masterproefonderwerp boekte ik toch mooie resultaten. Beide componenten zijn volledig functioneel en klaar voor gebruik. Hiervoor was het nodige onderzoek vereist, en ook dit heeft voldoende vruchten afgeworpen. Het debuggen van CTScript heeft eveneens tot mooie resultaten geleid. Daar waar de agendacomponent robuustheid en een intelligent algoritme vereiste, was het noodzakelijk in de verkoopcomponent voldoende flexibiliteit aan te bieden. Hierdoor mag ik toch stellen dat deze masterproef diverse uitdagingen inhield. Naast deze resultaten die rechtstreeks verband houden met de opdracht, heeft deze masterproef me uiteraard veel bijgebracht. Het ontwikkelen binnen een bestaande applicatie is iets wat tijdens de opleiding haast niet aan bod kwam. Dit zorgde af en toe voor de nodige frustraties en ontmoedigingen. Ge-
HOOFDSTUK 5. RESULTAAT
69
lukkig werd ik bijgestaan door een team van ervaren mensen die me dan ook de nodige tips and tricks konden bijbrengen om vlotter met dergelijke problemen om te gaan. Zo leerde ik bijvoorbeeld ook een applicatie profilen om het performantieprobleem tot op het been te ontleden. Bij de afwerking van deze masterproef hoorde ook een installer. Deze voorzien van de nodige toeters en bellen bleek een hele uitdaging. Al bij al heb ik enkele mooie, leerrijke maanden achter de rug. In ruil voor het noeste werk kreeg ik alvast een dosis voldoening van het resultaat en een werkaanbieding bij MI4C. Ik hoop dan ook van harte dat dit product verder mag bijdragen aan het succes van MI4C. Hopelijk zal ik hier zelf verder mogen aan blijven meehelpen. In de inleiding bedankte ik reeds iedereen die deze ervaring mogelijk maakte. Eenmaal bedanken lijkt me immers te weinig. Daarom wil ik mijn dank hier graag nogmaals uitspreken. Ik denk hierbij niet enkel aan mijn promotoren maar ook aan iedereen binnen MI4C en de docenten van Hogeschool Gent die druk in de weer zijn om ons, studenten, naar een diploma te loodsen. Bedankt iedereen!
Bijlage A
Use Cases A.1 A.1.1
Aanmaak belscript Doel
Deze use case beschrijft eigenlijk de algemene werking van de applicatie CTScript. De supervisor kan een belscript maken, specifiek voor een bepaalde opdracht. Dit belscript kan dan gebruikt worden om de operators door de opdracht te leiden. Dankzij een belscript kunnen zij de juiste vragen stellen en beslissingen nemen op het juiste moment. Deze functionaliteit is dus grotendeels voorzien in CTScript. Het komt er dus op neer dat de nodige componenten voor zowel agendaplanning als verkoopbeheer moeten ge¨ıntegreerd worden. De nodige configuratie bij het gebruiken van deze modules moet wel voorzien worden zodat alle correct kan (samen)werken.
A.1.2
Primaire actor
Call Center Supervisor
A.1.3
Precondities
• De supervisor beschikt over de nodige gegevens i.v.m. de opdracht. • CTScript is gestart.
A.1.4
Postconditie
• Er is een belscript dat kan gebruikt worden bij het uitvoeren van een taak.
A.1.5
Algemeen pad
1. De supervisor kiest ervoor een nieuw belscript aan te maken. 2. Het systeem maakt automatisch een leeg scherm en toont dit. 3. De supervisor kiest ervoor een bestaande HTML-template als basis te gebruiken.
70
BIJLAGE A. USE CASES
71
4. Het systeem laadt dit template en geeft het weer. 5. De supervisor plaatst een nieuwe component op het template. 6. Het systeem geeft de mogelijkheid om deze component te configureren. 7. De supervisor vult de nodige parameters in. 8. Het systeem registreert deze en past zo het scherm aan (terug naar stap 5 of verder naar 9) 9. De supervisor kiest ervoor om het project op te slaan als belscript. 10. Het systeem slaat dit nieuwe belscript op.
A.1.6
Alternatieve paden
3. De supervisor kiest ervoor een nieuw scherm te maken zonder HTMLtemplate. (a) Naar stap 5.
BIJLAGE A. USE CASES
A.2 A.2.1
72
Agendaplanning Doel
Deze module zal instaan voor het inplannen van nieuwe afspraken in de agenda van vertegenwoordigers. Het call center staat in voor het boeken van vertegenwoordigers bij potenti¨ele klanten van een ander bedrijf. Op deze manier moet het bedrijf hier zelf geen tijd aan spenderen. Iedere vertegenwoordiger heeft zijn persoonlijke agenda, hiermee moet rekening gehouden worden.
A.2.2
Primaire actor
Call Center Agent (operator genoemd)
A.2.3
Secundaire actor
Call Center Supervisor
A.2.4
Precondities
• De werkpost van de operator heeft verbinding met het internet • Er is een telefoongesprek met een mogelijke klant tot stand gebracht. • CTScript is actief en het belscript is geladen.
A.2.5
Postcondities
• Er werd een afspraak gepland op de meest effici¨ente wijze. • De vertegenwoordiger kan deze afspraak bekijken.
A.2.6
Algemeen pad
1. Het systeem krijgt de bekende gegevens van de klant. 2. De operator stelt de nodige vragen aan de klant en vult de verkregen gegevens in. 3. Het systeem stelt enkele mogelijke agenda’s voor waarin een afspraak kan gemaakt worden. 4. De operator kiest een agenda. 5. Het systeem vraagt de nodige, concrete gegevens voor de afspraak. 6. De operator geeft de gegevens in (eventueel na vragen aan de klant). 7. Het systeem verwerkt de nieuwe afspraak en verstuurd ze naar de externe kalender.
BIJLAGE A. USE CASES
A.2.7
73
Alternatieve paden
1. De klant blijkt niet ge¨ınteresseerd. (a) Het gesprek wordt vroegtijdig afgesloten. (b) De operator duidt aan dat deze klant geen interesse had en maakt geen afspraak. 3. Er zijn geen vertegenwoordigers vrij binnen de gekozen tijdsspanne. (a) De operator vraagt aan de klant of een ander moment past. i. Ja? Terug naar stap 3. ii. Neen? A. Het gesprek wordt afgebroken. B. De operator duidt aan dat de klant wel interesse heeft maar er geen afspraak kon gemaakt worden. 3. Er kan geen verbinding gemaakt worden met de agenda’s (a) De operator zorgt dat het connectieprobleem opgelost is. (b) De operator probeert de agenda’s nogmaals op te halen. i. Gelukt? Terug naar stap 3. ii. Niet gelukt? A. Het gesprek wordt afgebroken. B. De operator duidt aan dat de klant wel interesse had maar dat wegen storing het gesprek moest afgebroken worden. 4. Er blijkt geen afspraak mogelijk te zijn in de aangeboden agenda(’s). (a) De operator past de gegevens aan. (b) Opnieuw naar stap 3. 4. De klant kan toch niet op een van de aangeboden momenten. (a) De operator past de gegevens aan. (b) Opnieuw naar stap 3. 7. De nieuwe afspraak kan niet opgeslagen worden in de externe agenda. (a) Het systeem toont hiervan een melding. (b) De operator kan het connectieprobleem controleren en eventueel (laten) oplossen. (c) De operator kiest ervoor opnieuw te proberen. i. Het systeem probeert opnieuw de afspraak vast te leggen. 8. De operator kiest ervoor het opslaan uit te stellen. (a) Het systeem slaat de afspraak tijdelijk op om later opnieuw op te slaan.
BIJLAGE A. USE CASES
A.3
74
Verkoopbeheer
A.3.1
Doel
Deze module zal worden gebruikt om vast te leggen welke klanten in welke producten ge¨ınteresserd zijn en/of welke ze willen kopen. Deze worden geregistreerd in de centrale databank en achteraf doorgegeven naar de opdrachtgever (bv fabrikant).
A.3.2
Primaire actor
Call Center Agent (operator genoemd)
A.3.3
Secundaire actor
Call Center Supervisor
A.3.4
Precondities
• Er is een telefoongesprek met een mogelijke klant tot stand gebracht. • CTScript is actief
A.3.5
Postcondities
• Een of meerdere producten werden verkocht aan de klant en geregistreerd. • De opdrachtgever werd op de hoogte gebracht.
A.3.6
Algemeen pad
1. Het systeem krijgt de bekende gegevens van de klant. 2. De operator stelt de nodige vragen aan de klant en vult de verkregen gegevens in. 3. Het systeem stelt de mogelijke producten voor. 4. De operator geeft uitleg bij deze producten aan de klant. 5. De operator duidt aan welke producten de klant wenst te kopen. 6. Het systeem registreert de aankoop en verwerkt deze. 7. Het systeem stuurt hiervan een melding naar de opdrachtgever.
A.3.7
Alternatieve paden
Alternatieve paden voor stappen 1 en 2 zijn gelijk aan die van “use case Agendaplanning”. 5. De klant wenst geen aankoop te doen (a) De operator beindigd het gesprek
BIJLAGE A. USE CASES
75
(b) De operator duidt aan dat de klant niet genteresseerd en niets wenst te kopen. 5. Er treedt een probleem op tijdens het melden van de verkoop bij de opdrachtgever. (a) Het systeem probeert het opnieuw i. Gelukt? Use case afgerond ii. Niet gelukt? Het systeem bewaart de melding voor latere verwerking.
Bronnen [1] Website MI4C http: // www. mi4c. be [2] Website ASKIA http: // www. askia. com [3] Website Crystal Reports http: // www. crystalreports. nl [4] Website SyncMyCal http: // www. syncmycal. com/ [5] Website KeepandShare http: // www. keepandshare. com/ [6] Website Did it Better http: // www. diditbetter. com/ [7] Website Plaxo http: // www. plaxo. com/ [8] Website Google Calendar http: // www. google. com/ calendar [9] Website Google Data API nl-NL/ apis/ calendar/
http: // code. google. com/ intl/
[10] Google Maps API http: // code. google. com/ intl/ nl-NL/ apis/ maps/ documentation/ geocoding/ [11] Google Directions API http: // code. google. com/ intl/ nl-NL/ apis/ maps/ documentation/ directions/ [12] Website Yahoo! Calendar http: // calendar. yahoo. com [13] Website Yahoo! yui/ calendar/