Sasu Pirttiperä Data utilization software for assisting power plant project sales Vaasa 2022 School of Technology and Innovations Master’s thesis in Automation and Computer Science Energy and Information Technology 2 UNIVERSITY OF VAASA School of Technology and Innovations Author: Sasu Pirttiperä Title of the Thesis: Data utilization software for assisting power plant project sales Degree: Master of Science in Technology Programme: Automation and Computer Science Supervisor: Jouni Lampinen Instructor: Paulina Salo Year: 2022 Pages: 85 ABSTRACT: A business opportunity in power plant project sales goes through several stages before a quote can be made. Previously made quotes can offer insight on how earlier projects were sold in certain areas or countries. Therefore, a salesperson working in energy business will often want to compare the cost and scope of current power plant projects with earlier sold projects. The role of web applications continues to grow. Increasing amount of software developers write their software for web browsers. In addition, modern software development tools such as Django and React allow efficient web development. Since the popularity of web applications is increasing, web browsers have become the main platform for new applications. In this thesis, a prototype web application is designed and developed. The application allows a salesperson to compare current power plant projects with previously sold projects. The compar- ison process should mainly illustrate how the costs of the compared projects differ from one another. The goal of the application is to enable sales personnel to access relevant data and make comparisons by utilizing just a single application instead of using many separate systems. This reduces the workload in sales department and increases the productivity in power plant project sales. The prototype application developed in this thesis will be integrated into energy feasibility tools platform, which hosts several different applications used in energy sales. Furthermore, the ap- plication should utilize data located on Wärtsilä Data Platform. The prototype is written with Python and JavaScript programming languages. The backend server is created by utilizing Django web framework. The user interface of the application is constructed with React and Semantic UI libraries. The users of the application are authenticated with the help of OAuth 2.0 authorization framework. In this thesis, a working prototype application was designed and developed. The resulting appli- cation allows a salesperson to compare different power plant projects and examine the details of individual projects. The application developed in the thesis can be used in the future as a model for similar systems utilizing Wärtsilä Data Platform data. Currently, the application is mainly designed for engine power plant data. However, in the future the application could be modified to work better with energy storage data. Finally, it should be investigated whether machine learning algorithms could be used to offer recommendations for users based on the data of previous projects. KEYWORDS: power plant, project sales, data utilization tool 3 VAASAN YLIOPISTO Tekniikan ja innovaatiojohtamisen yksikkö Tekijä: Sasu Pirttiperä Tutkielman nimi: Data utilization software for assisting power plant project sales Tutkinto: Diplomi-insinööri Oppiaine: Automaatio ja tietotekniikka Työn valvoja: Jouni Lampinen Työn ohjaaja: Paulina Salo Valmistumisvuosi: 2022 Sivumäärä: 85 TIIVISTELMÄ: Voimalaitosprojektin myyntiprosessi koostuu useista vaiheista, joiden aikana liiketoimintamahdollisuudesta kehittyy tarjous. Aiemmin tehdyt tarjoukset voivat tarjota tietoa siitä, kuinka edellisiä projekteja on myyty tietyissä maanosissa tai valtioissa. Tästä syystä myyntihenkilöt haluavat usein vertailla meneillään olevien projektien kustannuksia ja laajuutta aiemmin myytyihin projekteihin. Web-sovellusten rooli on kasvanut vuosien varrella. Kasvava joukko sovelluskehittäjiä kirjoittaakin nykyään sovelluksiaan web-selaimille. Tämän lisäksi modernit kehitystyökalut kuten Django ja React lisäävät sovelluskehityksen tehokkuutta. Web-sovellusten kasvava rooli onkin tehnyt web-selaimista tärkeimmäin alustan uusille sovelluksille. Tämän diplomityön tarkoituksena on suunnitella sekä kehittää prototyyppi web-sovellus. Tämä sovellus auttaa myyjiä vertailemaan meneillä olevia voimalaitosprojekteja aiemmin myytyihin projekteihin. Vertailuprosessin päämäärä on lähinnä havainnollistaa, kuinka eri projektien kustannukset eroavat toisistaan. Työn tavoite on auttaa myyjiä hyödyntämään ja vertailemaan voimalaitosprojektien dataa käyttämällä pelkästään yhtä sovellusta. Mikäli voimalaitosdataa voitaisiin vertailla yhdellä sovelluksella useiden hajanaisten sovelluskokonaisuuksien käyttämisen sijaan, myyjien työtaakka vähentyisi ja samalla tuottavuus voimalaitosprojektien myynnissä kasvaisi. Tässä diplomityössä kehitetty prototyyppisovellus liitetään osaksi energy feasibility tools työkalua, joka toimii alustana useille eri voimalaitossovelluksille. Tämän lisäksi työssä kehitetty sovellus hyödyntää Wärtsilä Data Platform yritystietovarastossa olevaa dataa. Työssä toteutettava protyyppisovellus ohjelmoidaan Python ja JavaScript ohjelmointikieliä käyttäen. Palvelimen toiminnallisuudet luodaan käyttämällä Django web-sovelluskehystä. Sovelluksen käyttöliittymä rakennetaan hyödyntämällä React ja Semantic UI kirjastoja. Protyyppisovelluksen käyttäjät tullaan todentamaan käyttämällä OAuth 2.0 kehystä. Tässä diplomityössä suunniteltiin ja kehitettiin toimiva prototyyppisovellus. Tätä sovellusta käyttävät myyjät pystyvät vertailemaan erilaisia voimalaitosprojekteja sekä tarkastelemaan yksittäisten voimalaitosprojektien yksityiskohtia. Työssä kehitetty sovellus voisi toimia tulevaisuudessa mallina vastaavan kaltaisille Wärtsilä Data Platform dataa hyödyntäville sovelluksille. Tällä hetkellä sovellus on suunniteltu lähinnä moottorivoimalaitosprojekteja varten. Tulevaisuudessa sovellusta voitaisiin räätälöidä siten, että se sopisi paremmin myös energian varastointia koskeviin projekteihin. Varteenotettavaa olisi myös tutkia, pystyisikö koneoppimismenetelmillä tarjota käyttäjille dataan perustuvia suosituksia. AVAINSANAT: voimalaitos, projektimyynti, dataa hyödyntävä työkalu 4 Preface First, I would like to thank my supervisor Prof. Jouni Lampinen for remarkably clear feed- back and extremely punctual instructions. The clarity of the instructions allowed me to create the structure for this thesis and finish writing it relatively easily. In addition, I want to thank my thesis instructor Paulina Salo for her encouraging attitude and for helping me with the key concepts and data related to this thesis. Since the thesis included working with several different systems, I wish to thank Tomi Korpi for helping me with all the problems related to software and code. Finally, I would like to thank my managers Sami Kujanpää and Jan-Anders Backlund for removing differ- ent obstacles and offering me the opportunity to write this thesis at Wärtsilä. Vaasa, 2.6.2022 Sasu Pirttiperä 5 Contents 1 Introduction 11 1.1 Objective of the thesis 12 1.2 Structure of the thesis 13 2 Power plant project 14 2.1 Scope of supply 14 2.1.1 Basic engineered equipment delivery 15 2.1.2 Extended engineered equipment delivery 15 2.1.3 Engineering, procurement, and construction 15 2.1.4 Process engineering, procurement, and construction 16 2.2 Terminology 16 2.2.1 Opportunity 17 2.2.2 Quote 17 2.2.3 Bill of material 17 2.3 Wärtsilä energy solutions 18 2.3.1 Engine power plants 18 2.3.2 Energy storage 19 3 Required technology 20 3.1 Programming languages 20 3.1.1 Python 22 3.1.2 JavaScript 22 3.2 Databases 23 3.2.1 Relational databases 25 3.2.2 Data warehouses 25 3.3 Frameworks and libraries 26 3.3.1 Django 26 3.3.2 React 28 3.3.3 Semantic UI 29 3.4 Security 31 3.4.1 Authorization 31 6 3.4.2 Encryption 33 3.5 Energy feasibility tools platform 34 4 Plan for the development process 35 5 Design of the application 37 5.1 Starting point 37 5.1.1 Data 37 5.1.2 Requirements 39 5.2 High-level design of the system 40 5.2.1 Structure of the system 40 5.2.2 Authorization design 41 5.2.3 Logic behind the user interface 42 5.3 Backend design 44 5.4 Frontend design 46 5.4.1 User interface design 46 5.4.2 Required React components 49 6 Implementation of the application 51 6.1 Backend code 51 6.1.1 Connecting to Wärtsilä data platform 51 6.1.2 Django models 53 6.1.3 Django web application programming interface 54 6.1.4 Backend functionalities for authentication 59 6.2 Frontend code 61 6.2.1 Frontend functionalities for authentication 61 6.2.2 Implementing the user interface 63 7 Results 71 8 Conclusions 79 References 81 7 Figures Figure 1. Different scopes of supply contract types. (Modified from Wärtsilä, 2021, pp. 90–91.) ............................................................................................................................ 16 Figure 2. Compiling a source program (a) and running the target program (b). (Reconstructed from Aho, et al., 2007, p.2.) .................................................................. 21 Figure 3. Directly executing a source program with user inputs by using an interpreter. (Modified from Aho, et al., 2007, p.2.) ........................................................................... 21 Figure 4. Three-tier architecture. (Modified from Silberschatz, et al., 2011, p. 25.) ..... 24 Figure 5. Typical data warehouse architecture. (Modified from Silberschatz, et al., 2011, p. 890.) ............................................................................................................................ 26 Figure 6. Architecture of Django REST framework. (Modified from BezKoder, 2021.) .. 28 Figure 7. Comparing Semantic UI with plain HTML. ....................................................... 30 Figure 8. The abstract protocol flow of OAuth 2.0. (Reconstructed from Hardt, 2012, p. 7.) .................................................................................................................................... 32 Figure 9. Two parties sharing a secret key to communicate privately. (Modified from Katz & Yehuda, 2020.) ............................................................................................................ 33 Figure 10. A single user securely storing data. (Modified from Katz & Yehuda, 2020.) . 33 Figure 11. Simplified illustration of the database tables of interest (tables have hundreds of columns and therefore not all the column names are displayed in the image). ....... 38 Figure 12. High-level view of the system. ....................................................................... 40 Figure 13. Authenticating a user and fetching power plan project quotes. ................... 42 Figure 14. Flowchart describing the high-level logic of the user interface. ................... 43 Figure 15. Mapping a Python class containing quote data to the corresponding database table in WDP. ................................................................................................................... 44 Figure 16. The table for selecting powerplant project quotes. ...................................... 46 Figure 17. Filtering the list of quotes by clicking the table header and selecting filters. 47 Figure 18. By clicking compare button the quotes on the comparison list can be compared with one another. A user can either compare contract details or area costs. ........................................................................................................................................ 48 8 Figure 19. Quote details can be examined by clicking on the name of the quote. This process directs a user to a new page, which displays the details of the selected quote. ........................................................................................................................................ 49 Figure 20. The required React components. .................................................................. 50 Figure 21. The location of the prototype application in the front page of energy feasibility tools platform. ................................................................................................................ 71 Figure 22. The loading screen that is shown when authenticating a user. .................... 72 Figure 23. The list of example projects (example projects 4 and 5 are on the comparison list). The table has more filterable columns after sales region, but those are not displayed to fit the image to this document. .................................................................................. 73 Figure 24. Filtering out projects based on country (by removing U.S.A. example projects 2, 4, and 5 will disappear from the list). ......................................................................... 73 Figure 25. Comparing contract data between two projects in the quote comparison modal (a project can be removed from comparison in this view by pressing the trash bin button next to the name of the project). ....................................................................... 74 Figure 26. Comparing area costs of two different power plant projects in the quote compare modal. .............................................................................................................. 75 Figure 27. The left side of the quote detail page displaying the quote details and contract data. ................................................................................................................................ 76 Figure 28. The right side of the quote detail page displaying the area costs of the selected project. ............................................................................................................................ 77 Tables Table 1. Relevant model fields mapping to WDP. The user of the prototype application should be able to use some of these fields to filter the list of power plant quotes. ..... 45 Algorithms Algorithm 1. Django settings for WDP connection. ........................................................ 52 Algorithm 2. The database router class for WDP connection. ....................................... 52 9 Algorithm 3. The required Django models mapping to database tables in WDP. .......... 53 Algorithm 4. The required Django model serializers. ..................................................... 55 Algorithm 5. Specifying the related Django model and the fields that will be included in the data that is sent as a response to a frontend client. ................................................ 55 Algorithm 6. Encrypting id values. .................................................................................. 56 Algorithm 7. Decrypting encrypted id values. ................................................................ 57 Algorithm 8. The required Django ViewSets. ................................................................. 57 Algorithm 9. Fetching power plant solution data used in the prototype application. ... 58 Algorithm 10. The required URLs for requesting data from the backend server. .......... 58 Algorithm 11. The authentication process in the backend server. ................................. 59 Algorithm 12. The function used to request an access token for a user. ....................... 60 Algorithm 13. The function used to authenticate users. ................................................ 60 Algorithm 14. HTTP redirect to authorization endpoint. ............................................... 61 Algorithm 15. Sending an authorization code to the backend server, which will complete the rest of the OAuth 2.0 process and then return the list of power plant project quotes. ........................................................................................................................................ 62 Algorithm 16. Function declarations in QuoteBrowserPage component. ..................... 64 Algorithm 17. Fetching and cleaning comparison data fetched from the backend server. ........................................................................................................................................ 65 Algorithm 18. Rendering the main view of the application. .......................................... 65 Algorithm 19. Rendering the header row of the quote selection table. ........................ 66 Algorithm 20. The button used to add and remove quotes from the comparison list. . 67 Algorithm 21. Rendering the rows of the quote selection table. ................................... 68 Algorithm 22. The tab panes for different comparison modes in QuoteComparisonModal component. .................................................................................................................... 69 Algorithm 23. The modal containing the components required to render the comparison table. ............................................................................................................................... 70 Algorithm 24. The list of utility functions that helped to develop the application. ....... 70 10 Abbreviations AES Advanced encryption standard API Application programming interface BOM Bill of material CRM Customer relationship management CSS Cascading style sheets DBMS Database management system EEQ Engineered equipment delivery EPC Engineering, procurement, and construction HTML Hypertext markup language HTTP Hypertext transfer protocol JIT Just-in-time JSON JavaScript object notation JSX JavaScript syntax extension LCOE Levelized cost of energy OAuth Open authorization ORM Object-relational mapping REST Representational state transfer SQL Structured query language UI User interface URL Uniform resource identifier WDP Wärtsilä data platform 11 1 Introduction A sales process of a power plant projects consists of several phases. If an energy business opportunity is promising, a quote can be sent to a customer. A salesperson working in energy business will often want to compare current power plant projects with previously sold projects to gain better insight about the cost and the scope of projects in certain areas or countries. Software has become irreplaceable technology in science, engineering, and business (Pressman, 2010, p. 2). Recently, software has been trending towards web-based appli- cations. Conventional binary desktop applications are not as flexible as web applications, which do not require installation or manual updates (Taivalsaari & Mikkonen, 2011, p. 174). As a response to growing number of web applications, developers will more often use web browsers as the primary application platform for their software instead of spe- cific operations systems or hardware. (Taivalsaari et al., 2008, p. 302). One of the benefits of developing web applications is the availability of modern web frameworks. For in- stance, Python web framework Django increases the speed of application development. Moreover, JavaScript libraries such as React allow web developers to build complex user interfaces. With the help of beforementioned development tools the development of web applications is efficient. This thesis describes the development process of a prototype web application. The ap- plication will be integrated into earlier developed energy feasibility tools platform, which runs on typical web browsers. Energy feasibility tools platform consist of several appli- cations that can help users, for instance, to calculate levelized cost of energy (LCOE), compare Wärtsilä products in different conditions, or examine power plant base solu- tions. Previously made power plant project opportunities and quotes will be used as a starting point of the thesis. The power plant project sales data has been earlier integrated into Wärtsilä Data Platform (WDP), which combines data from scattered sources inside the 12 organization. The focus of the thesis is on developing an application, which utilizes some of the data stored on this data warehouse. 1.1 Objective of the thesis The goal of this thesis is to develop a new application, which will be integrated into Wärt- silä’s energy feasibility tools platform. This application utilizes power plant project sales data stored on WDP. In practice, the thesis involves on developing both the backend server functionalities used to query and format WDP data and the user interface (UI) running on a web browser. Since the data stored on WDP can be sensitive, the thesis will also involve designing and developing an authorization process to authenticate users. The purpose of the application is to help sales personnel to compare currently ongoing power plant projects with previously sold projects. The application should also allow sales personnel to compare different quotes made in the past with one another. The goal of the comparison is to illustrate how the contract data and the area costs between com- pared projects differ. The comparison process should allow sales personnel to gain better insight about their current projects, which can help them in providing price indication for customers. The new prototype application aims to reduce the workload of sales personnel by offer- ing a single application for utilizing previous sales data. Currently, a salesperson must manually find previously made quotations from scattered sources in order to compare those with current projects. The goal of the new application is to reduce the time that it takes to compare new power plant projects with older projects, thus increasing the productivity of the sales department. The new application tries to establish a systematic way to utilize WDP data. This means that a backend server should be able to access data stored on WDP and forward the data to a frontend client, which in turn would construct an UI from the data. By developing a 13 working prototype application, the documented application can be used as a guide for creating similar applications in the future. This would reduce the need to reinvent the wheel next time when developing a software utilizing WDP data. 1.2 Structure of the thesis First, chapter 2 introduces the key terminology for power plant project sales. In chapter 3 the required technology for developing the application is described. The plan for the design and development processes is presented in Chapter 4. The design of the system behind the application is shown in chapter 5. Chapter 6 describes the implementation of the application, including various examples of the source code. The finished applica- tion developed in this thesis is illustrated in Chapter 7. Finally, chapter 8 concludes this thesis. 14 2 Power plant project Power plants produce electricity. Different type of power plants, however, may have var- ying goals. Some power plants such as thermal and nuclear power plants tend to run continuously and produce power output at a steady rate, whereas gas turbines may be used only a short period of time in a day as a response to peak load demand. The con- struction of power plants requires careful planning. Important factors to be considered when building a thermal power plant include, for example, the availability of cooling wa- ter, availability of fuel, rail and road connections, and character of soil. (Nag, 2002, pp. 1, 8–9) Modern society and technology are dependent on power plants. Without electricity, vi- tal systems such as cooling, heating and communication would not function. (Drbal et al., 2012, p. 1) Overall, the generation of electricity is a complex subject and is out of scope of this thesis. Instead of concentrating on the engineering aspects of power gen- eration, this chapter focuses on explaining some of the key power plant project concepts from the perspective of a power plant project sales. The goal of this chapter is to intro- duce all the important terminology that is essential for understanding the later chapters of this thesis. 2.1 Scope of supply Power plant solutions can have different scopes. In power plant projects a scope of sup- ply defines which engineering, construction, and installation processes are done by a power plant solution provider, and which are left to the responsibility of a customer. More generally, scope is determined by all the objectives and requirements needed to finish a project (Grant, 2021). According to Grant (2021) defining the scope is essential since managers can use it to estimate project costs and schedule. In the following sub- chapters, four different Wärtsilä scope of supply contract types for power plant projects are introduced. 15 2.1.1 Basic engineered equipment delivery Basic engineered equipment delivery (Basic EEQ) refers to a service in which only the main equipment and auxiliaries needed for a power plant are supplied and engineered. This type of contract includes transportation, engineering, and materials. However, Basic EEQ does not include the installation of the power plant. Instead, only technical advisory regarding the installation and commissioning of the power plant is provided. (Wärtsilä, 2021, p. 90) 2.1.2 Extended engineered equipment delivery Extended Engineered Equipment Delivery (Extended EEQ) is a contract type where the supplier provides engineering for all equipment and materials, instead of just the main components as in Basic EEQ. Similarly, to Basic EEQ, Extended EEQ does not include in- stallation. Therefore, a third-party contractor must be hired to carry out the installation of the power plant. (Wärtsilä, 2021, p. 90) 2.1.3 Engineering, procurement, and construction A typical engineering, procurement, and construction (EPC) contract includes project management, site management and supervision. Furthermore, the power plant solution provider is responsible for engineering, materials, equipment as well as the construction and installation of the entire power plant solution. (Pícha et al., 2015, p. 398) The con- struction work in EPC contracts also include all the subsoil and foundational work needed for the power plant (Wärtsilä, 2021, p. 91). 16 2.1.4 Process engineering, procurement, and construction A process engineering, procurement, and construction (Process EPC) contract has almost all the same features as beforementioned EPC contract. The main difference is that in Process EPC the installation is only done above floor level. Therefore, the client is re- sponsible of performing any subsoil and foundation construction works needed for the power plant. (Wärtsilä, 2021, p. 91) The difference between scope of supply contracts and their respected added values is illustrated below (see Figure 1). Figure 1. Different scopes of supply contract types. (Modified from Wärtsilä, 2021, pp. 90–91.) 2.2 Terminology Similar to other fields of expertise, power plant projects also have their own terminology. In order to understand power plant projects sales, it is essential that the key terms are properly explained. Following subchapters aim to describe the key terms related to power plant project sales. The terminology introduced in this section is used in the pro- totype application described in the later chapters of this thesis. The terms introduced in 17 this section are described from the viewpoint of customer relation management (CRM) software user. In fact, all of these terms have their own database tables that can be ac- cessed with Salesforce CRM software. 2.2.1 Opportunity In Salesforce CRM software, an opportunity object stores important information about a promising business deal. (Salesforce, 2021a) In a power plant project context, an op- portunity object can hold information about the project’s destination country, sales re- gion, related quotes, fiscal year, current stage, and other essential details related to the business deal. If an opportunity is promising, it can develop into a single or several quotes. 2.2.2 Quote Quote objects in Salesforce CRM software can be created from an opportunity. A quote represents proposed prices for products and services of a company. (Salesforce, 2021b) As an example, a quote object related to engine power plant project might store infor- mation about engine details, main fuel, fuel type, scope of supply, and its related oppor- tunity. As mentioned, several quote objects can be created from a single opportunity. For this reason, a quote object has one field, which indicates whether the quote is the most promising one from the set of possible quotes created from a business opportunity object. 2.2.3 Bill of material Every power plant must have a bill of material (BOM). BOM is a list of raw materials, components, and set instructions needed to produce a product (Reid & Sanders, 2019, p. 491). In a power plant project, a single BOM item could be, for example, an engine, a 18 water tank, or a gas pressure control valve. In Salesforce software, each BOM item has a field, indicating to which BOM the BOM item belongs to. If compared to, say, shopping list, BOM is the receipt and BOM items are the purchased items in that receipt. 2.3 Wärtsilä energy solutions The focus of Wärtsilä’s power plant business is on engine power plants and energy stor- age systems. The company claims to offer flexible power plant solutions that allows in- creasing the amount of renewable energy. One of the goals of Wärtsilä’s energy solutions is to stabilize the power grid, which is affected by the irregularity caused by the increas- ing amount of renewable energy systems. (Wärtsilä, 2021, pp. 4–5) 2.3.1 Engine power plants Internal combustion engines utilize chemical energy contained in the fuel to produce mechanical power (Heywood, 1988, p. 1). By burning or oxidating the fuel in the engine, the chemical energy is converted to thermal energy. The resulting thermal energy causes increase in the pressure and temperature of the gases inside the engine. The pressurized gas expands and causes the mechanical linkages to convert the energy in the gas into mechanical energy, thus rotating the crankshaft of the engine. (Pulkrabek, 2000, p. 1) The energy produced by internal combustion engines can be applied in both power gen- eration and transportation. Wärtsilä has engine power plants installed all around the globe. Currently, Wärtsilä offers several different engine power plant solutions, which can run with various fuels. Possible fuels for engines used in these plants are natural gas and liquid fuels such as heavy fuel oil, light fuel oil, and liquid biofuel. Additionally, Wärtsilä produces multi fuel power plants, which can switch between different fuels depending on the fuel availability. In addition to fuel flexibility, engine power plants are operationally flexible and can be used 19 for baseload power generation as well as balancing dynamic systems such as wind or solar power. (Wärtsilä, 2021, pp. 8, 17, 32, 96–99) 2.3.2 Energy storage Solar and wind power generation can be unstable and might have large impact on the power grid. One solution to this problem is to use an energy storage system that can stabilize solar and wind power generation. The primary goal of energy storage systems is to reduce power fluctuations caused by unstable power generation systems, thus im- proving the overall power quality of solar and wind power. (Xuewei, et al., 2020, p. 464) Since weather conditions affect the output of wind and solar power generation, energy storage systems are becoming increasingly critical. (Wärtsilä, 2021, p. 65) Wärtsilä is one of the companies offering modular energy storage systems. One of the company’s prod- ucts called GridSolv Max is an energy storage system consisting of only one ISO 40’ unit. GridSolv Max includes batteries, safety system, power distribution, and air conditioning system. (Wärtsilä, 2022) 20 3 Required technology Software has been trending from traditional desktop applications towards web applica- tions running on a web browser (Taivalsaari & Mikkonen, 2011, p. 174). Currently, the development of web applications consists of large number of different tools and tech- nologies. In fact, it is not possible for a single developer to equally well master all the different tools needed for modern web development. Furthermore, typically developers must be able to work on a large number of different tasks instead of only focusing on a narrow set of problems. Since web development is under rapid technological changes, a group of generalists can typically adapt to new changes more efficiently compared to a team of specialists. (Northwood, 2018, pp. 2, 9) This chapter introduces the software tools and technology, which are needed to imple- ment the application developed in this thesis. The prototype developed in the thesis is created by using a typical set of tools and technologies that are required to build a mod- ern web application. The goal of this chapter is to familiarize reader with different pro- gramming languages, database tools, libraries, and frameworks that are used later in the implementation chapter. The set of tools is determined by Wärtsilä’s energy feasibility tools platform, which will host the prototype application developed in the thesis. This implies that the protype application must use same programming languages, frame- works, and other tools as its host platform. The thesis, however, does not focus on de- ployment pipelines, although those are important part of software development. 3.1 Programming languages Programming languages describe computations to both machines and humans. Before a program can be run, the source code of the program written in some programming lan- guage must be translated into suitable form that can be executed by a computer. A com- piler is a software system that is responsible for this translation process. (Aho, et al., 2007, p.1) 21 The goal of a compiler is to translate a source program written in one language into an identical program written in the desired target language (see Figure 2). A compiler will also report errors that are found in the source program during the translation process. If the compiled target program is an executable, it can process user inputs to produce out- puts (see Figure 2). (Aho, et al., 2007, pp.1–2) Figure 2. Compiling a source program (a) and running the target program (b). (Reconstructed from Aho, et al., 2007, p.2.) A compiler is not the only type of language processor. An interpreter is another common language processor, which directly executes user inputs and instructions defined by a source program (see Figure 3). As opposed to a compiler, an interpreter does not produce target program as a translation. Typically, an interpreter is much slower mapping inputs to outputs compared to a machine-language target program that is produced by a compiler. However, since interpreters executes source programs a statement at a time, they can often give better error diagnostics than compilers. (Aho, et al., 2007, p.2) Figure 3. Directly executing a source program with user inputs by using an interpreter. (Modified from Aho, et al., 2007, p.2.) 22 3.1.1 Python Python is an interpreted and object-oriented programming language that is ideal for rapid application development and scripting. The language has a simple syntax and the programs written in Python are typically much more compact and readable compared to equivalent programs written in C or C++. Even though interpreted languages are not as fast as compiled languages, critical functions and modules that require speed can still be written in C or C++ and be used from Python interpreter. Therefore, Python can be used as command language or extension for applications written in compiled languages. (Van Rossum, 2003, p. 3) As a general-purpose language Python can be applied to wide variety of different prob- lems. For instance, Python is very popular in web development, data analytics, and ma- chine learning. In addition to being applicable, Python is also portable, running on Win- dows and several Unix variants including Linux and macOS (Python Software Foundation, 2022). 3.1.2 JavaScript JavaScript is a popular programming language that was designed and implemented ini- tially by Brendan Eich. Currently, JavaScript is used by majority of web pages. The goal of JavaScript is to allow web pages to dynamically customize their presentation according to user interactions. Despite the name, JavaScript and the programming language Java are not technically very similar. (Wirfs-Brock & Eich, 2020, pp. 2–4) However, in order to reduce the time that it takes to learn JavaScript concepts, its basic syntax was designed to be similar with languages such as Java and C++ (Mozilla, 2022a). JavaScript can be used as an interpreted or just-in-time (JIT) compiled language (Mozilla, 2022b). As opposed to standard compilation, in JIT compilation the program is not com- piled in advance. Instead, JIT compilation is done on demand, thus compiling only the 23 methods that are being executed. (Krall, 1998) Other important characteristic of JavaS- cript is that its functions are first class citizen, meaning they can be used in a same way as variables (Banks & Porcello, 2017, p. 32). Therefore, a function in JavaScript can be used as argument for another function, can be returned by different function, or can be assigned as a value to some variable. (Mozilla, 2022c) Both object-oriented and procedural programming are supported in JavaScript (Mozilla, 2022a). Object-oriented programming refers to a programming style that utilizes data abstraction and inheritance by using user-defined data types called classes. As opposed to object-oriented programming, in procedural programming the focus is on designing algorithms to perform computations. In procedural languages this is achieved by passing arguments to functions and returning arguments from functions. (Stroustrup, 1988, pp. 11, 13, 20) JavaScript conforms ECMAScript Language Specification (ECMA-262) (Mozilla, 2022b). This standard defines the data types, notational conventions, and other important spec- ifications (Ecma International, 2022). It is to mention, that the popular data interchange format called JavaScript object notation (JSON) has also its own standard (Ecma International, 2017). Despite the name, JSON is not dependent on JavaScript, meaning it can be used in other programming languages as well (Bassett, 2015, pp. 2, 4). 3.2 Databases A database is a collection of data, which typically contains relevant information to an organization. In order to access databases, a database-management systems (DBMS) must be utilized. DBMS consist of interrelated data and a set of programs that can be used to access this data. The goals of DBMS are managing large bodies of information, defining structure for stored information, allowing manipulation of information, and en- suring that the system is secure. (Silberschatz, et al., 2011, p. 1) 24 Databases are essential in every enterprise and are applicable in different situations. As an example, the database used in university can store information about the students’ grades and course registrations, whereas the database used in banking might store cus- tomer information such as banking transactions and loans. The ubiquity of databases means that almost everyone uses them. However, the users of databases might not be aware of this since they access databases through an UI that hides the details of this interaction. (Silberschatz, et al., 2011, pp. 2–3) Users are not typically directly interacting with the database systems. Instead, the re- mote database users are working on client machines connected to the server machine, on which the database system is running. Typically, a client machine acts only as frontend and does not contain any direct database calls. In this case the database calls are left to the responsibility of the application server, which can communicate with the database system. This type of architecture is called three-tier architecture (see Figure 4) and it is suitable for web applications. (Silberschatz, et al., 2011, pp. 23, 25) Figure 4. Three-tier architecture. (Modified from Silberschatz, et al., 2011, p. 25.) 25 3.2.1 Relational databases A relational data model utilizes a collection of tables to describe both the data as well as the relationships between these data tables. Basically, a relational database is just a col- lection of tables with unique names. Each of the database tables can have multiple of columns each having a unique name. The rows of a database tables describe relations among a set of values. (Silberschatz, et al., 2011, pp. 12, 37, 39) The link or relation be- tween two different tables is based on the data that is common to these tables. One benefit of a relational data model is that it increases organizations’ understanding about the relationships among the data that they are storing. (IBM Cloud Education, 2019) Relational databases can be accessed by using structured query language (SQL). Despite its name, SQL is used for several other purposes than just querying data. In addition to making queries, SQL can be used to define structure of the data, modifying data, or spec- ifying security constraints. SQL was originally developed in 1970s by IBM. Over time SQL has become the standard relational database language. (Silberschatz, et al., 2011, p. 57) 3.2.2 Data warehouses A data warehouse is a centralized repository of data. The data stored in a data warehouse is typically gathered from multiple different sources and can be analysed by using SQL queries (see Figure 5). (Silberschatz, et al., 2011, p. 885). There are various of reasons for an organization to use a data warehouse. Organizations might, for instance, have large amounts of data, but no easy way to access it. A data warehouse can allow easier way to access all the essential data from all around the organization. Since a data ware- house helps in the utilization of various data sources, it supports fact-based business decisions in organizations. (Kimball & Ross, 2002, pp. 2–3) 26 Figure 5. Typical data warehouse architecture. (Modified from Silberschatz, et al., 2011, p. 890.) 3.3 Frameworks and libraries Modern web development relies heavily on number of different libraries and frame- works. This section describes a typical set of tools used to develop both the backend and frontend functionalities of a web application. In this thesis frontend refers to the UI run- ning on a web browser. Backend in turn refers to the server, which provides services and resources to the frontend client. The communication between the frontend client and the backend server is done by using application programming interface (API) that utilizes HTTP requests and responses for communication. 3.3.1 Django Django is an open-source web development framework available for Python (Django Software Foundation, 2021). It offers high-level abstractions of typical web development patterns, thus saving developers’ time and making the web sites easy to maintain. 27 Furthermore, Django aims to reduce unnecessary repetition in web development. (Holovaty & Kaplan-Moss, 2009, pp. 3, 8) Django has a build in object-relational mapping (ORM) (Django Software Foundation, 2022). ORM allows the database tables to be read and modified by using object-oriented programming (Cvetković & Janković, 2010, p. 148). In Django Python objects mapping to database tables are called models. (Django Software Foundation, 2022). Django models allow developers to access, create, and modify database tables effortlessly without di- rectly writing SQL. However, Django still allows developers to write raw SQL queries when desired. It is possible to utilize Django as a web API. This means that Django can work as a backend server for a frontend client that is created by using some other framework and program- ming language. Web APIs can be created by using Django representational state transfer (REST) framework. REST is a popular architectural style used for designing networked applications (Zhou et al., 2014, p.358). The key functionalities of Django REST framework include serializers, view sets, and URLs. Serializers are capable of converting complex data and Django models into native Python datatypes that can be easily rendered into JSON (Encode OSS Ltd, 2021a). Both ORM and non-ORM data sources are supported by serializers (Encode OSS Ltd, 2022). View sets use Django models and serializers to create API endpoints that can be used to view or edit Django models. The web API can be accessed by using URLs, which are connected to view sets. (Encode OSS Ltd, 2021b) The architecture of Django REST framework is il- lustrated on the next page (see Figure 6). 28 Figure 6. Architecture of Django REST framework. (Modified from BezKoder, 2021.) Previous paragraphs described some of the backend functionalities of Django web framework and Django REST framework. In addition to backend functionalities, Django has also several tools such as forms and templates that can be used to build the frontend of a web application. In this thesis the frontend development is created with React and therefore Django frontend functionalities are not discussed further. It is to mention, however, that Django frontend tools are still important part of Django framework in sit- uations where a developer decides to utilize Django for both the backend and the frontend development. 3.3.2 React React is an open-source JavaScript library that is used for building interactive UIs. Typi- cally, an UI created with React is composed of several components that all have their own set of states. The changes in the states of React components will cause React to update and render these changes, thus making web pages interactive. (Meta Platforms, Inc., 2022a) 29 React uses so called JavaScript syntax extension (JSX) for describing how an UI should be displayed. JSX allows for combining both markup and logic into the same file. In React these units that contain both the logic and the markup are called components. (Meta Platforms, Inc., 2022b) Components are conceptually similar to JavaScript functions, meaning they accept inputs and return React elements that describe what should hap- pen in the computer screen as outputs. Components can be used to split the code de- scribing an UI into several independent and reusable units. (Meta Platforms, Inc., 2022c) As mentioned, React components have states that affect how the web page will be ren- dered. React components can be written as classes or hooks. Hooks are functional com- ponents that allow developers to use React features and states without writing tradi- tional classes. The problem with React classes is that they can become overly complex to work with over time. The goal of hooks is to allow simpler way to use states as well as reuse stateful logic between different components. (Meta Platforms, Inc., 2022d) As op- posed to React classes, hooks do not need, for example, a constructor or a separate ren- der function to function properly. (Meta Platforms, Inc., 2022e) 3.3.3 Semantic UI Web pages are created by using hypertext markup language (HTML). The structure of a web document is handled by using HTML tags. HTML tags can describe which part of a document is heading, paragraph, bulleted list, table, and so on. By structuring web pages with HTML tags, the readability of web documents is increased. Web browsers are capa- ble of processing HTML files and displaying the processed output to a user. (Larsen, 2013) Cascading style sheets (CSS) define the style of a web document. With CSS a developer can control, for example, the size and color of fonts and the space between items on a web page, making the appearance of the web page richer as opposed to plain HTML pages. In a nutshell, CSS determines a set of rules which control the appearance of an HTML page. CSS rules can be embedded into HTML documents. (Larsen, 2013) 30 Although HTML and CSS are important part of frontend web development, they can be- come laborious to work with. Semantic UI makes it possible for a software developer to write concise HTML when creating web pages (see Figure 7). At its core, Semantic UI serves as a theming framework, which increases the speed of designing web pages com- pared to using just plain HTML and CSS (Lukic, 2018). Semantic UI can be used together with JavaScript libraries such as React. Figure 7. Comparing Semantic UI with plain HTML. 31 3.4 Security 3.4.1 Authorization One of most essential parts of software development is to ensure that only authenti- cated users can use the software. OAuth 2.0 is an authorization framework that enables a third-party application to gain limited access to an HTTP service. The access can be granted on behalf of a resource owner by using an approval interaction between the HTTP service and the owner of the resource or alternatively by allowing the third-party application to gain access on its own behalf. (Hardt, 2012, p. 1) When a third-party application needs to access of restricted resource in the traditional client-server authentication model the resource owner must share its credentials with the third party. This causes several problems such as the third-party application is re- quired to save the resource owner’s credentials for later use and the third-part applica- tion gaining overly broad access to the resource owner’s resources. OAuth uses author- ization layer, which separates the role of the client from that of the resource owner, thus addressing the issues with the traditional client-server authentication model. (Hardt, 2012, p. 5) There are four different roles in OAuth. A resource owner is an entity, which can grant access to a protected resource. A resource server hosts the protected resource and can accept and respond to protected resource request by using an access token. A client is an application, which makes the protected resource request on behalf of the resource owner using its authorization. An authorization server issues access tokens to the client after the resource owner is successfully authenticated. (Hardt, 2012, p. 6) The abstract protocol flow of OAuth 2.0 is shown in Figure 8. Hardt (2012, p. 7–8) de- scribes the interaction between the four roles of OAuth 2.0 with the following steps shown on the next page: 32 a) First, a client sends an authorization request directly or via an authorization server to the resource owner. b) A resource owner sends an authorization grant, which is a credential expressing the resource owner’s authorization to the client. The authorization grant has type, which depends on the types supported by the authorization server and the method that the client uses to request authorization. c) The client uses the authorization grant to request an access token from an au- thorization server. d) The authorization server validates the authorization grant send by the client. If the authorization grant is valid, the authorization server issues an access token. e) The client uses the access token for authentication and request a protected re- source from a resource server. f) The resource server checks whether the access token is valid. If validation was successful, the client’s request can be served. Figure 8. The abstract protocol flow of OAuth 2.0. (Reconstructed from Hardt, 2012, p. 7.) 33 3.4.2 Encryption The security in classical encryption schemes relies on a secret key, which is shared by the communicating parties and is unknown to the possible eavesdropper. The same secret key is used for encrypting the plaintext as well as decrypting the ciphertext. The parties can be separated by distance assuming they have successfully shared the secret key (see Figure 9). In addition, an individual party can use private-key cryptography to communi- cate with itself securely over time (see Figure 10). (Katz & Yehuda, 2020) Figure 9. Two parties sharing a secret key to communicate privately. (Modified from Katz & Ye- huda, 2020.) Figure 10. A single user securely storing data. (Modified from Katz & Yehuda, 2020.) 34 There are several algorithms that can protect electronic data. One of the popular algo- rithms called advanced encryption standard (AES) specifies a symmetric block cipher ca- pable of encrypting and decrypting information. The goal of encrypting is to convert data to incomprehensible form. The encrypted ciphertext can later be decrypted back into its original form. The AES algorithm can use cryptographic keys of size 128, 192, and 256 bits to encrypt and decrypt data. Furthermore, AES process data blocks of size 128 bits, meaning the input and the output of the algorithm consist of sequences of 128 bits. (Dworkin, et al., 2001, pp. 1,7) 3.5 Energy feasibility tools platform Wärtsilä’s energy feasibility tools platform hosts applications that help users in several task related to power plant projects. A user can utilize this site, for example, to perform different calculations related to power plant solutions or examine components of the desired power plant base solution. Furthermore, calculations can be performed using different currencies. Energy feasibility tools platform utilized Django web framework for the backend server and React JS for the UI running on a web browser. The database related to the energy feasibility platform is running on Amazon cloud and is accessed with Django ORM. The communication between the backend and frontend is done by using Django REST Frame- work. The source code of the prototype application developed in this thesis will be inte- grated into energy feasibility tools platform’s codebase. Energy feasibility tools platform runs on three different runtime environments. Develop- ment environment is used to test and experiment recently developed features. Quality assurance environment is used to ensure that the new features are working properly. Finally, the production environment is used to run the production version of the software used by the end users. 35 4 Plan for the development process The goal of the prototype application is to utilize data stored on WDP. The first step of the application development process is to design and build connection between energy feasibility tools platform backend server and WDP. Next, corresponding Django models describing the relevant WDP data should be created. After models have been created, those should be transformed into proper format that can be utilized by a frontend user who sends HTTP requests to the backend API. The connection between the backend and frontend is established by utilizing Django REST framework. After the connection between backend and WDP has been established and when corre- sponding models describing the database tables are in suitable form, the frontend for the prototype application should be created. The frontend client will be programmed by using JavaScript, utilizing React and Semantic UI libraries. First step in the frontend development is to ensure that the users of the prototype ap- plication have an authorization to utilize relevant power plant project data. Oauth2.0 will be used for authenticating users. When the connection between frontend and backend is established, frontend should be able to receive relevant WDP data about power plant projects in JSON format. The data in the fetched JSON is then used to create the UI for the prototype application. The steps for developing the application are the following: 1. Establish connection between feasibility platform backend and WDP. 2. Program backend functionalities for the WDP data. a. Create Django models that map to WDP tables. b. Program Django REST API functionalities. c. Write backend functionalities for authentication. 3. Program frontend functionalities for the application. a. Build functionalities to authenticate users. b. Create the required React components and the UI. 36 The development process described on the previous page starts by first designing the entire system. The design phase is shown in the next chapter, and it defines the required database tables, user requirements, structure, logic, and authentication process needed to create the prototype application. In addition, the design chapter describes the idea behind the backend server functionalities and the frontend UI. By using the design deci- sion made in the design chapter, the actual implementation of the prototype application can begin. The implementation phase is shown in chapter 6. The implementation chap- ter aims to illustrate the relevant source code needed to program the application devel- oped in this thesis. 37 5 Design of the application This chapter describes the design process of the prototype application. First, the re- quired WDP database tables are described. After the relevant data has been discussed, the requirements for the application are defined. With the help of the requirements, the design of high-level structure, authorization, and logic for the new application are illus- trated. Moreover, design decisions for both the backend and frontend are described. The design decisions made in this chapter will be used to as a base for the implementation phase shown in next chapter. 5.1 Starting point 5.1.1 Data Wärtsilä power plant project data will be used as the starting point of the design process. The required data is stored on WDP, which is a data warehouse utilizing Amazon Redshift technology. WDP stores information about various projects from around the organiza- tion. The database tables of interest with simplified names in this thesis are:  Opportunity  Quote  Configurable  BOMEdit (bill of material that has been edited)  BOMItemEdit (an edited item in the bill of material list)  Contract These database tables have rather complex relationships (see Figure 11). The complexity of these tables has increased over time, meaning that some of the database tables have been added just recently and the data that they store might have been presented in some other way in the past. New columns are also frequently added to these tables. 38 Figure 11. Simplified illustration of the database tables of interest (tables have hundreds of col- umns and therefore not all the column names are displayed in the image). As Figure 11 illustrates, a Salesforce opportunity object can have multiple Salesforce quotes, but a quote object is always related to only one opportunity. Furthermore, BOM 39 object can have several BOM items, but a BOM item must always be related to only one BOM. In addition, Salesforce configurable object has link to opportunity, quote, BOM, and contract objects. Configurable object can store multiple ids of these objects, while these objects are always related to only one configurable object. Since configurable ob- ject has links to several tables, the id values that it stores can be used, for instance, to fetch data from these other tables. In this thesis the previously described database ta- bles will be accessed by utilizing ORM. 5.1.2 Requirements The goal of the prototype application is to allow sales personnel working in power plant project sales to compare different power plant solution quotes with one another. In addition, a user should be able to examine the details of individual quotes. When the application starts, a user should be able to filter the list of comparable projects and choose the desired projects for comparison. When a user has added the desired power plant projects to the compare list, the user should be able to compare both the contract data and the area costs of the selected quotes. The contract data holds information about the sales price, currency, and margin of the selected project. In addition, total cost, onshore cost, and offshore cost of the project is stored in the contract data. Onshore cost includes all the costs in the power plant site location country, whereas offshore cost refers to the costs outside the site location coun- try. Total cost is the sum of these two before mentioned costs. The area costs of a power plant project in turn stores information how much each area of a power plant project costs. Different areas can include, for instance, engine hall, spare parts, project manag- ing, and piping. Since the users of the prototype application utilize sensitive sales data, it is crucial that they are authenticated. This implies that, some kind of authorization framework must be utilized. The Summary of the requirements is shown on the next page. 40  Allow a user to filter the list of power plant sales projects and choose projects for comparison based on the projects’ country, scope of supply, stage, and other relevant information.  Compare contract data and area cost between different quotes.  Allow user to examine the details of individual quotes.  Ensure that only authenticated users can access the data. 5.2 High-level design of the system 5.2.1 Structure of the system Energy feasibility tools platform currently uses only one database. Since the new appli- cation needs data stored on WDP as well, the application server should also be con- nected to WDP (see Figure 12). After the server has been connected to WDP, the frontend client can access data from two different database via the backend server. Figure 12. High-level view of the system. 41 As Figure 12 on the previous page demonstrates, the system consists of a frontend client and a backend server. The purpose of the frontend client is to serve as a UI for the user, whereas the backend server queries data from the connected databases (in this thesis from WDP). The backend server also formats and sends the received data back to the frontend client, where it can be displayed for the user in some suitable format. 5.2.2 Authorization design The users of the prototype application must be authenticated before they can access and compare power plant solution data. In this thesis OAuth 2.0 framework is used to authenticate users. The authorization process illustrated in Figure 13 on the next page is done in the following steps: a) The frontend client sends an authorization request to Salesforce API authoriza- tion endpoint. b) Salesforce API then sends an authorization code as a response back to the client. c) After receiving the authorization code, the frontend client sends it to the backend server. d) The backend server redirects the received authorization code to Salesforce API token endpoint. e) If the authorization code is valid, an access token is sent back to the backend server. f) By using the access token, the backend server request user information from Salesforce API user info endpoint. g) Salesforce API returns a response containing requested user information. The au- thentication program running on the backend server can then use the received user information to authenticate the user. h) If the user is allowed to access the power plant solution data, the backend server will fetch the list of power plant project quotes from WDP. i) WDP will return a list of quotes specified in a query made by the backend server. 42 j) The backend server will send the received quotes to the frontend client, where the user can examine and compare these quotes. Figure 13. Authenticating a user and fetching power plan project quotes. 5.2.3 Logic behind the user interface Authorized users of the protype application will be directed to a page where power plant project quotes can be examined and selected. If a user has no authorization to access WDP, the user is prevented from using the application. Users can filter the list of power plant project quotes by country, scope of supply, engine type, or other relevant infor- mation. Furthermore, users can add the desired quotes to a comparison list. The appli- cation should have a button that could be used to open a new view that displays the 43 comparison of the quotes on the comparison list. The user should also be able to exam- ine details of individual quotes by clicking on the name of the quote. Figure 14 illustrates the flowchart of the high-level logic of the UI. Figure 14. Flowchart describing the high-level logic of the user interface. 44 5.3 Backend design It is not necessary to write raw SQL queries to read data from WDP data warehouse. Instead of directly using SQL queries, ORM can be utilized. This means that one must only define Django models in Python code in order to map those objects to database tables and query the data (see Figure 15). Furthermore, it is not mandatory to define every single column in a database table in the corresponding Python object. In this thesis the goal is to use only the power plant data that is the most relevant for developing the prototype application. Figure 15. Mapping a Python class containing quote data to the corresponding database table in WDP. The design of the Django models in the backend defines, which database columns must be fetched from WDP. Some of the columns can be used for filtering, whereas others hold otherwise useful information (see Table 1). 45 Table 1. Relevant model fields mapping to WDP. The user of the prototype application should be able to use some of these fields to filter the list of power plant quotes. Field name Purpose Explanation WDP table name info Name of the business oppor- tunity Opportunity scope filter Scope of supply Quote stage filter Current stage of the project Opportunity sales_region filter Europe, Asia, etc. Opportunity country filter Destination country Opportunity engine_type filter Gas engine, diesel engine, etc. Quote engine_quantity filter - Quote business_line filter Type of power plant (engine plant or energy storage) Opportunity main_fuel filter - Quote back_up_fuel filter - Quote MW_electrical info Electrical power Opportunity close_date info The close date of the project Opportunity primary info Primary quote (True/False) Quote configurable id A field used to fetch cost and sales price data from Contract objects Configurable bom_edit id A field used to fetch data from BOMItemEdit objects to con- struct the sum of different area costs Configurable The fields presented in Table 1 are useful for displaying the initial list of power plant quotes that is displayed for the user of the application. More detailed comparison data about contracts and BOM items can be fetched by using id values located at the end of Table 1 when user adds a quote to the comparison list. Contract data holds information about project’s cost and sales price, whereas BOM item data can be used to construct the sum of different area costs. 46 5.4 Frontend design 5.4.1 User interface design After fetching the relevant power plant solution data, the UI of the prototype application can be rendered. The main view in the application should contain the list of quotes that can be compared. By using an interactive table, a user can examine interesting power plant project quotes and add those to a comparison list (see Figure 16). The main view should also include buttons that can be used to direct users to comparison view, reset- ting table filters, and clearing the comparison list. Furthermore, users should be able to filter the list of quotes by clicking on the table headers (see Figure 17). Figure 16. The table for selecting powerplant project quotes. 47 Figure 17. Filtering the list of quotes by clicking the table header and selecting filters. After a user have selected the desired quotes and added those to the comparison list, the user should be able to open a modal to display the comparison between the selected quotes. The comparison modal can be opened by pressing the comparison button shown in Figure 16. This comparison modal should have a tab from which two different compare views could be opened (see Figure 18). The first view in the comparison modal could be used to compare the quote details and contract data between the projects on the comparison list. As mentioned before, con- tract data holds information about the sales price, margin, and costs of a power plant project. The second view could be used to compare the area costs between different quotes. By comparing the area costs users could examine how the costs in different pro- ject areas such as engine hall, electrical equipment, project management differ in the selected quotes. 48 Figure 18. By clicking compare button the quotes on the comparison list can be compared with one another. A user can either compare contract details or area costs. In addition to comparing different quotes, users should be able to examine the details of individual quotes. For this reason, users should be directed to a new page containing the quote details when clicking the name of the quote in the quote selection table (see Fig- ure 19). 49 Figure 19. Quote details can be examined by clicking on the name of the quote. This process directs a user to a new page, which displays the details of the selected quote. 5.4.2 Required React components The UI of the prototype application is constructed from several React components. In this thesis only functional components (React hooks) are used, meaning there is no need to write classes in the frontend code. The implementation details of the components are shown in the next chapter. A React component called SalesforceAuth is used for authenticating users. If a user has rights to use Salesforce data, authentication component will redirect the user to a new component called QuoteBrowserPage, which has several children. 50 QuoteSelectionTable component is one of the children of QuoteBrowserPage. QuoteSe- lectionTable will display the fetched Salesforce quotes and allow users to select them for comparison. Furthermore, QuoteSelectionTable has a link to another component called QuoteDetail. In addition to QuoteSelectionTable, QuoteBrowserPage has also another child component called QuoteComparisonModal. This modal has one child component called QuoteComparisonTable, which will display the comparison for selected quotes. Overall, six different JavaScript files must be written to create the required components (see Figure 20). Figure 20. The required React components. 51 6 Implementation of the application This chapter describes the required source code used to build the prototype application. Since the prototype consist of both the server and client, the codebase is relatively large. Therefore, not every single line of the source code is demonstrated in this thesis. Espe- cially the React components used to create the UI, error handling, and different utility functions are not described in the most detailed way possible. Furthermore, some parts of the source code might include sensitive information and for this reason few of the implementation details are left out from this document. 6.1 Backend code 6.1.1 Connecting to Wärtsilä data platform The first step in the backend development is to create a connection between energy feasibility tools platform and WDP. The new application shall be named as quote browser. Creating a new application in Django can be done with the following command: python manage.py startapp quote_browser This command invokes Python interpreter to run Django utility program that creates a new application in the specified directory. After the new application has been created, the connection with WDP should be established. The next step is to add new database and database router into Django project’s settings file (see Algorithm 1). The parameters for WDP database are read from a file storing the project’s environmental variables. After the new database router and database have been defined in the settings file, the actual code for the new database router must be written. Django will always implicitly use the default database router, if not otherwise defined. Therefore, any other database routers must be explicitly defined. Next, let us define a new database router class, which 52 is used whenever the new quote browser application must fetch data from WDP (see Algorithm 2). DATABASE_ROUTERS = ('quote_browser.models.WdpRouter',) DATABASES = { # ..., 'wdp': { 'ENGINE': 'django_redshift_backend', 'HOST': env('WDP_HOST'), 'NAME': env('WDP_NAME'), 'USER': env('WDP_USER'), 'PASSWORD': env('WDP_PASSWORD'), 'PORT': env('WDP_PORT'), }, } Algorithm 1. Django settings for WDP connection. class WdpRouter: def db_for_read(self, model, **hints): if model._meta.app_label == 'quote_browser': return 'wdp' def db_for_write(self, model, **hints): if model._meta.app_label == 'quote_browser': return False def allow_migrate(self, db, app_label, model_name=None, **hints): if app_label == 'quote_browser': return False Algorithm 2. The database router class for WDP connection. The new database router should only allow feasibility tools backend to read data from WDP. Therefore, writing or migrating data to WDP is forbidden. Since Django labels each of its applications, it is possible to define that the connection to WDP is made only by the applications with a certain label. This functionality allows the new application to con- nect to WDP instead of the default database whenever data is requested for reading. 53 6.1.2 Django models In Django ORM each model maps to a database table. In this thesis each Django model maps to a database table stored in WDP. Salesforce database tables located in WDP have hundreds of columns and not every one of those are needed for the application devel- oped in the thesis. Fortunately, Django makes it possible to map only to some of the database columns. Furthermore, the name of the model can differ from the correspond- ing database table name and the model fields can also have different names than the columns in the mapped database. Algorithm 3 describes the required Django models. class Opportunity(models.Model): # Define Opportunity model fields here class Meta: # Define Opportunity meta options here class Quote(models.Model): # Define Quote model fields here class Meta: # Define Quote meta options class Configurable(models.Model): # Define Configurable model fields here class Meta: # Define Configurable meta options here class Contract(models.Model): # Define Contract model fields here class Meta: # Define Contract meta options here class BomItemEdit(models.Model): # Define BomItemEdit model fields here class Meta: # Define BomItemEdit meta options here Algorithm 3. The required Django models mapping to database tables in WDP. To successfully map an object to a database, Django needs to be informed about the original column name of the object field (in case it differs from the new name). The code snippet describing this functionality is demonstrated on the next page. 54 class Quote(models.Model): scope = models.CharField( db_column='original name of scope here', max_length=30 ) # ... In addition to defining the original column name for the model fields, the name of the original database table must be defined in the meta class of the model: # Inside Quote class: class Meta: db_table = 'original name of database table here' Since the database tables can have relations with one another, those must also be de- fined in the Django models. As an example, Salesforce Quote object has many-to-one relationship with Salesforce Opportunity object. In Django many-to-one relationship is defined with foreign key: class Quote(models.Model): opportunity = models.ForeignKey( Opportunity, on_delete=models.CASCADE, db_column='opportunity__c' ) # ... 6.1.3 Django web application programming interface After Django models have been constructed, the functionalities allowing a frontend cli- ent to access data from the backend server needs to be created. Django REST framework uses URLs, serializers, and view sets to handle HTTP requests, query data, format data, and send HTTP responses back to the client. Django serializers allow transferring query set data into Python datatypes, which can be then rendered to content type such as JSON. The backend server should be able format and return three different HTTP responses (fetch quote, contract, and area cost data). 55 Algorithm 4 describes the basis for the required model serializers used to format query set data before it can be sent back to a frontend client. class QuoteSerializer(serializers.ModelSerializer): class Meta: # Define QuoteSerializer meta options here class ContractSerializer(serializers.ModelSerializer): class Meta: # Define ContractSerializer meta options here class BomItemEditSerializer(serializers.ModelSerializer): class Meta: # Define BomItemEditSerializer meta options here Algorithm 4. The required Django model serializers. A model serializer classes are based on Django models. The meta class of model serializer defines the related model as well as the model fields that should be included when send- ing data back to a client. Algorithm 5 demonstrates how the model and field names can be defined inside the meta class. # Inside QuoteSerializer class: class Meta: model = Quote # <- serializer is based on Quote model fields = [ # <- the fields that will be sent to client 'name', 'scope', 'stage', 'sales_region', 'country', 'engine_type', 'configurable', # ... ] read_only_fields = fields Algorithm 5. Specifying the related Django model and the fields that will be included in the data that is sent as a response to a frontend client. If a serializer field is in another model instead of the model defined in the meta class, its source must be defined. This is demonstrated on the next page. 56 class QuoteSerializer(serializers.ModelSerializer): # this field is located in Opportunity object country = serializers.CharField( source='opportunity.country', read_only=True ) # ... It is possible to modify the values of the model fields in serializers. To achieve this, seri- alizer method field can be used to define set of rules that can change the output of a given Django model field. As an example, encryption function can be applied to the field containing configurable id: class QuoteSerializer(serializers.ModelSerializer): # ... configurable = serializers.SerializerMethodField() def get_configurable(self, obj): return encrypt(obj.configurable.id) A frontend user of the application does not have to know the real id values of configura- ble and BOM objects. Therefore, encryption and decryption functions are created. The encryption function (see Algorithm 6) is used to encrypt the id values of configurable and BOM fields before they are sent to the frontend client. The encrypted id values are later used to fetch contract and area cost data. To fetch correct data the id values must be decrypted (see Algorithm 7). The encryption functions are written with the help of PyCryptodome, which is a cryptography package available for Python. def encrypt(text): # Add padding to input str so its size is multiple of 16 text = pad(text.encode(), AES.block_size) # Create AES object with secret key by using # Ciphertext Block Chaining mode cipher = AES.new(settings.AES_KEY.encode(),AES.MODE_CBC) # Return encrypted url-safe str with initial vector # (replace chars '/' and '+' with '_' and '-')) return base64.b64encode(cipher.iv + cipher.encrypt(text), b'_-').decode() Algorithm 6. Encrypting id values. 57 def decrypt(text): # Decode url-safe input str text = base64.b64decode(text.encode(), b'_-') # Initialization vector is the first 16 bytes of input iv = text[:AES.block_size] # Create similar AES object as in encrypt function cipher = AES.new(settings.AES_KEY.encode(), AES.MODE_CBC, iv) # Remove padding and return decrypted str # (input text after 16 bytes) return unpad(cipher.decrypt(text[AES.block_size:]), AES.block_size).decode() Algorithm 7. Decrypting encrypted id values. After Django models and serializer have been created, the view sets informing how Django ORM should query data and which serializer should be used to format that data must be defined. Django view set can return the data as a HTTP response. In this thesis three view sets are needed (see Algorithm 8). class QuoteViewSet(viewsets.ViewSet): # Check whether user is authenticated and retrieve # the list of power plant project quotes here class ContractViewSet(viewsets.ViewSet): # Decrypt configurable object id defined in HTTP request # and retrieve Contract object with this id here class BomItemEditViewSet(viewsets.ViewSet): # Decrypt BOMItem object id defined in HTTP request and # retrieve the sum of BOM items in different areas here Algorithm 8. The required Django ViewSets. Next, let us concentrate on QuoteViewSet, which is used to fetch the initial list of power plant project quotes. Algorithm 9 on the next page defines what type of query should be made to WDP (no raw SQL queries needed). After the query has been made a model serializer is used to format the received data. The formatted data is then sent back to the client as an HTTP response. The resulting HTTP response is used to construct the first view of the UI displayed in the frontend client. 58 # Inside the POST function of QuoteViewSet class: scopes = ['Basic EEQ', 'Extended EEQ', 'EPC', 'Process EPC'] stages = ['Tailor', 'Negotiate', 'Finalize', 'Closed Won', 'Closed Lost'] queryset = Quote.objects.select_related( 'opportunity', 'configurable', ).filter( primary=True, configurable__isnull=False, configurable__bom_edit__isnull=False, scope__in=scopes, opportunity__stage__in=stages, ).prefetch_related( 'configurable__contract' ).filter( configurable__contract__type='Total', configurable__contract__margin_amount__isnull=False, ).order_by('-opportunity__close_date') serializer = QuoteSerializer(queryset, many=True) return Response(serializer.data) Algorithm 9. Fetching power plant solution data used in the prototype application. After Django models, serializers, and view sets have been constructed, let us define three endpoints to which a frontend client can make HTTP requests (see Algorithm 10). The endpoints are defined by using Django URLs, which are connected to earlier demon- strated Django view sets. The first URL is used to fetch the initial list of quotes. The two other URLs are utilized to fetch contract and BOM item data. router = routers.DefaultRouter() router.register(r'quotes', views.QuoteViewSet, base name='quote') router.register(r'contracts', views.ContractViewSet, basename='contract') router.register(r'bomitems', views.BomItemEditViewSet, basename='bomitemedit') app_name = 'quote_browser' urlpatterns = router.urls Algorithm 10. The required URLs for requesting data from the backend server. 59 6.1.4 Backend functionalities for authentication Users must be authenticated before they can access WDP data. The authentication pro- cess starts initially from the frontend client, which requests an authorization code. This authorization code is then sent to the backend server. In the backend server the authorization code is used to request an access token from Salesforce API. After the access token has been received it is in turn used to request user information. The user data can be then used to validate the user. The authentication process is done in QuoteViewSet before the WDP data is queried (See Algorithm 11). # Inside of the POST function of QuoteViewSet auth_code = request.data['code'] access_token = None authenticated = None if auth_code: access_token = sf_request_access_token(auth_code) if access_token: authenticated = sf_authenticate_user(access_token) if authenticated: # Make the database query and return response # as described earlier in Algorithm 9 else: # Return empty response Algorithm 11. The authentication process in the backend server. Let us focus on some of the details shown in Algorithm 11. As described, an authorization code is included in a POST request send by the frontend client. This code is then used as a parameter for the function that requests an access token from Salesforce (see Algo- rithm 12). In order to get appropriate access token, the application that is making the request must have appropriate client id, secret, and redirect URLs. These parameters were received from Salesforce before the prototype application was developed. 60 def sf_request_access_token(auth_code): token_endpoint = 'url of token endpoint here' body = { 'grant_type': 'authorization_code', 'code': auth_code, 'client_id': settings.SF_CLIENT_ID, 'client_secret': settings.SF_CLIENT_SECRET, 'redirect_uri': settings.SF_REDIRECT_URL, } response = requests.post(url=token_endpoint, data=body) if response.ok: return response.json().get('access_token') else: return False Algorithm 12. The function used to request an access token for a user. The actual function for authenticating users takes the access token returned by Algo- rithm 12 as an input and uses this token to request user data from Salesforce user infor- mation endpoint (see Algorithm 13). This user data is used to determine whether the user can access WDP data. It is to mention that the details of the user validation per- formed in Algorithm 13 are intentionally left out from this document. def sf_authenticate_user(access_token): headers = { 'Authorization': f'Bearer {access_token}', } user_endpoint = 'url of user info here' user_info = requests.get(url=user_endpoint, headers=headers) # Determine whether user has the right to use # Salesforce data from the user info if valid_user(user_info): return True else: return False Algorithm 13. The function used to authenticate users. 61 6.2 Frontend code 6.2.1 Frontend functionalities for authentication The first step in the frontend development is to ensure that users are authenticated. After the authentication process, the user will be redirected to the web page where the list of power plant quotes will be rendered. The functional React component and its states used for the authentication is shown below: function SalesforceAuth() { const [isError, setIsError] = useState(false) const [errorMessage, setErrorMessage] = useState('') const [quotes, setQuotes] = useState(null) // ... } SalesforceAuth component has three states. Changes in the values of these states will cause React to update and re-render the web page. SalesforceAuth component will try to search an authorization code parameter from the URL of the current page. If the com- ponent cannot find the authorization code, it will try to make HTTP redirect to Salesforce authorization endpoint and request this code (see Algorithm 14). // Inside SalesforceAuth component: const params = new URLSearchParams(window.location.search) const authorizeCode = params.get('code') if (authorizeCode === null) { let authorizeURL = new URL('authorize endpoint here') let authorizeParams = authorizeURL.searchParams authorizeParams.append('client_id', clientID) authorizeParams.append('redirect_uri', redirectURL) authorizeParams.append('response_type', 'code') window.location.href = authorizeURL } else { // Send authorization code to backend and fetch quotes } Algorithm 14. HTTP redirect to authorization endpoint. 62 The process described in Algorithm 14 will cause SalesforceAuth component to change the URL of the current page. The URL will be changed to Salesforce authorization URL, which will include the authorization code. This will cause the React component to update. After SalesforceAuth component can find the authorization code from the URL, the code variable defined in SalesforceAuth will not be null anymore and therefore this compo- nent can make POST request including the authorization code to the backend server, where the rest of the OAuth 2.0 process takes place (see Algorithm 15). // If URL param code is not null: let base = 'base url of energy feasibility platform' // This URL was defined in the backend code (Django URLs): let apiURL = new URL('/quote_browser/api/quotes/', base) let apiParams = { headers: new Headers({ 'Content-Type': 'application/json' }), method: 'POST', body: JSON.stringify({authorizeCode}) // send the code } fetch(apiURL, apiParams).then(response => { if (response.status !== 200) { throw Error(response.statusText) } return response.json() }).then(data => { if (data.length === 0) { setIsError(true) setErrorMessage('No access to Salesforce data') } else { setQuotes(data) // <- use power plant project data } }).catch(err => { setIsError(true) setErrorMessage(String(err)) }) Algorithm 15. Sending an authorization code to the backend server, which will complete the rest of the OAuth 2.0 process and then return the list of power plant project quotes. If the authentication process continued in the backend server was successful, the data will be queried from WDP and returned back to the frontend client. During the authen- tication process, however, a loader must be shown to a user to indicate that the authen- tication process is taking place. The code for the loader is shown on the next page. 63 {loadingMessage} After the quotes are successfully fetched, the state called quotes will change, thus up- dating SalesforceAuth component. If the list of quotes is not null and its size is larger than zero, the user will be redirected to the URL of QuoteBrowserPage component, which will display the UI of the prototype application. The list of quotes fetched from WDP will also be included when redirecting the user to the new page: if (quotes !== null && quotes.length !== 0) { return ( ) } 6.2.2 Implementing the user interface After authentication and fetching the list of quotes, the user is directed to a React com- ponent called QuoteBrowserPage. This component will receive the list of power plant quotes as an input (props). QuoteBrowserPage component is also be used to define func- tions, values, and states used inside its child components. The variables and states used in QuoteBrowserPage are the following: function QuoteBrowserPage(props) { const quotes = props.location.state const filterValues = getQuoteFilterValues(quotes) const quoteFilters = getQuoteFilters(quotes) const [filters, setFilters] = useState(quoteFilters) const [compareQuotes, setCompareQuotes] = useState(null) // ... } Filters (scope, country, engine type, etc.) and filter values (for example, scope filter has filter values: EEQ, EPC, etc.) of QuoteBrowserPage can be constructed from the list of 64 input quotes. This implies, that when new filters or filter values will be added in the future, these changes can be made by only modifying the backend server code. The frontend UI will automatically adapt to these changes. In addition to variables and states, QuoteBrowserPage has several functions (see Algorithm 16). These functions can be passed as an input parameter to the child components. function QuoteBrowserPage(props) { // ... function setFilter(filter, name, isFiltered) {} function setFilterAll(filterName, filters) {} function resetFilters() {} function filterQuote(quote) {} function addCompareQuote(configurableId, data) {} function removeCompareQuote(configurableId) {} function clearCompareQuotes() {} function fetchComparisonData(quote) {} } Algorithm 16. Function declarations in QuoteBrowserPage component. Next, let us examine some of the functions shown in Algorithm 16. As mentioned, a user should be able to filter the list of power plant project quotes. Updating filters can be done with the following function, which changes the state called filters in QuoteBrowser- Page component: function setFilter(filter, name, isFiltered) { setFilters(prevFilters => ({ ...prevFilters, [filter]: { ...prevFilters[filter], [name]: isFiltered } })) } In addition to displaying and filtering data, the application should have functionalities to compare data. Comparison data about contracts and area costs can be fetched from the backend server by using configurable and BOM id values received in the quote data (see Algorithm 17). In addition to other functionalities, QuoteBrowserPage should also be able to render the main view of the application (see Algorithm 18). 65 function fetchComparisonData(quote) { let abortController = new AbortController() let signal = abortController.signal // Use encrypted configurable id to fetch contract data const configrableId = quote.configurable // Use encrypted BOMEdit id to fetch area cost data const bomEditId = quote.bom_edit Promise.all([ FeasibilityApiClient.getSalesforceContracts( configrableId, signal), FeasibilityApiClient.getSalesforceBomItemEdits( bomEditId, signal) ]).then(([contracts, areaCosts]) => { const cleanedContracts = cleanContractData(contracts) const cleanedAreaCosts = cleanAreaCostData(areaCosts) const merged = {...quote, ...cleanedContracts} const compareQuote = { contract: merged, area: cleanedAreaCosts } addCompareQuote(configrableId, compareQuote) }).catch(err => console.log(err)) } Algorithm 17. Fetching and cleaning comparison data fetched from the backend server. return (