Ylläpitodokumentti

Ohjelmistotuotantoprojekti TAHKO (syksy 2001)

Heikki Hiltunen

Tero Kallio

Anu Leponiemi

Piia Porvali

Petri Savolainen

Janne Savukoski


Sisällys

1. Tietokanta-osajärjestelmä
1.1. DBSlave
1.1.1. getConnection
1.1.2. getFromDatabase
1.1.3. getPageLogic
1.1.4. getLogicXSL
1.1.5. getStringFromURL
1.1.6. login
1.1.7. loadOffer
1.1.8. saveOffer
1.1.9. updateOffer
1.1.10. getSellerAndCustomerIds
1.1.11. arrayToVector
1.2. DBResult
1.2.1. getRowCount
1.2.2. getColumnCount
1.2.3. getObject
1.2.4. getString
1.2.5. getInt
1.2.6. getDouble
1.2.7. toXML
1.2.8. toDOM
2. Filtteri-osajärjestelmä
2.1. XMLFilter
2.2. DependencyFilter
2.3. ProductItem
2.4. ProductFactory
2.5. DependencyFactory
2.6. DependencyRule
2.7. DependencyCore
2.8. ItemNode
3. Servlet
3.1. Servlet
4. Apache
4.1. FopWrapper
4.2. XmlProcessor
4.3. TomcatWrapper
5. Käyttöliittymä
5.1. Perus-XML
5.1.1. Tagit
5.2. Tarjous-XML
5.2.1. Tagit
5.3. XSL
5.3.1. Asiakashakutulosten näyttäminen
5.3.2. Tuotehakutulosten näyttäminen
5.3.3. Tarjouksen senhetkisen tilanteen näyttäminen
5.4. Java-skriptit
5.4.1. Tuotteiden hintojen laskeminen
5.4.2. Tuotteen lisääminen
5.4.3. Tuotteen poistaminen
5.4.4. Asiakkaan lisääminen tai vaihtaminen

Luku 1. Tietokanta-osajärjestelmä

1.1. DBSlave

Luokka, joka hoitaa tietokannan kanssa kommunikoinnin. Luokka on toteutettu staattisena kirjastoluokkana, mutta koska se tarvitsee erinäisiä parametreja JDBC-yhteyden muodostamiseen, täytyy ne asettaa setDBServer-metodilla, ennen kuin muita metodeita voidaan käyttää. Metodi asettaa kaikki tarvitavat parametrit staattisiin muuttujiin ja rekisteröi JDBC-ajurin.

1.1.1. getConnection

on luokan sisäiseen käyttöön ja palauttaa tietokantayhteyden.

1.1.2. getFromDatabase

Metodi hakee tietoa tietokannasta. Soveltuu yksinkertaisiin tietokantahakuihin. Rakentaa saamiensa parametrien perusteella SQL-kyselyn ja muodostaa saadusta ResultSetistä DBResult-olion (tämä sen takia, että käytetty tietokantayhteys luodaan ja suljetaan metodin sisällä, eikä JDBC takaa että ResultSetiä voidaan enää käyttää yhteyden sulkemisen jälkeen). Virhetilanteen kohdatessa tuotetaan DBException. Finally-haarassa varmistetaan, että kaikki tietokantaresurssit varmasti vapautetaan.

1.1.3. getPageLogic

Metodi hakee sivun logiikka XML:än. Ensin haetaan logicxml-taulusta XML:n URL käyttäen getDromDatabase-metodia. Tämän jälkeen haetaan itse XML URLin osoittamasta paikasta käyttäen apumetodia getStringFromURL. Virhetilanteissa tuotetaan DBException.

1.1.4. getLogicXSL

Kuten getPageLogic, mutta URL haetaan logicxsl-taulusta.

1.1.5. getStringFromURL

Metodi avaa URL-yhteyden annetulla URLilla ja lukee sen sisällön merkkijonoon. Ei sisällä mitään virheenkäsittelyä. Tarkoitettu sisäiseen käyttöön (getPageLogic ja getLogicXSL).

1.1.6. login

Metodi tarkastaa käyttäjän sisäänkirjautumisen. Yrittää hakea myyjätietoja contact-taulusta annetun käyttäjänimen ja salasanan perusteella. Mikäli mitään ei löydy, tuotetaan InvalidLoginException. Jos tiedot löytyvät, ne palautetaan.

1.1.7. loadOffer

Metodi lataa tietokantaan talletetun tarjouksen. Tarjous on offer-taulussa XML-muodossa. Mikäli mitään ei löytynyt, tuotetaan DBException.

1.1.8. saveOffer

Metodi tallettaa tarjouksen tietokantaan. Tarjous annetaan metodille XML-muodossa, joten pystyäkseen asettamaan offer-taulun contact_id- ja customer_id-kentät, metodin täytyy kaivaa ne ensin ulos XML:stä. Tähän käytetään apumetodia getSellerAndCustomerIds. Tämän jälkeen kyseiset ID:t, aikaleima sekä annettu tarjouksen XML talletetaan XML-tauluun INSERT-lauseella.

1.1.9. updateOffer

Metodi päivittää tarjousta, joka on jo talletettu tietokantaan. Muuten kuten saveOffer, mutta käyttää tietojen talletukseen UPDATE-lausetta.

1.1.10. getSellerAndCustomerIds

safeOfferin ja updateOfferin käyttämä apumetodi, joka parsii seller_id- ja customer_id-kentät tarjousXML:ästä. Tämä tapahtuu rakentamalla XML:stä DOM-puu ja hakemalla siitä kyseiset elementit.

1.1.11. arrayToVector

Tämä on yksinkertainen apumetodi, jota käytetään joissain metodeissa mukavuussyistä getFromDatabase-metodia kutsuttaessa. Se rakentaa taulukosta vektorin.

1.2. DBResult

Luokka tietokantahakujen tuloksien palauttamiseen. Kopioi jossainmäärin ResultSetin yleistä toiminnallisuutta. Sisältää rivejä ja sarakkeita, joissa tietoa Object-olioina. Tietoja voi hakea joko yksitellen tai muuttamalla koko tuloksen XML:äksi. Tuloksen voi muutta myös DOM-puuksi. Tiedot ovat talletettu sarakkeita vastaaviin vektoreihin. Sarakevektorit taas ovat laitettu hajautustauluun, josta ne saa sarakkeen nimen perusteella.

Konstruktorissa annetaan hakutuloksen sisältävä ResultSet ja taulun nimi, josta tulos saatiin. Luo sarakevektorit ja hajautustaulun. Laskee rivit ja sarakkeet.

1.2.1. getRowCount

Metodi palauttaa rivien määrän.

1.2.2. getColumnCount

Metodi palauttaa sarakkeiden määrän.

1.2.3. getObject

Metodi palauttaa annetulta riviltä ja sarakkeelta löytyvän Objectin. Metodista on kaksi versiota, joista toisessa sarakkeeseen viitataan nimellä ja toisessa indeksillä. Jos sarakkeen nimi tai indeksi on virheellinen tuotetaan NoSuchColumnException. Jos rivin indeksi on virheellinen tuotetaan NoSuchRowException.

1.2.4. getString

Metodi palauttaa annetulta riviltä ja sarakkeelta löytyvän arvon merkkijonona. Arvo haetaan ensin kutsumalla getObject-metodia. Merkijonoksi muuntaminen tapahtuu toString-metodilla, joten tämän pitäisi onnistua aina, mikäli arvo ei ole null. Jos arvo on null, palautetaan null. Tästäkin metodista on versio sekä sarakkeen nimelle, että indeksille.

1.2.5. getInt

Metodi palauttaa annetulta riviltä ja sarakkeelta löytyvän arvon kokonaislukuna. Arvo haetaan ensin kutsumalla getObject-metodia. Mikäli arvo on null tai jokin muu, kuin Number-luokan ilmentymä, tuotetaan InvalidValueTypeException. Muutoin palautetaan luvun kokonaislukuarvo. Tästäkin metodista kaksi versiota.

1.2.6. getDouble

Metodi palauttaa annetulta riviltä ja sarakkeelta löytyvän arvon doublena. Arvo haetaan ensin kutsumalla getObject-metodia. Mikäli arvo on null tai jokin muu, kuin Number-luokan ilmentymä, tuotetaan InvalidValueTypeException. Muutoin palautetaan luvun double-arvo. Tästäkin metodista kaksi versiota.

1.2.7. toXML

Metodi rakentaa DBResultin tiedot sisältävän XML-merkkijonon.

1.2.8. toDOM

Metodi rakentaa DBResultin tiedot sisältävän DOM-puun.

Luku 2. Filtteri-osajärjestelmä

2.1. XMLFilter

Hyvin yksinkertainen luokka, joka vain käyttää DBResult:in toXML-metodia.

2.2. DependencyFilter

Sisältää staattisen filter-metodin, joka uorittaa tuotelistan prosessoinnin tuoteriippuvuuksien ja asiakkaan profiilitietojen perusteella. Varsinaiseen prosessointiin luokka käyttää DependencyCore-luokkaa. Parametreina saatujen DBResult-olioiden muuttamiseen DependencyCoren ymmärtämiksi Item- ja DependencyRule- olioiksi käytetään sisäluokkia ProductFactory ja DependencyFactory. Koska Item on interface, sille on tehty toteutus ProductItem, joka myös on DependencyFilterin sisäluokka. Kun DependencyCore on merkinnyt tuotelistan tuotteet, rakennetaan alkuperäisestä syötteenä annetusta listasta DOM-puu, (DBResultin toDOM-metodilla) joka käydään läpi ja siihen lisätään selectable-tagit DependencyFilterin merkintöjen mukaisesti. Lopuksi DOM-puu muutetaan XML-merkkijonoksi.

2.3. ProductItem

Yksinkertainen Item-interfacen toteutus. Sisältää ID:n (id) ja tilan (state).

2.4. ProductFactory

Sisältää staattisen metodin createProducts, joka muuttaa DBResult-olion ProductItem taulukoksi. Käy yksinkertaisesti läpi kaikki DBResultin rivit ja luo niiden pohjalta ProductItem-olioita. Ainoa DBReultista käytettävä tieto on id, tila alustetaan arvolla YES. Mikäli tapahtuu jokin virhe (esim. DBResult ei sisällä tarvittuja tietoja) kirjoitetaan siitä merkintä lokiin ja palautetaan tyhjä taulukko.

2.5. DependencyFactory

Sisältää staattisen metodin createDependencies, joka muuttaa DBResult-olion DependencyRule-taulukoksi. Käy läpi DBResultin rivit ja luo niiden pohjalta DependencyRule-olioita. Mikäli tapahtuu jokin virhe (esim. DBResult ei sisällä tarvittuja tietoja) kirjoitetaan siitä merkintä lokiin ja palautetaan tyhjä taulukko.

2.6. DependencyRule

Kuvaa kahden tuotteen välistä riippuvuutta. Tuotteisiin viitataan Object-tyyppisillä tunnisteilla source ja target. Riippuvuuden tyyppi ilmaistaan kokonaisluvulla. Tyyppiä varten on määritelty vakiot TYPE_INCLUDE ja TYPE_EXCLUDE, muun tyyppisiä riippuvuuksia ei ole. Konstruktorissa annetaan tuotteiden tunnisteet ja tyyppi. Mikäli lähde tai kohde ovat samoja tai tyyppi on jokin muu kuin TYPE_INCLUDE tai TYPE_EXCLUDE, tuotetaan IllegalArgumentException. Luokassa on lisäksi aksessorit lähteelle, kohteelle ja tyypille.

2.7. DependencyCore

Sisältää staattisen metodin processDependencies, joka prosessoi annetun Item-taulukon (available [=tuotelista]) toisen Item-taulukon (selected [=profiilitiedot]) ja näiden välisten riippuvuussuhteiden (dependencies) perusteella.

Available-taulukon Item:ien tilaksi asetetaan joko YES, NO tai MORE seuraavan logiikan mukaan: (Merkitään availablea A:lla ja selectediä S:llä. Itemien a ja b välistä include-sääntöä merkitään a+>b ja exclude-sääntöä a->b)

Jos a kuuluu A:han ja b kuuluu S:ään ja on olemassa sääntö a->b tai b->a, on a:n tila NO. Jos a ja b kuuluvat A:han ja on olemassa sääntö a+>b ja b:n tila on NO, on myös a:n tila NO. Jos a kuuluu A:han ja on olemassa sääntö a+>b ja b:n tila ei ole NO, mikäli se sisältyy A:han, on a:n tila MORE. Muutoin a:n tila on YES.

Metodi käyttää apuna luokkaa ItemNode, jonka avulla muodostetaan available-taulukon alkioista verkko. Jokainen verkon solmu (ItemNode-olio) vastaa yhtä available-taulukon alkiota. Siitä on kaaret niihin solmuihin, jotka tarvitsevat sen (eli on olemassa vastaava include-sääntö). Ajatuksena on ensin luoda verkon solmut (tilaksi alustetaan YES), prosessoida sitten include-säännöt ja lisätä niitä vastaavat verkon kaaret (ja asettaa vastaavien solmujen ja Itemien tilaksi MORE). Lopuksi käsitellään exclude-säännöt. Kun jonkin solmun (ja Itemin) tilaksi asetetaan NO, voidaan nyt käydä rekursiivisesti läpi kaikki sitä tarvitsevat solmut ja asettaa niidenkin tilaksi NO. Rekursio on toteutettu ItemNode-luokassa. Sääntöjen käsittelyn helpottamiseksi available-taulukon Itemejä vastaavat solmut asetetaan ensin hajautustauluun, josta ne löytyvät nopeasti Itemin ID:n avulla. Selected-taulukon Itemeille taas luodaan HashSet, jonka avulla saadaan selville mitkä Itemit sisältyvät selected-taulukkoon.

2.8. ItemNode

Luokka helpottamaan riippuvuussuhteiden setvimistä, kuten DependencyCore:n kohdalla kerrottiin. Sisältää yhden Item-olion, sen tilan sekä listan niistä ItemNode-olioista, jotka tarvitsevat tätä (eli verkon kaaret). Konstruktorissa annetaan Item ja sen sekä kyseisen ItemNoden tilaksi asetetaan YES.

Metodi addRequirer lisää yhden ItemNoden tarvitsijoiden listaan.

Metodi setState asettaa ItemNoden ja sen sisältämän Itemin tilan. Mikäli tila on NO, käydään läpi kaikki tarvitsijalistaan merkityt solmut ja kutsutaan niillekkin metodia setState(NO). Kutsua ei kuitenkaan tehdä, jos solmun tila on jo valmiiksi NO. Tämä estää algoritmia jäämästä ikuiseen silmukkaan, mikäli verkko sisältää syklejä. Jotta prosessointi toimisi oikein, ei setStatea saa kutsua arvolla NO ennenkuin kaikki verkon kaaret ovat varmasti asetettu.

Luku 3. Servlet

3.1. Servlet

Servlet-osajärjestelmä on TAHKO:n keskeisin osajärjestelmä. Se välittää käyttäjän tekemät http-requestit eteenpäin TAHKO:n sisällä. Kaikki kommunikaatio käyttäjän/käyttöliittymän kanssa tapahtuu Servlet-osajärjestelmän välityksellä.

Servlet-osajärjestelmässä on vain yksi luokka: TahkoServlet, joka on aivan tavallinen HttpServlet:in aliluokka. Kuten servletit yleensä, se kuormittaa metodit init(), doGet() ja doPost().

Init() hakee web.xml-tiedostossa määritellyt alkuparametrit (esim. tietokannan nimi, tilapäistiedostojen hakemisto) ja alustaa niiden perusteella Servletin, DBSlaven ja TomcatWrapperin.

doPost() pelkästään delegoi saamansa kutsut doGet() -metodille.

TahkoServletin doGet()-metodi on TAHKO:n sydän. Se käskee käyttäjältä saatujen pyyntöjen perusteella Db-osajärjestelmää tekemään tietokantahakuja, ApacheWrapperia sekä käsittelemään xml-tiedostoja että kääntämään ja suorittamaan JSP-sivuja. Käyttäjälle doGet() palauttaa käyttöliittymä-html -sivuja. doGet()-metodin toteuttaminen oli suoraviivaista suunnitelman perusteella, koska monimutkaisuus on piilotettu muihin osajärjestelmiin.

Luku 4. Apache

4.1. FopWrapper

Tämä on toteutukseltaan yksinkertainen työkaluluokka, joka sisältää vain yhden staattisen funktion. Sitä käytetään muuntamaan profiili-xml PDF-muotoon. Välivaiheena on fo-xml, joka saadaan Profiili-xml:stä xsl-muunnoksen avulla. Muunnokseen käytetään XmlProcessor -luokkaa. Apachen Fop muuntaa näin saadun fo-xml:n PDF:ksi. Virhetilanteessa aiheutetaan PDFProcessingException, joka on TahkoExceptionin aliluokka.

4.2. XmlProcessor

Tämä on toteutukseltaan yksinkertainen työkaluluokka. Sitä käytetään xsl-muunnosten tekemiseen xml-dokumenteille. Ainoan staattisen funktion toteutus sisältää tavanomaisia kutsuja Apachen Xalaniin. Xalanin käytön aikana syntyneet virheet kirjoitetaan tahkon lokiin. Virhetilanteessa aiheutetaan XMLProcessingException, joka on TahkoExceptionin aliluokka.

4.3. TomcatWrapper

Tämä luokka kapseloi Apachen Tomcat JSP-koneen TAHKO:n tarkoituksia varten. Tomcatia käytetään tässä luokassa paitsi jsp-sivujen ajamiseen, niin myös niiden kääntämiseen. TomcatWrapper tallettaa jo servleteiksi käännetyt jsp-sivut HashMap:iin, jotta niitä ei joka ajokerralla tarvitsisi kääntää uudestaan (kääntäminen on todella hidas toimenpide). Tällainen Apachen Tomcatin integroiminen osaksi omaa ohjelmaa on monimutkaista verrattuna Fop:n ja Xalanin integrointiin.

Tavallisten alustusten lisäksi konstruktorissa luodaan HashMap, johon talletetaan <servlet,pageId> -pareja sitä mukaa kun JSP-sivuja käännetään.

Translate-funktio kääntää JSP-sivun ja sijoittaa tuloksena saadun servletin HashMap:iin. Tomcatin rakenteesta johtuen tämä on helpommin sanottu kuin tehty. Joudutaan tekemään omat (sisäluokka-) implementaatiot JspCompilationContext, Mangler ja Options -rajapinnoille sekä kirjoittamaan aliluokat JspLoader ja ClassLoader -luokille.

Service-funktio etsii HashMap:sta pageId:tä vastaavan servletin, ja välittää tälle annetun requestin. Jotta Service-metodi voisi palauttaa servletin työn tuloksen Stringinä, se välittää servletille itse tehdyn implementaation HttpServletResponse -rajapinnasta. Tämä implementaatio käyttää apunaan itse tehtyä ServletOutputStream:n aliluokkaa, ja pystyy siten palauttamaan Stringin getResponse() -metodillaan. TAHKO:ssa tämä string on XML-muotoinen, niinsanottu data-xml.

Luku 5. Käyttöliittymä

5.1. Perus-XML

Tahko-järjestelmää voidaan konfiguroida muuttamalla kolmen tyyppisiä XML- ja XSL-tiedostoja. Yksi näistä muutettavista XML-tiedostoista on käyttöliittymä-XML. Käyttöliittymä-XML luo pohjan koko järjestelmän perusrakenteelle; se kertoo, millaisista sivuista järjestelmä koostuu. Näistä "sivuaihioista" muodostetaan HTML-sivuja logiikka-XSL:n logiikkasääntöjen ja käyttöliittymä-XSL:n ulkoasusääntöjen perusteella.

Esimerkkisovelluksen, tarjouskonfiguraattorin, käyttöliittymä-XML sisältää seuraavat elementit, jotka on listassa lueteltu hierarkkisesti rakenteensa perusteella:

  • ui
    • form action="select_customer | select_product" target="_self" submit="Ok" method="post"
      • input type="text" name="customer"/
      • select_customer | select_product
      • db-result table="customer | product | user"
      • records | no_records_found
        • record
          • selectable type="Y| N | M"
          • column name="tietokantataulun sarakkeen nimi"

5.1.1. Tagit

DATA-tagi pitää sisällään kaiken XML-dokumenttiin kuuluvan datan. Se on päätagi, joka kokoaa alleen siis kaiken, mitä käyttöliittymä-XML:ssa on.

Käyttöliittymä koostuu "hakukentistä" eli HTML-lomakkeista, joilla haetaan tietoa ja ohjaillaan sivustolla navigointia erilaisten sääntöjen perusteella. UI-tagi sisältää hakukentän määrittelyyn tarvittavan tiedon. Koneisto, joka tämän määrittelyn perusteella luo varsinaisen sivun, on XSL-tiedostoissa.

FORM-tagi sisältää lomakkeen määrittelyn. Lomake on aina UI-tagin sisällä.

Taulu 5.1. FORM-lomakkeen attribuutit ja niiden käyttö

Tagi

Attribuutit

Mahd. arvot

action

Haun käsittelevä logiikkasivu

Asiakkaan tai tuotteen valinta (select_customer|select_product)

target

Kohde, jossa tulos näytetään

_self. Hakutulos näytetään samassa kehyksessä, josta kutsu lähtee.

submit

Submit-napin teksti

Mikä tahansa merkkijono. Käytetty Ok:ta.

method

Metodi, jolla lomake lähetetään

POST tai GET. Käytetty POST:ia.

INPUT-tagi määrittelee varsinaisen hakukentän, joss haut määritellään. Tämä voi olla tyypiltään esimerkiksi tekstikenttä.

INPUT-tagi sisältää SELECT_CUSTOMER-tagin, jos haku on asiakashaku ja SELECT_PRODUCT-tagin, jos hakutulos on tuotteita.

DB-RESULT-tagin sisällä ovat tietokantahaun tulokset. Tällä tagilla on attribuutti TABLE, joka on sen taulun nimi, josta tiedot haetaan. Tämän kentän arvoksi käy mikä tahansa taulu, josta haetaan tietoja, tässä tapauksessa tarjouskonfiguraattorin tietoja.

RECORDS-tagin sisällä ovat kaikki tietokantahan palauttamat rivit kukin omana RECORD-taginaan, tai NO_RECORDS_FOUND-tagi, jos haussa ei löytynyt yhtään riviä. Tämä tagi on aina tyhjä, ts. sen sisällä ei ole muita tageja.

SELECTABLE-tagi kertoo, voiko käyttäjä valita tuotteen. Tagi on käytössä ainoastaan tilanteissa, joissa valitaan tuotteita. Kertoo, onko tuote valittavissa vai ei, tai valitaanko mukaan myös muita tuotteita tämä tuote valittaessa.

Taulu 5.2. SELECTABLE-tagin attribuutit ja niiden käyttö

Attribuutti

Selitys

Mahd. arvot

type

Kertoo, onko tuote valittavissa vai ei, tai valitaanko mukaan myös muita tuotteita

Y: tuote on valittavissa

N: Tuotetta ei voida valita. Jokin on jo valittu, tai asiakkaalla aikaisemmin oleva tuote estää valinnan

M: Jos tuote valitaan, lisätään mukaan tarjoukseen myös muita tuotteita, jotka ovat pakollisia, jotta kyseistä tuotetta voi käyttää.

COLUMN-tagi sisältää tietokantahaun palauttaman rivin yhden sarakkeen.

5.2. Tarjous-XML

Tarjous-XML on senhetkinen tarjous datamuotoisena. Tästä dokumentista muodostetaan XSL-tyylitiedoston avulla HTML-sivu, joka esittää tarjouksen senhetkisen tilanteen.

Esimerkkisovelluksen tarjous-XML sisältää seuraavat elementit, jotka on listassa lueteltu hierarkkisesti rakenteensa perusteella:

  • ui
    • show_offer
      • profile
      • element name="seller | customer | product | freetext | discount | valid" id="CDATA"
      • field name="sarakkeen nimi tietokannassa"

5.2.1. Tagit

DATA-tagi on juuritagi, joka pitää sisällään kaiken datan.

UI-tagi määrittelee näytettävän käyttöliittymän samaan tapaan kuin käyttöliittymä-XML:ssa.

SHOW_OFFER määrittelee, että mukana näytetään seuraava profiili. Tagia käytetään tarjouksen tilanteen näyttöön tarkoitetussa kehyksessä.

PROFILE-tagi sisältää tarjouksen senhetkisen tilanteen tiedot, jotka esitetään ELEMENT- ja edelleen FIELD-tagien sisällä.

ELEMENT-tagien sisällä eritellään jokainen tarjouksen osa. Oheisessa taulukossa ELEMENT-tagin attribuutit:

Taulu 5.3. ELEMENT-tagin attribuutit ja niiden käyttö

Attribuutti

Selitys

Mahd. arvot

name

Tarjouksen osan nimi

seller: myyjän tiedot

customer: asiakkaan tiedot

product: yksittäisen tuotteen tiedot

freetext: tervehdys tai muu vastaava vapaamuotoinen teksti

discount: tarjouksen alennusprosentti

valid: tarjouksen voimassaoloaika

FIELD-tagi sisältää tarjouksen eri osiin liittyvät yksittäiset tiedot. Tagi on aina ELEMENT-tagin sisällä. Tagilla on yksi mahdollinen attribuutti: NAME, joka kertoo osaan liittyvän tiedon sarakkeen nimen tietokannassa. Sen mahdollisia arvoja ovat kaikki sarakkeiden nimet, jotka haetaan kannasta ja pidetään tallessa profiilissa.

5.3. XSL

XSL-tiedostoissa on yleisiä eri dokumentteihin liittyviä XSL-tageja, jotka on esitelty seuraavassa taulukossa.

Taulu 5.4. Yleisiä dokumenttiin liittyviä XSL-tageja

Attribuutti

Selitys

match=/

Juurielementti määrittää dokumentin peruskomponentit eli dokumentin alun, Java-skriptit ja dokumentin lopun.

match=ui/form

Elementissä määritellään hakukentän lomake ja lomakkeen kentät.

5.3.1. Asiakashakutulosten näyttäminen

match=select_customer/db_result/records: Tässä määritellään asiakashaun tuloksena saatavan taulukon alku, otsikot ja loppu.

match=select_customer/db_result/no_records_found: Tässä kerrotaan käyttäjälle, ettei haussa löytynyt asiakkaita.

match=select_customer/db_result/records/record: Tässä näytetään hakutuloksena saatu rivi. Valintalinkki on JavaScript-kutsu, joka lisää halutun asiakkaan oikean puoleisen kehyksen setCustomer-kenttään ja lähettää lomakkeen.

5.3.2. Tuotehakutulosten näyttäminen

match=select_product/db_result/records: Tässä määritellään taulukon alku, otsikkorivi ja loppu, jossa hakutulos näytetään.

match=select_product/db_result/no_records_found: Tässä kerrotaan käyttäjälle, ettei haussa löytynyt tuotteita.

match=select_product/db_result/records/record: Tässä näytetään hakutuloksena saatu rivi. Valintalinkki on JavaScript-kutsu, joka lisää halutun tuotteen oikean puoleisen kehyksen addProduct kenttään ja lähettää lomakkeen. Jos tuotetta ei voida jostain syystä valita kerrotaan siitä käyttäjälle.

5.3.3. Tarjouksen senhetkisen tilanteen näyttäminen

match=ui/show_offer: Tässä rakennetaan tarjouksen sen hetkisen tilanne. Määritellään tarvittavat kentät ja otsikot. Myyjän, asiakkaan ja tuotteiden tiedot käsitellään omassa templatessa.

match=profile/element[@name='seller']: Tässä muutetaan myyjän tiedot html:ksi, jotta ne voidaan näyttää.

match=profile/element[@name='customer']: Tässä muutetaan asiakkaan tiedot html:ksi, jotta ne voidaan näyttää.

match=profile/element[@name='product']: Tässä muutetaan yksittäisen tuotteen tiedot html:ksi, jotta ne voidaan näyttää. Tuotteiden kappalemääriä, yksikköhintoja ja yhteishintoja varten määritellään omat kentät, joiden arvoina on oletusarvot tai käyttäjän jo aikaisemmin antamat uudet arvot.

5.4. Java-skriptit

Lisäksi Tahko-järjestelmän esimerkkisovelluksen toimintojen toteutuksessa on käytetty selainpään Java-skriptiä. Tämä mahdollistaa ennen kaikkea hintojen nopean laskemisen sitä mukaa, kun asiakas muuttaa jonkin osakomponentin hintaa, tai valitsee uuden tuotteen. Toiminta on paljon nopeampaa, kun välillä ei tarvitse tehdä palvelinkutsuja.

Java-skriptin käyttö ei ole kuitenkaan ollenkaan välttämätöntä rakennettaessa sovelluksia Tahko-järjestelmällä.

5.4.1. Tuotteiden hintojen laskeminen

Kun tarjoukseen lisättyjen tuotteiden hintoja tai kappalemääriä muutetaan, lasketaan yksittäisen tuotteen kokonaishinta, kaikkien tuotteiden kokonaishinta ja alennuksen jälkeen saatava loppuhinta Java-skriptin avulla. Laskemisen suorittaa yksi funktio, joka tekee kaiken tarvittavan laskennan. Funktiota kutsutaan jokaisen tuotteen kappalemäärä-, kappalehinta- ja kokonaishinta- sekä tuotteiden kokonaishinta - ja tarjouksen loppuhinta -kentissä onChange-tapahtuman käsittelyssä. Kokonaishinnoissa kutsutaan funktiota siksi, että ne eivät ole editoitavia kenttiä, joten niihin tehdyt muutokset eivät vaikuta tarjouksen lopulliseen hintaan. Vain tuotteen kappalemäärän, kappalehinnan ja alennusprosentin muuttaminen vaikuttaa tarjouksen loppuhintaan.

5.4.2. Tuotteen lisääminen

Tuotteen lisääminen toimii siten, että tuotehakutuloksena saadusta listasta painetaan Lisää-linkkiä, jolloin kutsutaan addProduct-funktiota lisättävän tuotteen id parametrina. Funktio lisää lisättävän tuotteen id:n tarjouskehyksen lomakkeessa olevaan addProduct-piilokenttään. Tämän jälkeen tarjouslomake lähetetään ja tuote lisätään tarjoukseen.

5.4.3. Tuotteen poistaminen

Tuote poistetaan tarjouksesta painamalla Poista-linkkiä tarjouskehyksessä halutun tuotteen kohdalta, jolloin kutsutaan removeProduct-funktiota parametrina poistettavan tuotteen id. Funktio lisää poistettavan tuotteen id:n tarjouskehyksen lomakkeessa olevaan removeProduct-piilokenttään. Tämän jälkeen tarjouslomake lähetetään ja tuote poistetaan tarjouksesta.

5.4.4. Asiakkaan lisääminen tai vaihtaminen

Tuotteen lisääminen toimii siten, että tuotehakutuloksena saadusta listasta painetaan Lisää-linkkiä, jolloin kutsutaan addProduct-funktiota lisättävän tuotteen id parametrina. Funktio lisää lisättävän tuotteen id:n tarjouskehyksen lomakkeessa olevaan addProduct-piilokenttään. Tämän jälkeen tarjouslomake lähetetään ja tuote lisätään tarjoukseen.