• No results found

Design & implementation av kösystemet Inline

N/A
N/A
Protected

Academic year: 2022

Share "Design & implementation av kösystemet Inline"

Copied!
87
0
0

Loading.... (view fulltext now)

Full text

(1)

Design & implementation av kösystemet Inline

Design and implementation of the queue system Inline

Niclas Fredriksson

Fakultet för hälsa, natur- och teknikvetenskap Datavetenskap

C-uppsats 15 hp

Handledare: Katarina Asplund Examinator: Stefan Alfredsson Oppositionsdatum: 20190115

(2)
(3)

i

Sammanfattning

Att stå i en kö till ett ärende är något som alla människor gör regelbundet och ses oftast som ett hinder i ett samhälle där allt ska gå fortare och mer effektivt. Det finns idag inte något känt hjälpmedel för butiker och kunder att hantera väntetiden på vid fysiska besök förutom att tillsätta fler personal. Detta examensarbete beskriver en prototyp av ett kösystem som ska vara en början på lösningen till detta problem. Idéen till prototypen framställdes av Altran och har som mål att i slutprodukten effektivisera kösystemen i dagens fysiska butiker.

Kösystemet ska möjliggöra för kunder att ställa sig i en ärendekö till en vald butik genom en applikation och anlända till butiken när han/hennes tur börjar närma sig. I denna uppsats presenteras resultatet av projektet som utformade sig i två applikationer med ett web API.

Den ena applikationen är till för butikens kunder där varje kund har möjligheten att välja en butik och tillhörande ärende som han/hon kan ställa sig i kö till. Tillsammans med web API:et får kunden information om köposition och estimerad väntetid. Den andra

applikationen är till för butikspersonalen för att skapa och välja de kassor och ärenden som kunderna köar till. Tillsammans med web API:et kan personalapplikationen hantera kön enligt FCFS-metoden (First Come, First Served). Utöver prototypen ligger det också i Altrans intresse att av projektet hitta de dolda problemen i kösystemets idé och utforska eventuella lösningar. Denna uppsats presenterar därför även en analys av de problem som uppdagades och ger alternativa lösningar.

(4)

ii

Abstract

Standing in a queue for a service is something that all people do on a regular basis and is usually seen as an obstacle in a society where we expect that everything should go faster and more efficiently. There is currently no known solution for stores and customers to handle the waiting time during physical visits except to recruiting more staff. This degree project describes a prototype of a queuing system that should be a solution to this problem. The idea for the prototype was produced by Altran and aims to streamline the queuing system in today's physical stores. The queuing system should enable customers to stand in a queue to a selected store through an application and arrive at the store when his / her turn starts to approach. The resulting system consist of two applications with a web API. One application is for the store's customers, where each customer has the opportunity to choose a store and an associated service that he / she can queue for. Together with the web API, the customer receives information about the position and estimated waiting time. The second application is for store staff, where they can create and select the cash registers and services that customers queue for. Together with the web API, the personnel application can handle the queue according to the FCFS method. In addition to the prototype, it is also in the interest of Altran to find the hidden problems with this idea and explore and analyse the solutions. Therefore, this degree project will also present an analysis of the problems discovered and provides with alternative solutions.

(5)

iii

Innehållsförteckning

1. Introduktion ... 1

1.1 Projektets bakgrund ... 1

1.2 Syfte och mål ... 1

1.3 Viktiga resultat ... 2

1.4 Disposition av uppsatsen ... 2

2. Bakgrund ... 3

2.1 C# ... 3

2.2 Xamarin ... 4

2.3 Windows Presentation Foundation - WPF ... 4

2.3.1 Extensible Application Markup Language - XAML ... 5

2.4 Webbservern... 7

2.4.1 ASP.NET Core ... 7

2.4.2 Representational State Transfer - REST ... 8

2.4.3 Asynkron programmering ... 9

2.5 MSSQL... 10

2.6 SignalR ... 10

2.7 Sammanfattning ... 11

3. Kravanalys ... 12

3.1 Översikt ... 12

3.2 Mobilapplikationen ... 13

3.3 Personalapplikationen ... 15

3.4 Webbservern... 17

3.5 Sammanfattning ... 18

4. Systemöversikt, webbserver och databas ... 19

4.1 Systemöversikt ... 19

4.1.1 Systemnamn... 19

4.1.2 Kommunikation ... 19

4.2 Inline-databasen ... 21

4.2.1 Databasdesign ... 21

4.2.2 Stores ... 22

4.2.3 Desks ... 23

4.2.4 Errands ... 23

(6)

iv

4.2.5 Client ... 24

4.2.6 Queueticket ... 24

4.3 Inline-webbserver ... 26

4.3.1 Controllers ... 26

4.3.2 Dataproviders... 30

4.3.3 ClientHub... 31

4.4 Köposition och tidsestimering ... 32

4.4.1 Skapa kölapp... 32

4.4.2 Hämta nästa kölapp ... 33

4.4.3 Köplats ... 36

4.4.4 Tidsestimering ... 38

4.5 Sammanfattning ... 40

5. Applikationerna ... 41

5.1 Färgschema... 41

5.2 Personalapplikationen - frontend ... 43

5.2.1 Login- och registreringsfönster ... 43

5.2.2 Huvudfönster ... 46

5.2.3 Servicefönster ... 48

5.3 Personalapplikationen - backend ... 50

5.3.1 Klassen HttpConnect ... 50

5.3.2 Klassen SignalRClient ... 52

5.3.3 Ta bort kassor/ärenden ... 53

5.4 Mobilapplikationen - Frontend... 56

5.4.1 Start- och ärendesidan ... 56

5.4.2 Kösidan ... 59

5.5 Mobilapplikationen - backend ... 62

5.5.1 Position i kön ... 62

5.5.2 Tidsestimering ... 63

5.5.3 Kundens tur... 64

5.6 Sammanfattning ... 64

6. Resultat och utvärdering ... 65

6.1 Resultat ... 65

6.1.1 Webbservern ... 65

(7)

v

6.1.2 Personalapplikationen ... 66

6.1.3 Mobilapplikationen ... 67

6.2 Utvärdering... 68

6.2.1 Köhantering ... 68

6.2.2 Tidsestimeringen ... 69

6.2.3 Xamarin ... 71

7. Slutord ... 72

Referenser ... 73

Bilaga A ... 75

Bilaga B ... 76

(8)

vi

Figurer

2.1 Exempelkod för att presentera en knapp i XAML . . . 5

2.2 Resultatet av kodexemplet från figur 2.1 . . . 6

2.3 Exempel på hierarkin i XAML . . . 6

2.4 Exempel på HttpPost-deklaration . . . 8

3.1 Användarflöde för start av applikation till kund får service . . . 14

3.2 Användarflöde för start av applikation till kund står i kö . . . 16

3.3 Användarflöde för köhantering på webbservern . . . 18

4.1 Systemöversikt på kommunikation mellan de fyra systemdelarna . . . 20

4.2 UML-diagram över Inlinedatabasen . . . 22

4.3 Rutt-deklaration för Inlinewebbservern . . . 27

4.4 Klassdiagram för Controllers i Inline-webbservern . . . 28

4.5 CreateDesk-funktionen i klassen DeskController . . . 29

4.6 Dataprovider klassdiagram . . . 30

4.7 Detaljbild på DeskDataProviderflöde . . . 31

4.8 SQL-förfrågan för att skapa ny kölapp . . . 33

4.9 NextInLine-funktionen i QueueController-klassen . . . 33

4.10 SQL-förfrågan för att hämta nästa kund i kön . . . 34

4.11 SignalR-anrop till nästa kund i kön . . . 35

4.12 Funktionen UpdateQueueInformationToClients . . . 36

4.13 SQL-förfrågan för att gruppera alla kunder efter EID . . . 37

4.14 SQL-förfrågan för att beräkna alla kunder framför en viss kund . . . 37

(9)

vii

4.15 SignalR-anrop till UpdateQueueInformation till mobilapplikationen . . . 38

4.16 Matematisk formel för estimerad väntetid för kunder . . . 39

4.17 Anrop till GetAverageWTime . . . 39

4.18 SQL-förfrågan för att hämta medelvärde väntetiden i en ärendekö . . . 39

4.19 Kod för att beräkna väntetid och skicka ut till berörd kund . . . 40

5.1 Personalapplikationens färgschema . . . 42

5.2 Mobilapplikationens färgschema . . . 42

5.3 Bild på login fönstret . . . 43

5.4 Bild på felinmatning i loginfönstret . . . 44

5.5 Design på registreringsfönstret . . . 45

5.6 Bild på felinmatning i registreringsfönstret . . . 46

5.7 Design av huvudfönstret . . . 47

5.8 Design av meny i huvudfönstret . . . 48

5.9 Storyboard-kod . . . 48

5.10 Design av servicefönstret . . . 49

5.11 Skapa ett nytt ärende i klassen HttpConnect . . . 50

5.12 GetNextInLine funktion i klassen HttpConnect . . . 51

5.13 Bild på misslyckad SignalR-kontakt . . . 52

5.14 SignalR klient konstruktor . . . 53

5.15 RemoveDesk-funktion . . . 53

5.16 Ta bort kassa-varning . . . 54

5.17 ErrandRemove-funktion . . . 55

(10)

viii

5.18 Ta bort ärende-varning . . . 55

5.19 Design av startsidan för mobilapplikationen . . . 57

5.20 Design av ärendesidan för mobilapplikationen . . . 58

5.21 Förfrågan om kund vill fortsätta till vald kö . . . 59

5.22 Design av kösidan för mobilapplikationen . . . 60

5.23 Popup-fönster som meddelar kunden att det är dennes tur . . . 61

5.24 UpdateQueueInformation-funktion . . . 62

5.25 StartTimer-funktionen . . . 63

5.26 Funktionen UpdateEstTime . . . 63

5.27 Funktionen AlertCustomer . . . 64

(11)
(12)

1

1. Introduktion

1.1 Projektets bakgrund

Att stå i en kö är något som alla har erfarenheter av och oftast inte positiva sådana. Ändå används sällan någon form av elektroniskt hjälpmedel för att minska eller hantera köer, till exempel på ett bankkontor eller ett apotek. Detta trots den negativa inverkan köandet har på kundens övergripande uppfattning om företagets servicekvalité [1].

Detta projekt är en prototyputveckling i C# som grundar sig på en idé från konsultföretaget Altran i Karlstad om att effektivisera de kösystem som existerar i butiker idag och att förenkla vardagen för kunder. Idén är att möjliggöra för kunder att ställa sig i kö utan att fysiskt göra det till ett ärende de har i en vald butik. Detta skulle innebära att en kund kan ställa sig i en kö och anlända till butiken när hans/hennes tur börjar närma sig istället för att stå och vänta på plats.

1.2 Syfte och mål

Syftet med detta projektarbete är att skapa en prototyp av ett system som med två applikationer och ett webbaserat API med tillhörande databas ska hantera och vara ett komplement eller ersättning till fysiska köer i serviceinriktade butiker. En av de två

applikationerna är en mobilapplikation där kunder kan ansluta sig till en butik för att ställa sig i en kö. Denna kö är kopplad till ett ärende som kunden vill ha service kring och den första positionen i kön ska disponeras ut till en ledig kassa inom butiken. Den andra applikationen är en personalinriktad applikation där butikens anställda väljer kassor och ärenden samt hanterar sina kunder i kön. Uppdraget har framställts av Altran i intresse av att ha ett bassystem för eventuell vidareutveckling av ett kösystem som ska lanseras till företag och kunder. Till skillnad från en fysisk butik, där kunder ställer sig i en kö till en kassa, så ska detta system hantera köer efter ärenden och låta personalen själv välja vilka ärenden de kan och vill hantera. Det slutgiltiga målet med systemet är att sedan vidareutveckla prototypen så att den kan ersätta eller integreras med de fysiska kölappautomaterna i butiken så att personal kan hantera kunder som både har valt att stå i kö i butiken och genom applikationen.

Mobilapplikationen är byggd med hjälp av Xamarin (se avsnitt 2.2), personalapplikationen är implementerad i WPF (se avsnitt 2.3) och webbservern till dessa är utvecklad i ASP.NET Core (se avsnitt 2.4).

(13)

2

1.3 Viktiga resultat

Det är tre viktiga resultat som denna prototyp uppfyller. Det första resultatet är en

mobilapplikation som presenterar valmöjligheterna mellan butiker och de ärenden varje butik tillhandahåller. Mobilapplikationen är också tillgänglig på flera plattformar för att få in en så stor målgrupp som möjligt. Det andra resultatet är en prototyp av en applikation som

personalen i butiken ska använda. Denna applikation möjliggör för personalen att skapa kassor och ärenden där kunder kan tas emot samt ge personalen valmöjligheten att välja vilka ärenden de vill hantera. Detta resulterar i att personalen kan välja att ta emot de ärenden som har högst tryck för att minska väntetiden för kunderna. Det tredje resultatet med detta

kösystem är web API:et som hanterar förfrågningar från kunder och personal och disponerar ut information om köposition och en beräknad väntetid till kunderna.

1.4 Disposition av uppsatsen

Nästa kapitel i denna uppsats – kapitel 2 – presenterar bakgrunden till projektet. Detta kapitel tar upp de verktyg och metoder som har använts för att lösa uppdraget. Vidare i kapitel 3 beskrivs kravanalysen bakom projektet, dvs. de krav som Altran ställde på de olika delarna i systemet. Kapitel 4 handlar om översikten av systemet och en detaljbeskrivning av hur webbservern tillsammans med databasen är uppbyggda för att hantera kösystemet. I kapitel 5 presenteras applikationerna som personalen och kunderna ska använda. Detta kapitel tar upp både hur frontend av applikationen ser ut och hur backend hanterar uppgifterna. Kapitel 6 handlar om resultatet och utvärderingen. Här tas resultat från varje del av systemet upp tillsammans med de mål som lyckades och de mål som misslyckades. I detta kapitel redogörs även såväl de positiva som de negativa delarna i projektet ur ett tekniskt perspektiv, vilka problem som har uppkommit och vad som skulle kunna vara lösningen på dessa. Slutligen i kapitel 7 beskrivs de personliga erfarenheter och tankar kring resultatet av projektet.

(14)

3

2. Bakgrund

Detta kapitel tar upp bakgrunden till projektet samt ger beskrivningar av de verktyg som används i lösningen. I avsnitt 2.1 beskrivs programspråket C# och dess fördelar. Beskrivning av Xamarin och WPF-ramverket ges i avsnitt 2.2 respektive 2.3. I avsnitt 2.4 presenteras de verktyg webbservern hanterar som omfattar ASP.NET Core, REST-konceptet och Asynkron Programmering. Fortsättningsvis i avsnitt 2.5 redogörs för MSSQL som är systemets databas- verktyg. I det sista avsnittet, 2.6, presenteras biblioteket SignalR och dess möjligheter.

2.1 C#

Mobilapplikationen, personalapplikationen och webbservern är alla utvecklade i

programspråket C#. C# är ett objektorienterat programspråk, vilket betyder att man bygger upp program i klasser och objekt. En klass kan beskrivas som en modell över hur begrepp ska hanteras eller struktureras, medan ett objekt är en instans av en klass som samverkar med andra objekt [2]. C#:s struktur stödjer fullt ut de fyra grundstenarna i objektorienterad programmering: inkapsling, arv, polymorphism och abstraktion [3]. Jämfört med programspråket C, som är ett lågnivåspråk, är C# ett högnivåspråk. Detta betyder att utvecklaren kan fokusera mer på lösningar på logiska problem än på programkodsbaserade problem [4]. C# tar exempelvis hand om skräpinsamling, är mer typsäkert, lätt att integrera med andra microsoftbaserade verktyg och är ett av programspråken i .NET (se avsnitt 2.4.1) som har ett stort kodbibliotek för att underlätta Client/Serverutveckling [5].

Anledningen till att detta projekt har utvecklats i programspråket C# är att det är ett av de programspråk som stöds i .NET och det är också ett av de programspråk jag har mest erfarenhet av.

(15)

4

2.2 Xamarin

Smartphones är idag någonting de flesta äger och hanterar till vardags i stora delar av världen och de ses inte längre som lyxvaror. Det finns ett helt hav av olika mobiltillverkare och det kan vara svårt för en utvecklare att välja rätt plattform och operativsystem för att nå ut till så många användare som möjligt. Enligt statistiken [6] har Android den största marknaden i Europa idag med iOS som sin största konkurrent. Trots det, även om utvecklaren väljer att utveckla programmet i Android missar han/hon ca en tredjedel av användarna.

Xamarin är en samling verktyg som löser detta problem genom att ha programmeringsspråket C# som bas till både Android- och iOS-utveckling. Med hjälp av verktygen kan utvecklare utveckla inbyggda användargränssnitt till Android och iOS med samma kod i bakgrunden.

Programmet blir då ett så kallat plattformsoberoende program. Ett plattformsoberoende program är ett program som kan exekveras från minst två plattformar, som till exempel Microsoft Windows och Linux [7]. Genom att använda två verktyg, Xamarin.iOS och Xamarin.Android som medföljer Xamarin kan utvecklare forma användargränssnittet efter iOS och Androids behov. Detta gör Xamarin genom att översätta back-end C#-kod till deras gränssnittsspråk. När en iOS-användare startar en applikation som är utvecklad genom

Xamarin kompilerar Xamarins kompilator AOT(Ahead-Of-Time) ner applikationen direkt till ARM(Advanced RISC Machine) assemblerkod. Om användaren istället använder en

Androidbaserad mobiltelefon med samma applikation kompilerar Xamarins kompilator först ner koden till Intermediate Language (IL) som sedan kompilerar enligt JIT(Just-In-Time) till assemblerkod för processorn [8]. I detta projekt är mobilapplikationen utvecklad i C#

Xamarin för att effektivt nå cirka 98 % av europas användare [6].

2.3 Windows Presentation Foundation - WPF

WPF är ett ramverk för Windows skrivbordsapplikationer som är inriktat på att utveckla användargränssnitt. I WPF bygger man programmet med hjälp av två programspråk, märkspråket Extensible Application Markup Language (XAML, se avsnitt 2.3.1) och C#.

XAML används för att definiera användargränssnittet, binda komponenter till data och utföra 2- och 3D-animationer medan C# används som bakomliggande kod för att definiera

komponenternas beteende. Detta resulterar i en flexibel hantering av mer avancerade

(16)

5

kontroller och komponenter [9]. I detta projekt utvecklas butikspersonalens

skrivbordsapplikation med C# som använder WPF för att ge ett användarvänligt GUI (Graphical User Interface), ha mer flexibla verktyg för att anpassa applikationen till användarens behov samt för att den ger fler valmöjligheter till tredjepartskontroller vid behov.

2.3.1 Extensible Application Markup Language - XAML

XAML är det språk som används i WPF (se avsnitt 2.3) för att definiera gränssnittelement, gränssnittbaserade funktioner och händelser [10]. XAML är ett märkspråk som direkt representerar objektinstansering och exekvering. Därför har element som har skapats i XAML samma förmåga att interagera med systemresurser som till exempel med

nätverksåtkomst och filsystem-IO, samtidigt som de kan representera ett GUI i realtid [11]. I XAML använder man sig av taggar för att definiera vad som ska och inte ska presenteras för användaren. Dessa taggar fungerar som en referens för kompilatorn för att urskilja text från element och funktioner [12]. I följande bildexempel (se figur 2.1) använder jag en start-tagg till elementet knapp (Button) som är en referens till ett knappelement inbyggt i systemet. Jag sätter storleksrestriktioner på knappens bredd (Width), höjd (Height) och textstorlek

(FontSize). Därefter skriver jag “Klicka här!” efter knappens tagg innan jag slutligen använder en sluttagg på knappen , “</Button>”.

Figur 2.1 Exempelkod för att presentera en knapp i XAML

När programmet exekverar texten noterar den att det är en knapp med egenskaper som en bredd på 250 pixlar, en höjd på 150 pixlar och att all text associerat med denna knapp ska ha en textstorlek på 40 punkter. Mellan starttagen och sluttaggen anges den text som ska visas på knappen (se figur 2.2).

(17)

6

Figur 2.2 Resultatet av kodexemplet från figur 2.1

XAML-strukturen är ett hierarkiskt träd (se exempel i figur 2.3) där varje element kan ha enbart en förälder. Oftast hittar man högst upp i trädet själva fönstret, där alla visuella

komponenter ska presenteras, som sedan grenar ut i paneler som hjälper till att hålla element i position. Längst ner i trädet hittar vi komponenter, till exempel knappar, med attribut.

Figur 2.3 Exempel på hierarkin i XAML

(18)

7

2.4 Webbservern

Webbservern i detta projekt är mellanlagret mellan mobilapplikationen (Xamarin) och

personalapplikationen (WPF). Webbserverns uppgifter består av att ge personalapplikationen möjlighet att logga in i sin butik, få tillgång till sina ärenden och att hämta den nästa mest prioriterade kunden i kön. Den ger även mobilapplikationerna tillgång till att hämta alla butiker och ärenden, visar antal personer som står i kö till varje ärende samt ger en estimerad väntetid. Webbservern är med andra ord applikationernas API mellan varandra och

databasen. För att servern ska kunna ta hand om förfrågningar från flera olika plattformar över nätet, oftast på samma gång, använder jag ASP.NET Core med REST (se 2.4.2) som struktur på kommunikationen och merparten av koden baseras på asynkron programmering (se avsnitt 2.4.3).

2.4.1 ASP.NET Core

ASP.Net Core är ett gratis open-source ramverk som stödjer utveckling av webbaserade program med C# och C++ som programmeringsspråk. Det finns flera fördelar med att välja Core. Till skillnad från ASP.NET, som har de inbyggda modellerna MVC(Model-View- Controller) och Web API (Application programming interface) separerade, har ASP.NET Core båda dessa i en modell [13]. MVC är en mjukvaruarkitektur, det vill säga systemets strukturella beteende, som går ut på att skilja applikationens logik från resten av

användargränssnittet. M i MVC står för “Model” och är den del som representerar datan och logiken i systemet. V i MVC står för “View” och representerar användargränssnittet till modellerna och ger möjlighet till interaktion med modellerna för användare. C i MVC står för

”Controllers” och är den del som bearbetar händelser och event mellan Model och View. [14]

ASP.NET Core är även byggd för plattformarna Windows, macOS och Linux, vilket gör det mer lätthanterligt att byta operativsystem även efter lanseringen av systemet. Eftersom servern är tillgänglig över internet från mobilapplikationen och personalapplikationen kan ASP.NET Core tillhandhålla bibliotek för att bland annat skapa webbkontakt och skapa en MVC-struktur [15].

(19)

8

2.4.2 Representational State Transfer - REST

REST är en struktur för att designa nätverksbaserad kommunikation mellan klient och server, som regel med HTTP-protokollet [16]. Denna struktur är de förfrågningar vi gör idag till olika sidor på internet. En länk till en nyhetsartikel kan exempelvis se ut så här:

https://kvallsnyheter/senaste/mat

På samma sätt skickar man förfrågningar till en server genom att göra en förfrågan till en förbyggd rutt i serverkoden som exempelvis:

https://MyServer/API/GetAllProducts

Servern ligger och passivt väntar på förfrågan från klienter och letar efter en passande rutt när en begäran anländer. Om rutten finns kan servern hantera denna förfrågan och skicka tillbaka ett svar till sin anropare. REST använder alla operationer i CRUD (Create, Read, Update, Delete), som är de fyra basoperationerna för bestående lagring inom programmering [17]. I ett REST-koncept implementerar man efter CRUD genom att först implementera en klass där man ger klassen en rutt, exempelvis “api/CreateDesk”. Sedan deklarerar man operationerna i klassen med HttpGet, HttpPost, HttpUpdate och HttpDelete (se figur 2.4).

Figur 2.4 exempel på HttpPost-deklaration

Får webbservern en förfrågan från en klient om att hämta alla butiker i databasen genom rutten “../api/CreateDesk” så vet programmet att den funktionen som har deklarerats med HttpPost(“CreateDesk”) (se figur 2.4) är den rätta vägen att gå.

(20)

9

2.4.3 Asynkron programmering

När man hanterar webbaserade applikationer, skriver data till filer, gör I/O eller går igenom stora matematiska beräkningar, kan dessa aktiviteter potentiellt blockera programmets andra processer och tvinga applikationen att vänta. Ibland kan till exempel webbåtkomsten vara långsam, vilket kan bero på att programmet väntar på ett svar från servern eller läser mycket data från en fil. Det resulterar i att programmet känns långsamt och icke-responsivt, vilket i sin tur resulterar i låg användarvänlighet.

För att förhindra dessa flaskhalsar och motverka nedsatt prestanda i programmet är mina program skrivna enligt en asynkron programmeringsstruktur. Asynkron är ett synonym till

“inte samtidigt”, vilket lätt kan missförstås som att programmet inte kan exekvera två saker samtidigt. Det som menas med asynkron programmering i den här miljön är att ett program kan kommunicera asynkront med andra utomstående moduler (Webbkontakt, I/O etc). Det vill säga att systemen inte kräver ett svar på en förfrågan direkt. Ett bra exempel kan vara att jämföra en sms-tjänst med ett telefonsamtal. Om du skickar ett sms till någon förväntar du dig kanske inte alltid ett svar direkt, utan utför andra aktiviteter tills du får ett sms tillbaka, det vill säga att du har en asynkron kommunikation. När du ringer någon är du upptagen med att kommunicera med den du ringer till och du förväntar dig en direkt kommunikation med den du talar med. Du har därför en synkron kommunikation [18].

I asynkron programmering i C# finns det två viktiga nyckelord, “async” och “await”. Async är en deklaration av en metod som anger att den nämnda metoden ska ha någon form av asynkront anrop i koden. Det vill säga att metoden exekverar synkront (en funktion i taget) tills en “await” deklaration anges. En “await”-deklaration anger man innan ett anrop till en asynkron metod. Det betyder att modulen man har anropat ger tillbaka kontrollen till anroparen med ett åtagande att producera ett resultat [19]. Det program som har kallat den blockerande metoden asynkron kan nu fortsätta exekvera andra delar i programmet som är oberoende av anropet. Detta medför att en användare till exempel kan klicka vidare till nästa sida i programmet eller stänga av programmet utan att behöva vänta på ett svar från

webbservern.

(21)

10

2.5 MSSQL

MSSQL (Microsoft Structured Query Language) är den databas som används i detta projekt för att spara, modifiera och hämta data såsom butiker, kunder, ärenden, kassor och kölappar.

MSSQL är en databashanterare som är skapad av Microsoft och använder en SQL-dialekt (Structured Query Language) som heter T-SQL (Transact-SQL) för att kommunicera med relationella databaser [20] [21].

T-SQL, som används en del i denna uppsats, är en förlängning av SQL-programspråket och som utöver SQL-standard tillåter procedur-programmering och lokala variabler. T-SQL har inbyggda hjälpfunktioner för att hantera strängar, datum och matematiska formler [22].

2.6 SignalR

SignalR är ett bibliotek som lanserades 2013 av Microsoft och som gör utveckling av realtidsfunktioner över internet lättare för utvecklare. På webbservern skapar man en så kallad Hub som är ett centrum för klienter för att ha en dubbelriktad kommunikation med webbservern. Webbservern kan med hjälp av denna Hub pusha ut information till alla som är i kontakt med denna hub [23]. När en klient tar kontakt med en Hub genereras ett unikt ID till den uppkopplade klienten. Detta ID heter ConnectionID och används som en referens för adressen till klienten [24]. Det finns flera inbyggda funktioner i signalR för att pusha ut information till klienter. Till exempel kan man pusha ut information till alla klienter med Clients.All.SendAsync(string method, object arg) eller pusha tillbaka ett meddelande till sändaren genom Clients.Caller.SendAsync(string method, object arg). Parametern “method”

är namnet på funktionen på mottagarens sida där meddelandet ska tas emot och parametern

“arg” (argument) är meddelandet. I detta projekt används de inbyggda funktionerna Caller, för att skicka tillbaka information till användaren, och Groups för att selektivt skicka information till applikationerna. Groups-funktionen används för att sortera alla klienternas ConnectionID till grupper och därmed skicka ett meddelande till alla inom den gruppen genom att deklarera Clients.Group(string groupname).SendAsync(string method, object arg)[24].

(22)

11

2.7 Sammanfattning

I detta kapitel har jag presenterat bakgrunden till projektet och hur köer och väntetider skulle kunna reduceras inom vissa områden genom att utveckla ett kösystem som inriktar sig på konsumenter och butikspersonal. Jag har också beskrivit de viktigaste delarna i systemet som är bra att känna till för att få en förståelse för kommande kapitel. Den första delen som diskuterades var det objektorienterade programspråket C# som är det programspråket som kommer att tas upp mest i följande kapitel om implementationen och design. Det andra var Xamarin som är ett verktyg för att använda samma kod till flera olika plattformar som mobil eller Ipad, Android eller iOS operativsystem. Jag har också tagit upp olika koncept och strukturer, som REST-konceptet och asynkron programmering, som är viktigt att känna till för att läsaren ska kunna förstå grundprinciperna till varför dessa koncept och strukturer används. Här återfanns även en detaljerad beskrivning av WPF, som är ramverket för

personalapplikationen. I avsnittet om WPF förklarade jag även XAML som är det märkspråk som används i WPF för att presentera användargränssnittet. Jag diskuterade även att

webbservern är uppbyggd av ASP.NET Core, om dess styrkor och underliggande strukturer som används tillsammans med MSSQL, som är en central del i att hämta och spara data från och till kunder och personal. Kapitel 2 tog även upp biblioteket SignalR som utgör en stor del av kommunikationen mellan personalapplikationen och mobilapplikationen.

(23)

12

3. Kravanalys

I detta kapitel går jag igenom kravspecifikationen av projektet. I följande avsnitt listar jag alla de krav som Altran framförde och de analyser jag gjorde. Dessa krav och analyser är

kategoriserade efter område i systemet. I avsnitt 3.2 presenteras krav och analyser som berör mobilapplikationen. I avsnitt 3.3 beskrivs personalapplikationens projektkrav och analyser.

Avsnitt 3.4 tar upp kraven och analysen av webbservern.

3.1 Översikt

Detta projekt är en idé från Altran som går ut på att digitalisera kölappar till en mobil. För att förverkliga denna idé ville Altran ha ett kösystem som innehåller en mobilapplikation till de kunder som vill ställa sig i en kö, en personalapplikation för personalen att hantera denna kö och en webbserver som ska fungera som ett API mellan mobilapplikationen,

personalapplikationen och databasen. Den högsta prioriteten i detta projekt var att få systemet att fungera funktionellt i en perfekt värld, det vill säga en prototyp av Altrans idé. Detta betyder att säkerhetsaspekter som skydd mot intrång, ej godtagbart användande av systemet och stresstester hade låg prioritet. Detta betyder att projektet inte är lanserat efter

projektperioden och kräver därför en vidareutveckling. Orsaken är att ett projekt med två applikationer, en webbserver och en databas är en för stor uppgift för en person att testa och färdigställa till lanseringsklar status under de få veckor som stod tillförfogande för projektet.

(24)

13

3.2 Mobilapplikationen

I kravanalysen tillsammans med uppdragsgivaren (Altran) kom vi fram till följande krav för mobilapplikationen. Den ska kunna:

1. Användas på både Android- och iOS-plattformar

2. Presentera valbara butiker (skapade i personalapplikationen) 3. Presentera valbara ärenden (skapade i personalapplikationen) 4. Presentera ett användarvänligt GUI

5. Göra det möjligt för en kund att stå i en ärendekö 6. Presentera en kölapp med:

a. en estimerad väntetid som uppdateras vid förändringar i kön

b. en positions variabel som visar hur många kunder som står i kön framför

Mobilapplikationens huvudsakliga krav på funktionalitet är att ge kunden möjlighet att ställa sig i en kö. Därför började jag med att sammanställa ett övergripande användarflöde som representerar processen från det att applikationen startar tills det att kunden får service (se figur 3.1). I användarflödet startar man först applikationen som börjar med att hämta alla butiker från webbservern. Kunden väljer därefter vilken butik han/hon vill ställa sig i kö hos.

Valet av butik resulterar i att mobilapplikationen hämtar alla ärenden som är associerade med butiken. Kunden väljer därmed ett ärende från vald butik, skickar detta ärendets id och sitt personliga kund id till webbservern och får tillbaka ett kö-id. Därefter väntar

mobilapplikationen på en ledig kassa tills en kassa som kan hantera det valda ärendet öppnas.

Man kontrollerar sedan vem som är nästa kund i kön genom att kolla vem som har väntat längst. Om det är användarens tur så tilldelas kunden kassan som är ledig.

(25)

14

Figur 3.1 Användarflöde för start av applikation till kund får service

(26)

15

3.3 Personalapplikationen

I kravanalysen tillsammans med uppdragsgivaren (Altran) kom vi fram till följande krav för personalapplikationen. Den ska ge användaren möjlighet att kunna:

1. Logga in på en butik med butikens namn och lösenord 2. Registrera en ny butik

3. Presentera valbara kassor 4. Skapa nya kassor

5. Ta bort kassor

6. Ha ett användarvänligt GUI 7. Presentera valbara ärenden

a. Man ska kunna välja mer än ett ärende 8. Skapa nya ärenden

9. Ta bort ärenden

10. Hantera kunder som ställt sig i en ärendekö

a. Ska enbart få kunder med det valda ärendet b. Ska kunna välja nästa kund i kön

11. Se en kölapp med kölappsnummer, namn på kunden, vilket ärende som kunden valt och information om kunden (som är valfritt för kunden).

Den viktigaste funktionaliteten personalapplikationen ska kunna utföra är att hantera kunder som står i en ärendekö. De kunder som presenteras för personalapplikationen har alltid de ärenden som personalen har valt att ta emot. Med denna bakgrund startade jag en analys genom att rita ett användarflöde för personalapplikationen där processen startar från det att applikationen startar tills det att kunden får service (se figur 3.2). I detta användarflöde börjar processen med att hämta alla kassor och ärenden till personalapplikationen, som presenterar dessa för användaren som valmöjligheter. När en kassa och X antal ärenden har valts

fortsätter processen vidare till hanteringen av kunderna. Denna hantering loopar tills personen stänger av sin applikation eller avbryter fler inkommande kunder.

(27)

16

Figur 3.2 Användarflöde för start av applikation och kundservice

(28)

17

3.4 Webbservern

I kravanalysen tillsammans med uppdragsgivaren (Altran) kom vi fram till följande krav för webbservern. Den ska kunna:

1. Hantera HTTP-förfrågningar från klienter 2. Hämta, spara, skapa och ta bort data i en databas

3. Beräkna och skicka ut nästa kund till personalapplikationen enligt FCFS 4. Estimera och meddela en väntetid till varje kund i köerna

5. Skicka ut information om köplats till kunderna

6. Skicka ut information om totalt antal köande i ett ärende till personalen

Webbservern är informationscentret i systemet där de flesta beräkningar och utdelningar av data sker. Redan i projektets analysfas insåg jag att webbservern kommer att ha ett högt tryck på grund av att den ska hantera data från och till webbservern från alla klienter (kunder och personal). Webbservern ska även beräkna vem som är nästa i kön samt ge alla kunder en tidsestimering på hur lång tid det är kvar tills det är den kundens tur. Det viktigaste kravet för webbservern är att den ska kunna beräkna och skicka ut nästa kund i kön till

personalapplikationen. Figur 3.3 visar hur användarflödet över webbservern hanterar att ta in nästa kund i kön när en kassa blir ledig. Då systemet ska innehålla två klienter (kund och personal) som avbryter sina köprocesser så är det viktigt att hantera dessa och meddela båda klienterna för att undvika missförstånd. Om en kund väljer att avbryta eller om det helt enkelt inte stått någon i kön, så ska personalen meddelas att kön är tom. Detsamma om en kund ställer sig i en ärendekö som ingen i personalen är redo att ta emot så måste båda klienterna få upplysning om detta. Kunden behöver veta att kön står stilla och all personal som är

inloggade i butiken behöver veta att kunder står och väntar så att personalen kan byta till det ärendet.

(29)

18

Figur 3.3 Användarflöde för köhantering på webbservern

3.5 Sammanfattning

I detta kapitel presenterades de krav som framfördes av Altran och de analyser som gjordes för kösystemet. Kapitlet delades upp i tre avsnitt som detaljerat går in på varje del av systemet och vilka krav som ställdes. I avsnitt 3.2 presenterades mobilapplikationens krav som omfattar GUI och backend-funktionaliteter. Avsnitt 3.3 beskrev personalapplikationens krav och analyser. I det sista avsnittet, 3.4, presenterades webbserverns krav, som bland annat handlade om köposition och tidsestimering.

(30)

19

4. Systemöversikt, webbserver och databas

I detta kapitel presenteras en översikt över hela systemet tillsammans med beskrivningen av webbservern och databasen. I avsnitt 4.1 presenteras systemöversikten där jag går igenom hur systemet fungerar mellan de fyra systemdelarna: databasen, webbservern, mobilapplikationen och personalapplikationen. I avsnitt 4.2 beskrivs databasens relationer och en detaljerad beskrivning av varje enskild tabell. I avsnitt 4.3 presenteras en detaljerad beskrivning av webbservern och dess funktionaliteter. I avsnitt 4.4 tas beräkningen av köposition och tidsestimeringen upp tillsammans med dess problem och lösningar. Det sista avsnittet, 4.5, ger en sammanfattning av kapitel 4.

4.1 Systemöversikt

4.1.1 Systemnamn

Detta system är döpt till Inline, som i svensk översättning blir “i kö”. Tankarna går också till ordet “Online”, vilket tillsammans passar ett system som hanterar köer över nätet. I detta projekt är varje namn på systemdelarna en kombination av “Inline” och dess funktionella uppgift för att binda ihop dem till ett gemensamt varumärke. Till exempel heter databasen i detta projekt “Inline-databasen” och personalapplikationen heter “Inline

Personalapplikation”.

4.1.2 Kommunikation

Inline består av fyra delar, vilka är webbservern, personalapplikationen, mobilapplikationen och databasen. Systemet är byggd runt webbservern vars huvudsakliga uppgift är att hantera och bearbeta förfrågningar från mobilapplikationen och personalapplikationen. Detta kan till exempel handla om att logga in, skapa nya butiker, få estimerad väntetid och fördela nästa kund i kön till en kassa. Figur 4.1 illustrerar hur kommunikationen mellan applikationerna och webbservern fungerar. Som man kan se har personalapplikationen och

mobilapplikationen aldrig direkt kontakt med varandra utan kommunikationen går igenom webbservern med två olika kommunikationsmetoder: controllers (se avsnitt 4.3.1) och SignalR (se avsnitt 2.6), där controllers hanterar personliga förfrågningar och SignalR hanterar att ge ut information kontinuerligt till alla klienter som ligger i serverns clienthub.

(31)

20

Det mesta av informationen som applikationerna och kösystemet använder sig av är lagrat i databasen och är endast tillgänglig genom Inline-webbservern.

Figur 4.1 Systemöversikt på kommunikation mellan de fyra systemdelarna

(32)

21

4.2 Inline-databasen

Det mesta av informationen som applikationerna och kösystemet använder sig av är lagrat i databasen. I detta avsnitt kommer jag först att ge en helhetsbild av relationsdatabasen och därefter delar jag upp varje tabell i varsitt mini-avsnitt där jag förklarar mer ingående om tabellens tänkta funktion.

4.2.1 Databasdesign

Som databas använder jag Microsoft SQL Server (MSSQL) med Microsoft SQL Server Management Studio (MSSMS) som mjukvara för att konfigurera, hantera och administrera databasen. Anledningen till att jag valde denna uppsättning till databasen var att jag är mest van denna miljö och har redan alla komponenter som krävs installerade på min dator. I detta projekt utför databasen för det mesta inte några krävande uppgifter utan bara hämtar, sparar, tar bort och hittar enstaka värden, vilket betyder att få avancerade Sql-förfrågningar kommer att ske i systemet. När jag skissade på databasen hade jag i åtanke att kösystemet kommer att ha fem viktiga informationsdelar som krävs för att programmet ska fungera. Dessa är butiker (Stores), kassor (Desks), Ärenden (Errands), kölappar (Queuetickets) och kunderna (Client).

Dessa fem informationsdelar var min utgångspunkt när jag designade databasen. Min handledare på Altran ville även att en kund ska kunna välja ett användarnamn och att personalen ska kunna logga in på sitt företag med ett gemensamt lösenord. I figur 4.2

presenteras UML-diagrammet över Inlinedatabasen och tabellernas relationer med varandra.

(33)

22

Figur 4.2. UML-diagram över Inlinedatabasen

4.2.2 Stores

Tabellen Stores innehåller varje butiksnamn och lösenord. Denna del i databasen används av både personalapplikationen och mobilapplikationen. Personalen använder denna tabell för att logga in i systemet med användarnamn och lösenord som matchar databasens information.

Personalapplikationen skickar den inmatade datan till webbservern som i sin tur skickar en SQL-fråga till databasen baserat på uppgifterna. Kunderna med mobilapplikationen använder denna tabell genom webbservern för att både välja vilken butik de vill göra sitt ärende i och hämta de ärenden som butiken tillgodoser. Tabellen är enkelt uppbyggt med tre kolumner. Ett ID som är primärnyckel och refereras som SID (förkortning Store ID). Denna primärnyckel är även en främmandenyckel i kassa-tabellen (se avsnitt 4.2.3) samt ärende-tabellen (se avsnitt 4.2.4). Kolumnen Storename (butiksnamn) är butikens namn och password (lösenord) är dess lösenord för inloggning för personalapplikationen.

(34)

23

4.2.3 Desks

Tabellen Desks i databasen är den tabell som innehåller information om kassorna som personalapplikationen använder. Mobilapplikationen har inte tillgång till denna information då det är oväsentligt för kunderna att ha information om kassorna från databasen då

kösystemet bygger på att man ställer sig i en ärendekö och inte i en kassa. När en kund är först i kön får den information om vilken kassa den ska gå till men kassan kommer inte att hämtas från databasen. Hur kassorna disponeras till kunderna kan man läsa mer om i avsnitt 4.4.2 som handlar om hur kön fungerar. I tabellen för kassorna finns det data om kassans namn och om kassan är upptagen eller inte. Kassans namn refereras som deskname och namnges av personalen för att enkelt kunna skilja kassorna åt utifrån den arbetsmiljö de jobbar i. Till exempel kan en arbetsplats namnge kassorna i nummerordning medan en annan arbetsplats kan namnge kassorna efter avdelning. Den andra kolumnen som avgör om en kassa är upptagen eller inte, refererar jag som available (tillgänglig). Available är till för att personalapplikationen ska hindras från att kunna välja en kassa som redan är vald av någon annan personal i butiken. Denna kolumn har datatypen bit och sätts till 1 eller 0 (sant eller falskt). För att relatera kassorna till rätt butik har denna tabell en nyckel kallad SID som är en främmandenyckel till primärnyckeln SID i Stores-tabellen. Relationen mellan Desks-tabellen och Stores-tabellen är en “en-till-många” -relation där en Store kan ha flera Desks medan en Desk bara kan tillhöra en Store.

4.2.4 Errands

Ärende-tabellen är den tabell som tillhandahåller information om de serviceärenden ett företag erbjuder sina kunder. Denna tabell innehåller fyra kolumner (se figur 4.2) där två kolumner innehåller information för både personal- och mobilapplikationen. Den ena kolumnen innehåller den data som namnger ärendet och refereras som errandname (ärendenamn). Tanken med denna kolumn är att ge kunden en kort beskrivning av vad ärendet handlar om. Den andra kolumnen är erranddescription (ärendebeskrivning) som innehåller mer detaljerad information om vad ärendet omfattar. Dessa två kolumner, som deskname i Desk-tabellen (se avsnitt 4.2.3), är upp till personalen med personalapplikationen att bestämma. För att relatera varje ärende i tabellen till ett företag så har Errands-tabellen en främmandenyckel av Stores-tabellens primärnyckel, SID. Relationen mellan Errands-tabellen

(35)

24

och Stores-tabellen är en “en-till-många” relation, där ett ärende bara kan tillhöra en butik medan en butik kan ha många ärenden.

4.2.5 Client

Client-tabellen (kund-tabellen) är den tabell som innehåller all nödvändig information om kunderna. Altran ville inte att databasen skulle innehålla någon personlig information om kunderna, samt att någon inloggning inte skulle behövas för att använda appen. Detta resulterar i en liten tabell där vi enbart har kolumnerna CID (primärnyckel), clientname (användarnamn) och information. Clientname sätts av kunden första gången den startar applikationen på sin mobil och kunden har möjlighet att ändra sitt användarnamn.

Informationskolumnen är data som kunden valfritt väljer att fylla i. Detta kan exempelvis vara personnummer för snabbare hjälp vid kassan eller någon specialinformation som kan vara viktigt för personalen att veta.

4.2.6 Queueticket

Queueticket är i min databas en tabell som representerar kölappar i systemet. Denna tabell binder ihop ärende- och client-tabellen i databasen för att få tag på information om kön. En av relationerna är den mellan kön och kunden, dvs Errands-tabellen och Queueticket-tabellen, där EID är en främmande nyckel till primärnyckeln EID i Errands-tabellen. Detta är en “en- till-många”-relation där en kölapp enbart kan ha ett ärende medan ett ärende kan ha flera kölappar. Nästa relation är den mellan kölapp-tabellen och kund-tabellen. Denna relation existerar för att varje kölapp ska kunna hämta en kund samt kundens information till personalapplikationen. Denna relation är också en “en-till-många”-relation där en kölapp enbart kan ha en kund medan en kund kan finnas på flera kölappar. Utöver

främmandenycklarna sparas information om vem som har servat denna kölapp samt tid och datum då kölappen är skapad. Informationen om vem som har servat kölappen kan man hitta i kolumnen “servedby” som ska ha två funktioner. Först ska man kunna gå tillbaka och se vilken kassa som har servat vilken kund. Sedan ska detta attribut fungera som en koll på om kölappen får service av en annan kassa. “servedby”-kolumnen (se figur 4.2) löser problemet med att när en kassa i en butik ger service till en kund så finns det ingen indikator om att den kunden är under service förrän servicen är klar (endeddate). Problematiken blir då att Inline-

(36)

25

webbservern hämtar denna kund när en annan kassa i butiken vill ha nästa kund och det blir en kund till två olika kassor. Med andra ord, om ”servedby” har värdet null så är kölappen i kö. Tiden och datumet då kölappen har blivit skapad refererar jag som “createddate” och sätts när kölappen skapas. Denna data används för att tillämpa en FCFS-algoritm där den som har väntat längst får placeringen längst fram i kön. Den sista kolumnen är “endeddate” som innehåller information om datumet då kölappen blivit servad. Denna data är viktig för att få en beräknad väntetid för varje kund i kön (se avsnitt 4.4.4).

(37)

26

4.3 Inline-webbserver

Webbservern till Inline-systemet är mellanlagret mellan applikationerna, som kunder och personal använder, och databasen med HTTPS med REST (se avsnitt 2.4.2) och SignalR (se avsnitt 2.6) som struktur. I detta projekt designade jag webbservern till att vara en stor del i klienternas funktion. Det innebär att nästan all data som klienterna har nytta av kommer från databasen och datan som ges är specifik beroende på de val som har gjorts. Till exempel så får varje kund inte tillgång till alla ärenden förrän den har valt en butik och då får kunden bara ärendena som den butiken har. Det negativa med denna form av tung webbserver är att det blir fler anrop mellan klient och webbserver än om man hade skickat all data samtidigt, vilket resulterar i att webbservern får ett högt tryck. Det positiva med detta är att det minskar trycket på klienterna och att nästan ingen onödig information skickas. För att webbservern ska kunna hantera att skicka små mängder specifik data så designade jag webbservern utifrån tre huvuddelar: Controllers, Dataproviders och Clienthub, vilka beskrivs nedan.

4.3.1 Controllers

Controllers är de klasser som vägleder inkommande CRUD-förfrågningar från klienter till rätta klasser och funktioner. Dessa klasser är byggda så att när webbservern får en förfrågan från en klient som berör en specifik grupp av data så behandlas och vägleds förfrågan till ett objekt som har hand om den gruppen data. Detta görs genom att använda biblioteket

Microsoft.AspNetCore.Mvc där man kan omfördela http-förfrågningarna från en klient till en klass på webbservern genom att definiera den klassens rutt med hjälp av “route” (se figur 4.3).

(38)

27

Figur 4.3. Rutt-deklaration för Inlinewebbservern

Controllers-klasserna har ett referensnamn följt av ordet “Controllers”. Exempelvis

“StoresController” (som i figur 4.4) är den klass som rutten ska gå till om en klient har en förfrågan om att hämta, spara, ändra eller ta bort någonting i tabellen “Stores” (butiker) i databasen. Inline-webbservern innehåller fem stycken controllers: Storescontroller,

Deskscontroller, Errandscontroller, Clientcontroller och Queuecontroller. Som man kan se i figur 4.4 har dessa controllers ingen relation till varandra. Detta är för att dessa klasser enbart väntar på anrop från klienterna med den information som behövs för att utföra förfrågan.

Varje controller-klass har dock en relation med en dataproviders-klass som hämtar data från databasen (se avsnitt 4.3.2).

(39)

28

Figur 4.4. Klassdiagram för Controllers i Inline-webbservern

Alla dessa fem controllers kan accessas av en klient genom HTTP-förfrågan https://localhost:44387/api/ ”controller namn” från personalapplikationen eller

https://[IPadress]:44387/api/ ”controller namn” från mobilapplikationen. Controllers har jag designat utifrån vilken av datagrupperna man vill ha tillgång till, som exempelvis Store, Desk eller Client. För att ytterligare specificera vad man vill göra med denna grupp av data, som till exempel att skapa en ny Desk till sin butik, så måste HTTP-förfrågan även innehålla ytterligare en väg för att webbservern ska välja rätt funktion i klassen. I figur 4.5 visas funktionen som anropas när en klient skickar https://localhost:44387/api/Desks/CreateDesk till klassen DeskController.

(40)

29

Figur 4.5. CreateDesk-funktionen i klassen DeskController

I DeskController-klassen deklareras först funktionen med att det måste vara en post-förfrågan som frågar efter rutten “../createDesk”. Denna funktion kallar på den dataprovider-funktion som hanterar skapande av nya kassor och skickar tillbaka sant eller falskt till klienten

beroende på om operationen lyckades eller inte. In-parametern “[FromBody] Desks desk” (se figur 4.5) berättar för funktionen att meddelandet från klienten innehåller information baserat på Desk-objektet och översätter därmed informationen i meddelandet från JSon-format1 till Desk-objekt. Här skickas objektet desk vidare till klassen dataproviders (se avsnitt 4.3.2) där informationen i desk innehåller datan om vad det nya desk-namnet ska vara och vilket butiks- id (SID) den ska refereras till. Klasserna DeskController, ClientController, ErrandsController och StoreController liknar varandra i strukturen och därför beskrivs dessa inte i detalj.

QueueController däremot behärskar beräkningen av köpositionen och tidsestimeringen och därför går jag in mer i detalj om denna klass i avsnitt 4.4.

1 JSon (JavaScript Object Notation) är ett textbaserat format som används för att enkelt och med låg prestandakrav utbyta data. [26]

(41)

30

4.3.2 Dataproviders

Dataproviders (dataleverantörer) är de klasser som hämtar data från databasen. Strukturen på dessa klasser liknar controllerklasserna (se avsnitt 4.3.1) där varje klass hämtar en specifik grupp data från databasen med SQL-queries (se figur 4.6). Som i Controller-klasserna har inte Dataproviders-klasserna någon relation med varandra på grund av att de enbart lyssnar på anrop från sin controller-klass.

Figur 4.6. Dataprovider klassdiagram

Ett exempel är klassen “DeskDataProvider” som enbart ska hantera och hämta data från tabellen “Desk” i Inline-databasen. Anledningen till att jag använder denna design även på Dataproviders är för att den följer en struktur som gör det lätt att förstå och förenklar

felsökning på webbservern. Det gör också så att jag kan återanvända variabler och på så sätt få en renare kod. Då Controller-delen av Inline-webbserver tar hand om förfrågningarna från klienterna tar Dataproviders-delen hand om kontakten med databasen. I figur 4.7 ser man en detaljskiss på hur flödet mellan DesksController, DeskDataProvider och InlineDatabasen ser ut. De andra klasserna, StoresDataProvider, ErrandsDataProvider, ClientDataProvider och fungerar på samma sätt som DeskDataProvider. Dvs att exempelvis StoresDataprovider enbart hanterar svar från StoresController. QueueDataProvider-klassen till skillnad från de andra klasserna bistår QueueController med information om köpositionering och

tidsestimering vilket presenteras i avsnitt 4.4.

(42)

31

Figur 4.7. Detaljbild på DeskDataProviderflöde

4.3.3 ClientHub

I Inline-webbservern används SignalR-verktyg för att skicka ut information i realtid till klienterna. När webbservern startar skapar den en hub (se avsnitt 2.6) för både mobil -och personalapplikationen som jag kallar för “ClientHub”. Clienthub-klassen innehåller enbart en funktion som kallas för SetConnection. SetConnection är den funktion som klienterna

anropar för att få sitt ID (SID för personalapplikationen och CID för mobilapplikationen) refererat till sitt unika ConnectionID för att Inline-webbservern ska kunna skicka ut information om:

● Antal köande kunder som är före i kön till mobilapplikationen

● Vems tur det är till berörd kund

● Tidsestimeringen till mobilapplikationen

Anledningen till att personalapplikationen också är uppkopplad till SignalR utan att någon information skickas till den är för att det var tänkt att personalapplikationen skulle få ta del av information om butikens status, som till exempel antal köande, men det fanns inte tillräckligt med tid att implementera den under projektperioden.

De SignalR-funktioner som möjliggör dessa tre uppgifter till mobilapplikationen är

implementerade i QueueController-klassen och kan läsas mer om i avsnitt 4.4 om köposition och tidsestimering.

(43)

32

4.4 Köposition och tidsestimering

Detta avsnitt tar upp den största delen av systemet: beräkning av köposition och

tidsestimering. De två klasser som tar hand om denna beräkning är QueueController och QueueDataProvider. QueueController hanterar anrop från klienterna som med hjälp av QueueDataProviders kontakt med databasen beräknar och disponerar ut information om köposition och tidsestimering till kunderna.

I avsnitt 4.4.1 finns en beskrivning av hur skapandet av en ny kölapp fungerar. Vidare i avsnitt 4.4.2 redogörs hur webbservern hanterar när en kund har fått service och ska

disponera ut nästa kund i kön. Avsnitt 4.4.3 tar upp hur köplatsen för kunderna beräknas och skickas ut till varje berörd kund. Slutligen i avsnitt 4.4.4 presenteras tidsestimeringen i detta projekt.

4.4.1 Skapa kölapp

Kön i detta system utgår från FCFS-strukturen. Varje gång en kund via mobilapplikationen ställer sig i en kö, meddelas Inline-webbservern med informationen id på kunden(CID) och id på valt ärende (EID). Med denna information skapar webbservern en ny “Queueticket” i databasen och sätter “createddate”(se avsnitt 4.5) till dagens datum och tid genom att anropa databasen med SQL-förfrågan nedan (se figur 4.8).

(44)

33 Insert into QueueTicket(EID, CID, createddate) OUTPUT Inserted.QID

Values(@EID, @CID, GETDATE())

Figur 4.8. SQL-förfrågan för att skapa ny kölapp

Genom att använda “Inserted.QID” (se figur 4.8) bes databasen returnera den skapade

kölappens identifikationsnummer för att sända tillbaka till kunden. Kundens plats i ärendekön är den tidpunkt som kölappen blivit skapad på i jämförelse med de andra som står i kön, det vill säga antalet kölappar som har en äldre tid och datum än den aktuella kölappen.

4.4.2 Hämta nästa kölapp

För att hämta nästa kund som har väntat längst inom de ärenden som personalen önskar så skickar personalapplikationen en http-förfrågan till Inline-webbserverns “NextInLine”- funktion som finns i queuecontroller-klassen (se Figur 4.9).

Figur 4.9. NextInLine-funktionen i QueueController-klassen

(45)

34

Det sker tre viktiga steg när en personalanvändare ber Inline-webbservern om att få nästa kund i kön. Det första steget är att besluta om och sätta ett sluttidsvärde för förra kunden som blivit servad av personalanvändaren. Tidssättningen sker om QID-värdet i den dynamiska inparametern inte är “None”, vilket är standardvärdet för parametern om inget annat har satts (se avsnitt 5.3.1). Tidssättningen sker genom att uppdatera den aktuella QID-radens kolumn

“endeddate”(se avsnitt 4.2.6) med dagens datum på databasen.

Det andra steget handlar om att hämta nästa kund i kön. Detta sker genom att anropa webbservern med SQL-förfrågan i figur 4.10.

SELECT TOP 1 q.QID, e.ErrandName, c.Information, c.CID, e.EID FROM QueueTicket q INNER JOIN Client c ON q.CID = c.CID INNER JOIN Errands e ON q.EID = e.EID

WHERE q.EID IN({0}) AND servedby IS NULL order by createddate asc;

{0} = string.Join(",", ((IList<int>)EIDList).ToArray()));

Figur 4.10. SQL-förfrågan för att hämta nästa kund i kön

Denna SQL-förfrågan kombinerar ihop tabellerna queueticket, client och errands till en temporär tabell för att få all information som behövs för personalapplikationen och kundapplikationen. Den information som hämtas från denna tabell är:

● q.QID

Kölappens id-nummer som skickas till personalapplikationen som identifiering för personalen gentemot kundens QID för att försäkra sig om att det är rätt persons tur.

● e.Errandname

Skickas enbart till personalen. Eftersom personalen kan välja att ta emot flera ärenden krävs det att personalen vet vilket av ärendena kunden vill ha service inom.

● c.Information

Kundens inmatade information till personalen för att snabba på serviceprocessen.

● c.CID

Kundens id för att hitta rätt ConnectionID med signalR(se avsnitt 4.3.3) och pusha ut information till den kunden att det är dennes tur.

(46)

35

För att få den kund som har väntat längst i denna kö så används “top 1” “orderby

createddate” och asc. Dessa tre påståenden i SQL-förfrågningen sorterar alla resultat efter det äldsta datumet plus tid och returnerar enbart den rad som ligger högst i tabellen.

Det tredje steget handlar om att skicka den nya informationen till båda applikationerna. QID, Errandname och information returneras till sändaren. Kunden tilldelas namnet på kassan (deskname). Kunden tilldelas deskname genom att göra ett signalR-anrop (se figur 4.11) där Group (se avsnitt 4.3.3) är kundens “grupp” som tilldelas med ett connectionID, ”result[3]”

som är kundens CID, och “myturn” är namnet på funktionen på mobilapplikationen som meddelar kunden att det är dennes tur.

Figur 4.11. SignalR-anrop till nästa kund i kön

(47)

36

4.4.3 Köplats

Den köplats som varje kund har beräknas varje gång det skapas en ny kölapp (se avsnitt 4.4.1) och varje gång personalapplikationen ber om nästa kund i kön (se avsnitt 4.4.2) genom att anropa funktionen “UpdateQueueInformationToClients” i klassen queuecontroller (se figur 4.12)

Figur 4.12. Funktionen UpdateQueueInformationToClients

Denna funktion använder SignalR-anrop för att skicka ut information om både köplats och tidsestimeringen till kunderna. Mer i detalj om hur tidsestimeringen fungerar beskrivs i avsnitt 4.4.4. Denna funktion tar emot två inparametrar, EID och en standard inparameter CustomerID. EID(ErrandID) är det ID på den ärendekö som positionsberäkningen gäller och CustomerID är en enskild kunds CID. Anledningen till att det är ett defaultvärde på

CustomerID är att denna funktion gör skillnad på om det är en ny kölapp som har skapats eller en kund som har blivit servad. Detta är på grund av att när en ny kölapp skapas så kommer denna kölapp alltid hamna sist i kön och det är därför inte väsentligt att uppdatera alla som står i kön framför. Det som skiljer dessa två villkor åt är att den ena loopar igenom en CID-lista medan den andra beräknar position och tidsestimering på en CID. Om

(48)

37

inparametern CustomerID är noll betyder det att en kund har blivit servad i en ärendekö och att alla i den kön ska få en ny position och en ny tidsestimering. Om detta är fallet börjar funktionen med att para ihop alla kundernas ID som står i ärendekön till en lista med hjälp av Queuedataproviders GroupCIDByEID-funktion (se figur 4.12) som anropar databasen med SQL-förfrågan i figur 4.13.

SELECT CID FROM QueueTicket WHERE EID = {0}

AND servedby IS NULL AND endeddate IS NULL;

{0} = string EID.

Figur 4.13 .SQL-förfrågan för att gruppera alla kunder efter EID

Därefter loopar funktionen igenom alla CID i listan och anropar QueueDataproviders GetPositionByCID-funktion. Denna funktion anropar databasen med en SQL-förfrågan som beräknar antal rader av alla väsentliga rader (de som står i berörd ärendekö) där startdatumet är mindre än kundens startdatum (se figur 4.14).

SELECT COUNT(*) FROM QueueTicket WHERE createddate <

(SELECT createddate FROM QueueTicket WHERE CID = @cid

AND servedby IS NULL) AND EID = @eid

AND endeddate IS NULL;

@eid = string CID(inparameter)

@eid = string EID(inparameter)

Figur 4.14. SQL-förfrågan för att beräkna en kunds position

Det är viktigt att klargöra att detta postionsvärde representerar kundens plats i kön och inte kundens position. Det vill säga att om kunden har plats ett i kön så betyder det att det är en person framför denna kund.

(49)

38

Efter att positionsvärdet har hämtat så skickar UpdateQueueInformationToClients- funktionen, med hjälp av SignalR, ut den nya informationen till den kund som den nya informationen berör genom att anropa UpdateQueueInformation på mobilapplikationen med hjälp av Group (se avsnitt 2.6), där gruppnamnet är kundens CID (se figur 4.15).

Figur 4.15. SignalR-anrop till UpdateQueueInformation till mobilapplikationen

4.4.4 Tidsestimering

Tidsestimeringen i detta projekt är den cirkatid när en kund kan förvänta sig att ha första platsen i kön. Denna tidsestimering är en viktig del av systemet för att uppnå funktionaliteten att kunna ställa sig i en kö utan att vara på plats i butiken. Om en kund inte vet ungefärlig tidpunkt så kan det leda till att kunden antingen går dit för tidigt, eller för sent och missar sin plats. Under projektets gång har flera idéer på hur tidsestimeringen ska fungera kommit upp och dessa har alla sina för-och nackdelar. En mer detaljerad beskrivning av problemet och en idé på lösningen kan läsas om i avsnitt 6.2.1.

I detta projekt beräknas tidsestimeringen utifrån ett medelvärde som är beräknat på alla rader i Queueticket-tabellen som har ett startdatum (createddate) och ett slutdatum (endeddate).

Detta medelvärde baserat på tiden det har tagit för varje enskild kund i databasen från det att kunden har skapat kölappen (se avsnitt 4.4.1) tills det att den kölappen har blivit servad av butiken (se avsnitt 4.4.2). Den matematiska formeln för varje enskild kund ser ut som i Figur 4.16.

(50)

39 Estimerad väntetid = M(x) * p

Där𝑀(𝑥) = 𝑥1+ 𝑥2 +....+𝑥𝑝 𝑛

x = skillnaden i sekunder mellan createddate och endeddate n = antalet x

p = kundens position

Figur 4.16. Matematisk formel för estimerad väntetid för kunder

Tidsestimeringen för varje kund beräknas och skickas ut till varje enskild kund i UpdateQueueInformationToClients-funktionen i QueueController. För att först få den estimerade väntetiden M(x) (se figur 4.16) så anropar UpdateQueueInformationToClients- funktionen QueueDataProviders GetAverageWTime med inparametern EID (Se Figur 4.17) efter det att köplatsen för kunden har fastställts.

Figur 4.17. Anrop till GetAverageWTime

GetAverageWTime i dataproviders-klassen använder inparametern EID (ärende ID) för att beräkna medelvärdet på väntetiden mellan alla de kölappar inom det ärendet som har blivit servade av butiken. SQL-förfrågan GetAverageWTime (se figur 4.18) returnerar medelvärdet i sekunder mellan createddate och endeddate på alla rader där inparametern EID finns.

SELECT AVG(DATEDIFF(ss, createddate, endeddate)) AS avgerage_seconds FROM QueueTicket

WHERE EID = @eid;

@eid = string EID(inparameter)

Figur 4.18. SQL-förfrågan för att hämta medelvärde väntetiden i en ärendekö

(51)

40

Returvärdet från GetAverageWTime multipliceras sedan med den köplats som kunden har i kön och skickar ut informationen med hjälp av SignalR till berörd kund (se figur 4.19).

Denna köplats hämtades tidigare av UpdateQueueInformationToClients-funktionen för att informera kunderna om sina köplatser (se avsnitt 4.4.3).

Figur 4.19. Kod för att beräkna väntetid och skicka ut till berörd kund

4.5 Sammanfattning

I detta kapitlet förklaras översikten av systemet tillsammans med Inline-webbservern och tillhörande databas. Kapitlet beskrev de viktigaste funktionaliteterna i systemet som är köposition och tidsestimeringen. I avsnitt 4.1 presenterades översikten av systemet där namnet på systemet förklarades samt hur kommunikationen mellan de olika delarna i systemet fungerar. I avsnitt 4.2 hanterades databasen till systemet och alla de tabeller som den tillhör. Här fanns en detaljerad beskrivning av varje tabell och anledningen till att de existerar. Vidare i avsnitt 4.3 förklarades Inline-webbserverns klasser och hur SignalR hanteras. I det sista avsnittet, 4.4, presenterades hur kösystemet fungerar med hur

webbservern skapar och hämtar nästa kölapp samt beräknar köposition och tidsestimeringen.

References

Related documents

- Kunna teckna en integral utifrån en given graf med inskrivna funktioner och sedan beräkna integralens värde. Se 3412 b) ovan. - Kunna visa om ett givet uttryck är en lösning till

Inspirerad av Michels Foucaults intresse (Foucault 1984) för när författaren individualiseras i den västerländska traditionen skisserar Woodmansee ett viktigt historiskt skede,

Till höger om knappen Start i aktivitetsfältet fi nns även knappen Aktivitetsvy som du använder för att visa öppna appar och snabbt växla mellan

• Funktioner med lång exekveringstid (många gånger tiden för anrop) är inte lämpliga för inline. • Funktioner som är rekursiva

• Kompilatorn kan inte veta om anrop sker till funktion som inte är definierad. • Länkaren har översikt över alla definierade funktioner och varnar om anrop sker till funktion

Utifrån denna ståndpunkt torde krigföringsprinciperna – vilka främst applicerats på konventionella krig – vara giltiga även i konflikter av hybrid karaktär.12 Det är

Att individualiserad musik eller sång påverkar kommunikationen under omvårdnadsarbetet mellan vårdare och personer med demens redogörs i flera studier (Götell m fl 2002; Götell m

[r]