Scriptie ingediend tot het behalen van de graad van PROFESSIONELE BACHELOR IN DE ELEKTRONICA-ICT
Product price management application with PIM integration Jonathan Dewilde en Rob Liekens Departement Wetenschappen en Techniek Opleiding Elektronica-ICT Academiejaar 2014-2015
Interne promotor: Patrick Van Houtven Externe promotors: Frederik De Galan Nick De Kock
Versie: 12 juni 2015
Dankwoord
Met het schrijven van dit dankwoord leggen we de laatste hand aan onze scriptie. Het was een periode waarin we veel hebben geleerd, zowel op technisch als analytisch gebied. We willen graag even stilstaan bij de mensen die ons de afgelopen achttien weken enorm gesteund en geholpen hebben. In de eerste plaats willen we de werknemers van ons stagebedrijf Xplore Group bedanken voor de fijne samenwerking. We willen ons in het bijzonder richten tot Frederik De Galan en Nick De Kock, de bedrijfspromotors die ons met raad en daad bijstonden doorheen het gehele verloop van de stage. Daarnaast willen we graag onze AP promotor Patrick Van Houtven en de algemene stageco¨ordinator Tim Dams bedanken voor hun goede begeleiding en adviezen. Antwerpen, 12 juni 2015 Jonathan Dewilde en Rob Liekens
i
Abstract Het onderwerp van deze scriptie is de ontwikkeling van een verkoopkanaal afhankelijke prijsberekeningsapplicatie die kan communiceren met het Product Content Management systeem van Hybris, in opdracht van Xplore Group. Deze scriptie beschrijft de technologie en structuur van de prijsberekeningsmodule, alsook het algoritme ontwikkeld om de ideale verkoopprijzen te berekenen. Het Hybris Product Content Management systeem, ´e´en van de leiders op het gebied van PIM (Product Information Management), laat gebruikers toe om product informatie centraal aan te maken, beheren en publiceren. Het idee achter onze applicatie is dat een webshop beheerder, die zijn artikelen wil aanbieden via diverse online verkoopkanalen (bv. Amazon, Bol.com,...) met de price management applicatie automatisch de meest effici¨ente verkoopprijs per verdeler kan berekenen, en dat deze prijs vervolgens doorgestuurd wordt naar het PIM systeem. Om dit te verwezenlijken is een Java-based backend ontwikkeld, gekoppeld aan een SQL database die prijsgerelateerde informatie bevat. De user interface bestaat uit een HTML5-based frontend met AngularJS, Bootstrap en jQuery integratie. Onderlinge communicatie gebeurt via REST services. Het resultaat is een dynamische, schaalbare en gebruiksvriendelijke webapplicatie waarin alle product prijsinformatie beheerd kan worden, en waarmee bovendien synchronisatie met een PIM systeem mogelijk is.
ii
Inhoudsopgave
Dankwoord
i
Abstract
ii
Lijst van afkortingen
ix
Glossarium
x
1 Situering 1.1 Bedrijf . . . . . . . . . 1.2 Project . . . . . . . . . 1.2.1 Introductie . . . 1.2.2 Doel . . . . . . 1.2.3 Vereisten . . . . 1.2.4 Samenvatting . 1.2.5 Conclusie . . . . 1.3 Technologie¨en . . . . . 1.3.1 Backend . . . . 1.3.2 Front end . . . 1.4 Libraries & frameworks . 1.4.1 Backend . . . . 1.4.2 Front end . . . 1.5 Tools . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
1 1 2 2 3 3 7 8 9 9 12 13 13 15 18
2 Bespreking Price Management Application 2.1 Inleiding . . . . . . . . . . . . . . . . . . 2.2 Aanpak . . . . . . . . . . . . . . . . . . . 2.3 Use cases . . . . . . . . . . . . . . . . . . 2.3.1 User use cases . . . . . . . . . . . 2.3.2 Business use case overview . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
20 20 20 22 22 23
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
iii
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
INHOUDSOPGAVE 2.4
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
25 25 25 26 26 26 31 36 43 47 47 47 49 50 50 56 60
3 Resultaten 3.1 Doelstellingen . . . . . . . . . 3.2 Resultaten . . . . . . . . . . . 3.2.1 Login . . . . . . . . . . 3.2.2 Navigatie . . . . . . . . 3.2.3 Algemene functionaliteit 3.2.4 Zoekfilters . . . . . . . 3.2.5 Dashboard . . . . . . . 3.2.6 Product . . . . . . . . 3.2.7 Sales channels . . . . . 3.2.8 Overige pagina’s . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
61 61 62 63 64 66 68 70 72 85 87
4 Besluit 4.1 Reflectie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88 89
A Use cases A.1 CRUD . . . . . . . . . . A.1.1 Suppliers . . . . . A.2 GET Products . . . . . . A.3 Price enrichment . . . . . A.3.1 Price overwrites . A.4 Calculate prices . . . . . A.4.1 Calculate selected A.4.2 Calculate all . . . A.5 Send prices . . . . . . . .
90 90 90 92 93 93 94 94 94 95
2.5
2.6
2.7 2.8
2.9
Workflow . . . . . . . . . 2.4.1 User workflow . . 2.4.2 Business workflow Technical . . . . . . . . . 2.5.1 Introductie . . . . 2.5.2 Architectuur . . . 2.5.3 Design . . . . . . 2.5.4 Backend . . . . . 2.5.5 Front end . . . . User interface . . . . . . 2.6.1 Introductie . . . . 2.6.2 Design . . . . . . Sequence diagram . . . . Business logic . . . . . . 2.8.1 Price logic . . . . 2.8.2 Status logic . . . Testing . . . . . . . . . .
iv . . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
INHOUDSOPGAVE A.5.1 A.5.2 A.6 Status A.6.1 A.6.2
Send selected . . . . . . . . . Send all . . . . . . . . . . . . management . . . . . . . . . . Show statuses of selected prices Show products with errors . . .
v . . . . .
. . . . .
. . . . .
. . . . .
95 95 96 96 96
B ER diagram B.1 ER diagram parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97 98
C Bespreking overige applicatiepagina’s C.1 Transport . . . . . . . . . . . . . . . . . . . C.1.1 Regions . . . . . . . . . . . . . . . . C.1.2 GLS colli . . . . . . . . . . . . . . . C.1.3 GLS freight . . . . . . . . . . . . . . C.2 Packaging . . . . . . . . . . . . . . . . . . C.2.1 Aanmaken van een nieuwe verpakking C.2.2 Wijzigen van een verpakking . . . . . C.2.3 Verwijderen van een verpakking . . . C.2.4 Overzicht ’Packaging’ pagina . . . . C.3 Supplier . . . . . . . . . . . . . . . . . . . C.3.1 Aanmaken van een nieuwe leverancier C.3.2 Wijzigen van een leverancier . . . . . C.3.3 Verwijderen van een leverancier . . . C.3.4 Overzicht ’Supplier’ pagina . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
102 102 102 105 107 109 109 109 110 110 111 111 111 112 112
Lijst van figuren
1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 1.24 1.25 1.26
Logo Xplore Group . . . . . . . . . . . . . . Basic project overview . . . . . . . . . . . . Logo Java . . . . . . . . . . . . . . . . . . Logo SQL . . . . . . . . . . . . . . . . . . JPQL Query Flow . . . . . . . . . . . . . . JPA Principle . . . . . . . . . . . . . . . . . JAX-RS Principle . . . . . . . . . . . . . . Logo Java Enterprise Edition . . . . . . . . Logo MySQL . . . . . . . . . . . . . . . . . Logo WildFly . . . . . . . . . . . . . . . . . Logo HTML5 . . . . . . . . . . . . . . . . Logo CSS3 . . . . . . . . . . . . . . . . . . Logo Javascript . . . . . . . . . . . . . . . Basic Architecture Hibernate . . . . . . . . Basic Architecture RESTEasy . . . . . . . . Logo Apache Maven . . . . . . . . . . . . . Logo Quartz . . . . . . . . . . . . . . . . . Estimated hardware cost to crack a password Logo Bootstrap . . . . . . . . . . . . . . . Angular's MVW structure . . . . . . . . . . Font Awesome icon examples . . . . . . . . Logo jQuery . . . . . . . . . . . . . . . . . Smart-table example . . . . . . . . . . . . . Logo Eclipse . . . . . . . . . . . . . . . . . Logo Git en Bitbucket . . . . . . . . . . . . Atlassian Products . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
1 2 9 9 9 10 10 11 11 11 12 12 12 13 13 14 14 14 15 15 16 16 17 18 18 19
2.1 2.2 2.3
Agile Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User use case overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Business use case overview . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21 23 24
vi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . in 1 year . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
LIJST VAN FIGUREN
vii
2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.19 2.20 2.21 2.22 2.23 2.24
User workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . Business workflow . . . . . . . . . . . . . . . . . . . . . . . . . . General project overview . . . . . . . . . . . . . . . . . . . . . . . Internet Explorer 403 Error . . . . . . . . . . . . . . . . . . . . . CRUD REST actions . . . . . . . . . . . . . . . . . . . . . . . . . Flow of products and prices between Price Management Application Technical flow overview . . . . . . . . . . . . . . . . . . . . . . . Price Management Application Overview . . . . . . . . . . . . . . Development Stack Overview . . . . . . . . . . . . . . . . . . . . Simplified ER diagram . . . . . . . . . . . . . . . . . . . . . . . . REST API Methods . . . . . . . . . . . . . . . . . . . . . . . . . Bootstrap grid structure . . . . . . . . . . . . . . . . . . . . . . . Angular view structure . . . . . . . . . . . . . . . . . . . . . . . . Sequence diagram . . . . . . . . . . . . . . . . . . . . . . . . . . Price influential parameters . . . . . . . . . . . . . . . . . . . . . Basic price logic . . . . . . . . . . . . . . . . . . . . . . . . . . . Fixed product cost logic . . . . . . . . . . . . . . . . . . . . . . . Fixed transport cost logic . . . . . . . . . . . . . . . . . . . . . . Minimum profit calculation logic . . . . . . . . . . . . . . . . . . . Final price . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Status overview scheme . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . and PIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
25 25 26 27 28 29 30 31 32 33 37 44 45 49 50 51 52 53 54 55 59
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.20 3.21
Login screen . . . . . . . . . . . . . . . . . Navigatiemenu in open en gesloten toestand Compact screen navigation menu . . . . . . Navigation bar . . . . . . . . . . . . . . . . Save changes button . . . . . . . . . . . . . Save confirmation popup . . . . . . . . . . Export to Excel button . . . . . . . . . . . . Details button . . . . . . . . . . . . . . . . Search filters . . . . . . . . . . . . . . . . . Search & sort tables . . . . . . . . . . . . . Dashboard error overview . . . . . . . . . . Dashboard buttons . . . . . . . . . . . . . . Product search page . . . . . . . . . . . . . Select sales channels page . . . . . . . . . . Column select functionality . . . . . . . . . Packaging button . . . . . . . . . . . . . . Packaging menu . . . . . . . . . . . . . . . Price overwrite page . . . . . . . . . . . . . Product transport page . . . . . . . . . . . Calculation & Status page . . . . . . . . . . Status info on mouse hover . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
63 64 65 65 66 66 67 67 68 69 71 71 72 73 74 74 75 76 77 78 79
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
LIJST VAN FIGUREN
viii
3.22 3.23 3.24 3.25 3.26 3.27 3.28 3.29 3.30 3.31 3.32 3.33 3.34
Price calculation information button . . . . . . . . . . Price calculation information menu . . . . . . . . . . General information from product details page . . . . General price information from product details page . Price overwrite information from product details page Status information from product details page . . . . . Creation information from product details page . . . . Add product page . . . . . . . . . . . . . . . . . . . Editable table field . . . . . . . . . . . . . . . . . . . Zone button . . . . . . . . . . . . . . . . . . . . . . Delete button . . . . . . . . . . . . . . . . . . . . . Delete sales channel error popup . . . . . . . . . . . Sales channel page overview . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
79 80 81 82 82 83 83 84 85 85 86 86 87
C.1 C.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9 C.10 C.11 C.12 C.13 C.14 C.15
Editable table field . . . . . . Delete region error popup . . Region page overview . . . . Select region option . . . . . Editable table field . . . . . . GLS colli page overview . . . Select region option . . . . . Editable table field . . . . . . GLS freight page overview . . Editable table field . . . . . . Delete packaging error popup Packaging page overview . . . Editable table field . . . . . . Delete supplier error popup . Supplier page overview . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
103 103 104 105 105 106 107 107 108 109 110 110 111 112 112
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
Lijst van afkortingen
API Application Programming Interface
AWS Amazon Web Services
CRUD Create, Read, Update and Delete
DTO Data Transfer Object
DOM Document Object Model
ERP Enterprise Resource Planning
GUI Graphical User Interface
IDE Integrated Development Environment
JEE Java platform, Enterprise Edition
JPA Java Persistence API
KDF Key Derivation Function
MVW Model-View-Whatever
ORM Object Relational Mapping
PIM Product Information Management
POC Proof Of Concept
SPA Single Page Application
SQL Structured Query Language
UI User Interface
ix
Glossarium
Agile softwareontwikkeling: methode van softwareontwikkeling die toelaat dynamischer met het ontwikkelingsproces om te gaan.
Brute force attack: een crypto analytische aanval, die gebruik maakt van rekenkracht om domweg alle mogelijke wachtwoordcombinaties uit te testen, zonder het gebruik van algoritmen om dit proces te versnellen.
Commit,push,pull: Git terminologie die gebruikt wordt voor het samenvoegen van code kopieen van verschillende ontwikkelaars.
Continuous integration: het meermaals per dag samenvoegen van developercode kopie¨en op een gedeelde mainline.
Entiteit: een object waarover door middel van een ER diagram gegevens worden vastgelegd, meestal als onderdeel van het ontwerp van een databank.
Kanban: een specifieke agile ontwikkelingsmethode.
Module: een module is een losstaand onderdeel in een systeem, dat apart gecre¨eerd en gebruikt kan worden in verschillende systemen.
Rainbow table: een eenvoudige tabel met mogelijke wachtwoorden en hun overeenkomstige hashes.
Repository: opslaglocatie.
Scrum: een specifieke agile ontwikkelingsmethode.
x
Hoofdstuk
1
Situering Dit document beschrijft de price management applicatie voor het bedrijf Xplore Group. In de eerste plaats wordt hier uitgelegd wat de aanleiding en de vereisten van het project waren. Verder biedt deze situering de nodige uitleg over verschillende gebruikte technologie¨en, tools en bibliotheken.
1.1
Bedrijf
Xplore Group is een bedrijf dat deel uitmaakt van de alom gekende Cronos Group. Xplore Group werd in 1997 opgestart als een IT consultancy bedrijf, met de nadruk op het leveren van hoge kwaliteit IT oplossingen aan hun klanten, door het gebruik van Java en PHP solutions. Binnen Xplore Group zijn er nog een aantal kleinere bedrijven, waaronder XT-i, het bedrijf waar onder andere onze externe promotors, Frederik De Galan en Nick De Kock, voor werken. Het merendeel van de mensen die meewerken aan het project waartoe onze prijscalculator behoort, zijn medewerkers van XT-i, hoewel er ook enkele collega's van Xplore Group ingeschakeld zijn.
Figuur 1.1: Logo Xplore Group 1
HOOFDSTUK 1. SITUERING
1.2
2
Project
1.2.1
Introductie
Consumenten maken meer en meer gebruik van grote verkoopplatformen, zoals bijvoorbeeld Amazon of Bol.com, om een product te verkrijgen. Het aanbod is er gewoonlijk veel hoger en de prijzen liggen over het algemeen lager, wat het voor kopers dus zeer aantrekkelijk maakt. Dit zorgt ervoor dat webshops vaak ook kiezen voor deze bijkomende verkoopstrategie om hun producten aan te bieden. Zo heeft onder andere Mike Boon, een collega van onze externe promotors, een aantal webwinkels, waarop hij speelgoed en fietshelmen aanbiedt. Naarmate de webshop groeide, werd het echter steeds moeilijker om alle artikelen handmatig te beheren (voorheen gebeurde dit via Microsoft Excel) . Hierdoor is het idee ontstaan om dit beheer te automatiseren, en daarbij ook de prijsberekening automatisch te laten verlopen. Het project bestaat dus eigenlijk uit twee delen:
De ontwikkeling van een product management systeem, het zogenaamde PIM systeem, waarin alle verkoopartikelen en productgerelateerde eigenschappen beheerd worden. Dit systeem zal productdata naar de price management applicatie doorsturen.
De ontwikkeling van een prijsberekeningsmodule, waarin alle prijsgerelateerde eigenschappen van de verkoopartikelen beheerd worden. Deze module zal bovendien de finale verkoopprijs per product per verkoopkanaal berekenen, en deze vervolgens naar het PIM systeem doorsturen.
Merk op dat het eerste deel van het project ontwikkeld wordt door een ander team van Xplore Group, en dus buiten het bestek van deze scriptie valt. Dit brengt ons bij het tweede deel van het project en daarmee ook bij onderwerp van deze scriptie: het ontwikkelen van een software applicatie die de prijsberekeningen automatiseert, en vervolgens de berekende ideale prijzen terugstuurt naar het PIM systeem.
Figuur 1.2: Basic project overview
HOOFDSTUK 1. SITUERING
1.2.2
3
Doel
Het doel is om voor het PIM systeem een prijsberekeningsmodule te ontwikkelen die automatisch de beste prijs per product per verkoopkanaal berekent, aan de hand van een aantal parameters. De price calculator is niet gebaseerd op bestaande software, en wordt ontwikkeld als een losstaande module, aan de hand van voorwaarden afgeleid uit een aantal gesprekken met onze bedrijfsbegeleiders en Mike Boon, de beheerder van de webshops. De applicatie zou moeten zorgen voor een sterke centralisatie van prijsdata en een automatisatie van prijsdataverwerking, met verschillende grote voordelen als gevolg:
Significante verlaging van de kans op fouten;
Duidelijk overzicht van relevante informatie;
Tijdsbesparing.
1.2.3
Vereisten
User requirements Prijsberekening De belangrijkste vereiste van onze price calculator is uiteraard de mogelijkheid om verkoopprijzen per product per verkoopkanaal te berekenen. Indien de uiteindelijke verkoopprijs niet correct zou zijn, gaat dit gepaard met rampzalige verliezen in verkoop en/of winst. De price management application staat of valt dus met de ideale prijsberekening. Kort samengevat moeten per product per verkoopkanaal 2 prijzen berekend gaan worden: enerzijds de minimumprijs en anderzijds de maximumprijs. De parameters die deze prijzen be¨ınvloeden kunnen opgedeeld worden in de onderstaande groepen:
Aankoopprijs en BTW;
Leverancier;
Verpakking;
Verkoopkanaal;
Transport;
Winst.
HOOFDSTUK 1. SITUERING
4
Basic operations: create, read, update en delete Het moet mogelijk zijn voor de beheerder om op elke pagina enkele basisoperaties uit te voeren. Read en update zijn overal noodzakelijk, create en delete zijn afhankelijk van de entiteit. Producten worden uit het PIM systeem opgehaald, en prijsinformatie wordt na bepaalde acties automatisch aangemaakt, dus hiervoor zullen create en delete acties overbodig zijn. Voor alle andere entiteiten (verpakking, leverancier, transport en verkoopkanaal), moet ook create en delete functionaliteit voorzien worden. Het is uiteraard essentieel dat al deze basisoperaties simpel en snel uitgevoerd kunnen worden, zodat de gebruikers zo weinig mogelijk hinder ondervinden bij het aanroepen van deze acties. Mass updates Naast de basisoperaties, moet het mogelijk zijn om bepaalde velden op een makkelijke manier te updaten voor een grote hoeveelheid producten en/of prijzen. Deze bulk updates moeten duidelijk en overzichtelijk weergegeven worden. Ook is het niet voldoende om waardes simpelweg te overschrijven, of overal dezelfde waarde in te voeren, maar ook simpele berekeningen (x+y en x-y) moeten uitgevoerd kunnen worden. Ook hier is het vanzelfsprekend dat de aanpassingen vlot moeten verlopen, zodat de gebruiker weinig tot geen vertraging ondervindt na het uitvoeren van een mass update. Status management De applicatie moet op een overzichtelijke manier kunnen weergeven waar eventuele fouten en/of verouderde prijzen opgetreden zijn. Hiervoor zullen een aantal statussymbolen ge¨ıntegreerd moeten worden, die voor verschillende doeleinden gebruikt kunnen worden. Zo kan er bijvoorbeeld makkelijk weergegeven worden of:
Prijsinformatie voor een bepaald product reeds gekend is door de prijscalculator;
Prijzen herberekend moeten worden (bijvoorbeeld na het veranderen van de aankoopprijs van een product);
Prijzen (her)verzonden moeten worden naar het Hybris hoofdsysteem.
HOOFDSTUK 1. SITUERING
5
Dynamisch De applicatie moet een dynamisch karakter hebben. Dit houdt in dat de prijsberekeningsmodule gebouwd moet worden op een manier waarbij business gerelateerde veranderingen van informatie makkelijk opgevangen kunnen worden. Praktisch zal dit erop neerkomen dat alle waardes op product en/of prijsniveau overschrijfbaar moeten zijn om onder andere promoties, bijzondere verzend- of verpakkingsmethodes en dergelijke op te vangen. Ook technologische veranderingen moeten makkelijk op te vangen zijn. Er is dus een hoge compatibiliteit vereist met verschillende elektronische apparaten (smartphones, tablets, laptops en desktop computers) en besturingssystemen. User friendly De price calculator moet gebruiksvriendelijk zijn. Er zal op sommige plaatsen ontzettend veel data weergegeven moeten worden op een overzichtelijke manier. Onder andere zoekfilters, sorteerbare tabellen en duidelijke links naar gerelateerde pagina's in de applicatie zijn dus een must.
HOOFDSTUK 1. SITUERING
6
Business requirements Hybris synchronisatie Nieuwe producten moeten uit het hoofdsysteem opgehaald kunnen worden. Na het verrijken van de product prijsinformatie en het berekenen van de minimum en maximumprijs, moet de ideale prijs op een bepaalde manier naar het PIM systeem gestuurd kunnen worden. Scalability Onze applicatie wordt in de eerste plaats door het bedrijf ontwikkeld voor de klant, maar met een groot aantal andere potenti¨ele klanten in het achterhoofd. De prijscalculator wordt op het moment dus vooral als POC (Proof Of Concept) ontwikkeld, maar we kunnen er al vanuit gaan dat de mogelijkheid bestaat dat de module later ook voor andere bedrijven gebruikt moet kunnen worden. De applicatie moet dus zo ontworpen worden dat uitbreidingen in de toekomst makkelijk mogelijk zijn. Technical requirements Modulaire opbouw De keuze voor een aparte module voor de prijsberekening is nogal vanzelfsprekend. Aangezien de price calculator applicatie op deze manier ge¨ımplementeerd kan worden als een vrijstaande component, kan de module parallel ontwikkeld worden met het voorgenoemde PIM systeem. Bovendien maakt dit het mogelijk om in de toekomst uitbreidingen aan deze component te maken, zonder dat het hoofdsysteem gewijzigd moet worden. Omgekeerd zou het dan ook perfect mogelijk zijn om van hoofdsysteem te veranderen en deze prijscalculator te blijven gebruiken. Hybris communication through REST Het Hybris PIM systeem bevat een REST API, waarmee de prijzen en producten verzonden/ontvangen dienen te worden.
HOOFDSTUK 1. SITUERING
1.2.4
7
Samenvatting
Concreet kunnen we stellen dat het eindresultaat moet voldoen aan volgende eisen:
De applicatie moet per product twee prijzen kunnen berekenen: een minimum- en maximumprijs;
Op elke pagina moeten een aantal basisoperaties uitgevoerd kunnen worden: Create, Read, Update en Delete;
De gebruiker kan mass (bulk) updates uitvoeren;
De toepassing is voorzien van een status management tool, die weergeeft waar mogelijke fouten voorkomen;
De tool moet een dynamisch karakter hebben;
De applicatie moet gebruiksvriendelijk zijn;
De applicatie moet een modulaire structuur bezitten;
Er moet synchronisatie met het hoofdsysteem (Hybris) mogelijk zijn;
De applicatie moet makkelijk aangepast kunnen worden voor nieuwe, gelijkaardige toepassingen.
HOOFDSTUK 1. SITUERING
1.2.5
8
Conclusie
Uit de prijsberekeningsvereisten kunnen we afleiden dat er een relatief ingewikkeld relationeel databasemodel opgesteld zal moeten worden, om alle verschillende parameters te kunnen omvatten. Om dit databasemodel compatibel te maken met de software, zal gebruik gemaakt moeten worden van ORM (Object-relational mapping). Qua softwareomgeving wordt gekozen voor Java, vermits Xplore Group een Java gespecialiseerd bedrijf is. Met behulp van ORM is het dan mogelijk om de CRUD (Create, Read, Update, Delete) acties in Java uit te voeren. Omdat de applicatie dynamisch moet zijn, wordt als gebruikersomgeving gekozen voor een webapplicatie, vermits deze universeel bruikbaar zou zijn (een installatie op het toestel van de gebruiker is hierbij ook overbodig). Bovendien zijn er voor webapplicaties een groot aantal frameworks en plugins beschikbaar om de toepassing schaalbaar en gebruiksvriendelijker te maken. In deze omgeving moet gezorgd worden dat de gebruiker afgeschermd wordt van de onderlinge complexe relaties van het databasemodel. Elke pagina zal dus enkel de informatie bevatten rond ´e´en bepaald onderwerp om verwarring voor de gebruikers te vermijden. De applicatie zal modulair zijn, waardoor het kan meegroeien met de veranderende eisen van de gebruikers. Deze modulaire aanpak, met een extra aandachtspunt voor scalability, zorgt ervoor dat het in de toekomst relatief makkelijk wordt om aanpassingen te maken. Door deze modulaire opbouw zal het mogelijk moeten zijn om op een bepaalde manier te kunnen communiceren met het hoofdsysteem. Ook de gebruikersomgeving zal op ´e´en of andere manier met ons backend (Java) systeem moeten kunnen communiceren.
HOOFDSTUK 1. SITUERING
1.3
Technologie¨ en
1.3.1
9
Backend
Java: Java is een platform onafhankelijke objectgeori¨enteerde programmeertaal, die syntactisch grotendeels gebaseerd is op C++. Aangezien ons stagebedrijf gespecialiseerd is in Java en PHP solutions, is de keuze voor Java vanzelfsprekend.
Figuur 1.3: Logo Java
SQL: SQL is een gestandaardiseerde taal voor een relationeel database managementsysteem. Met de taal kunnen databanken aangemaakt of aangepast worden. Ook wordt de taal gebruikt om data uit een database op te vragen.
Figuur 1.4: Logo SQL
JPQL: Java Persistence Query Language is een taal die sterke gelijkenissen vertoont met SQL qua syntax, maar toegepast wordt op objecten van JPA entiteiten in plaats van rechtstreeks op de database tabellen.
Figuur 1.5: JPQL Query Flow, Bron:[12]
JPA: Java Persistence API wordt gebruikt om de toegang tot en het beheer van data tussen java klassen en een relationele database te regelen. JPA is geen product maar een specificatie. Het kan dus niet op zichzelf bestaan, maar is een collectie van interfaces. Er zijn vele JPA implementaties(bijvoorbeeld Java EE Application Server, Hibernate,...).
HOOFDSTUK 1. SITUERING
10
Figuur 1.6: JPA Principle, Bron:[10]
JAX-RS: JAX-RS is een Java programming language API voor RESTful Web Services. Hierbij worden annotations toegepast om de ontwikkeling en implementatie van web service clients te vergemakkelijken. De communicatie tussen backend en Hybris, alsook de onderlinge communicatie tussen backend en front end maken hiervan gebruik. De belangrijkste annotations zijn: – @Path: specifieert het relatieve pad van de methode of klasse; – @Get: HTTP request type dat duidelijk maakt dat er geen parameters meegegeven worden, en dat er iets opgehaald moet worden; – @Post: wordt gebruikt wanneer er een methode word aangeroepen waar een parameter aan wordt meegegeven; – @Consumes: specifieert het datatype dat gebruikt wordt in een request; – @Produces: specifieert het datatype dat verzonden wordt nadat een request is uitgevoerd.
Figuur 1.7: JAX-RS Principle, Bron:[5]
HOOFDSTUK 1. SITUERING
11
Computing platform
JEE: Java Platform Enterprise Edition biedt een API en runtime environment aan, die gebruikt kan worden voor development en deployment van enterprise software. De software voor dit platform wordt hoofdzakelijk in Java geschreven, en het platform zelf bestaat voornamelijk uit modulaire componenten die draaien op een application server. De grote verschillen met de Standard Edition van het Java Platform zijn de vele uitbreidingen van de functionaliteit van bestaande application programming interfaces, en de toegevoegde API voor web services en object-relational mapping. Een product kan pas als Java EE compatibel bestempeld worden wanneer het voldoet aan bepaalde requirements.
Figuur 1.8: Logo Java Enterprise Edition
Database management
MySQL: MySQL is het populairste (open source) managementsysteem voor relationele databanken. Onderhouden, aanmaken en opvragen van data uit een databank gebeurd via SQL. MySQL valt onder de GPL v.2 licentie en is bezit van de Oracle Corporation.
Figuur 1.9: Logo MySQL
Application server
WildFly: WildFly is een open source cross-platform application server, die JEE implementeert en geschreven is in Java. Vroeger was WildFly gekend als Jboss Application Server, maar bij de overname van het bedrijf Jboss door Red Hat is de naam gewijzigd. Er is echter nog steeds veel bruikbare informatie te vinden onder de oude naam.
Figuur 1.10: Logo WildFly
HOOFDSTUK 1. SITUERING
1.3.2
12
Front end
HTML5 (HyperText Markup Language 5): de nieuwste versie van de HTML standaard. HTML is een taal die gebruikt wordt om documenten op te maken, die gepubliceerd kunnen worden op het internet, en bekeken kunnen worden met behulp van een webbrowser. Vermits onze applicatie universeel bruikbaar moet zijn, is HTML de logische keuze. Op deze manier kan iedere gebruiker, onafhankelijk van het gebruikte toestel en/of besturingssysteem, een versie van de tool openen.
Figuur 1.11: Logo HTML5
CSS3 (Cascading Style Sheets 3): CSS wordt gebruikt om de vormgeving van HTML documenten vast te leggen. CSS kan zowel toegepast worden in de te stijlen HTML pagina's, als in een apart *.css bestand, met een verwijzing vanuit de HTML pagina's. Vermits er gekozen is voor een HTML applicatie, is het gebruik van CSS onvermijdelijk.
Figuur 1.12: Logo CSS3
Javascript: een programmeertaal geschikt om scripts te schrijven, die gebruikt worden om interactieve webpagina's te cre¨eren. De keuze voor HTML, gecombineerd met de verwachte functionaliteit van de applicatie, maakt het gebruik van Javascript noodzakelijk.
Figuur 1.13: Logo Javascript
HOOFDSTUK 1. SITUERING
1.4
13
Libraries & frameworks
Hieronder worden alle bibliotheken en frameworks die we voor dit project gebruikt hebben kort toegelicht. Bij verdere interesse kan gerelateerde code teruggevonden worden in het portfolio onder 'Finaal product/third party code'.
1.4.1
Backend
Hibernate: Hibernate ORM is een object-relational mapping bibliotheek voor java. Het bied een framework aan dat gebruikt wordt voor het mappen van een objectgeori¨enteerd domeinmodel naar een relationele database. Dit gebeurt door elke database tabel te koppelen aan ´e´en of meerdere Java klasse(s). Hibernate is gratis software die uitgeven wordt onder de GNU Lesser General Public License.
Figuur 1.14: Basic Architecture Hibernate, Bron:[11]
RESTEasy: RESTEasy is een JBoss project, dat verschillende frameworks aanbiedt voor het bouwen van RESTful Web Services en RESTful Java applicaties. Het is een volledig gecertificeerde en portable implementatie van de JAX-RS specification.
Figuur 1.15: Basic Architecture RESTEasy, Bron:[9]
HOOFDSTUK 1. SITUERING
14
Apache Maven: Maven is een framework dat bestaat uit een aantal plugins die gezamenlijk gebruikt kunnen worden als build automation tool. Maven beschrijft hoe software gebouwd wordt, en welke dependencies de software heeft. Hoewel er al jaren ondersteuning is voor C#, Ruby, Scala en andere programmeertalen, wordt Maven nog steeds hoofdzakelijk gebruikt voor Java projecten.
Figuur 1.16: Logo Apache Maven
Quartz: Quartz is een open source job scheduling library die in bijna elke Java applicatie ge¨ıntegreerd kan worden. Tijdsschema's worden in deze bibliotheek opgesteld in de vorm 'cron expressions', wat het mogelijk maakt om zowel zeer makkelijke als ongelooflijk ingewikkelde tijdsplanningen op te stellen.
Figuur 1.17: Logo Quartz
Bcrypt: Bcrypt is een KDF (Key Derivation Function) voor wachtwoorden, gebaseerd op het Blowfish cipher (een symetric-key block cipher). Bcrypt voegt random salts toe aan de wachtwoorden om omvorming met behulp van rainbow tables te voorkomen. Een bijkomend voordeel is het adaptief karakter van bcrypt: het aantal encryptie herhalingen, ook gekend als de 'cost' of work factor, kan verhoogd worden zodat de code resistant blijft tegen brute-force attacks wanneer de kracht van hedendaagse computers vergroot.
Figuur 1.18: Estimated hardware cost to crack a password in 1 year, Bron: [7]
HOOFDSTUK 1. SITUERING
1.4.2
15
Front end
Bootstrap: Bootstrap is een front-end framework dat gebruikt wordt om op een snelle en makkelijke manier een mooi design aan een webpagina te geven. Ook zijn er een hele hoop gratis thema templates voor te vinden, wat het nog simpeler maakt om een webpagina een professionele look te geven. Wij hebben gebruik gemaakt van het SB Admin 2 thema, een administratorgerichte en gebruiksvriendelijke web application user interface (bron: http://startbootstrap.com/ template-overviews/sb-admin-2/).
Figuur 1.19: Logo Bootstrap
AngularJS: AngularJS is een Javascript MVW (Model-View-Whatever) framework dat de tekortkomingen van HTML bij de ontwikkeling van dynamische views aanpakt. AngularJS is vooral populair bij het ontwikkelen van SPA's (Single Page Applications), omwille van de vele krachtige mogelijkheden van het framework. Zo is er onder andere ondersteuning voor two-way databinding, partial views en directives (een manier om nieuwe herbruikbare HTML tags te ontwikkelen).
Figuur 1.20: Angular's MVW structure,Bron:[2]
HOOFDSTUK 1. SITUERING
16
Font Awesome: Font Awesome is een CSS framework dat bestaat uit een uitgebreide collectie iconen, die als glyphs (karakters van een lettertype) aangeroepen kunnen worden. Het lettertype dat speciaal hiervoor gecre¨eerd wordt, noemt men hierdoor ook wel een icon font. Een groot voordeel aan het gebruik van een icon font in vergelijking met gewone iconen, is het feit dat deze op dezelfde manier aan te passen zijn als tekst. Men kan dus makkelijk visuele eigenschappen zoals de kleur, grootte of schaduw van de iconen naar eigen wensen aanpassen, met behulp van CSS.
Figuur 1.21: Font Awesome icon examples
jQuery (v.1.11): jQuery is een zeer uitgebreide Javascript library die vooral gericht is op het verkorten en vergemakkelijken van standaard Javascript functies, zoals event handling, HTML DOM manipulatie, animaties en Ajax calls. Merk op dat er op het moment van schrijven al een jQuery 2.0 versie uitgebracht is, maar deze ondersteunt geen Internet Explorer 6,7 en 8 meer. Aangezien deze webbrowsers tegenwoordig toch nog regelmatig worden gebruikt, is beslist om een oudere jQuery versie te implementeren.
Figuur 1.22: Logo jQuery
Editable table: Editable table is een compacte jQuery plugin die elke tabel verandert in een aanpasbaar spreadsheet. Vermits de klant voor de ontwikkeling van onze applicatie al zijn berekeningen in Excel deed, is dit een ideale plugin om de applicatie een vertrouwd uiterlijk te geven.
Bootstrap datepicker: een klein kalender widget waarop een datum geselecteerd kan worden, in Bootstrap stijl. Deze plugin vergemakkelijkt de 'zoeken op datum' functionaliteit in onze applicatie. Dit is een perfecte visuele additie voor de applicatie, aangezien het thema van de gebruikersomgeving reeds op Bootstrap gebaseerd is.
HOOFDSTUK 1. SITUERING
17
Smart Table: Smart Table is een AngularJS module die kan worden gebruikt om data op een duidelijke en simpele manier in tabelvorm te tonen, sorteren en filteren. Hiervoor zijn een groot aantal alternatieven beschikbaar, maar Smart Table is ´e´en van de betere keuzes omwille van verschillende redenen: – Gebruiksvriendelijk: de HTML tabel opmaak blijft hetzelfde als voordien, met uitzondering van enkele toegevoegde attributen in de table tags. Bovendien zijn custom builds mogelijk, en is het relatief simpel om eigen plugins in de bibliotheek te implementeren; – Compact: de minified versie is slechts 4kB groot; – 1 dependency: de enige dependency van de bibliotheek is AngularJS, wat reeds gebruikt wordt; – Stabiele release: redelijk veel AngularJS-based alternatieven zijn nog steeds enkel in b`eta versie beschikbaar.
Figuur 1.23: Smart-table example, Bron:[3]
HOOFDSTUK 1. SITUERING
1.5
18
Tools Eclipse: Eclipse is vooral bekend voor zijn open source Java IDE (Integrated Development Environment), waar ook hier gebruik van gemaakt wordt. Verder zijn er een groot aantal add-ons en plugins voor deze IDE beschikbaar.
Figuur 1.24: Logo Eclipse
MySQL Workbench: MySQL Workbench wordt in dit project enkel gebruikt voor het beheer van onze online MySQL database, hoewel het programma veel meer functionaliteit bezit. Zo kunnen er onder andere ook databasemodellen met ontworpen en gegenereerd worden.
Git: Git is een gratis open source version control systeem dat zeer makkelijk bruikbaar is. Git maakt het mogelijk om op een overzichtelijke manier met meerdere mensen aan een softwareproject te werken. Om Git te kunnen gebruiken is het uiteraard noodzakelijk om een repository te bezitten. Hier is gekozen voor een Atlassian Bitbucket repository om een aantal verschillende redenen: – Xplore Group was al bekend met andere Atlassian software, zoals Confluence, JIRA en HipChat; – Integratie met andere Atlassian software is mogelijk. Nieuwe commits worden voor dit project bijvoorbeeld weergegeven als een HipChat boodschap; – Bitbucket is gratis (voor maximum 5 gebruikers); – We hadden als studenten al gebruik gemaakt van Bitbucket in het verleden, en waren er toen zeer tevreden over. Ook zorgt dit ervoor dat er nu geen registratieproces meer doorlopen moet worden.
Figuur 1.25: Logo Git en Bitbucket
SmartGit: SmartGit is een gratis Git client die het mogelijk maakt om op een grafische manier toegang te krijgen tot Git. Dit maakt het gebruik van scripts om verschillende Git acties (push, pull, commit) uit te voeren volledig overbodig.
Dropbox: Dropbox is een populaire cloud sharing service voor allerlei bestanden. Op deze manier kan documentatie, analyses en technische schema's makkelijk onderling gedeeld worden. Bovendien is Dropbox gratis in gebruik voor een beperkte hoeveelheid opslagruimte, die op verschillende manieren sterk vergroot kan worden.
HOOFDSTUK 1. SITUERING
19
JIRA: JIRA is een project management tool van Atlassian, dat gebruikt kan worden om taken te cre¨eren en beheren. Elke taak kan hierbij een eigen prioriteit en verwachte datum van voltooiing toegewezen krijgen. Verder kan JIRA ook fouten opslaan en documenteren. JIRA is bovendien een ideale tool voor agile softwareontwikkeling: development methodes als scrum en kanban zitten standaard in het programma verwerkt.
Confluence: Confluence is een ander populair product van Atlassian. Het wordt omschreven als een team management tool. Het gebruik van Confluence zorgt er onder andere voor dat verschillende gebruikers projectgerelateerde documentatie makkelijk kunnen delen met hun teamgenoten. In dit project is Confluence onder andere gebruikt om een overzicht van het project te schetsen, installatie-en configuratiestappen voor bepaalde software te documenteren, een algemene planning aan te maken en nuttige bronnen te delen.
Bamboo: Bamboo is een continuous integration en delivery tool voor softwareprojecten van Atlassian. Het wordt gebruikt om veranderingen in code automatisch te deployen naar een server, na het uitvoeren van een aantal (optionele) testen.
HipChat: HipChat, ons laatste gebruikte Atlassian programma, is een instant messaging programma, waarin groepschats en videochats mogelijk zijn. Ook zijn er voor HipChat mobiele apps, en is er een optie om boodschappen bij afwezigheid van de ontvanger via mail te versturen. Verder is ook hier integratie met andere Atlassian software mogelijk. Deze superieure chatapplicatie maakt communicatie met collega’s op bijna elk moment van de dag mogelijk.
Figuur 1.26: Various Atlassian Products
Hoofdstuk
2
Bespreking Price Management Application 2.1
Inleiding
De berekening van de ideale prijs van een product op een bepaald verkoopkanaal is niet zo eenvoudig. Er zijn tenslotte een zeer groot aantal parameters die in rekening gebracht worden. Deze bespreking beschrijft de uitwerking van de in het vorige hoofdstuk besproken requirements (zie 1.2.3), alsook onze projectaanpak en de toelichting van de motivatie achter bepaalde gemaakte keuzes.
2.2
Aanpak
Voor de uitwerking van dit project hebben we gekozen voor een agile aanpak, omdat er meer van een idee/concept vertrokken is, dan van een product met strikte vereisten. Vanaf het begin bleek dat de klant nog veel knopen moest doorhakken, waardoor vrijwel meteen beslist is dat een agile approach de way-to-go was. Zowel de klant als de interne promotors zijn vanaf het begin sterk bij het project betrokken, door op geregelde basis meetings te houden en zichtbare delen van het project te tonen en te testen. Op deze manier kon het product zich zeer dynamisch ontwikkelen, en terwijl perfect afstemmen naar de eisen van de klant. Verder is er doorheen het project constant continuous integration gebruikt. Doordat alle teamleden op regelmatige tijdstippen per dag nieuwe commits uitvoerden, zijn grote integratieproblemen op de main branch vermeden.
20
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
Figuur 2.1: Agile Development, Bron: [4]
21
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.3
22
Use cases
Om de user, business en technical requirements te helpen bepalen en visualiseren, zijn zowel user use cases als business use cases opgesteld. Deze scriptie zal zich beperken tot het bespreken van de algemene use case overviews. Bij verdere interesse kunnen enkele use cases teruggevonden worden in bijlage A. Ook zijn alle use cases terug te vinden in de folder 'Finaal product/Schema's' van het portfolio.
2.3.1
User use cases
De user use cases kunnen opgesplitst worden in vijf groepen, die elk bestaan uit een aantal taken die de gebruiker kan ondernemen:
CRUD functionaliteit: dit is ´e´en van de meest uitgebreide groepen, vermits voor elke entiteit met invloed op de prijsberekening Create, Read, Update en Delete functionaliteit voorzien moet zijn;
Price enrichment: de gebruiker moet op product en prijsniveau parameterwaarden (of overwrites) kunnen invullen om de berekende prijs naar wens te be¨ınvloeden;
Hybris synchronisatie: – Nieuwe en geupdate producten ophalen uit het Hybris PIM systeem; – Berekende prijzen terugsturen naar het Hybris systeem.
Prijsberekening: na het verkrijgen en verrijken van de prijsgerelateerde productinfo moet de gebruiker een prijs kunnen laten berekenen;
Status management: de gebruiker moet in staat zijn om fouten op een overzichtelijke en duidelijke manier te kunnen vinden en interpreteren.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
23
User use case overview
Figuur 2.2: User use case overview
2.3.2
Business use case overview
Het business use case overview beschrijft hoe ge¨ınteresseerde partijen hun gewenste doel kunnen bereiken door gebruik te maken van de applicatie, en welke activiteiten/acties nodig zijn om dit doel te bereiken. Algemeen kan gesteld worden dat het project gesplitst is in twee delen, zoals eerder reeds vermeld is (zie 1.2.1). In de price management application zullen een aantal stappen uitgevoerd moeten worden vooraleer de berekende prijs in Hybris getoond kan worden: 1. Producten moeten ingeladen worden uit Hybris. Merk op dat dit ook elk uur automatisch gebeurt (zie figuur 2.3) 2. Voor elk product dienen de gewenste verkoopkanalen geselecteerd te worden. 3. Prijsgerelateerde parameters worden ingevuld en/of overschreven. 4. Prijzen moeten berekend worden (zie Price logic) 5. De berekende prijzen worden verzonden naar het PIM systeem van Hybris. Merk op dat dit ook elk uur automatisch gebeurt (zie figuur 2.3) 6. Voor elke prijs wordt gecontroleerd op fouten via het status management. Zowel fouten bij het verzenden en berekenen van prijzen, alsook aanpassingen van gebruikte parameters zullen een error status weergeven (zie Status logic).
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
Figuur 2.3: Business use case overview
24
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.4 2.4.1
25
Workflow User workflow
Een gebruiker moet om zijn doel te kunnen bereiken een aantal vaste stappen doorlopen. Eerst moet hij zich identificeren door middel van credentials (gebruikersnaam en wachtwoord). Wanneer de credentials goedgekeurd worden, voert hij zijn gewenste handeling(en) uit, zoals bijvoorbeeld het aanmaken van sales channels, leveranciers wijzigen, of prijzen berekenen. Tenslotte moeten de wijzigingen opgeslagen worden om de actie te finaliseren.
Figuur 2.4: User workflow
2.4.2
Business workflow
Om de prijs van een product te berekenen dienen er een aantal stappen te gebeuren: 1. Een nieuw product wordt toegevoegd in het Product Information Management systeem; 2. Dit product wordt opgehaald door de price calculation module; 3. Parameters met prijsinvloed worden ingevoerd en/of overschreven; 4. Prijzen worden berekend; 5. De prijzen worden teruggestuurd naar het Hybris PIM systeem.
Figuur 2.5: Business workflow
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.5
Technical
2.5.1
Introductie
2.5.2
Architectuur
26
Algemeen projectoverzicht Vooraleer de prijscalculator uitgelegd wordt, is hier het volledige project geschetst. Zie onderstaande figuur 2.6 voor een algemeen overzicht van het project. De productinformatie van de webshop wordt beheerd door het centrale Product Content Management systeem van Hybris, in het algemeen een PIM systeem genoemd. Vanuit dit systeem vertrekt productdata naar alle andere componenten. Informatie over de voorraden van de producten wordt bijgehouden met behulp van Navision, een Enterprise Resource Planning en boekhouding tool van Microsoft. Deze software zal updates van stockinformatie doorzenden naar het PIM systeem. Merk op dat momenteel enkel de voorraden van de rechtstreekse verkoopkanalen (Kinderenkoning.be en Mynutty.be) opgevolgd worden. Deze rechtstreekse verkoopkanalen worden beheerd met Magento, een open source eCommerce managementsysteem voor webshops. In de rechterbovenhoek van de figuur staat de price calculation module, het onderwerp van deze scriptie. Deze module zal, zoals alle andere componenten, productinformatie ontvangen van het PIM systeem.
Figuur 2.6: General project overview
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
27
Technical flow Zoals reeds vermeld in de use case bespreking op pagina 22 kunnen de mogelijke acties in de applicatie opgedeeld worden in verschillende stukken:
Authenticatie;
CRUD operaties;
Hybris synchronisatie: – GET products; – PUT/POST prices;
Prijscalculatie.
In dit deel worden al deze processen iets technischer toegelicht. Authenticatieproces De gebruiker dient zijn inlog gegevens in te geven in de web applicatie. Deze worden via REST door gestuurd naar de WildFly application server, waar het wachtwoord gehashed wordt met behulp van het bcrypt algoritme, en vervolgens de combinatie wachtwoord&inlognaam vergeleken wordt met de database voor een match. Indien de login gegevens correct ingevuld werden, wordt er een authorisatie token naar de browser teruggestuurd in de vorm van een cookie. Indien de inloggegevens fout waren, wordt er een HTTP error code 403 (Forbidden) teruggestuurd, en krijgt de gebruiker hier een melding van.
Figuur 2.7: Standaard Internet Explorer 403 Error CRUD operaties Via de web applicatie kan de gebruiker makkelijk per entiteit verschillende CRUD acties uitvoeren. Wanneer de gebruiker zijn wijzigingen vervolgens opslaat, worden deze via de corresponderende REST actie (zie figuur 2.8) naar de WildFly server verzonden. Voor elke entiteit zijn voor deze REST communicatie 2 DTO's voorzien:
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
28
´e´en DTO voor read functionaliteit, omdat hier tevens een 'in use' status wordt meegezonden, zodat er na het laden van een pagina geen objecten verwijderd kunnen worden die parent zijn van andere objecten;
een tweede DTO wordt gebruikt om de wijzigingen terug te sturen naar de server. Dit verloopt op de volgende manier: – Eerst wordt deze DTO geparsed naar de daadwerkelijke entiteit; – Vervolgens wordt deze doorverwezen naar status management, waar wordt gecontroleerd of de veranderingen invloed hebben op de prijs calculatie. Zo ja, dan worden de relevante statussen (zie Status logic) gewijzigd; – Als laatste stap worden de wijzigingen gepersisteerd door de Hibernate ORM tool.
Figuur 2.8: CRUD REST actions GET products Deze functie wordt automatisch elk uur uitgevoerd als een asynchrone job. Dit gebeurt met behulp van de Quartz scheduler. Er is verder ook nog een optie om deze methode manueel aan te roepen via de web applicatie. De werking is als volgt:
In de database wordt de laatste synchronisatiedatum bij gehouden. Deze datum wordt gebruikt in de REST call naar Hybris, om alle producten die aangemaakt of gewijzigd zijn sinds de synchronisatiedatum, op te halen;
Hierna worden de opgehaalde Hybris producten geconverteerd naar de product entiteit van de applicatie server. Deze producten worden gesplitst in nieuwe- en gewijzigde producten, door ze te gaan vergelijken met rijen in de producttabel van de applicatie database;
Voor de nieuwe producten worden er een aantal default waardes ingevuld. Verder wordt de beste (kleinst mogelijke) verpakking gekozen aan de hand van de productafmetingen. Voor gewijzigde producten worden enkel de parameters afkomstig uit Hybris geupdate, waarna enkele statussen(zie Status logic) aangepast worden indien nodig.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
29
PUT/POST prices Net als de Hybris GET products methode, wordt deze functie elk uur automatisch uitgevoerd als een asynchrone job met behulp van de Quartz scheduler. Ook hier is weer een optie om de taak manueel te triggeren. Deze taak verloopt als volgt:
Eerst wordt de 'send' status van de door te sturen prijzen op 'sending' gezet;
Hybris heeft een POST REST methode om nieuwe prijzen te versturen, en een PUT REST methode om bestaande prijzen te updaten. Omdat er voor de price management application geen enkele manier is om op voorhand te weten of een prijs bestaand of onbestaand is in het Hybris syteem, worden voor alle te verzenden prijzen eerst de POST (create) methode uitgevoerd. Enkel voor prijzen waarbij deze REST call een 404 error terugstuurt, zal de PUT (update) methode aangeroepen worden;
Tenslotte wordt de send status aangepast naar 'sent' voor prijzen die succesvol doorgestuurd zijn, of naar de corresponderende error code voor prijzen waarbij fouten opgetreden zijn.
Figuur 2.9: Flow of products and prices between Price Management Application and PIM Calculate prices Deze functie kan enkel manueel getriggerd worden via de web applicatie. Na het aanroepen van de functie, wordt ook hier weer een asynchrone job gestart met behulp van de Quartz scheduler. Deze taak gebeurt als volgt:
Alle prijzen die berekend dienen te worden, krijgen een calculation status 'calculating';
De prijzen worden ´e´en voor ´e´en berekend. Meer info over de prijslogica kan bij het onderdeel Price logic gevonden worden;
Bij een succesvolle prijsberekening wordt de calculation status op 'calculated' gezet. Indien een error optreedt wordt als calculation status van de desbetreffende prijs de overeenkomstige error code ingevuld.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
30
Technical flow overview De onderstaande figuur (2.10) illustreert hoe de aparte componenten van de product price management application met elkaar en het PIM systeem communiceren.
Figuur 2.10: Technical flow overview
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.5.3
31
Design
Al vanaf het begin was het duidelijk hoe ons algemeen ontwerp er zou uitzien: een web applicatie als frontend, die via REST services communiceert met een Java backend, die op zijn beurt communiceert met het PIM systeem en de database. Als frontend is er gekozen voor een webapplicatie, met als frameworks een combinatie van AngularJS en Bootstrap, en daar bovenop nog een aantal kleine toegevoegde plugins, zoals editable table en Smart Table. Met dit totaalpakket van technologie¨en, frameworks en libraries, hebben we een performante en intu¨ıtieve SPA gebouwd. Vooral de databinding van AngularJS is een veelgebruikte feature, die de applicatie zeer developer en user friendly maakt. Als backend is er een WildFly application server, waarop een Java application draait. Voor de communicatie met de front end hebben we een RESTful API ge¨ımplementeerd met behulp van JAX-RS. Dit hebben we ook gebruikt voor onze REST calls naar Hybris. Voor de communicatie met de database is er gebruikt gemaakt van een combinatie van JPA en Hibernate als ORM. Omdat alle data nodig voor de prijsberekening niet door Hybris gekend is, is er een MySQL database aangemaakt zodat deze data in de price management application ingegeven kan worden.
Figuur 2.11: Price Management Application Overview
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
32
Development stack Er is voor continuous integration gekozen om integratieproblemen zo veel mogelijk proberen te vermijden. Om dit te verwezenlijken is gewerkt met lokale Git repositories, die meerdere keren per dag gesynchroniseerd worden met de master branch op Bitbucket. Als test server wordt er gebruik gemaakt van een Amazon Web Services ec2 instance waar Ubuntu 12 op draait. Op deze server staan zowel onze application server als onze database. Om onze applicatie te deployen naar de application server, wordt gebruik gemaakt van Atlassian's continuous integration tool Bamboo: op het einde van elke dag zal de recentste projectversie van Bitbucket opgehaald worden, om deze vervolgens te builden op de testserver met behulp van Maven. Ook zijn er enkele basistesten ge¨ıntegreerd in het Bamboo proces. Een bijkomend voordeel van Bamboo is dat het tot de Atlassian stack behoort, en dus gelinkt kan worden aan andere Atlassian programma's. Alle stappen in verband met commits en builds worden zo bijvoorbeeld in het Atlassian chatprogramma HipChat getoond, zodat developers meteen op de hoogte zijn van mogelijke problemen, ook indien deze problemen bij een geautomatiseerd proces zouden optreden.
Figuur 2.12: Development Stack Overview
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
33
Database Omdat niet alle data nodig voor de prijsberekening door Hybris gekend is, is er gekozen om een MySQL database te linken aan onze applicatie. Na een gesprek met de klant, is als eerste stap in het ontwikkelingsproces een relationeel model uitgewerkt. Dit model is vervolgens nog meerdere keren gewijzigd, om zo goed mogelijk tegemoet te komen aan de eisen van de klant. ER diagram De figuur hieronder illustreert de relaties tussen de verschillende entiteiten in ons datamodel. Merk op dat deze figuur maar een compacte versie van het ER diagram is. Zie bijlage B op pagina 97 voor het volledige ER diagram.
Figuur 2.13: Simplified ER diagram Relaties Op de volgende pagina worden de relaties tussen de verschillende entiteiten kort uitgelegd. Verder zijn in bijlage B op pagina 98 enkele tabellen bijgevoegd die de betekenis van alle gebruikte parameters verduidelijken. Elke tabel in deze bijlage stelt een aparte entiteit van het entity relationship diagram voor.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
34
Packaging: deze entiteit bevat de verschillende mogelijke verpakkingen die gebruikt worden voor een product. Packaging is enkel afhankelijk van het product en optioneel, maar er zijn meerdere verpakkingen mogelijk (many-to-many relatie). Zo kan er bijvoorbeeld een doos met noppenfolie gecombineerd worden, of extra cadeauverpakking in rekening gebracht worden. De afmetingen van de verpakking zijn optionele eigenschappen, vermits bij bv. een strik enkel de prijs belangrijk is. Aan de hand van de afmetingen van een product kan automatisch de meest geschikte doos en de bijhorende verpakkingsprijs bepaald worden. Met de afmetingen van de verpakking en het gewicht van het product, kan vervolgens bepaald worden of het product via GLS Colli(geschikt voor kleine pakketten en goedkoop) of GLS Freight(geschikt voor grotere pakketten en duur) verzonden zal worden. Supplier: deze entiteit bevat de kortingen per leverancier (zowel aankoopkorting als staffelkorting). Een leverancier zal meerdere producten leveren, terwijl elk product maar ´e´en leverancier heeft (one-to-many relatie). Product: deze entiteit bevat alle toebehoren van een product (algemene informatie, winstmarges, prijzen, kosten enzovoort). Ook zijn er op productniveau een aantal overwrites/flags beschikbaar. Zo kan er bijvoorbeeld beslist worden of de listing price genegeerd mag worden door het aanpassen van de listing price flag. Elk product wordt op verschillende kanalen verkocht en elk kanaal zal verschillende producten aanbieden (many-to-many relatie). Ook zal een product meerdere prijzen hebben (1 prijs per sales channel), maar elke prijs zal wel aan 1 product gebonden zijn (one-to-many relatie). Ook zal een product per regio een verschillende transportkost en Drop&Ship prijs hebben (one-tomany relatie). Transport: deze entiteit bevat de transportkost en Drop&Ship prijzen. Het transport van een product is landafhankelijk. Er zullen dus meerdere transporten per product en per land mogelijk zijn (one-to-many relatie). Price: er zullen verschillende prijzen zijn voor een product (many-to-one relatie). Tegelijk zullen er aan elk kanaal ook verschillende prijzen gekoppeld zijn (many-to-one relatie), namelijk 1 prijs per product. Een prijs zal mogelijk overwrites hebben maar dit is niet noodzakelijk het geval (one-to-(n)one relatie). Hoewel de optimale prijs geen overwrite is, hebben we deze hier toch geplaatst omdat deze ook optioneel en kanaalafhankelijk is. Voor de rest bestaat de prijs uit een aantal noodzakelijke, berekende velden (one-to-one relatie met calculated). Price overwrite: zie Price. Price calculated: zie Price.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
35
Channel: er zijn vele kanalen die elk een aantal producten verkopen (many-to-many relatie). De producten hebben allemaal een afzonderlijke prijs, dus een kanaal zal aan meerdere prijzen gekoppeld zijn (one-to-many relatie). Elk kanaal zal leveren in verschillende zones (one-to-many relatie). Per kanaal zal een land van bestemming gedefinieerd worden (one-to-one relatie), waarvoor we de transportprijzen berekenen. Region: een regio kan voorkomen in meerdere zones en een zone kan bestaan uit meerdere regio's (many-to-many relatie). Meestal zal een regio een volledig land zijn, maar dit is niet altijd het geval. Voor Sardini¨e bijvoorbeeld, zal GLS een hogere transportkost aanrekenen dan de rest van Itali¨e. Zone: de relaties van zone zijn al besproken in channel en region. GLS Colli: Belgi¨e heeft per bestemming (regio) meerdere GLS Colli tarieven (one-to-many relatie), die afhankelijk zijn van de afmetingen en het gewicht van het pakket. GLS Freight: Belgi¨e heeft per bestemming (regio) meerdere GLS freight tarieven (one-tomany relatie), die afhankelijk zijn van de afmetingen en het gewicht van het pakket. Parameters Zie bijlage B op pagina 98 voor meer informatie over de parameters uit het ER diagram.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.5.4
36
Backend
Zoals zichtbaar in het Price Management Application Overview op pagina 31, is er als ontwikkelingsplatform gebruik gemaakt van Java Enterprise Edition. De ontwikkelde applicatie draait op een WildFly application server, die gedeployed wordt op een Ubuntu 12 omgeving in de cloud. Inhoudelijk bestaat de backend grotendeels uit een REST API voor communicatie met de front end GUI, en code voor de communicatie met Hybris. Verder wordt in dit onderdeel ook job scheduling en security toegelicht. CRUD functionaliteit Nadat de entiteiten en hun onderlinge relaties die reeds beschreven zijn in het ER diagram, is van dit diagram een databasemodel opgesteld. Dit database model is op zijn beurt met behulp van ORM, in dit geval de Hibernate plugin, omgezet in Java klassen die bruikbaar zijn in de backend applicatie. Dit liet ons toe om, met behulp van JPQL queries, heel makkelijk CRUD functionaliteit te implementeren. In de code hieronder wordt gedemonstreerd hoe een read mogelijk is van alle producten die nog geen prijs hebben, of waar de prijsberekening niet meer up to date is. Listing 2.1: query to read products without prices or with outdated prices TypedQuery
q u e r y = em . c r e a t e Q u e r y ( ”SELECT DISTINCT p , p r i FROM P r o d u c t p LEFT JOIN p . p r i c e s p r i LEFT JOIN p r i . p r i c e O v e r w r i t e pow LEFT JOIN p r i . p r i c e C a l c u l a t e d pc WHERE NOT EXISTS ( SELECT p r i c FROM P r i c e p r i c WHERE p r i c . p r o d u c t=p ) OR pc . s t a t u s P r i c e=FALSE” , O b j e c t [ ] . c l a s s ) ;
Zoals zichtbaar in de onderste regel van het codevoorbeeld, heeft de CRUD functionaliteit een extra dimensie die nog niet besproken is: status. Statussen bijhouden is in deze applicatie essentieel, vermits er op verschillende plaatsen desynchronisatie van data kan optreden. Het status management wordt verder uitgelegd in het onderdeel Status logic op pagina 56.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
37
REST API De voorgenoemde REST API is op een consistente en logische manier opgebouwd.Dit is de algemene structuur die gebruikt is: /pricing/rest/entiteit/subentiteit/aantal Merk op dat de subentiteit en het aantal niet overal essentieel zijn, en al dan niet toegepast worden afhankelijk van de nodige actie. Om verschillende CRUD acties te onderscheiden, is gebruik gemaakt van HTTP methodes.
Figuur 2.14: REST API Methods, Bron:[8] Met het onderstaande codevoorbeeld wordt gedemonstreerd hoe de verschillende HTTP REST methodes voor een entiteit ge¨ımplementeerd zijn. Listing 2.2: Region entity RESTful service example /* * * T h i s c l a s s p r o d u c e s a RESTful s e r v i c e t o r e a d / w r i t e t h e c o n t e n t s o f t h e * Region i n f o . */ @Path ( ” / r e g i o n ” ) @RequestScoped public class RegionResourceRestService { @Inject private RegionRepository r e p o s i t o r y ; @GET @Produces ( MediaType . APPLICATION JSON ) p u b l i c L i s t l i s t R e g i o n ( ) { return r e p o s i t o r y . findAllOrderedByName ( ) ; } @PUT @Consumes ( MediaType . APPLICATION JSON ) @Produces ( MediaType . APPLICATION JSON ) p u b l i c v o i d u p d a t e ( L i s t r e g n ) { r e p o s i t o r y . updateRegion ( regn ) ; } @POST @Consumes ( MediaType . APPLICATION JSON ) @Produces ( MediaType . APPLICATION JSON )
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
38
p u b l i c v o i d c r e a t e ( L i s t r e g n ) { r e p o s i t o r y . createRegion ( regn ) ; } @DELETE @Path ( ” /{ i d }” ) @Produces ( MediaType . APPLICATION JSON ) p u b l i c v o i d remove ( @PathParam ( ” i d ” ) long i d ) { int idint = ( int ) id ; Region regn = r e p o s i t o r y . f i n d B y I d ( i d i n t ) ; r e p o s i t o r y . deleteRegion ( regn ) ; } }
Hybris REST connectie Voor de communicatie met Hybris, wordt de REST API van Hybris aangesproken vanuit de backend. Om dit te bereiken is gebruik gemaakt van RESTeasy. Listing 2.3: Hybris PIM connection implementation @Override public int updatePrice ( String catalog , PriceCalculated priceCalculated , Price price ) { R e s t e a s y C l i e n t c l i e n t = new R e s t e a s y C l i e n t B u i l d e r ( ) . b u i l d ( ) ; ResteasyWebTarget t a r g e t = c l i e n t . target ( baseUrl ) . p a t h ( ” / p r i c e m o d u l a t o r / c a t a l o g s / ”+c a t a l o g+” / p r o d u c t / ”+p r i c e . g e t P r o d u c t ( ) . g e t S k u ()+ ” / u p d a t e P r i c e R o w ” ) ; S t r i n g code=c a t a l o g . t o U p p e r C a s e ()+ ” ”+p r i c e . g e t C h a n n e l ( ) . getName ( ) . t o U p p e r C a s e ()+ ” ”+p r i c e . getProduct ( ) . getSku ( ) . toUpperCase ( ) ; Double p r i c e D o u b l e = p r i c e C a l c u l a t e d . g e t O p t i m a l P r i c e ( ) ; Response r e s p o n s e = n e w D e f a u l t B u i l d e r ( t a r g e t ) . p o s t ( E n t i t y . j s o n ( new U p d a t e P r i c e B o d y P o s t ( code , p r i c e D o u b l e ) ) ) ; LOG . i n f o ( ” u p d a t e P r i c e ( ) r e s p o n s e : {} ” , r e s p o n s e . g e t S t a t u s ( ) ) ; return response . getStatus ( ) ; }
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
39
Scheduler Om de performantie en het gebruiksgemak van de applicatie te vergroten, worden bepaalde functies asynchroon op een bepaalde tijdsbasis uitgevoerd. Om dit te verwezenlijken is er gebruik gemaakt van de Quartz scheduler library. De implementatie van deze bibliotheek bestaat uit een takenplanner, waar alle jobs (de functies die asynchroon uitgevoerd moeten worden) gepland worden. Listing 2.4: Job scheduler code @PostConstruct public void s c h e d u l e J o b s ( ) { try { s c h e d u l e r = new S t d S c h e d u l e r F a c t o r y ( ) . g e t S c h e d u l e r ( ) ; scheduler . setJobFactory ( cdiJobFactory ); createOutdatedPricingJob ( ) ; scheduleHybrisProductSyncJob ( ) ; scheduleHybrisPriceSyncJob ( ) ; createHybrisPriceSyncSpeciJob (); scheduler . start (); printJobsAndTriggers ( scheduler ); } catch ( S c h e d u l e r E x c e p t i o n e ) { LOG . e r r o r ( ” E r r o r w h i l e c r e a t i n g s c h e d u l e r ” , e ) ; }
De planning van de jobs kan opgesplitst worden in periodische en manueel getriggerde jobs (schedule & create taken). In functie zijn ze bijna identiek, maar enkel bij de periodische jobs wordt er een trigger gecre¨eerd, waarin de periodiciteit beschreven staat met behulp van de cron notatie. Onderstaande code toont een cron notatie, die eenmaal per uur betekent. Daarop volgt een voorbeeld van de code gebruikt om een job te cre¨eeren en plannen. Listing 2.5: Cron notation - once every hour p r i v a t e s t a t i c f i n a l S t r i n g HYBRIS PRODUCT SYN CRON = ” 0 0 0/1 1/1 * ? * ” ;
Listing 2.6: Job creation and scheduling code - Nick De Kock p u b l i c v o i d t r i g g e r H y b r i s P r o d u c t S y n c J o b ( ) throws S c h e d u l e r E x c e p t i o n { s c h e d u l e r . t r i g g e r J o b ( JobKey . j o b K e y ( ” h y b r i s −p r o d u c t −s y n c ” , ” p r i c i n g ” ) ) ; } p r i v a t e v o i d s c h e d u l e J o b ( S t r i n g jobName , S t r i n g groupName , S t r i n g t r i g g e r N a m e , C l a s s extends Job> j o b C l a s s , S t r i n g c r o n ) throws S c h e d u l e r E x c e p t i o n { JobKey j o b K e y = JobKey . j o b K e y ( jobName , groupName ) ; JobDetail jobDetail ;
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
40
i f ( s c h e d u l e r . c h e c k E x i s t s ( jobKey ) ) { j o b D e t a i l = s c h e d u l e r . g e t J o b D e t a i l ( jobKey ) ; } else { // C r e a t e s j o b i f i t d o e s n ’ t e x i s t y e t LOG . i n f o ( j o b K e y + ” d o e s n ’ t e x i s t y e t , c r e a t i n g J o b D e t a i l ” ) ; jobDetail = JobBuilder . newJob ( j o b C l a s s ) . w i t h I d e n t i t y ( jobKey ) . build (); } TriggerKey triggerKey = T r i g g e r K e y . t r i g g e r K e y ( t r i g g e r N a m e+”−”+jobKey , groupName ) ; Trigger trigger ; i f ( scheduler . checkExists ( triggerKey )) { trigger = scheduler . getTrigger ( triggerKey ); } else { // C r e a t e s t r i g g e r and s c h e d u l e s j o b i f i t d o e s n ’ t e x i s t y e t LOG . i n f o ( t r i g g e r K e y + ” d o e s n ’ t e x i s t y e t , c r e a t i n g T r i g g e r and i m m e d i a t e l y s c h e d u l i n g ” + j o b D e t a i l ) ; t r i g g e r = T r i g g e r B u i l d e r . newTrigger () . withIdentity ( triggerKey ) . withSchedule ( CronScheduleBuilder . cronSchedule ( cron )) . f o r J o b ( j o b K e y . getName ( ) , j o b K e y . g e t G r o u p ( ) ) . build (); scheduler . scheduleJob ( jobDetail , t r i g g e r ) ; } }
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
41
Security Authenticatie gebeurt via bcrypt. In de database wordt de combinatie username en password bijgehouden, waarbij het wachtwoord in ge¨encrypteerde vorm volgens het bcrypt algoritme opgeslagen wordt. Als een gebruiker besluit om in te loggen, worden zijn gegevens via de front end door de REST API naar de backend gestuurd. Hier wordt gecontroleerd of de gebruiker bestaat. Zo ja, dan wordt gecontroleerd of het gehashte passwoord overeenkomt met dat in de database. Als deze check ook 'true' terugstuurt, zal een web token teruggestuurd worden in de vorm van een cookie, die vanaf dan gebruikt kan worden om alle REST calls te authoriseren. Het onderstaande codevoorbeeld demonstreert hoe de security service ge¨ımplementeerd is: Listing 2.7: Security service implementation - Nick De Kock @ApplicationScoped p u b l i c c l a s s S e c u r i t y S e r v i c e I m p l implements S e c u r i t y S e r v i c e { @Inject private UserRepository userRepository ; p r i v a t e f i n a l byte [ ] jsonWebTokenKey ; p r i v a t e L o g g e r LOG = L o g g e r F a c t o r y . g e t L o g g e r ( S e c u r i t y S e r v i c e I m p l . c l a s s ) ; public SecurityServiceImpl () { jsonWebTokenKey = new byte [ 6 4 ] ; new SecureRandom ( ) . n e x t B y t e s ( jsonWebTokenKey ) ; } @Override p u b l i c S t r i n g a u t h e n t i c a t e ( S t r i n g username , S t r i n g p a s s w o r d ) { U s e r u s e r = u s e r R e p o s i t o r y . getByUsername ( username ) ; i f ( u s e r == n u l l ) { LOG . i n f o ( ” U s e r n o t f o u n d f o r {} ” , username ) ; return n u l l ; } i f ( BCrypt . checkpw ( pas sw or d , u s e r . g e t P a s s w o r d ( ) ) ) { LOG . i n f o ( ” S u p p l i e d p a s s w o r d i s c o r r e c t f o r {} ” , username ) ; S t r i n g jsonWebToken = J w t s . b u i l d e r ( ) . s e t S u b j e c t ( username ) . s i g n W i t h ( S i g n a t u r e A l g o r i t h m . HS256 , jsonWebTokenKey ) . compact ( ) ; LOG . i n f o ( ” R e t u r n i n g jsonWebToken {} ” , jsonWebToken ) ; r e t u r n jsonWebToken ; } else { LOG . i n f o ( ” S u p p l i e d p a s s w o r d i s i n c o r r e c t f o r {} ” , username ) ; return n u l l ; } } @Override p u b l i c boolean a u t h o r i z e ( S t r i n g jsonWebToken ) { try { Jws j w s = J w t s . p a r s e r ( ) . s e t S i g n i n g K e y ( jsonWebTokenKey )
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
42
. p a r s e C l a i m s J w s ( jsonWebToken ) ; LOG . i n f o ( ” S u c c e s s f u l l y p a r s e d jsonWebToken w i t h username {} ” , j w s . getBody ( ) . g e t S u b j e c t ( ) ) ; return true ; } catch ( S i g n a t u r e E x c e p t i o n e ) { LOG . i n f o ( ” U n a b l e t o a u t h o r i z e jsonWebToken {} ” , jsonWebToken ) ; return f a l s e ; } } }
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.5.5
43
Front end
Zoals te zien in figuur 2.11, bestaat de front end uit een HTML5 applicatie met AngularJS, jQuery en Bootstrap integratie. Hier bovenop zijn nog een aantal kleine plugins gebruikt die reeds toegelicht zijn in het onderdeel Libraries & frameworks op pagina 15 . Structuur De front end is gestructureerd als een standaard AngularJS applicatie: er is een HTML hoofdbestand, met een aantal kleinere HTML bestanden die dynamische 'views' bevatten. Afhankelijk van de gevolgde route, wordt ´e´en van deze views in het hoofdbestand weergegeven, gecombineerd met de vaste inhoud van het hoofdbestand. De vaste inhoud bestaat in dit geval enkel uit hoofdingen en menu's. Als AngularJS javascript files wordt gebruik gemaakt van services, controllers en een routecontroller. De routecontroller bepaald welke dynamische views wanneer getoond moeten worden. De controllers zijn in feite javascript bestanden gelinkt aan een bepaald dynamisch view. Ter verduidelijking dit voorbeeld: de routecontroller zal ervoor zorgen dat bij het openen van een link naar '#/Dashboard' de dynamische 'dashboard.html' geladen wordt in het HTML hoofdbestand, en daarbij wordt ook de bijhorende dashboard controller geladen. AngularJS services worden in dit geval gebruikt om de REST services te configureren. Indien een AngularJS controller vervolgens gebruik wilt maken van ´e´en van deze rest services, kan dit makkelijk door het toevoegen van de correcte dependency en het aanroepen van de gewenste methode. Het onderstaand voorbeeld toont hoe de REST services in AngularJS geimplementeerd zijn, en vervolgens hoe ze aangeroepen kunnen worden. Listing 2.8: Angular REST service example s e r v i c e s . factory ( ’ channels ’ , function ( $resource ) { return $ r e s o u r c e ( ’ / p r i c i n g / r e s t / channel ’ , {} , { query : { method : ’GET ’ , i s A r r a y : true }, update : { method : ’PUT ’ , i s A r r a y : true }, create : { method : ’POST ’ , i s A r r a y : true } }) });
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
44
Aanroepen in de page controller kan, na het toevoegen van de dependency 'channels', op de volgende manier: Listing 2.9: Angular REST call example $ s c o p e . c h a n n e l C o l l e c t i o n= channels . query ({} ,{} , function ( returnValue , responseHeaders ) { // a c t i o n on s u c c e s s }, function ( httpResponse ) { connectionError ( httpResponse . status , ) ; });
UI De basis van het UI is het thema SB Admin 2 (Bron: [1]), waarop een hele hoop wijzigingen en uitbreidingen zijn aangebracht. Het eindresultaat van het UI kan bij Resultaten op pagina61 teruggevonden worden. De technische uitdagingen aan dit user interface, waren de schaalbaarheid en plaatsing van alle elementen. De elementen zijn grotendeels gepositioneerd door het gebruik van de Bootstrap grid structuur, waarmee elke pagina duidelijk in schaalbare stukken opgedeeld kan worden. Verder is het mogelijk om verschillende Bootstrap attributes toe te wijzen aan HTML tags, zodat ze afhankelijk van de schermgrootte optimaal gepositioneerd worden.
Figuur 2.15: Bootstrap grid structure, Bron:[6]
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
45
Verder zorgt het gebruik van AngularJS ervoor dat niet de volledige pagina geladen en gepositioneerd moet worden, maar enkel het dynamische 'view'. Headers en menubalken blijven hierdoor ongeschonden, vanaf de eerste pagina door de browser geladen is.
Figuur 2.16: Angular view structure
Databinding Nog een voordeel van AngularJS, is de mogelijkheid om op een makkelijke manier aan databinding te doen: er hoeven enkel een paar attributes toegevoegd te worden aan de HTML tags waarin men een bepaalde waarde wil weergeven. Verder zijn ook opties voor databinding van collecties mogelijk. Hierbij zal AngularJS ervoor zorgen dat voor elk element in de collectie het gewenste HTML object gecre¨eerd wordt door het gebruik van ng-repeat. Het spreekt voor zich dat hiervan veelvuldig gebruik gemaakt is in het project. De code op de volgende pagina demonstreert hoe eenvoudig het is om met behulp van AngularJS een tabel te cre¨eren voor x elementen met y properties. Het voorbeeld implementeert bovendien ook search & sort functionaliteit met behulp van de AngularJS plugin Smart Table. Hiervoor zijn de attributen st-table, st-sort en st-search aan de tabelstructuur toegevoegd.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION Listing 2.10: Angular ng-repeat example < t a b l e i d=” s u p p l i e r T a b l e ” s t −t a b l e=” s u p p l i e r C o l l e c t i o n ” s t −s a f e −s r c=” s e a r c h C o l l e c t i o n ” c l a s s=” t a b l e t a b l e −s t r i p e d ”> Name P u r c h a s e d i s c o u n t S c a l e d i s c o u n t t r > | | | t r > < t r ng−r e p e a t=” s u p p l i e r i n s u p p l i e r C o l l e c t i o n ” i d=” {{ s u p p l i e r . i d }} ”> {{ s u p p l i e r . name}} td> {{ s u p p l i e r . p u r c h a s e D i s c o u n t }} td> {{ s u p p l i e r . s c a l e D i s c o u n t }} td> t r > t a b l e >
46
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.6
47
User interface
2.6.1
Introductie
Het hoofddoel van de applicatie is om het prijsberekeningsproces te automatiseren, zodat door het gebruik van de applicatie tijd en denkwerk gespaard wordt. Om dit te bereiken is per takengroep een aparte pagina gemaakt, waar updates uitgevoerd kunnen worden. Tevens is er voor elk product ook een detail pagina, waarmee alle informatie over de prijsinformatie van een product overzichtelijk wordt weergegeven en aangepast. Vanuit elk resultaat op een takenpagina kan via een link naar de detailpagina van het desbetreffende product genavigeerd worden. Om op de specifieke pagina's het overzicht te bewaren zijn er een hele reeks zoekfilters toegevoegd. Daarbuiten kan men nog eens specifiek elke tabel op kolom filteren en sorteren. Deze zoekfilters worden als URL parameters opgeslagen, zodat browser navigatie (back & forward knoppen) makkelijk gebruikt kan worden. Waar nodig is mass update functionaliteit voorzien. Dit houdt in dat een gebruiker een parameter van een selectie van producten (of alle producten) in ´e´en actie kan aanpassen. Niet alleen simpelweg overschrijven is mogelijk, maar ook wiskundige basisbewerkingen (+ en -). Verder is de applicatie voorzien van een gedetailleerd statusoverzicht, en een dashboard waarop veelvoorkomende acties en error management van de 20 meest relevante fouten uitgevoerd worden.
2.6.2
Design
Volgens deze bron [13], bezit een goed ontworpen UI een aantal kenmerken. Hieronder worden deze kenmerken opgelijst, en wordt er kort toegelicht hoe rekening gehouden is met deze kenmerken in de applicatie:
Clarity: alle tekst is in duidelijk, kort en bondig Engels geformuleerd. Er is geen ingewikkelde woordenschat gebruikt, en waar nodig zijn popups toegevoegd om een boodschap te verduidelijken.
Concision: zoals hiervoor vermeld, is tekst zo kort mogelijk gehouden. Dit vermijdt dat het scherm er te 'vol' of 'warrig' gaat uitzien.
Familiarity: bepaalde elementen zullen voor nieuwe gebruikers nog steeds vertrouwd aanvoelen. Dit is onder andere mogelijk door het gebruik van Bootstrap. De grid structuur en knoppen in dit framework worden alom toegepast, waardoor de nieuwe gebruikers zich automatisch iets meer thuis gaan voelen in deze onbekende omgeving.
Responsiveness: door het gebruik van de databinding van AngularJS zullen aangepaste waardes vrijwel meteen overal in het user interface aangepast worden. Verder is het
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
48
zo dat fouten relatief snel opgevangen worden, zodat geen onmenselijke wachttijden bij het uitvoeren van bepaalde acties ontstaan. Bovendien worden langdurige taken als een asynchrone job gepland door de backend, zodat de gebruiker hier geen hinder van ondervindt.
Consistency: elke pagina heeft een specifiek takenpakket, dat overal op dezelfde manier ge¨ımplementeerd wordt. Verder zijn user interface objecten op elke pagina op dezelfde manier gestructureerd: knoppen staan indien mogelijk overal op dezelfde plaats, tabellen komen op elke pagina terug,etc.
Aesthetics: het uiterlijk van de applicatie is het eerste dat een potenti¨ele nieuwe gebruiker te zien krijgt. Hoewel een mooie applicatie niet essentieel is om zijn bestemde taken correct uit te voeren, is het wel aangenamer voor de gebruiker. In dit geval is voor dit aspect het Bootstrap thema SB Admin 2 [1] gebruikt, een thema speciaal ontworpen voor administrator gerichte toepassingen zoals deze.
Efficiency: het gebruik van asynchrone jobs voor grote taken en het tijdelijk opslaan van wijzigingen op een pagina tot op de save button geklikt wordt, gecombineerd met de vlotte databinding van AngularJS, zorgen ervoor dat de applicatie zeer effici¨ent is. Een gebruiker kan eigenlijk enkel bij connectieproblemen merkbare hinder ondervinden bij het uitvoeren van een actie.
Forgiveness: bij het optreden van fouten zal altijd een duidelijke foutboodschap aan de gebruiker overgebracht wordt door het gebruik van popup menu's. Met behulp van deze foutboodschappen kan de gebruiker eventuele fouten relatief snel lokaliseren en oplossen.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.7
49
Sequence diagram
Het onderstaande schema (figuur 2.17) visualiseert welke stappen uitgevoerd moeten worden om een prijs te berekenen. Merk op dat er vanuit gegaan wordt dat er nog helemaal geen data in de applicatie aanwezig is bij de start van het schema.
Figuur 2.17: Sequence diagram
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.8
50
Business logic
Het hoofddoel van de applicatie blijft de mogelijkheid om prijzen te berekenen. Dit onderdeel van de scriptie beschrijft de logica van deze prijsberekening, alsook de logica van het status managementsysteem.
2.8.1
Price logic
Introductie De perfecte verkoopsprijs berekenen is geen simpele opgave, vooral als deze afhangt van meerdere parameters en entiteiten die verschillende onderlinge relaties hebben. De onderlinge relaties zijn al eerder besproken in het ER diagram. De parameters uit dit diagram, die effectief invloed op de prijs hebben zijn hieronder grafisch weergegeven.
Figuur 2.18: Price influential parameters Al deze parameters opsommen is uiteraard niet voldoende. Er zullen bewerkingen uitgevoerd moeten worden om tot het correcte resultaat te komen. Om de berekening makkelijker en overzichtelijker te laten verlopen, is de prijscalculatie in een aantal delen opgesplitst:
Een vaste kost: deze is verder verdeeld in een productafhankelijke, transportafhankelijke en verkoopkanaal afhankelijke kost;
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
51
Winst;
Een variabele kost: deze bestaat uit een aantal procentueel opgeslagen kosten;
Bewerkingen na de prijsberekening: achteraf moeten een aantal controles en aanpasssingen gebeuren vooraleer de eindprijs bekomen wordt. Denk maar aan het afronden van een prijs etc.
Figuur 2.19: Basic price logic
Omdat de gebruiker grote flexibiliteit vereist van de applicatie (er zijn tenslotte een hele reeks optionele en overschrijfbare velden), moet er per blok een hoop logica worden toegepast. Deze logica is onmogelijk duidelijk in woorden te omschrijven, dus deze scriptie zal de verschillende kostenberekeningen verduidelijken aan de hand van een aantal schematische voorstellingen.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
52
Vaste kosten De fixed cost bestaat uit meerdere delen, die na berekening worden opgeteld om de totale vaste kost te vormen. Fixed product cost
Figuur 2.20: Fixed product cost logic F ixed product cost = purchase price + packaging cost + handling cost Fixed channel cost De fixed channel cost is relatief simpel wat een schematische voorstelling overbodig maakt: F ixed channel cost = f ixed channel commission + f ixed 3rd party channel commission In de bovenstaande formule verstaan we onder 3rd party software: applicaties die gebruikt worden om prijzen automatisch aan te passen en/of te deployen naar een bepaald verkoopkanaal, en hiervoor een vaste commissie vragen.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION Fixed transport cost
Figuur 2.21: Fixed product cost logic
F ixed transport cost = f ixed region cost + transport cost + admin cost
53
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
54
Winst Voor het berekenen van de winst zijn er eigenlijk twee marges die berekent moeten worden: een minimum, -en een maximum winstbedrag. Onderstaande figuur (2.22) toont de logica voor het bepalen van de minimumwaarde. Het maximum berekenen gebeurt uiteraard op gelijkaardige wijze.
Figuur 2.22: Minimum profit calculation logic
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
55
Variabele kosten Na het optellen van de vooraf bepaalde kosten, kunnen de variabele kosten voor dit bedrag bepaald worden. Op dit moment worden ook de minimum- en maximumprijs bepaald. Dit gebeurt via de onderstaande formules: M inimum price = (f ixed cost + f ork minimum) ∗ (1/1 − ((sales channel commission % + 3rd party commission % + region extra cost % + payment commission %)/100)) ∗ (1 + (BT W/100))
M aximum price = (f ixed cost + f ork maximum) ∗ (1/1 − ((sales channel commission % + 3rd party commission % + region extra cost % + payment commission %)/100)) ∗ (1 + (BT W/100)) Bewerkingen na de prijsberekening De berekende optimale prijs is niet altijd de prijs waaraan men wil verkopen. Voor de verkoop gebruikt men liever afgeronde waarde, zoals bv .95. Ook moet rekening gehouden worden dat er voor sommige producten een minimale prijs (listing price) is, waaronder niet verkocht mag worden van bepaalde leveranciers. Door de volgende logica toe te passen komt men op de finale verkoopsprijs. Merk op dat men verder rekent met het minimum. Dit is omdat de veronderstelling gemaakt wordt, dat de ideale verkoopprijs zich rond het minimum bevindt aangezien de concurrentie bij online verkoop zo talrijk is.
Figuur 2.23: Final price
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.8.2
56
Status logic
Het nut van status management in een beheertool is al meermaals in deze scriptie aangehaald: het zorgt er enerzijds voor dat problemen en waarschuwingen duidelijk weergegeven worden, en anderzijds stelt het de gebruiker gerust wanneer geen fouten bij een actie optreden. Status management is dus een overzichtelijke en uitgebreide manier om ten allen tijde feedback aan een gebruiker te bieden. Gebruikte statussen Price status In de applicatie zijn er verschillende veranderlijke parameters die invloed hebben op de prijsberekening. Als ´e´en van deze parameters wordt aangepast nadat er al een prijs berekend is, wil dit dus zeggen dat de berekende prijs niet meer up-to-date is. Indien dit voorvalt, wordt de volgende beschreven status (calculation status) gewijzigd. Om een gebruiker meer inzicht te geven in hoe zijn veranderingen de prijzen be¨ınvloeden, zijn er een reeks extra, meer gedetaileerde statussen toegevoegd, die per gedesynchroniseerd product weergeven door welke wijzigingen de prijs niet meer up-to-date is. Deze toegevoegde statussen zijn:
Product;
Packaging;
Price overwrite;
Channel;
Transport;
Supplier.
Het spreekt voor zich dat aanpassingen die geen invloed hebben op de prijsberekening (bijvoorbeeld een verandering van de naam van een sales channel), uiteraard niet voor een statuswijziging zullen zorgen. Dit is ge¨ımplementeerd door, bij het uitvoeren van elke mogelijke CRUD actie, de veranderingen eerst langs een status management functie te sturen. Op de volgende pagina bevindt zich een codevoorbeeld van de status management methode die aangeroepen wordt bij het updaten van verpakkingen:
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
57
Listing 2.11: Packaging status calculation code @Transactional p u b l i c v o i d u p d a t e S t a t u s P a c k a g i n g ( L i s t p a c k a g i n g ) { L i s t p a c k a g i n g I d L i s t=new A r r a y L i s t ( ) ; L i s t p a c k a g i n g I d L i s t S t a t u s U p d a t e=new A r r a y L i s t ( ) ; // g e t a l l p a c k a g i n g t h a t i s b e i n g u p d a t e d f o r ( P a c k a g i n g pack : p a c k a g i n g ) { p a c k a g i n g I d L i s t . add ( pack . g e t I d ( ) ) ; } TypedQuery
q u e r y 1 = em . c r e a t e Q u e r y ( ”SELECT pack FROM P a c k a g i n g pack WHERE pack . i d IN : p a c k a g i n g s ” , P a c k a g i n g . c l a s s ) ; query1 . setParameter ( ” packagings ” , p a c k a g i n g I d L i s t ) ; // c h e c k i f p a c k a g i n g u p d a t e i n f l u e n c e s p r i c e f o r ( P a c k a g i n g packNew : p a c k a g i n g ) { f o r ( P a c k a g i n g packOld : q u e r y 1 . g e t R e s u l t L i s t ( ) ) { i f ( packOld . g e t I d ()==packNew . g e t I d ( ) ) { i f ( ! packOld . g e t P r i c e ( ) . e q u a l s ( packNew . g e t P r i c e ( ) ) ) { p a c k a g i n g I d L i s t S t a t u s U p d a t e . add ( packNew . g e t I d ( ) ) ; } } } } // u p d a t e p a c k a g i n g s t a t u s f o r a l l p r i c e s a f f e c t e d by t h e p a c k a g i n g u p d a t e i f ( p a c k a g i n g I d L i s t S t a t u s U p d a t e . s i z e () >0){ TypedQuery
q u e r y = em . c r e a t e Q u e r y ( ”SELECT pc FROM P r i c e p r INNER JOIN p r . p r i c e C a l c u l a t e d pc INNER JOIN p r . p r o d u c t p INNER JOIN p . p a c k a g i n g s pack WHERE pack . i d IN : p a c k a g i n g s AND EXISTS ( SELECT pack FROM p . p a c k a g i n g s pack ) ” , PriceCalculated . class ); query . setParameter (” packagings ” , packagingIdListStatusUpdate ) ; for ( P r i c e C a l c u l a t e d priceC : query . g e t R e s u l t L i s t ( ) ) { priceC . setStatusPackaging ( false ); priceC . setStatusPrice ( false ); em . p e r s i s t ( p r i c e C ) ; } em . f l u s h ( ) ; } }
In de bovenstaande code gebeuren dus 4 dingen: 1. Ophalen van verpakkingen die gewijzigd zijn; 2. Voor elke verpakking controleren of een wijziging de prijs van de verpakking be¨ınvloedt; 3. Alle producten met een gewijzigde verpakkingsprijs ophalen; 4. Voor elk product de status 'Packaging' op false zetten.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
58
Calculation status Zoals bij de bespreking van de price status op pagina 50 reeds vermeld is, zal bij een prijs desynchronisatie de calculation status van de desbetreffende prijs op 'Changed' gezet worden. Andere mogelijke waarden voor deze status zijn:
Draft: deze status geeft aan dat er nog geen prijs berekend is;
Calculating: deze status wordt gegeven aan alle prijzen die (her)berekend worden, zodat de gebruiker bij lange wachttijden of trage connectie kan zien welke prijzen nog aan het berekenen zijn (of berekend, maar nog niet teruggezonden zijn). Ook bij serverpanne tijdens het uitvoeren van de calculatiejob, zal de status op 'Calculating' blijven staan, zodat de calculatie hervat kan worden wanneer de server opnieuw opgestart is;
Calculated: geeft weer dat de prijs correct berekend, en up-to-date is;
Error: Dit treed op als er een fout optreedt tijdens het berekenen van een prijs. Er zijn meerdere foutboodschappen mogelijk, waarvan de meeste te maken hebben met het feit dat er te weinig data aanwezig is om de berekening correct uit te voeren.
Send status Deze status is relatief eenvoudig en kan de volgende waardes verkrijgen:
Draft: de prijs is nog nooit verzonden;
Changed: als er een prijs verandert, geeft deze status aan dat de prijs opnieuw verstuurd dient te worden;
Sending: Alle prijzen die verzonden dienen te worden krijgen deze status. Dit heeft, net als de calculation status 'Calculating', als voordeel dat de gebruiker beter zicht heeft op wat er intern gebeurt, en zorgt er bovendien voor dat eventuele niet-verstuurde prijzen na een systeemcrash opnieuw verzonden kunnen worden;
Sent: de prijs is succesvol verzonden;
Error code: deze error code komt overeen met de error die Hybris terugstuurt als een bepaalde prijs niet verzonden kan worden. Momenteel zijn de mogelijke error codes: – 404: ofwel kan het product, ofwel het verkoopkanaal van de prijs niet gevonden worden in het PIM systeem; – 500: internal server error. Hoe de error in deze situatie kan optreden valt buiten het bestek van deze scriptie.
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
59
Status overview Figuur 2.24 toont de verschillende mogelijke statussen die een prijs kan verkrijgen, nadat bepaalde acties uitgevoerd zijn.
Figuur 2.24: Status overview scheme
HOOFDSTUK 2. BESPREKING PRICE MANAGEMENT APPLICATION
2.9
60
Testing
Omdat de applicatie optimale verkoopsprijzen moet gaan bereken is er op dit vlak geen plaats voor foutmarges. Tijdens de development fase is er dus veel aandacht besteed aan de controle van de berekeningsmethode. Dit hebben we bereikt door de klant vroeg in het proces te betrekken. De prijsberekeningsformule is aan de hand van overleggen in samenspraak met de klant ontwikkeld en doorheen het ontwikkelingsproces verder ge¨evolueerd. Er is in de loop van het project aan verschillende vormen van testing gedaan:
Unit testing: er zijn enkele basis unit tests geschreven, die CRUD acties kunnen testen. In de toekomst zullen er voor de prijsberekeningsmethode en het status management ongetwijfeld ook nog een aantal unit tests geschreven worden.
User acceptance testing: zoals in de inleiding van het onderdeel ?? al vermeld werd, is de klant vanaf het begin van het ontwikkelingsproces bij het project betrokken. Vanaf er een stuk functionaliteit af was, heeft de klant deze kunnen uitproberen in de testomgeving, en eventuele bugs of verbeteringen doorgegeven.
Operational testing: er is getracht zoveel mogelijk fouten op te vangen en vervolgens getest of al deze fouten de correcte feedback aan de gebruiker doorgeven. Verdere operational testing zal zeker gebeuren vooraleer de applicatie in productie genomen wordt.
Functional/manual testing: zoals altijd tijdens de ontwikkeling van software, is elk stuk code/functionaliteit uitvoerig getest vooraleer dit definitief ge¨ımplementeerd werd.
Hoofdstuk
3
Resultaten 3.1
Doelstellingen
Zoals vermeld in het Doel op pagina 3, was de bedoeling om voor het PIM systeem een prijsberekeningsmodule te ontwikkelen die automatisch de beste prijs per product per verkoopkanaal berekent, aan de hand van een aantal parameters. De applicatie zou moeten zorgen voor een sterke centralisatie van prijsdata en een automatisatie van prijsdataverwerking, met verschillende grote voordelen als gevolg:
Significante verlaging van de kans op fouten;
Duidelijk overzicht van relevante informatie;
Tijdsbesparing.
Verder waren er een hele hoop Vereisten besproken (vanaf pagina 3), waaraan de applicatie moest voldoen.
61
HOOFDSTUK 3. RESULTATEN
3.2
62
Resultaten
Vermits de eerste ontwikkelingsfase net afgelopen is, is het nog niet mogelijk om met zekerheid te zeggen dat de kans op fouten bij het beheer van verkoopprijzen lager is dan voordien. Ook of er een tijdsbesparing is, kan nog niet getest worden aangezien de gebruiker nog in de gewenningsfase van de software zit. Wel geeft de applicatie al zeker een duidelijk overzicht van relevante informatie. Verder voldoet de applicatie aan alle voorgenoemde Vereisten, dus we kunnen besluiten dat de doelstellingen gehaald zijn. Het resultaat van het ontwikkelingsproces dat besproken is in deze scriptie, is een volledig functionele web applicatie die producten kan ophalen, productinformatie kan verrijken, prijzen kan berekenen en deze prijzen tenslotte kan terugzenden naar het PIM systeem. Vanaf de volgende pagina wordt per webpagina alle mogelijke functionaliteit kort uitgelegd.
HOOFDSTUK 3. RESULTATEN
3.2.1
63
Login
Vooraleer de applicatie gebruikt kan worden, dient ingelogd te worden op de login pagina. Dit gebeurt door op de 'Login ' knop te klikken na het invoeren van de onderstaande gegevens:
Username: admin
Password: pricing
Figuur 3.1: Login screen Wanneer de login gegevens succesvol ingevoerd zijn, zal de gebruiker worden doorverwezen naar de homepage van de applicatie, het Dashboard.
HOOFDSTUK 3. RESULTATEN
3.2.2
64
Navigatie
Om van de ene naar de andere pagina in de applicatie te verplaatsen, kan zowel het navigatiemenu, als de compactere navigatiebalk gebruikt worden. Navigatiemenu Standaard weergave Het menu bevindt zich voor grotere schermen, zoals computers en laptops, aan de linkerzijde van de pagina. Met een klik op de pijl bovenaan in het menu, kan de menubalk ingeklapt worden, zodat meer informatie op het scherm getoond kan worden. Dit is vooral handig op pagina's zoals Price, waar soms ontzettend grote tabellen weergegeven moeten worden.
Figuur 3.2: Navigatiemenu in open en gesloten toestand Hierboven is het menu weergegeven in geopende en ingeklapte toestand. Merk op dat de pagina die momenteel geopend is, altijd iets donkerder weergegeven wordt in het menu. Op de linkerfoto bovenaan, is duidelijk zichtbaar dat de dashboard pagina geopend is.
HOOFDSTUK 3. RESULTATEN
65
Compacte weergave Voor kleinere tablets en smartphones, bevindt het menu zich in de balk bovenaan. Openen en sluiten van het menu gebeurt door op de knop in de rechterbovenhoek te drukken.
Figuur 3.3: Compact screen navigation menu Navigatiebalk Onder de titel van elke pagina is een compacte navigatiebalk te vinden, die weergeeft waar in het menu de gebruiker zich bevindt.
Figuur 3.4: Navigation bar
HOOFDSTUK 3. RESULTATEN
3.2.3
66
Algemene functionaliteit
Doorheen de applicatie is er een hele hoop functionaliteit die meermaals terugkomt. Zo zal er bijna overal een 'Save changes' knop te vinden zijn, en zal elke pagina ´e´en of meerdere tabellen weergeven. Wijzigingen opslaan In de linkeronderhoek van bijna elke pagina is een 'Save changes' knop te vinden. Alle wijzigingen die op deze pagina uitgevoerd zijn, worden pas definitief opgeslagen wanneer op deze knop geklikt wordt.
Figuur 3.5: Save changes button Na het selecteren van de knop, zal vervolgens een confirmatie popup tevoorschijn komen, zoals op het onderstaande voorbeeld. Indien de gebruiker beslist om de veranderingen definitief op te slaan, dient 'OK' geselecteerd te worden. Het selecteren van de 'Cancel' knop, zal zorgen dat de gebruiker terug op de originele pagina terecht komt en eventuele verdere aanpassingen kan doen, alvorens hij deze opslaat.
Figuur 3.6: Save confirmation popup Opmerking: indien de gebruiker besluit om wijzigingen niet op te slaan, is het voldoende om het browservenster te herladen.
HOOFDSTUK 3. RESULTATEN
67
Exporteren naar Excel De 'Export' knop kan op elke pagina(uitgezonderd Product Details) in de rechterbenedenhoek teruggevonden worden. Deze knop zorgt ervoor dat resultaten opgeslagen kunnen worden als een Excel tabel.
Figuur 3.7: Export to Excel button Link naar details pagina In alle tabellen die producten of productprijzen weergeven, is uiterst rechts een kolom 'Info' voorzien. Deze kolom bevat per rij een knop, waarmee makkelijk naar de detailpagina van het product genavigeerd kan worden.
Figuur 3.8: Details button
HOOFDSTUK 3. RESULTATEN
3.2.4
68
Zoekfilters
Elke pagina heeft verschillende manieren om naar bepaalde informatie te zoeken. Zoekfilters bovenaan de pagina Op een aantal pagina's kan bovenaan een aantal zoekvelden ingevuld worden, vooraleer resultaten weergegeven worden. Na het invullen van de gewenste zoekcriteria, gevolgd door een druk op de 'Search' knop, zullen alle resultaten onder het zoekvenster in tabelvorm weergegeven worden. Deze tabel kan bovendien ook nog verder gefilterd worden (zie Zoekfunctionaliteit in tabellen). Verder is er de optie om deze zoekfilter in te klappen door een klik op het icoon links naast 'Search filters'.
Figuur 3.9: Search filters Opmerking: indien de gebruiker alles wil tonen zonder het gebruik van de zoekfilter, selecteert hij bij 'General' het bolletje links naast 'SKU' vooraleer op de 'Search' knop te klikken.
HOOFDSTUK 3. RESULTATEN
69
Zoekfunctionaliteit in tabellen In alle tabellen (uitgezonderd Product Details), is er de mogelijkheid om te sorteren op kolomnaam, of te zoeken naar een bepaalde waarde in een kolom. Door een waarde in te vullen in de 'search..' velden, kan gezocht worden naar deze waarde. Sorteren gebeurt door te klikken op de vetgedrukte titel van een kolom, zodat een driehoekig pijltje naast de titel verschijnt. Als dit pijltje naar boven wijst, zal de tabel alfabetisch gerangschikt worden van A-Z volgens naam. Indien nogmaals op dit pijltje geklikt wordt, zal de tabel omgekeerd worden, zodat van Z naar A gesorteerd wordt. Het onderstaande voorbeeld demonstreert deze functionaliteit: de tabel is in dit geval alfabetisch gesorteerd op 'Name', en verder is er gefilterd naar rijen waarvan de waarde in kolom 'Purchase discount %' begint met het getal 3.
Figuur 3.10: Search & sort tables
HOOFDSTUK 3. RESULTATEN
3.2.5
70
Dashboard
Het dashboard is een overzichtspagina, die standaard geopend wordt nadat de gebruiker ingelogd is. Op deze pagina zijn een aantal belangrijke functies mogelijk, die hier uitgelegd worden. Error overview De tabel die weergegeven wordt op deze pagina, bevat een lijst van producten waarvan de prijzen fouten bevatten. Om prestatieredenen zullen hier maximaal 20 producten per keer getoond worden. Zoals te zien op het onderstaande screenshot, zijn in dit error overzicht een aantal verschillende statussen te vinden:
Channels linked: geeft weer of een product al gebonden is aan verkoopkanalen. Indien dit niet het geval is, zullen er ook nog geen prijzen voor het product beschikbaar zijn.
Price status: geeft weer of ´e´en van de prijzen van een bepaald product niet meer up-todate is. Deze status is een combinatie van verschillende statussen die op de statuspagina te vinden zijn, namelijk: – Product; – Packaging; – Price overwrite; – Sales channel; – Transport; – Supplier.
Calc status: geeft de berekeningsstatus van de prijzen van het product weer. Indien ´e´en van de prijzen herberekend wordt/moet worden, of nog nooit berekend is, zal ook deze status een waarschuwing tonen.
Sync status: geeft weer of de prijzen van het product naar Hybris doorgestuurd zijn. Ook hier zal een waarschuwing getoond worden wanneer de laatst berekende prijs nog niet doorgestuurd is.
HOOFDSTUK 3. RESULTATEN
71
Figuur 3.11: Dashboard error overview Extra: ook de statuskolommen kunnen hier gefilterd worden. Dit gebeurt door het ingeven van de letter 't' (true) voor statussen zonder problemen, of het invoeren van de letter 'f' (false) voor het weergeven van statussen met problemen. Overige functionaliteit Onder het error overview kunnen een aantal knoppen teruggevonden worden:
Calculate all: wanneer deze knop ingedrukt wordt, zal een taak gestart worden waarin alle verouderde/onberekende prijzen in het systeem (her)berekend worden. Denk eraan dat deze taak lang kan duren, zeker indien er een groot aantal prijzen met fouten in het systeem zitten. Als alternatief is er de optie om op de Calculation & Status pagina een aantal prijzen te selecteren die herberekend moeten worden.
Get new products: deze knop zal controleren of er nieuwe/gewijzigde producten in het Hybris PIM systeem zijn. Merk op dat deze taak automatisch elk uur uitgevoerd zal worden, en het meestal dus overbodig is om deze knop te gebruiken.
Send prices: knop om nieuwe en/of herberekende prijzen door te sturen naar het Hybris hoofdsysteem. Ook deze taak wordt elk uur automatisch uitgevoerd, wat het gebruik van de knop in de meeste gevallen niet noodzakelijk maakt.
Export: zie Exporteren naar Excel
Figuur 3.12: Dashboard buttons
HOOFDSTUK 3. RESULTATEN
3.2.6
72
Product
Dit is geen op zich bestaande pagina, maar een deel van het menu dat verder onderverdeeld is voor het gemak van de gebruiker. Search Deze pagina bestaat uit een aantal zoekfilters (zie Zoekfilters), gevolgd door een tabel die basisinformatie over het product weergeeft. Het nut van deze pagina is om makkelijk en vlot een bepaald product te kunnen vinden, om vervolgens de productdetails te kunnen bekijken, door op de details knop (zie pagina 67)te klikken.
Figuur 3.13: Product search page
HOOFDSTUK 3. RESULTATEN
73
Select sales channels Deze pagina wordt gebruikt om, na het toevoegen van nieuwe producten, de gewenste verkoopkanalen te selecteren. Voor al deze verkoopkanalen zal vervolgens een rij in de prijstabellen voorzien worden. Deze pagina bevat bovenaan ook weer een aantal velden waarop de productenlijst gefilterd kan worden. Zo wordt het bijvoorbeeld heel makkelijk om enkel de meest recente producten weer te geven door het gebruik van de datum filter. In de resultatentabel is het niet nodig om per product per verkoopkanaal het vakje aan te vinken. Indien een verkoopkanaal voor alle producten gebruikt zal worden, kan gewoon de select all knop bovenaan gebruikt worden, waardoor alle vakjes in de kolom van het verkoopkanaal automatisch aangevinkt zullen zijn.
Figuur 3.14: Select sales channels page Na het selecteren van de gewenste sales channels, moeten de wijzigingen uiteraard bevestigd worden met de 'Save changes' knop. Verder is ook hier functionaliteit om de informatie uit de tabel te exporteren naar Excel.
HOOFDSTUK 3. RESULTATEN
74
Price Deze pagina wordt gebruikt om prijs gerelateerde parameters op productniveau in te stellen. Omdat er zo'n uitgebreide hoeveelheid informatie op deze pagina weergegeven kan worden, is een bijkomende filter toegevoegd waarmee geselecteerd kan worden welke kolommen weergegeven moeten worden op het scherm. Deze filter is te vinden in de rechterbovenhoek van het resultatenscherm.
Figuur 3.15: Column select functionality In de Price pagina kan behalve een aantal waardes ook de verpakking(en) van een product geselecteerd worden. Dit gebeurt door een druk op de Packaging knop (zie onderstaande figuur) van het desbetreffende product.
Figuur 3.16: Packaging button Vervolgens zal een popup menu geopend worden, waarin een aantal knoppen te vinden zijn:
Add packaging: hiermee kan een verpakking aan het product toegevoegd worden. Vervolgens wordt op de naam van de toegevoegde verpakking geklikt en de gewenste verpakking geselecteerd.
Done: selecteer deze knop indien de toegevoegde verpakking(en) later opgeslagen moeten kunnen worden.
Cancel: selecteer deze knop indien de wijzigingen aan de productverpakking later niet opgeslagen moeten worden (bv. bij fouten).
HOOFDSTUK 3. RESULTATEN
75
Figuur 3.17: Packaging menu Opmerking: na het toevoegen van verpakkingen en het selecteren van 'Done' knop, moet nog steeds onderaan de pagina op 'Save changes' geklikt worden om de nieuwe/gewijzigde verpakking definitief op te slaan!
HOOFDSTUK 3. RESULTATEN
76
Price overwrites Deze pagina wordt gebruikt om prijs gerelateerde parameters op product-verkoopkanaal niveau in te stellen (voor een product dat verkocht wordt op x kanalen, zullen hier dus x resultaten getoond worden). Na het toepassen van de gewoonlijke zoekfilters, verkrijgt men een gelijkaardig resultaat als de onderstaande figuur.
Figuur 3.18: Price overwrite page De niet aanpasbare getallen in de tabel stellen de winsten en listing price op productniveau voor. In de input velden kan dan per verkoopkanaal een 'overwrite' waarde ingesteld worden. Deze overwrites zijn bijvoorbeeld nuttig wanneer een gebruiker op een bepaald verkoopkanaal veel meer concurrentie heeft, en dus beter iets minder winst maakt dan normaal om daardoor toch meer te verkopen dan de concurrentie. Met het 'ignore' vakje kan een vooropgelegde listing price van de leverancier op een bepaald verkoopkanaal genegeerd worden.
HOOFDSTUK 3. RESULTATEN
77
Transport Op deze pagina kunnen alle bestemming afhankelijke parameters van een bepaald product aangepast worden. Merk op dat enkel de bestemmingen van een product getoond worden, die als 'main region' gebruikt zijn voor de geselecteerde verkoopkanalen (zie Sales channels). Verdere informatie bij deze pagina is overbodig, vermits alle andere functionaliteit al uitgelegd is in het onderdeel Algemene functionaliteit.
Figuur 3.19: Product transport page
HOOFDSTUK 3. RESULTATEN
78
Calculation & Status Deze pagina toont alle statussen (behalve de 'Channels linked' status, vermits de prijs op dit ogenblik al bestaat en deze status dus altijd in orde zou zijn) en de berekende prijzen van de gewenste producten, alsook de laatste prijsberekeningsdatum. Deze statussen zijn:
Calc status: geeft de berekeningsstatus van de prijzen weer. Indien een prijs herberekend wordt/moet worden, of nog nooit berekend is, zal deze status een waarschuwing tonen.
Sync status: geeft weer of de prijzen naar Hybris doorgestuurd zijn. Ook hier zal een waarschuwing getoond worden wanneer de laatst berekende prijs nog niet doorgestuurd is.
Product: geeft weer of de productgerelateerde prijsparameters (bv. BTW,...) up-to-date zijn t.o.v. de laatste prijsberekening.
Packaging: geeft weer of de geselecteerde verpakkingen up-to-date zijn in de laatste prijsberekening t.o.v. de laatste prijsberekening.
Price OW: geeft weer of de price overwrite waarden, met andere woorden de productverkoopkanaal afhankelijke parameters, up-to-date zijn t.o.v. de laatste prijsberekening
Channel: geeft weer of de verkoopkanaal gebonden kosten up-to-date t.o.v. de laatste prijsberekening.
Transport: geeft weer of de transportkosten up-to-date zijn t.o.v. prijsberekening
Supplier: geeft weer of de kosten en/of kortingen van de leverancier up-to-date zijn t.o.v. de laatste prijsberekening.
Figuur 3.20: Calculation & Status page
aankoopprijs,
de laatste
HOOFDSTUK 3. RESULTATEN
79
Ook hier zijn de statuskolommen sorteer-en filterbaar. Alle statussen, met uitzondering van 'Calc' en 'Sync' status, kunnen gevonden worden door de letters 't' (true, toont de correcte statussen) of 'f' (false, toont de error statussen). Voor de 'Calc' status zijn de zoekmogelijkheden als volgt:
Status OK: Calculated
Momenteel de prijs aan het berekenen: Calculating
Error: – Missing data; – No colli; – No freight; – No transport
Voor 'Sync' zijn er deze keywords:
Draft;
Sending;
Sent;
Changed;
Error.
Opmerking: bij de 'Sync' en 'Calc' statuskolommen is het mogelijk om de huidige statusboodschap te tonen door met de muis over het status icoon te hoveren. Dit kan handig zijn om specifiekere informatie over een error te verkrijgen.
Figuur 3.21: Status info on mouse hover Verder is er op deze pagina nog een knop te vinden die meer informatie over de uitgevoerde prijsberekening weergeeft (zie figuur 3.22).
Figuur 3.22: Price calculation information button
HOOFDSTUK 3. RESULTATEN Een druk op deze knop opent het onderstaand menu.
Figuur 3.23: Price calculation information menu
80
HOOFDSTUK 3. RESULTATEN
81
Product Details Deze pagina is de meest uitgebreide pagina in de hele applicatie. Per product kan alle prijsgerelateerde informatie hier teruggevonden en aangepast worden. Deze pagina is productafhankelijk, en kan alleen geopend worden door in een resultatentabel op de Link naar details pagina knop te klikken. Er is op deze pagina dus ook geen zoekfunctionaliteit voorzien, vermits alle data al productspecifiek is. Wel is de pagina ingedeeld in verschillende inklapbare vensters, die allemaal een deel van de producteigenschappen bevatten. Zo zijn er vensters gemaakt voor:
Algemene informatie;
Algemene prijsinformatie;
Verkoopkanaal specifieke prijsinformatie;
Status informatie;
Productcreatie informatie.
Opmerking: al deze informatie kan uiteraard ook in de reeds besproken pagina's geselecteerd worden. De detailpagina dient louter om een gedetailleerd overzicht van prijsinformatie over een product weer te geven, zodat eventuele fouten of ongekende informatie makkelijk gevonden en verbeterd kunnen worden. Algemene informatie Dit venster toont enerzijds de informatie afkomstig uit Hybris (naam, SKU nummer, merk, gewicht en afmetingen), en anderzijds enkele producteigenschappen die in de Price Management Application geselecteerd moeten/kunnen worden (leverancier en transportmethode zijn verplicht, geschat gewicht en verpakking is optioneel).
Figuur 3.24: General information from product details page
HOOFDSTUK 3. RESULTATEN
82
Algemene prijsinformatie In dit venster wordt productspecifieke prijsinformatie ingesteld. Aan de linkerzijde worden alle prijzen en kosten weergegeven, en aan de rechterzijde de winsten. Merk op dat packaging cost een niet aanpasbaar veld is, vermits deze afhangt van de prijs van de geselecteerde verpakkingen. Om dit te omzeilen is er een packaging cost overwrite veld voorzien.
Figuur 3.25: General price information from product details page Verkoopkanaal specifieke prijsinformatie Dit onderdeel bevat alle verkoopkanaal specifieke parameters van de prijsbepaling, met andere woorden de 'price overwrite' parameters. Ook de selectie van de verkoopkanalen waarvoor een prijs berekend moet worden gebeurt hier. Verder worden rechts de minimum-, maximum- en finale prijs weergegeven.
Figuur 3.26: Price overwrite information from product details page
HOOFDSTUK 3. RESULTATEN
83
Status informatie Dit venster bevat een tabel, gelijkaardig aan de tabel op de reeds besproken Calculation & Status pagina. Verder zijn hier 2 knoppen te vinden: een knop voor het (her)berekenen van geselecteerde prijzen, en een knop voor het verzenden van een selectie prijzen naar het PIM systeem. Deze functionaliteit is ook reeds besproken in de voorgenoemde Calculation & Status pagina.
Figuur 3.27: Status information from product details page Productcreatie informatie Dit venster toont enerzijds de informatie afkomstig uit Hybris (naam, SKU nummer, merk, gewicht en afmetingen), en anderzijds enkele producteigenschappen die in de Price Management Application geselecteerd moeten/kunnen worden (leverancier en transportmethode zijn verplicht, geschat gewicht en verpakking is optioneel).
Figuur 3.28: Creation information from product details page
HOOFDSTUK 3. RESULTATEN
84
Add a product Op deze pagina kunnen eventueel nieuwe producten aan de Price Management Application toegevoegd worden. Dit zou echter enkel voor testredenen mogen gebeuren, vermits deze producten niet in Hybris aanwezig zijn, en het terugsturen van hun berekende prijzen gegarandeerd fouten zal veroorzaken. Deze pagina is dus nuttig om snel een prijs voor een fictief product te kunnen berekenen, maar niet aan te bevelen voor regelmatig gebruik.
Figuur 3.29: Add product page
HOOFDSTUK 3. RESULTATEN
3.2.7
85
Sales channels
Op deze pagina kunnen verkoopkanalen toegevoegd, gewijzigd of verwijderd worden. Aanmaken van een verkoopkanaal Toevoegen van een verkoopkanaal gebeurt op de volgende manier: 1. Druk op de knop 'Add channel' 2. Bovenaan de tabel zal een nieuwe rij verschijnen 3. Door op een veld in de rij te klikken, zal de waarde aangepast kunnen worden zoals op de onderstaande foto.
Figuur 3.30: Editable table field 4. Vervolgens kan stap 3 herhaald worden voor elk veld in de rij tot aan de 'Zones' kolom. Opmerking: het veld 'Currency' is optioneel, vermits alle eindprijzen in euro weergegeven worden. 5. Indien gewenst kunnen een aantal delivery zones toegevoegd worden aan het verkoopkanaal door een druk op de zone knop (zie onderstaande figuur). Vervolgens zal het onderstaand menu geopend worden. Zones toevoegen gebeurt op dezelfde manier als het toevoegen van verpakkingen op de Price pagina.
Figuur 3.31: Zone button Opmerking: Deze stap is optioneel, en heeft op geen enkele manier invloed op de prijsberekening. 6. Na het instellen van alle gewenste waardes dient een 'Main region' geselecteerd te worden. Deze regio kan eigenlijk ge¨ınterpreteerd worden als de regio van levering. Wanneer vanuit Belgi¨e verstuurd wordt voor een verkoopkanaal dat levert in Belgi¨e en Nederland, is het bijvoorbeeld het veiligst om Nederland te selecteren, vermits zo de hoogst mogelijke transportkosten in de prijscalculatie verwerkt zijn. 7. Selecteer de 'Save changes' knop en klik vervolgens op 'OK'.
HOOFDSTUK 3. RESULTATEN
86
Wijzigen van een verkoopkanaal Indien een bestaand verkoopkanaal gewijzigd dient te worden, dienen de stappen voor het Aanmaken van een verkoopkanaal vanaf stap 3 herhaald te worden. Verwijderen van een verkoopkanaal Een verkoopkanaal kan simpelweg verwijderd worden door op de onderstaande knop te drukken.
Figuur 3.32: Delete button Indien het verkoopkanaal dan niet verwijderd wordt, zal de onderstaande popup getoond worden. Deze popup betekent dat het verkoopkanaal momenteel nog in gebruik is door een aantal producten. Om dit op te lossen, dient de gebruiker op de Select sales channels pagina het vinkje bij dit verkoopkanaal voor alle producten uit te vinken.
Figuur 3.33: Delete sales channel error popup
HOOFDSTUK 3. RESULTATEN
87
Overzicht ’Sales channels’ pagina
Figuur 3.34: Sales channel page overview
3.2.8
Overige pagina’s
Alle overige ontwikkelde pagina's hebben min of meer dezelfde functionaliteit als de Sales channels pagina die vanaf bladzijde 85 besproken wordt. In bijlage C is meer informatie over deze pagina's beschikbaar indien gewenst.
Hoofdstuk
4
Besluit In functioneel opzicht voldoet het product aan de vooropgestelde eisen. Er worden producten vanuit het PIM systeem opgehaald, deze producten kunnen met informatie verrijkt worden, er kunnen prijzen berekend worden en tot slot kunnen deze berekende prijzen teruggestuurd worden naar het PIM systeem. Het succes van het project hing echter niet enkel af van de functionele vereisten, maar ook van de vraag of de applicatie bruikbaar zou zijn in een zakelijke omgeving en of de nieuwe tool een verbetering opleverde tegenover de voorgaande werkmethode. Uit de laatste gesprekken met de opdrachtgevers kan er geconcludeerd worden dat de tool wel degelijk een beter overzicht van de relevante informatie bevat. Door het simpele en intu¨ıtieve design, maar ook door de snelheid en performantie van een SPA, kan vermoedelijk ook een merkbare hoeveelheid tijd bespaard worden, hoewel dit door de huidige, korte periode van gebruik nog niet met zekerheid gezegd kan worden. Tijdens de ontwikkeling van de applicatie waren er twee beperkende factoren. Het eerste probleem was dat er een hele hoop nieuwe technologie¨en en tools aangeleerd moesten worden. Er was dus een zeer steile leercurve, zeker tijdens de eerste ontwikkelingsweken. De tweede factor, die versterkt werd door de eerste, was de omvang van het project in verhouding met de beschikbare tijd. Dit resulteerde in een aantal zaken die beter gekund hadden. Vooral unit testing had iets uitgebreider mogen gebeuren, en er had iets meer aandacht aan de leesbaarheid en onderhoudbaarheid van de code besteed moeten worden.
88
HOOFDSTUK 4. BESLUIT
4.1
89
Reflectie
We vonden het over het algemeen een zeer boeiende stage. Het was vooral interessant om te ontdekken hoe het voelt om het volledige ontwikkelingsproces van een project uit te voeren. Zowel de analytische als technische aspecten van softwareontwikkeling zijn aan bod gekomen, en we hebben op beide vlakken ontzettend veel kunnen bijleren. Hoewel er een aantal zaken waren die we onderschat hadden (vooral bij analytische taken), zijn we er toch in geslaagd om het project tot een goed einde te brengen en aan de eisen van de klant te voldoen. Verder zien we duidelijk het nut en potentieel van onze applicatie, en hebben we al een hele hoop uitbreidingen in gedachten. Hierbij denken we aan:
Automatische conversie van de eindprijs naar andere munteenheden;
Producten met hun berekende prijs automatisch aanbieden op het juiste verkoopkanaal;
Logboeken van prijzen bijhouden doorheen de tijd zodat analyses uitgevoerd kunnen worden;
Rekening houden met stockhoeveelheid bij de keuze van het transporttype en de berekening van de verkoopprijs;
...
Bijlage
A
Use cases Tijdens dit project zijn een groot aantal use cases beschreven. Deze kunnen allemaal teruggevonden worden in het portfolio onder ’Finaal product/schema's’. Hieronder worden enkele van de beschreven use cases weergegeven.
A.1
CRUD
Zoals weergegeven in figuur 2.2, zijn er relatief veel CRUD gerelateerde use cases. Om de grootte van dit document wat te beperken zijn deze niet allemaal in bijlage opgenomen. Aan de hand van het onderstaande voorbeeld wordt duidelijk gemaakt wat deze use cases inhouden. Men kan er dus vanuit gaan dat de andere CRUD gerelateerde cases in figuur 2.2 op een gelijkaardige manier beschreven zijn.
A.1.1
Suppliers
Read
90
BIJLAGE A. USE CASES Create
Update
91
BIJLAGE A. USE CASES
92
Delete
A.2
GET Products
Deze use case beschrijft hoe een gebruiker nieuwe/geupdate producten kan ophalen uit het Hybris PIM systeem. Merk op dat deze actie niet noodzakelijk door een gebruiker aangeroepen moet worden, maar ook via een job event getriggerd kan worden.
BIJLAGE A. USE CASES
A.3
93
Price enrichment
Deze sectie bestaat uit een aantal verschillende use cases, die in figuur 2.2 allemaal vooraf gegaan worden door het woord ’Product’ (met uitzondering van ’Product Status&calculated values’). Ook hier is de inhoud van deze use cases grotendeels gelijkaardig, en is er dus ook gekozen om maar ´e´en voorbeeld in deze bijlage op te nemen. Wat deze use cases onderscheidt van de CRUD use cases, is dat ze enerzijds zoekfunctionaliteit bevatten, en anderzijds geen Create/Delete functionaliteit bezitten.
A.3.1 Read
Update
Price overwrites
BIJLAGE A. USE CASES
A.4
Calculate prices
Deze use cases beschrijven hoe een gebruiker de prijsberekeningsmethode kan aanroepen.
A.4.1
Calculate selected
A.4.2
Calculate all
94
BIJLAGE A. USE CASES
A.5
95
Send prices
Deze use cases beschrijven hoe een gebruiker de gewenste prijzen naar Hybris kan doorsturen. Merk op dat deze actie niet noodzakelijk door een gebruiker aangeroepen moet worden, maar ook via een job event getriggerd kan worden.
A.5.1
Send selected
A.5.2
Send all
BIJLAGE A. USE CASES
A.6
96
Status management
Deze use cases beschrijven hoe een gebruiker na het uitvoeren van bepaalde acties kan zien of er fouten/verouderde prijzen voorkomen. Een prijsaanpassing van een verpakking zal bijvoorbeeld tot gevolg hebben dat alle prijzen van producten die deze verpakking gebruiken een error status verkrijgen. Er zijn een uitgebreid aantal statussen voorzien, die allemaal beschreven worden in het onderdeel status logic op pagina 56.
A.6.1
Show statuses of selected prices
A.6.2
Show products with errors
Bijlage
B
ER diagram
97
BIJLAGE B. ER DIAGRAM
B.1
ER diagram parameters
Packaging
Supplier
Supplier
Transport
98
BIJLAGE B. ER DIAGRAM Product
Price
99
BIJLAGE B. ER DIAGRAM Price Overwrite
Price Calculated
Sales channel
Delivery zone
100
BIJLAGE B. ER DIAGRAM Delivery region
GLS Colli
GLS Freight
101
Bijlage
C
Bespreking overige applicatiepagina’s C.1
Transport
Transport is geen bestaande pagina in de applicatie, maar enkel een onderverdeling in het menu om onderscheid te maken tussen transport gerelateerde pagina's en de rest. De pagina's die hiertoe behoren zijn:
Regions;
GLS Colli;
GLS Freight.
C.1.1
Regions
Deze pagina bevat de mogelijk regio's waarin geleverd kan worden, en hun extra kost. Deze extra kost kan eigenlijk ge¨ınterpreteerd worden als het retour risico dat leveringen in deze regio met zich meebrengen. Aanmaken van een nieuwe regio Toevoegen van een regio gebeurt op de volgende manier: 1. Druk op de knop 'Add region' 2. Bovenaan de tabel zal een nieuwe rij getoond worden 3. Door op een veld in de rij te klikken, zal de waarde aangepast kunnen worden zoals op de onderstaande foto. 102
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
103
Figuur C.1: Editable table field 4. Vervolgens kan stap 3 herhaald worden voor de volgende twee kolommen. 5. Selecteer de 'Save changes' knop en klik vervolgens op 'OK'. Wijzigen van een regio Indien een bestaande regio gewijzigd dient te worden, dienen de stappen voor het Aanmaken van een nieuwe regio vanaf stap 3 herhaald te worden. Verwijderen van een regio Een regio kan simpelweg verwijderd worden door op de 'Delete' knop te drukken. Indien de regio dan niet verwijderd wordt, zal de onderstaande popup getoond worden.
Figuur C.2: Delete region error popup Deze popup betekent dat de regio momenteel nog in gebruik is door ´e´en of meerdere kanalen en/of GLS tabellen. Om dit op te lossen, dient de gebruiker op de Sales channels pagina de regio van elk verkoopkanaal te controleren, en indien de regio nog voorkomt, deze te vervangen. Hierna moet op de pagina's GLS colli en GLS freight de volledige tabel voor die regio verwijderd worden (elke rij verwijderen met de 'Delete' knop) alvorens de regio verwijderd kan worden.
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S Overzicht ’Regions’ pagina
Figuur C.3: Region page overview
104
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
C.1.2
105
GLS colli
Deze pagina bevat de General Logistics Systems tarieven voor Colli transport in tabelvorm. Deze tarieven zijn afhankelijk van het gewicht en de afmetingen van het te verzenden pakket, dus zullen gewichten en afmetingen zeker in de tabel terug te vinden zijn. Voor het gewicht wordt er per rij een minimum en maximum gedefinieerd. Voor de afmetingen zijn er 2 eigenschappen toegevoegd:
Maximum lengte: zowel lengte, breedte als hoogte van de verpakking van een product wordt hiermee vergeleken (of de afmetingen van het product, indien geen verpakking gebruikt wordt).
Girth: 2x de hoogte + 2x de lengte + de langste zijde Verder is het GLS tarief afhankelijk van de regio, dus zal vooraleer er iets te zien is op deze pagina een regio geselecteerd moeten worden.
Figuur C.4: Select region option Aanmaken van een nieuwe GLS colli rij Toevoegen van een nieuw tarief voor een bepaald gewicht en bepaalde afmetingen in een bepaalde regio gebeurt op de volgende manier:
Selecteer een regio
Druk op de 'Add row' knop
Bovenaan de tabel zal een nieuwe rij aangemaakt worden
Door op een veld in de rij te klikken, zal de waarde aangepast kunnen worden zoals op de onderstaande foto.
Figuur C.5: Editable table field
Vervolgens kan stap 3 herhaald worden voor de overige kolommen.
Selecteer de 'Save changes' knop en klik vervolgens op 'OK'.
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
106
Opmerking: bij het aanmaken van een nieuwe regio, zal automatisch een volledige standaard GLS colli tabel aangemaakt worden, waarin alle gewicht en dimensie gerelateerde kolommen al correct ingevuld zijn, waardoor enkel de prijzen nog aangepast moeten worden. Wijzigen van een GLS colli rij Indien een bestaande GLS colli rij gewijzigd dient te worden, dienen de stappen voor het Aanmaken van een nieuwe GLS freight rij vanaf stap 4 herhaald te worden. Verwijderen van een GLS colli rij Een GLS colli rij kan simpelweg verwijderd worden door op de 'Delete' knop te drukken. Overzicht ’GLS colli’ pagina
Figuur C.6: GLS colli page overview
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
C.1.3
107
GLS freight
Deze pagina bevat de General Logistics Systems tarieven voor Freight transport in tabelvorm. Deze tarieven zijn afhankelijk van het gewicht en de afmetingen van het te verzenden pakket, dus zullen gewichten en afmetingen zeker in de tabel terug te vinden zijn. Voor het gewicht wordt er per rij een minimum en maximum gedefinieerd. Voor de afmetingen zijn er 2 eigenschappen toegevoegd:
Maximum lengte: zowel lengte, breedte als hoogte van de verpakking van een product wordt hiermee vergeleken (of de afmetingen van het product, indien geen verpakking gebruikt wordt).
Girth: 2x de hoogte + 2x de lengte + de langste zijde Verder is het GLS tarief afhankelijk van de regio, dus zal vooraleer er iets te zien is op deze pagina een regio geselecteerd moeten worden.
Figuur C.7: Select region option Aanmaken van een nieuwe GLS freight rij Toevoegen van een nieuw tarief voor een bepaald gewicht en bepaalde afmetingen in een bepaalde regio gebeurt op de volgende manier:
Selecteer een regio
Druk op de 'Add row' knop
Bovenaan de tabel zal een nieuwe rij aangemaakt worden
Door op een veld in de rij te klikken, zal de waarde aangepast kunnen worden zoals op de onderstaande foto.
Figuur C.8: Editable table field
Vervolgens kan stap 3 herhaald worden voor de overige kolommen.
Selecteer de 'Save changes' knop en klik vervolgens op 'OK'.
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
108
Opmerking: bij het aanmaken van een nieuwe regio, zal automatisch een volledige standaard GLS freight tabel aangemaakt worden, waarin alle gewicht en dimensie gerelateerde kolommen al correct ingevuld zijn, waardoor enkel de prijzen nog aangepast moeten worden. Wijzigen van een GLS freight rij Indien een bestaande GLS freight rij gewijzigd dient te worden, dienen de stappen voor het Aanmaken van een nieuwe GLS freight rij vanaf stap 4 herhaald te worden. Verwijderen van een GLS freight rij Een GLS freight rij kan simpelweg verwijderd worden door op de 'Delete' knop te drukken. Overzicht ’GLS freight’ pagina
Figuur C.9: GLS freight page overview
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
C.2
109
Packaging
Op deze pagina kunnen de verschillende verpakkingen aangemaakt worden. De eigenschappen van deze verpakkingen zijn:
Naam: naam van de verpakking;
Prijs: prijs van de verpakking;
Afmetingen: dit is enkel noodzakelijk voor dozen zodat bij het laden van nieuwe producten automatisch de meest geschikte doos geselecteerd kan worden. Voor extra verpakkingen zoals bubble wrap, cadeauverpakking, etc. zijn deze velden overbodig.
C.2.1
Aanmaken van een nieuwe verpakking
Toevoegen van een nieuwe verpakking gebeurt op de volgende manier: 1. Druk op de 'Add packaging' knop 2. Bovenaan de tabel zal een nieuwe rij aangemaakt worden 3. Door op een veld in de rij te klikken, zal de waarde aangepast kunnen worden zoals op de onderstaande foto.
Figuur C.10: Editable table field 4. Vervolgens kan stap 3 herhaald worden voor de overige kolommen. 5. Selecteer de 'Save changes' knop en klik vervolgens op 'OK'.
C.2.2
Wijzigen van een verpakking
Indien een bestaande verpakking gewijzigd dient te worden, dienen de stappen voor het Aanmaken van een nieuwe verpakking vanaf stap 3 herhaald te worden.
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
C.2.3
110
Verwijderen van een verpakking
Een verpakking kan simpelweg verwijderd worden door op de 'Delete' knop te drukken. Indien de verpakking niet verwijderd kan worden, zal onderstaande popup op het scherm verschijnen.
Figuur C.11: Delete packaging error popup Dit betekent dat de verpakking momenteel in gebruik is voor verschillende producten, en dus enkel verwijderd kan worden na dat de verpakking van deze producten gewijzigd is.
C.2.4
Overzicht ’Packaging’ pagina
Figuur C.12: Packaging page overview
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
C.3
111
Supplier
Op deze pagina kunnen de verschillende leveranciers, en hun leveringskortingen ingesteld worden.
C.3.1
Aanmaken van een nieuwe leverancier
1. Druk op de 'Add supplier' knop 2. Bovenaan de tabel zal een nieuwe rij aangemaakt worden 3. Door op een veld in de rij te klikken, zal de waarde aangepast kunnen worden zoals op de onderstaande foto.
Figuur C.13: Editable table field 4. Vervolgens kan stap 3 herhaald worden voor de overige kolommen. 5. Selecteer de 'Save changes' knop en klik vervolgens op 'OK'.
C.3.2
Wijzigen van een leverancier
Indien een bestaande leverancier gewijzigd dient te worden, dienen de stappen voor het Aanmaken van een nieuwe leverancier vanaf stap 3 herhaald te worden.
BIJLAGE C. BESPREKING OVERIGE APPLICATIEPAGINA’S
C.3.3
112
Verwijderen van een leverancier
Een leverancier kan simpelweg verwijderd worden door op de 'Delete' knop te drukken. Indien de leverancier niet verwijderd kan worden, zal onderstaande popup op het scherm verschijnen.
Figuur C.14: Delete supplier error popup Dit betekent dat de leverancier momenteel in gebruik is voor verschillende producten, en dus enkel verwijderd kan worden na dat de leverancier van deze producten gewijzigd is.
C.3.4
Overzicht ’Supplier’ pagina
Figuur C.15: Supplier page overview
Bibliografie
[1] Start Bootstrap. SB Admin 2. sb-admin-2/. 44, 48
http://startbootstrap.com/template-overviews/
[2] Riccardo Cardin. MVC e di spring e AngularJS. RiccardoCardin/mvc-e-di-spring-e-angular-js. 15 [3] Lorenzo Fox. Smart smart-table-website/. 17
Table
Introduction.
http://www.slideshare.net/ https://lorenzofox3.github.io/
[4] Mikell P. Groover. Automation, Production Systems, and Computer Integrated Manufacturing. Prentice Hall, 2000. 21 [5] Kenji Hasunuma. JAX-RS 1.1 explained. programming/2012/12/jaxrs1.html. 10
http://www.coppermine.jp/docs/
[6] Uche Ogbuji. Rapid web development with Bootstrap. developerworks/library/wa-bootstrap/. 44
http://www.ibm.com/
[7] Colin Percival. Stronger Key Derivation via Sequential Memory-Hard Functions, pp. 14. 14 [8] RestApiTutorial.com. Using HTTP Methods for RESTful Services. restapitutorial.com/lessons/httpmethods.html. 37
http://www.
[9] Jose Sandoval. RESTful Java Web Services. PACKT Publishing, november 2009. 13 [10] SourceMaking. Object Relational Design Patterns - Convert Procedural Design to Objects. http://kniterpa.com/object-relational-design-patterns/. 10 [11] The Hibernate Team. HIBERNATE - Relational Persistence for Idiomatic Java. https: //docs.jboss.org/hibernate/orm/4.3/manual/en-US/html single/. 13 [12] what-when how. Introducing JPQL Part 1 (EJB 3). http://what-when-how.com/ enterprise-javabeans-3/introducing-jpql-part-1-ejb-3/. 9
113
BIBLIOGRAFIE [13] Wikipedia. User Interface. https://en.wikipedia.org/wiki/User interface. 47
114