Meeskond "Head isu"

From ICO wiki
Jump to navigationJump to search

Team

  • Liisa Viljaste (Lember)
  • Kalev Paju
  • Elvin Risti
  • Katri Pokats

Summary (est)

Kuna oli teada kitsas ajapiirang, siis sai võetud kinni õpetaja pakutud teemast - kohvikuteema.

Algsest XML-st sai ka vastav andmemudel. Veebiteenusega muidugi sellist 1:1 väljundit pakkuda ei saa, kuna veebiteenusel ei saanud atribuute väljundisse (vähemalt meie näites).

Kitsas ajapiirang ei lasknud teha valmis kogu funktsionaalsust, mis sai algselt mõeldud.

Põhiline funktsionaalsus sai klientrakendustesse juurutatud, kuid administreerimise poolel desktop-rakendusel ei saanud kõike teostatud.

Tagantjärele mõeldes oleks pidanud skoopi kokku tõmbama ja mitte mõtlema nii laiaks süsteemi.

Tegemise käigus sai omandatud oskusi Visual Studio programmiga ja saime teada, et on ka .Net rakendustele teenused olemas, mida saab tasuta kasutada. Nii saime oma MSSQL andmebaasi, WSDL-teenuse ja veebiklientrakenduse sellele teenusele üles panna.

Tiimivahelise peamiseks suhtluskanaliks oli e-post, kuid sai ka kommenteeritud ja püstitatud ülesandeid vastavas keskkonnas, milleks valisime Springloopsi ticket-süsteemi, mis toetas ka versioonihaldust ja oli autentitav. Samuti sai kord nädalas loenguvaheajal lühikesi püstijala koosolekuid peetud, kus jaagasime omavahel tööülesandeid.

Saime teada et .Net rakenduse tegemine ei olegi nii raske kui seda algselt ette kujutasime. Kindlasti oli üllatus kui lihtsalt sai tehtud MSSQLi andmetest läbi LINQ veebiteenus.

Source files

Webservices:              http://headisu.somee.com/app/webservice-ver0.2.zip
Web application:          http://headisu.somee.com/app/KohvikuVeebiKlient.zip
Windows client for admin: http://headisu.somee.com/app/WpfHeadIsu-win_klient.zip

Used services

  • For version control and team discussion we used Springloops
For one project this is free for use
Used TortoiseSVN in Windows to commit and update to there
From there we serve private AdminService, public Cafes service and Web application

Web application: http://headisu.somee.com/

XML

Teise tiimi arvustus meie XML-le: https://wiki.itcollege.ee/index.php/Talk:Meeskond_%22Head_isu%22

XML

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="kohvik.xslt"?>
<!--
itkheadisu2011.slsapp.com
http://itkheadisu2011.slsapp.com/source/itkheadisu
Elvin Risti		eristi[at]itcollege.ee
Liisa Lember	lilember[at]itcollege.ee
Kalev Paju		kpaju[at]itcollege.ee
Katri Pokats
-->
<cafemenus>
  <cafes>
    <cafe id="1">
      <name>Reval</name>
      <address id="1">
        <coordinates long="59.430756" lat="24.74565" />
        <street>Pärnu mnt</street>
        <house>271</house>
        <houseExtra />
        <city>Tallinn</city>
        <!-- country -  ISO 3166-1 alpha-2 code - http://en.wikipedia.org/wiki/ISO_3166-2 -->
        <country>EE</country>
        <zip>10141</zip>
        <!-- opened is per location -->
        <opened year="2011">
          <weekdays>
            <!-- http://en.wikipedia.org/wiki/ISO_8601 -->
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">1</weekday>
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">2</weekday>
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">3</weekday>
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">4</weekday>
            <weekday begin="09:00:00+03:00" until="21:00:00+03:00">5</weekday>
            <weekday begin="10:00:00+03:00" until="15:00:00+03:00">6</weekday>
            <weekday isclosed="true">7</weekday>
          </weekdays>
          <exceptions>
            <date isclosed="true">2011-01-01</date>
            <date isclosed="true">2011-02-24</date>
            <date begin="12:00:00+03:00" until="19:00:00+03:00">2011-02-25</date>
          </exceptions>
        </opened>
        <comment lang="et">Asume kesklinnas Pärnu mnt ja Tatari nurgal.</comment>
      </address>
    </cafe>
    <cafe id="2">
      <name>Reval 2</name>
      <address id="3">
        <coordinates long="59.430756" lat="24.74565" />
        <street>Pärnu mnt</street>
        <house>272</house>
        <houseExtra />
        <city>Tallinn</city>
        <!-- country -  ISO 3166-1 alpha-2 code - http://en.wikipedia.org/wiki/ISO_3166-2 -->
        <country>EE</country>
        <zip>10141</zip>
        <!-- opened is per location -->
        <opened year="2011">
          <weekdays>
            <!-- http://en.wikipedia.org/wiki/ISO_8601 -->
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">1</weekday>
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">2</weekday>
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">3</weekday>
            <weekday begin="09:00:00+03:00" until="19:00:00+03:00">4</weekday>
            <weekday begin="09:00:00+03:00" until="21:00:00+03:00">5</weekday>
            <weekday begin="10:00:00+03:00" until="15:00:00+03:00">6</weekday>
            <weekday isclosed="true">7</weekday>
          </weekdays>
        </opened>
        <comment lang="et">Asume kesklinnas Pärnu mnt ja Tatari nurgal.</comment>
      </address>
    </cafe>
  </cafes>
  <menus>
    <menuscafe cafeid="1">
      <!-- currency -  ISO 4217 - http://en.wikipedia.org/wiki/ISO_4217 -->
      <currency>EUR</currency>
      <!-- @lang - ISO 639-1 - http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes -->
      <menu lang="et">
        <item type="food" subtype="roast">
          <name>Kiievi kotlett</name>
          <!-- @comment - simple comment -->
          <price comment="väike">2</price>
          <price comment="suur">3</price>
          <!-- availability: true/false -->
          <availability>true</availability>
          <comment>Väiksel portsul üks kotlett, suurel kolm.</comment>
        </item>
        <item type="drink">
          <name>Piim</name>
          <!-- @unit: string,litres -->
          <price quantity="0.33" unit="l">0.5</price>
          <availability>true</availability>
          <comment />
        </item>
        <item type="food" subtype="dessert">
          <name>Martsipani tort</name>
          <!-- @comment - simple comment -->
          <price comment="viil">1</price>
          <price quantity="0.8" unit="kg">9</price>
          <!-- availability: true/false -->
          <availability>true</availability>
          <comment>Tordil on valge jänese pilt.</comment>
        </item>
      </menu>
      <benefits>
        <benefit isprecent="true" name="ISIC kaart">5</benefit>
        <benefit isprecent="true" name="Püsikliendi soodustus">10</benefit>
        <benefit isprecent="false" name="Kampaania X soodustus">1.5</benefit>
      </benefits>
    </menuscafe>
  </menus>
</cafemenus>

XML Schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="cafemenus">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="cafes">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="cafe" maxOccurs="unbounded" >
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="name" type="xs:string" />
                    <xs:element name="address" minOccurs="1" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="coordinates" minOccurs="0" maxOccurs="1">
                            <xs:complexType>
                              <xs:attribute name="long" type="xs:decimal" use="required" />
                              <xs:attribute name="lat" type="xs:decimal" use="required" />
                            </xs:complexType>
                          </xs:element>
                          <xs:element name="street" type="xs:string" />
                          <xs:element name="house" type="xs:unsignedInt" />
                          <xs:element name="houseExtra" type="xs:string" />
                          <xs:element name="city" type="xs:string" />
                          <xs:element name="country" type="xs:string" />
                          <xs:element name="zip" type="xs:unsignedShort" />
                          <xs:element name="opened" maxOccurs="unbounded">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="weekdays">
                                  <xs:complexType>
                                    <xs:sequence>
                                      <xs:element minOccurs="7" maxOccurs="7" name="weekday">
                                        <xs:complexType>
                                          <xs:simpleContent>
                                            <xs:extension base="xs:unsignedByte">
                                              <xs:attribute name="begin" type="xs:time" use="optional" />
                                              <xs:attribute name="until" type="xs:time" use="optional" />
                                              <xs:attribute name="isclosed" type="xs:boolean" use="optional" />
                                            </xs:extension>
                                          </xs:simpleContent>
                                        </xs:complexType>
                                      </xs:element>
                                    </xs:sequence>
                                  </xs:complexType>
                                </xs:element>
                                <xs:element name="exceptions" minOccurs="0">
                                  <xs:complexType>
                                    <xs:sequence>
                                      <xs:element maxOccurs="unbounded" name="date">
                                        <xs:complexType>
                                          <xs:simpleContent>
                                            <xs:extension base="xs:date">
                                              <xs:attribute name="isclosed" type="xs:boolean" use="optional" />
                                              <xs:attribute name="begin" type="xs:time" use="optional" />
                                              <xs:attribute name="until" type="xs:time" use="optional" />
                                            </xs:extension>
                                          </xs:simpleContent>
                                        </xs:complexType>
                                      </xs:element>
                                    </xs:sequence>
                                  </xs:complexType>
                                </xs:element>
                              </xs:sequence>
                              <xs:attribute name="year" type="xs:unsignedShort" use="required" />
                            </xs:complexType>
                          </xs:element>
                          <xs:element name="comment">
                            <xs:complexType>
                              <xs:simpleContent>
                                <xs:extension base="xs:string">
                                  <xs:attribute name="lang" type="xs:string" use="required" />
                                </xs:extension>
                              </xs:simpleContent>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="id" type="xs:unsignedInt" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="id" type="xs:unsignedInt" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="menus">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="menuscafe" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="currency" type="xs:string" />
                    <xs:element name="menu">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element maxOccurs="unbounded" name="item">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="name" type="xs:string" />
                                <xs:element maxOccurs="unbounded" name="price">
                                  <xs:complexType>
                                    <xs:simpleContent>
                                      <xs:extension base="xs:decimal">
                                        <xs:attribute name="comment" type="xs:string" use="optional" />
                                        <xs:attribute name="quantity" type="xs:decimal" use="optional" />
                                        <xs:attribute name="unit" type="xs:string" use="optional" />
                                      </xs:extension>
                                    </xs:simpleContent>
                                  </xs:complexType>
                                </xs:element>
                                <xs:element name="availability" type="xs:boolean" />
                                <xs:element name="comment" type="xs:string" />
                              </xs:sequence>
                              <xs:attribute name="type" type="xs:string" use="required" />
                              <xs:attribute name="subtype" type="xs:string" use="optional" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="lang" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                    <xs:element name="benefits" minOccurs="0">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element minOccurs="0" maxOccurs="unbounded" name="benefit">
                            <xs:complexType>
                              <xs:simpleContent>
                                <xs:extension base="xs:decimal">
                                  <xs:attribute name="isprecent" type="xs:boolean" use="required" />
                                  <xs:attribute name="name" type="xs:string" use="required" />
                                </xs:extension>
                              </xs:simpleContent>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="cafeid" type="xs:unsignedInt" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
	  <html>
	  <body>
      <h1>Kohvikud</h1>
      <xsl:apply-templates select="/cafemenus/cafes/cafe" />
	  </body>
	  </html>
  </xsl:template>

  <xsl:template match="/cafemenus/cafes/cafe">
    <h2><xsl:value-of select="name"/></h2>
    <div class="addresses">
      <xsl:apply-templates select="address" />
    </div>
    <div class="menus" style="clear:both;">
      <xsl:call-template name="show_menus">
        <xsl:with-param name="cafe_id" select="@id"/>
        </xsl:call-template>
    </div>
    <hr />
  </xsl:template>

  <xsl:template match="address">
    <!-- variable "thisyear" should be come from querystring, currently we set it statically -->
    <xsl:variable name="thisyear" select="2011" />
    <div class="address" style="clear:both;">
    <xsl:choose>
      <xsl:when test="coordinates and coordinates/@long!='' and coordinates/@lat!=''">
        <img border="0" style="float:right;">
          <xsl:attribute name="src">http://maps.google.com/maps/api/staticmap?zoom=16&amp;size=200x200&amp;maptype=roadmap&amp;markers=color:red|label:A|<xsl:value-of select="coordinates/@long" />,<xsl:value-of select="coordinates/@lat" />&amp;sensor=false</xsl:attribute>
        </img>
      </xsl:when>
    </xsl:choose>
      <xsl:value-of select="street" />&#160;
      <xsl:value-of select="house" />
      <xsl:choose>
        <xsl:when test="houseExtra!=''">, <xsl:value-of select="houseExtra" /></xsl:when>
      </xsl:choose>, <xsl:value-of select="city" /><br />
      
      <xsl:choose>
        <xsl:when test="opened and opened/@year = $thisyear">
          <xsl:call-template name="show_opened">
            <xsl:with-param name="opened" select="opened[@year = $thisyear]"/>
          </xsl:call-template>
        </xsl:when>
      </xsl:choose>
    </div>
  </xsl:template>

  <xsl:template name="show_opened">
    <xsl:param name="opened" />
    <strong>Oleme avatud:</strong>
    <table border="1" cellpadding="0">
      <tr bgcolor="#9acd32">
        <th>päev</th>
        <th>alates</th>
        <th>kuni</th>
      </tr>
      <xsl:for-each select="$opened/weekdays/weekday">
        <tr>
          <td>
            <xsl:call-template name="getShortDayname">
              <xsl:with-param name="weekday" select="."/>
            </xsl:call-template>
          </td>
          <xsl:choose>
            <xsl:when test="@isclosed and @isclosed = 'true'">
              <td colspan="2">suletud</td>
            </xsl:when>
            <xsl:otherwise>
              <td>
                <xsl:value-of select="substring(@begin, 1, 2)" />:<xsl:value-of select="substring(@begin, 4, 2)" />
              </td>
              <td>
                <xsl:value-of select="substring(@until, 1, 2)" />:<xsl:value-of select="substring(@until, 4, 2)" />
              </td>
            </xsl:otherwise>
          </xsl:choose>
        </tr>
      </xsl:for-each>
    </table>
    <xsl:choose>
      <xsl:when test="$opened/exceptions and $opened/exceptions/date">
        <strong>Erandid:</strong>
        <table border="1" cellpadding="0">
          <tr bgcolor="#9acd32">
            <th>päev</th>
            <th>alates</th>
            <th>kuni</th>
          </tr>
          <xsl:for-each select="$opened/exceptions/date">
            <tr>
              <td>
                <xsl:value-of select="." />
              </td>
              <xsl:choose>
                <xsl:when test="@isclosed and @isclosed = 'true'">
                  <td colspan="2">suletud</td>
                </xsl:when>
                <xsl:otherwise>
                  <td>
                    <xsl:value-of select="substring(@begin, 1, 2)" />:<xsl:value-of select="substring(@begin, 4, 2)" />
                  </td>
                  <td>
                    <xsl:value-of select="substring(@until, 1, 2)" />:<xsl:value-of select="substring(@until, 4, 2)" />
                  </td>
                </xsl:otherwise>
              </xsl:choose>
            </tr>
          </xsl:for-each>
        </table>
      </xsl:when>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="show_menus" match="/cafemenus/menus">
    <xsl:param name="cafe_id" />

    <xsl:choose>
      <xsl:when test="/cafemenus/menus/menuscafe[@cafeid=$cafe_id]">
        <xsl:variable name="currency">
          <xsl:value-of select="/cafemenus/menus/menuscafe[@cafeid=$cafe_id]/currency" />
        </xsl:variable>
        <h3>Menüü</h3>
        <table border="1">
          <thead>
            <tr bgcolor="#9acd32">
              <th>Tüüp</th>
              <th>Nimetus</th>
              <th>Hinnad</th>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each select="/cafemenus/menus/menuscafe[@cafeid=$cafe_id]/menu/item">
              <tr>
                <td>
                  (<xsl:value-of select="@type" />
                  <xsl:choose>
                    <xsl:when test="@subtype">
                      --&gt; <xsl:value-of select="@subtype" />
                    </xsl:when>
                  </xsl:choose>)
                </td>
                <td>
                  <xsl:value-of select="name" />
                </td>
                <td>
                  <xsl:value-of select="price" />&#160;<xsl:value-of select="$currency"/>
                </td>
              </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </xsl:when>
      <xsl:otherwise>
        <h2>Menüü puudub</h2>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


  <xsl:template name="getShortDayname">
    <xsl:param name="weekday" />
    <xsl:choose>
      <xsl:when test="$weekday = 1">E</xsl:when>
      <xsl:when test="$weekday = 2">T</xsl:when>
      <xsl:when test="$weekday = 3">K</xsl:when>
      <xsl:when test="$weekday = 4">N</xsl:when>
      <xsl:when test="$weekday = 5">R</xsl:when>
      <xsl:when test="$weekday = 6">L</xsl:when>
      <xsl:when test="$weekday = 7">P</xsl:when>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Result preview

Screenshot1.png


HeadIsu ERD

HeadIsu2011ERD.png

WebService methods

Source

http://headisu.somee.com/app/webservice-ver0.2.zip

Public methods

Service location: http://headisu.somee.com/Cafes.asmx

  • getCafeMenus
  • getCafeWithAddresses
  • getCafes
  • getCities
  • getCountries
  • getMenu
  • getStates

Restricted methods

Service location: http://headisu.somee.com/AdminService.asmx
  • IsRole

Is user in role

  • deleteCafe

For admin: delete cafe entry

  • deleteFood

For admin: delete food entry

  • deleteFoodType

For admin: delete food's type

  • deleteMenu

For admin: delete menu entry

  • getCafeMenus
  • getCafeWithAddresses
  • getCafes
  • getCities
  • getCountries
  • getDayLog

For admin: get log for asked date

  • getMenu
  • getRolesList

Returns roles list

  • getStates
  • getTodayLog

For admin: get log only for today

  • isAdmin

Has user admin role

  • logout

logout user

  • removeBenefit

For admin: remove benefit name

  • removeCafeBenefit

For admin: remove cafe's benefit

  • removeFoodMenu

For admin: remove food from menu

  • saveBenefit

For admin: add/update benefit name

  • saveCafe

For admin: add/update cafe entry

  • saveCafeBenefit

For admin: add/update cafe's benefit

  • saveCountry

For admin: add/update country entry

  • saveState

For admin: add/update state entry

  • saveCity

For admin: add/update city entry

  • saveFood

For admin: add/update food entry

  • saveFoodMenu

For admin: add/update food to menu

  • saveFoodType

For admin: add/update food's type

  • saveMenu

For admin: add/update menu entry

Windows Application

  • made with WPF
  • for administrating only
  • using AdminService.asmx
WPF app setup: http://headisu.somee.com/app/WPFApp.zip
Username: admin
Pwd: ?????????

Screenshots

Headisu logging-in.png Headisu cafes-list.png

Web application

  • using Cafes.asmx

Web application is public at:

http://headisu.somee.com/

Web application startup preview:
Act screenshot.jpg

Web application selection preview:
Act screenshot selected.jpg

Initial design sketch for web application of daily menu display that was not fully realised due to time constraints:
Plan Screenshot.jpg