Merge branch 'master' into production
This commit is contained in:
commit
33261ecdb2
|
@ -13,7 +13,7 @@ WSGIPythonPath /vagrant/django/didgeridoo/
|
||||||
|
|
||||||
ServerAdmin webmaster@localhost
|
ServerAdmin webmaster@localhost
|
||||||
|
|
||||||
Alias /media/ /vagrant/django/didgeridoo/media/
|
Alias /media/ /srv/media/
|
||||||
Alias /static/ /vagrant/django/didgeridoo/static/
|
Alias /static/ /vagrant/django/didgeridoo/static/
|
||||||
|
|
||||||
<Directory /vagrant/django/didgeridoo/didgeridoo>
|
<Directory /vagrant/django/didgeridoo/didgeridoo>
|
||||||
|
@ -23,7 +23,7 @@ WSGIPythonPath /vagrant/django/didgeridoo/
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
|
|
||||||
<Directory /vagrant/django/didgeridoo/media>
|
<Directory /srv/media>
|
||||||
Require all granted
|
Require all granted
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
|
|
|
@ -11,134 +11,99 @@ Key:Value pairs of new currencys.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def get_exchange_rate():
|
def get_rss(url):
|
||||||
# zweitweise kann die resource nicht geladen werden.
|
|
||||||
# https://stackoverflow.com/a/43523497/4061870
|
|
||||||
# During weekends there are no updates.
|
|
||||||
# To develop i need a testresource.
|
|
||||||
# In that case i comment the Online Resource block and uncomment the
|
|
||||||
# development Block...
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# Online Resource block:
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
today = datetime.now().strftime("%Y-%m-%d")
|
|
||||||
SNB_URL = 'https://www.snb.ch/selector/de/mmr/exfeed/rss'
|
|
||||||
urlsocket = ''
|
urlsocket = ''
|
||||||
try:
|
try:
|
||||||
urlsocket = urllib.request.urlopen(SNB_URL)
|
urlsocket = urllib.request.urlopen(url)
|
||||||
|
return(urlsocket)
|
||||||
except urllib.error.URLError as e:
|
except urllib.error.URLError as e:
|
||||||
print('err: urllib.request.urlopen: ', e.reason)
|
print('err: urllib.request.urlopen: ', e.reason)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_rss(urlsocket):
|
||||||
if urlsocket:
|
if urlsocket:
|
||||||
root = ET.parse(urlsocket)
|
root = ET.parse(urlsocket)
|
||||||
root = ET.ElementTree(root)
|
rss_tree = ET.ElementTree(root)
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~
|
return(rss_tree)
|
||||||
# development block:
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# today = "2018-01-08"
|
|
||||||
# try:
|
|
||||||
# root = ET.ElementTree(file='rss')
|
|
||||||
# except Exception as e:
|
|
||||||
# print('exchange_rates.py_urlsocket failed %s (
|
|
||||||
# %s) on date: %s for %s'
|
|
||||||
# % (e, type(e), root))
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
# Namespaces
|
|
||||||
ns = {'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
|
||||||
'none': 'http://purl.org/rss/1.0/',
|
|
||||||
'dc': 'http://purl.org/dc/elements/1.1/',
|
|
||||||
'dcterms': 'http://purl.org/dc/terms/',
|
|
||||||
'cb': 'http://www.cbwiki.net/wiki/index.php/Specification_1.2/'
|
|
||||||
}
|
|
||||||
# Pathvariables to XML Namespaces
|
|
||||||
rate_path = 'cb:statistics/cb:exchangeRate/'
|
|
||||||
observation_path = 'cb:statistics/cb:exchangeRate/cb:observation/'
|
|
||||||
exchange_rates = {}
|
|
||||||
for item in root.findall('none:item', ns):
|
|
||||||
# for eatch item n the list we grab the release date
|
|
||||||
# to evaluate if its fresh data or old:
|
|
||||||
|
|
||||||
# THE CURRENCY DATE:
|
def get_exchange_rate(rss_tree, ns):
|
||||||
datetime_str = item.find('dc:date', ns).text
|
# Pathvariables to XML Namespaces with
|
||||||
# convert string to date object:
|
rate_path = 'cb:statistics/cb:exchangeRate/'
|
||||||
# https://stackoverflow.com/a/12282040/4061870
|
observation_path = 'cb:statistics/cb:exchangeRate/cb:observation/'
|
||||||
# seams like snb striked the microsecond somewhere
|
exchange_rates = []
|
||||||
# between Nov. and Dez. 2017 so maybe first check
|
|
||||||
# time type is with milliseconds:
|
for item in rss_tree.findall('none:item', ns):
|
||||||
|
datetime_str = item.find('dc:date', ns).text
|
||||||
|
try:
|
||||||
|
date = datetime.strptime(''.join(
|
||||||
|
datetime_str.rsplit(':', 1)),
|
||||||
|
"%Y-%m-%dT%H:%M:%S%z").strftime(
|
||||||
|
"%Y-%m-%d")
|
||||||
|
except Exception as e:
|
||||||
|
print('%s (%s)' % (e, type(e)))
|
||||||
try:
|
try:
|
||||||
date = datetime.strptime(''.join(
|
date = datetime.strptime(''.join(
|
||||||
datetime_str.rsplit(':', 1)),
|
datetime_str.rsplit(':', 1)),
|
||||||
"%Y-%m-%dT%H:%M:%S%z").strftime(
|
"%Y-%m-%dT%H:%M:%S.%f%z").strftime(
|
||||||
"%Y-%m-%d")
|
"%Y-%m-%d")
|
||||||
|
continue
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('%s (%s)' % (e, type(e)))
|
print('%s (%s)' % (e, type(e)))
|
||||||
try:
|
|
||||||
date = datetime.strptime(''.join(
|
|
||||||
datetime_str.rsplit(':', 1)),
|
|
||||||
"%Y-%m-%dT%H:%M:%S.%f%z").strftime(
|
|
||||||
"%Y-%m-%d")
|
|
||||||
continue
|
|
||||||
except Exception as e:
|
|
||||||
print('%s (%s)' % (e, type(e)))
|
|
||||||
continue
|
|
||||||
# Print dates for development:
|
|
||||||
# print("date:", date, "today:", today)
|
|
||||||
# only the values of today are used so check for date in XML:
|
|
||||||
if date == today:
|
|
||||||
# now search for the currency exchange rate:
|
|
||||||
target_currency = item.find(rate_path +
|
|
||||||
'cb:targetCurrency', ns).text
|
|
||||||
value = float(item.find(observation_path +
|
|
||||||
'cb:value', ns).text)
|
|
||||||
value = float(value) # convert to float
|
|
||||||
foreign_value = value # copy to new value to have both.
|
|
||||||
|
|
||||||
if item.find(observation_path + 'cb:unit_mult', ns) is None:
|
|
||||||
# because it's dangerous to check for present,
|
|
||||||
# i check for none here and have to set the target
|
|
||||||
# to 1. as im multiplying it later.
|
|
||||||
unit_mult = float("1.0")
|
|
||||||
else:
|
|
||||||
# shift left by 2 digits with "/"
|
|
||||||
# https://stackoverflow.com/questions/8362792/
|
|
||||||
# because some currencys differ widly from CHF
|
|
||||||
unit_mult = item.find(observation_path +
|
|
||||||
'cb:unit_mult', ns).text
|
|
||||||
# unit_mult defaults to '0' so we check for 8 decimal
|
|
||||||
# values (2..-6) they represent the fracton value to
|
|
||||||
# calculate the correct decimalpoint.
|
|
||||||
if unit_mult == '2': # thinking of Bitcoins
|
|
||||||
unit_mult = '0.01'
|
|
||||||
if unit_mult == '1':
|
|
||||||
unit_mult = '0.10'
|
|
||||||
if unit_mult == '-1':
|
|
||||||
unit_mult = '10'
|
|
||||||
if unit_mult == '-2': # Japan Yen
|
|
||||||
unit_mult = '100'
|
|
||||||
if unit_mult == '-3':
|
|
||||||
unit_mult = '1000'
|
|
||||||
if unit_mult == '-4':
|
|
||||||
unit_mult = '10000'
|
|
||||||
if unit_mult == '-5':
|
|
||||||
unit_mult = '100000'
|
|
||||||
if unit_mult == '-6': # indian rupies
|
|
||||||
unit_mult = '1000000'
|
|
||||||
unit_mult = float(unit_mult) # convert to float
|
|
||||||
# calculate the Currency to CHF:
|
|
||||||
foreign_value = 1 / value
|
|
||||||
foreign_value *= unit_mult
|
|
||||||
value = value / unit_mult
|
|
||||||
# truncate it to decimal values provided by the xml:
|
|
||||||
foreign_value_round = round(foreign_value, 5)
|
|
||||||
# Print nice setup of all calculated currencys for development:
|
|
||||||
# print("date:", date, " 1 ", target_currency, " costs: ",
|
|
||||||
# CHFvalue, "CHF and 1 ", base_currency, " costs: ",
|
|
||||||
# FOREIGNvalue_round, target_currency)
|
|
||||||
exchange_rates.update(
|
|
||||||
{target_currency: foreign_value_round})
|
|
||||||
# Print the Dictionary:
|
|
||||||
# print(exchange_rates)
|
|
||||||
else:
|
|
||||||
continue
|
continue
|
||||||
return(exchange_rates, today)
|
# now search for the currency exchange rate:
|
||||||
|
target_currency = item.find(rate_path +
|
||||||
|
'cb:targetCurrency', ns).text
|
||||||
|
value = float(item.find(observation_path +
|
||||||
|
'cb:value', ns).text)
|
||||||
|
value = float(value) # convert to float
|
||||||
|
foreign_value = value # copy to new value to have both.
|
||||||
|
|
||||||
|
if item.find(observation_path + 'cb:unit_mult', ns) is None:
|
||||||
|
# because it's dangerous to check for present,
|
||||||
|
# i check for none here and have to set the target
|
||||||
|
# to 1. as im multiplying it later.
|
||||||
|
unit_mult = float("1.0")
|
||||||
|
else:
|
||||||
|
# shift left by 2 digits with "/"
|
||||||
|
# https://stackoverflow.com/questions/8362792/
|
||||||
|
# because some currencys differ widly from CHF
|
||||||
|
unit_mult = item.find(observation_path +
|
||||||
|
'cb:unit_mult', ns).text
|
||||||
|
# unit_mult defaults to '0' so we check for 8 decimal
|
||||||
|
# values (2..-6) they represent the fracton value to
|
||||||
|
# calculate the correct decimalpoint.
|
||||||
|
if unit_mult == '2': # thinking of Bitcoins
|
||||||
|
unit_mult = '0.01'
|
||||||
|
if unit_mult == '1':
|
||||||
|
unit_mult = '0.10'
|
||||||
|
if unit_mult == '-1':
|
||||||
|
unit_mult = '10'
|
||||||
|
if unit_mult == '-2': # Japan Yen
|
||||||
|
unit_mult = '100'
|
||||||
|
if unit_mult == '-3':
|
||||||
|
unit_mult = '1000'
|
||||||
|
if unit_mult == '-4':
|
||||||
|
unit_mult = '10000'
|
||||||
|
if unit_mult == '-5':
|
||||||
|
unit_mult = '100000'
|
||||||
|
if unit_mult == '-6': # indian rupies
|
||||||
|
unit_mult = '1000000'
|
||||||
|
unit_mult = float(unit_mult) # convert to float
|
||||||
|
# calculate the Currency to CHF:
|
||||||
|
foreign_value = 1 / value
|
||||||
|
foreign_value *= unit_mult
|
||||||
|
value = value / unit_mult
|
||||||
|
# truncate it to decimal values provided by the xml:
|
||||||
|
foreign_value_round = round(foreign_value, 5)
|
||||||
|
# Print nice setup of all calculated currencys for development:
|
||||||
|
# print("date:", date, " 1 ", target_currency, " costs: ",
|
||||||
|
# CHFvalue, "CHF and 1 ", base_currency, " costs: ",
|
||||||
|
# FOREIGNvalue_round, target_currency)
|
||||||
|
data = [{'date': date,
|
||||||
|
'currency': target_currency,
|
||||||
|
'exchangerate': foreign_value_round}]
|
||||||
|
exchange_rates.append(data)
|
||||||
|
# Print the Dictionary:
|
||||||
|
print(exchange_rates)
|
||||||
|
return(exchange_rates)
|
||||||
|
|
|
@ -20,7 +20,8 @@ class ExchangeRate_date(models.Model):
|
||||||
class ExchangeRate(models.Model):
|
class ExchangeRate(models.Model):
|
||||||
name = models.ForeignKey(ExchangeRate_name)
|
name = models.ForeignKey(ExchangeRate_name)
|
||||||
date = models.ForeignKey(ExchangeRate_date)
|
date = models.ForeignKey(ExchangeRate_date)
|
||||||
exchange_rate_to_chf = models.DecimalField(max_digits=12, decimal_places=5)
|
exchange_rate_to_chf = models.DecimalField(max_digits=12,
|
||||||
|
decimal_places=5)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.name)
|
return str(self.name)
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
<!DOCTYPE html>
|
{% extends "webshop/base.html" %}
|
||||||
<head>
|
{% block section_title %}Currencies in CHF{% endblock %}
|
||||||
<link rel="stylesheet" href="{{ STATIC_URL }}/static/admin/css/base.css" />
|
{% block content %}
|
||||||
</head>
|
<h2> {{ message }} </h2>
|
||||||
<body>
|
<h3> Frühere Daten: </h3>
|
||||||
<div id="content" class="flex">
|
<h4> US Dollars: </h4>
|
||||||
<h1>Currencies in CHF</h1>
|
|
||||||
<p> {{ message }} </p>
|
|
||||||
<h2> Frühere Daten: </h2>
|
|
||||||
<br>
|
|
||||||
<h3> US Dollars: </h3>
|
|
||||||
{% if currency_USD_list %}
|
{% if currency_USD_list %}
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -28,7 +23,7 @@
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
<h3> EURO: </h3>
|
<h4> EURO: </h4>
|
||||||
{% if currency_EUR_list %}
|
{% if currency_EUR_list %}
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -48,7 +43,7 @@
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
<h3> Japanese Yenn: </h3>
|
<h4> Japanese Yenn: </h4>
|
||||||
{% if currency_JPY_list %}
|
{% if currency_JPY_list %}
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -69,7 +64,7 @@
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
<h3> Great Britain Pounds: </h3>
|
<h4> Great Britain Pounds: </h4>
|
||||||
{% if currency_GBP_list %}
|
{% if currency_GBP_list %}
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -90,5 +85,4 @@
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</body>
|
{% endblock %}
|
||||||
</html>
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter()
|
||||||
|
def boldcoffee(value):
|
||||||
|
# currency_of_customer = request.session['currency']
|
||||||
|
return '%s !!gefiltert!!' % value
|
||||||
|
|
||||||
|
# excample filter: {{ article.price_in_chf|boldcoffee }}
|
|
@ -1,7 +1,9 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from currencies.views import currencies
|
from currencies.views import currencies, currency_update
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^currencies/$', currencies),
|
url(r'^currencies/$', currencies),
|
||||||
|
url(r'^ajax/currency_update/$',
|
||||||
|
currency_update,
|
||||||
|
name='currency_update'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,82 +1,133 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
import datetime
|
from datetime import datetime
|
||||||
|
from django.views.generic.edit import UpdateView
|
||||||
from currencies.models import (ExchangeRate,
|
from currencies.models import (ExchangeRate,
|
||||||
ExchangeRate_date,
|
ExchangeRate_date,
|
||||||
ExchangeRate_name)
|
ExchangeRate_name)
|
||||||
from currencies import exchange_rates
|
from currencies import exchange_rates
|
||||||
|
from django.http import JsonResponse
|
||||||
|
|
||||||
|
|
||||||
|
def currency_update(request):
|
||||||
|
# https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html
|
||||||
|
if request.GET.get('currency_update', None) == 'CHF':
|
||||||
|
data = {}
|
||||||
|
else:
|
||||||
|
currency = request.GET.get('currency_update', None)
|
||||||
|
data = ExchangeRate.objects.filter(
|
||||||
|
name__name=currency).values(
|
||||||
|
'exchange_rate_to_chf').latest(
|
||||||
|
'date__date')
|
||||||
|
print('currency:', currency, 'data: ', data)
|
||||||
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
|
||||||
def currencies(request):
|
def currencies(request):
|
||||||
# this function fetches the data from exchange_rates.py
|
|
||||||
# evaluates if the values are already stored and
|
|
||||||
# prepares the view all dynamicaly.
|
|
||||||
# It can grow in terms of more Currencies over time automaticaly.
|
|
||||||
today = ''
|
|
||||||
raw_data = []
|
|
||||||
try:
|
|
||||||
raw_data, today = exchange_rates.get_exchange_rate()
|
|
||||||
except Exception as e:
|
|
||||||
print('views raw_data: ', raw_data, 'error:', e) # assert False
|
|
||||||
message_no = "Already querried today: "
|
|
||||||
message_yes = " Updated successfully: "
|
|
||||||
if raw_data:
|
|
||||||
print(raw_data)
|
|
||||||
for currency, rate in raw_data.items():
|
|
||||||
if ExchangeRate.objects.filter(
|
|
||||||
date__date=today,
|
|
||||||
name__name=currency):
|
|
||||||
message_no += currency + ", "
|
|
||||||
# A: https://stackoverflow.com/a/27802801/4061870
|
|
||||||
else:
|
|
||||||
if ExchangeRate_date.objects.filter(date=today)[:1]:
|
|
||||||
try:
|
|
||||||
# lustigerweise gibt .values() den value und die id
|
|
||||||
# zurück. Ohne .values() gibts nur den "value"
|
|
||||||
date_dict = ExchangeRate_date.objects.filter(
|
|
||||||
date=today).values()
|
|
||||||
except Exception as e:
|
|
||||||
print('exdate_exists %s (%s) on %s'
|
|
||||||
% (e, type(e), today))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
exdate = ExchangeRate_date.objects.create(
|
|
||||||
date=today)
|
|
||||||
exdate.save()
|
|
||||||
except Exception as e:
|
|
||||||
print('exdate_not_exists %s (%s) for %s'
|
|
||||||
% (e, type(e), today))
|
|
||||||
if ExchangeRate_name.objects.filter(
|
|
||||||
name=currency)[:1]:
|
|
||||||
try:
|
|
||||||
name_dict = ExchangeRate_name.objects.filter(
|
|
||||||
name=currency).values()
|
|
||||||
except Exception as e:
|
|
||||||
print('exname_exists %s (%s) on %s'
|
|
||||||
% (e, type(e), currency))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
exname = ExchangeRate_name.objects.create(
|
|
||||||
name=currency)
|
|
||||||
exname.save()
|
|
||||||
except Exception as e:
|
|
||||||
print('exname_not_exists %s (%s) on %s'
|
|
||||||
% (e, type(e), currency))
|
|
||||||
try:
|
|
||||||
exrate = ExchangeRate.objects.create(
|
|
||||||
# name_id=name_id,
|
|
||||||
name_id=ExchangeRate_name.objects.get(
|
|
||||||
name=currency).id,
|
|
||||||
# date_id=date_id,
|
|
||||||
date_id=ExchangeRate_date.objects.get(
|
|
||||||
date=today).id,
|
|
||||||
exchange_rate_to_chf=rate,
|
|
||||||
)
|
|
||||||
exrate.save()
|
|
||||||
message_yes += currency + ", "
|
|
||||||
|
|
||||||
except Exception as e:
|
"""this function fetches the data from swiss national bank
|
||||||
print('exrate_create %s (%s) on %s for %s'
|
evaluates if the values are already stored and
|
||||||
% (e, type(e), currency, today))
|
prepares a view all dynamicaly.
|
||||||
|
It can grow in terms of more Currencies over time automaticaly."""
|
||||||
|
|
||||||
|
# Namespaces
|
||||||
|
ns = {'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
||||||
|
'none': 'http://purl.org/rss/1.0/',
|
||||||
|
'dc': 'http://purl.org/dc/elements/1.1/',
|
||||||
|
'dcterms': 'http://purl.org/dc/terms/',
|
||||||
|
'cb': 'http://www.cbwiki.net/wiki/index.php/Specification_1.2/'
|
||||||
|
}
|
||||||
|
SNB_URL = 'https://www.snb.ch/selector/de/mmr/exfeed/rss'
|
||||||
|
try:
|
||||||
|
urlsocket = exchange_rates.get_rss(SNB_URL)
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views get_rss(): ', urlsocket, 'error:', e)
|
||||||
|
try:
|
||||||
|
rss_tree = exchange_rates.parse_rss(urlsocket)
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views parse_rss(): ', rss_tree, 'error:', e)
|
||||||
|
try:
|
||||||
|
raw_data = exchange_rates.get_exchange_rate(rss_tree, ns)
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views get_exchange_rate(): ', raw_data, 'error:', e)
|
||||||
|
|
||||||
|
today = datetime.now().strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
message_no = "Already querried: "
|
||||||
|
length_of_message_no = len(message_no)
|
||||||
|
message_yes = " Updated successfully: "
|
||||||
|
length_of_message_yes = len(message_yes)
|
||||||
|
# raw_data can be empty. In this case skip:
|
||||||
|
if raw_data:
|
||||||
|
for one_obj_of_list in raw_data:
|
||||||
|
for exchange_rate_of_one_day in one_obj_of_list:
|
||||||
|
date = exchange_rate_of_one_day['date']
|
||||||
|
currency = exchange_rate_of_one_day['currency']
|
||||||
|
exchangerate = exchange_rate_of_one_day['exchangerate']
|
||||||
|
# check for already existing exrates per day and add
|
||||||
|
# to message that its already been saved.
|
||||||
|
if ExchangeRate.objects.filter(
|
||||||
|
date__date=date,
|
||||||
|
name__name=currency):
|
||||||
|
message_no += currency + ' on ' + date + ", "
|
||||||
|
else:
|
||||||
|
if ExchangeRate_date.objects.filter(date=date)[:1]:
|
||||||
|
# if data and currency is not yet present, save it.
|
||||||
|
try:
|
||||||
|
# A: https://stackoverflow.com/a/27802801/4061870
|
||||||
|
# lustigerweise gibt .values() den value und die id
|
||||||
|
# zurück. Ohne .values() gibts nur den "value"
|
||||||
|
date_dict = ExchangeRate_date.objects.filter(
|
||||||
|
date=date).values()
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views/exdate_exists \
|
||||||
|
%s (%s) on %s'
|
||||||
|
% (e, type(e), today))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
exdate = ExchangeRate_date.objects.create(
|
||||||
|
date=date)
|
||||||
|
exdate.save()
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views/exdate_not_exists \
|
||||||
|
%s (%s) for %s'
|
||||||
|
% (e, type(e), date))
|
||||||
|
if ExchangeRate_name.objects.filter(
|
||||||
|
name=currency)[:1]:
|
||||||
|
# if data and currency is not yet present, save it.
|
||||||
|
try:
|
||||||
|
name_dict = ExchangeRate_name.objects.filter(
|
||||||
|
name=currency).values()
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views/exname_exists \
|
||||||
|
%s (%s) on %s'
|
||||||
|
% (e, type(e), currency))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
exname = ExchangeRate_name.objects.create(
|
||||||
|
name=currency)
|
||||||
|
exname.save()
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views/exname_not_exists \
|
||||||
|
%s (%s) on %s'
|
||||||
|
% (e, type(e), currency))
|
||||||
|
try:
|
||||||
|
# save item to where id's match.
|
||||||
|
exrate = ExchangeRate.objects.create(
|
||||||
|
# name_id=name_id,
|
||||||
|
name_id=ExchangeRate_name.objects.get(
|
||||||
|
name=currency).id,
|
||||||
|
# date_id=date_id,
|
||||||
|
date_id=ExchangeRate_date.objects.get(
|
||||||
|
date=date).id,
|
||||||
|
exchange_rate_to_chf=exchangerate,
|
||||||
|
)
|
||||||
|
exrate.save()
|
||||||
|
message_yes += currency + ' on ' + date + ", "
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print('currencies/views/exrate_create \
|
||||||
|
%s (%s) on %s for %s'
|
||||||
|
% (e, type(e), currency, date))
|
||||||
|
|
||||||
# prepare messages:
|
# prepare messages:
|
||||||
# python can not swap a char insinde a sting so i have
|
# python can not swap a char insinde a sting so i have
|
||||||
|
@ -87,12 +138,13 @@ def currencies(request):
|
||||||
message_yes = message_yes[::-1] # invert the string
|
message_yes = message_yes[::-1] # invert the string
|
||||||
message_yes = message_yes.replace(",", "!", 1) # replace f. , with !
|
message_yes = message_yes.replace(",", "!", 1) # replace f. , with !
|
||||||
message_yes = message_yes[::-1] # invert the string back
|
message_yes = message_yes[::-1] # invert the string back
|
||||||
|
# here we evaluate what kind of message is valid:
|
||||||
if len(message_no) > 24 and len(message_yes) > 23:
|
if len(message_no) > length_of_message_no\
|
||||||
|
and len(message_yes) > length_of_message_yes:
|
||||||
message = message_no + message_yes
|
message = message_no + message_yes
|
||||||
elif len(message_no) > 24:
|
elif len(message_no) > 24:
|
||||||
message = message_no
|
message = message_no
|
||||||
elif len(message_yes) > 23:
|
elif len(message_yes) > 18:
|
||||||
message = message_yes
|
message = message_yes
|
||||||
elif datetime.datetime.today().isoweekday() == 6:
|
elif datetime.datetime.today().isoweekday() == 6:
|
||||||
message = """Die Abfrage wurde ohne ergebniss beendet.
|
message = """Die Abfrage wurde ohne ergebniss beendet.
|
||||||
|
@ -106,61 +158,18 @@ def currencies(request):
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
message = """Die Abfrage wurde ohne ergebniss beendet.
|
message = """Die Abfrage wurde ohne ergebniss beendet.
|
||||||
Kann es sein dass die SNB aufgrund eines Feiertages
|
|
||||||
geschlossen ist?
|
|
||||||
"""
|
"""
|
||||||
|
# know we can query our data for presentaton:
|
||||||
currency_list = ExchangeRate.objects.all()
|
currency_list = ExchangeRate.objects.all()
|
||||||
currency_USD_list = ExchangeRate.objects.filter(name__name='USD')
|
currency_USD_list = ExchangeRate.objects.filter(
|
||||||
currency_EUR_list = ExchangeRate.objects.filter(name__name='EUR')
|
name__name='USD').order_by('date__date')
|
||||||
currency_JPY_list = ExchangeRate.objects.filter(name__name='JPY')
|
currency_EUR_list = ExchangeRate.objects.filter(
|
||||||
currency_GBP_list = ExchangeRate.objects.filter(name__name='GBP')
|
name__name='EUR').order_by('date__date')
|
||||||
# -------------------------------------------------------------------
|
currency_JPY_list = ExchangeRate.objects.filter(
|
||||||
# -------------------------------------------------------------------
|
name__name='JPY').order_by('date__date')
|
||||||
# I leave this part in the document as history.
|
currency_GBP_list = ExchangeRate.objects.filter(
|
||||||
# Problem is that i get the expected List with dictionaries like:
|
name__name='GBP').order_by('date__date')
|
||||||
# view_currencies_list[
|
# and publish it on template:
|
||||||
# {'date': '2017-12-29, 'USD':'1.00', 'EUR':'1.00', 'GBP':'1.00', 'JPY':'1.00'},
|
|
||||||
# {'date': '2017-12-30, 'USD':'1.00', 'EUR':'1.00', 'GBP':'1.00', 'JPY':'1.00'},
|
|
||||||
# ]
|
|
||||||
# but the dict of 'date:' does not seam to deliver the same values as
|
|
||||||
# the dict's of key name:'USD' im not able to fix this in moment.
|
|
||||||
# nor am i able to generate a HTML table with date | USD | EUR | ...
|
|
||||||
# -------------------------------------------------------------------
|
|
||||||
# -------------------------------------------------------------------
|
|
||||||
# prepare data to be displayed in a html table:
|
|
||||||
# https://stackoverflow.com/questions/8749158/removing-duplicates-from-dictionary#8749473
|
|
||||||
# A: https://stackoverflow.com/questions/37205793/django-values-list-vs-values#37205928
|
|
||||||
# B: https://stackoverflow.com/questions/6521892/how-to-access-a-dictionary-key-value-present-inside-a-list
|
|
||||||
# # search for currencies in a date and apend them to the list
|
|
||||||
# view_currency_list = []
|
|
||||||
# view_currencies_list = ExchangeRate_name.objects.all()
|
|
||||||
# view_dates_list = ExchangeRate_date.objects.all()
|
|
||||||
# count_date = 0
|
|
||||||
# count_currencies = 0
|
|
||||||
# for view_date in view_dates_list:
|
|
||||||
# count_date += 1
|
|
||||||
# view_currency_dict = {view_date}
|
|
||||||
# # view_currency_dict.update({})
|
|
||||||
# for view_currency in view_currencies_list:
|
|
||||||
# count_currencies += 1
|
|
||||||
# try:
|
|
||||||
# x = ExchangeRate.objects.filter(date__date=str(
|
|
||||||
# view_date),
|
|
||||||
# name__name=str(
|
|
||||||
# view_currency
|
|
||||||
# )).values() # A
|
|
||||||
# view_exchange_rate_to_chf = x[0]['exchange_rate_to_chf']
|
|
||||||
# except Exception as e:
|
|
||||||
# print('prepare_view %s (%s) for %s on %s is %s'
|
|
||||||
# % (e, type(e), view_currency, view_date,
|
|
||||||
# view_exchange_rate_to_chf))
|
|
||||||
# view_exchange_rate_to_chf = " "
|
|
||||||
#
|
|
||||||
# view_currency_dict.update({view_currency:
|
|
||||||
# view_exchange_rate_to_chf}) # B
|
|
||||||
#
|
|
||||||
# view_currency_list.append(view_currency_dict)
|
|
||||||
# assert False
|
|
||||||
return render(request,
|
return render(request,
|
||||||
'currencies/index.html',
|
'currencies/index.html',
|
||||||
{'currency_list': currency_list,
|
{'currency_list': currency_list,
|
||||||
|
|
|
@ -44,7 +44,6 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'currencies',
|
'currencies',
|
||||||
'bootstrap3',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -132,9 +131,34 @@ USE_TZ = True
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/1.10/howto/static-files/
|
# https://docs.djangoproject.com/en/1.10/howto/static-files/
|
||||||
|
# seams like it changed with 1.13+ (14.1.18|IH)
|
||||||
|
# https://stackoverflow.com/a/14800489/4061870
|
||||||
|
|
||||||
|
# Absolute path to the directory static files should be collected to.
|
||||||
|
# Don't put anything in this directory yourself; store your static files
|
||||||
|
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
|
||||||
|
# Example: "/home/media/media.lawrence.com/static/"
|
||||||
|
STATIC_ROOT = ''
|
||||||
|
|
||||||
|
# URL prefix for static files.
|
||||||
|
# Example: "http://media.lawrence.com/static/"
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
STATIC_ROOT = '/vagrant/django/didgeridoo/static/'
|
|
||||||
|
# Additional locations of static files
|
||||||
|
STATICFILES_DIRS = (
|
||||||
|
# Put strings here, like "/home/html/static" or "C:/www/django/static".
|
||||||
|
# Always use forward slashes, even on Windows.
|
||||||
|
# Don't forget to use absolute paths, not relative paths.
|
||||||
|
'/vagrant/django/didgeridoo/static',
|
||||||
|
)
|
||||||
|
|
||||||
|
# List of finder classes that know how to find static files in
|
||||||
|
# various locations.
|
||||||
|
STATICFILES_FINDERS = (
|
||||||
|
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||||
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||||
|
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||||
|
)
|
||||||
|
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
MEDIA_ROOT = '/srv/media/'
|
MEDIA_ROOT = '/srv/media/'
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
$("#id_currency_update").change(function () {
|
||||||
|
var currency_update = $(this).val();
|
||||||
|
$("#id_currency_update").val(currency_update);
|
||||||
|
$.ajax({
|
||||||
|
url: '/ajax/currency_update/',
|
||||||
|
data: {
|
||||||
|
'currency_update': currency_update
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (data) {
|
||||||
|
var foo = jQuery.parseJSON(data);
|
||||||
|
alert("es pop auf! --dies kommt von: static/js/app.js--." + foo.currency_update);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//document.getElementById('id_currency_update').getElementsByTagName('currency_update')
|
||||||
|
//$("#id_currency_update").val('USD').selected = 'selected';
|
||||||
|
|
||||||
|
//https://stackoverflow.com/a/30489067/4061870
|
||||||
|
// var obj = document.getElementById("id_currency_update");
|
||||||
|
// for(i=0; i<obj.options.length; i++){
|
||||||
|
// if(obj.options[i].value == "USD"){
|
||||||
|
// obj.selectedIndex = i;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var e document.getElementById("id_currency_update");
|
||||||
|
//e.value = currency_update;
|
|
@ -28,28 +28,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav class="navbar navbar-default">
|
{% block nav %}{% include "webshop/nav.html" %}{% endblock %}
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<a class="navbar-brand" href="{% url 'index' %}">
|
|
||||||
HOME
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li><a href="#">CART</a></li>
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
<li><a href="{% url 'profile' %}">PROFILE</a></li>
|
|
||||||
<li><a href="{% url 'logout' %}">LOGOUT</a></li>
|
|
||||||
{% else %}
|
|
||||||
<li><a href="{% url 'login' %}">LOGIN</a></li>
|
|
||||||
{% endif %}
|
|
||||||
<li><a href="#">CURRENCY</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-2">
|
<div class="col-md-2">
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% if category_list %}
|
{% if category_list %}
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -67,13 +49,15 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-10 ">
|
<div class="col-md-8 panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
<h1>
|
<h1>
|
||||||
{% block section_title %}{% endblock %}
|
{% block section_title %}{% endblock %}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-10 ">
|
<div class="panel-body">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,12 +66,37 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
{% block footer %}
|
{% block footer %}
|
||||||
This is a case study project of Ivan Hörler and Andreas Zweili. </br>
|
<div class="container text-center">
|
||||||
It is a school project/excercise and has no commercial intent.
|
<hr>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<ul class="nav nav-pills nav-justified">
|
||||||
|
<li>
|
||||||
|
<a id='school'
|
||||||
|
target='_blank'
|
||||||
|
href='http://www.ibz.ch'
|
||||||
|
>This is a case study project of Ivan Hörler and Andreas Zweili.
|
||||||
|
</br>
|
||||||
|
It is a school project/excercise and has no commercial intent.
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/currencies">Currencies</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">How to use</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
|
||||||
|
<script src="{% static 'js/app.js' %}"></script>
|
||||||
|
<script>{% block javascript %}{% endblock %}</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "webshop/base.html" %}
|
{% extends "webshop/base.html" %}
|
||||||
|
{% load customfilters %}
|
||||||
{% block section_title %}Articles{% endblock %}
|
{% block section_title %}Articles{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if articles_list %}
|
{% if articles_list %}
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
{% block nav %}
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="{% url 'index' %}">
|
||||||
|
HOME
|
||||||
|
</a>
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a href="#">CART</a></li>
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'profile' %}">PROFILE</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'logout' %}">LOGOUT</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'login' %}">LOGIN</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
<!-- https://pypi.python.org/pypi/django-select-multiple-field -->
|
||||||
|
<form method="POST" novalidate>
|
||||||
|
<select name="currency_update" id="id_currency_update">
|
||||||
|
<option value="CHF">CHF</option>
|
||||||
|
<option value="USD">USD</option>
|
||||||
|
<option value="GBP">GBP</option>
|
||||||
|
<option value="JPY">JPY</option>
|
||||||
|
</select>
|
||||||
|
{% csrf_token %}
|
||||||
|
</form>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!--
|
||||||
|
Es wird auf id im app.js file gemached.
|
||||||
|
die URL wird im app.js gesetzt
|
||||||
|
und mit urls.py weitergereicht.
|
||||||
|
dann auf name im views.py gemached und ausgeführt.
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
|
@ -11,6 +11,10 @@ urlpatterns = [
|
||||||
views.articles_in_category,
|
views.articles_in_category,
|
||||||
name='category'),
|
name='category'),
|
||||||
url('^', include('django.contrib.auth.urls')),
|
url('^', include('django.contrib.auth.urls')),
|
||||||
url(r'^profile/$', views.profile, name='profile'),
|
url(r'^profile/$',
|
||||||
url(r'^registration/$', views.registration, name='registration'),
|
views.profile,
|
||||||
|
name='profile'),
|
||||||
|
url(r'^registration/$',
|
||||||
|
views.registration,
|
||||||
|
name='registration'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,6 +11,7 @@ from webshop.models import (Article,
|
||||||
Picture)
|
Picture)
|
||||||
from webshop.forms import RegistrationForm
|
from webshop.forms import RegistrationForm
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@misc{django_extensions,
|
@misc{djangoextensions,
|
||||||
month = {{01}},
|
month = {{01}},
|
||||||
note = {{\url{https://github.com/django-extensions/django-extensions}}},
|
note = {{\url{https://github.com/django-extensions/django-extensions}}},
|
||||||
Urldate = {{2018-01-05}},
|
Urldate = {{2018-01-05}},
|
||||||
|
@ -16,3 +16,93 @@
|
||||||
year = {2016},
|
year = {2016},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@misc{removeadd,
|
||||||
|
month = {{01}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/21454467/7723859}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {Avinash Garg},
|
||||||
|
title = {{How to remove Add button in Django admin, for specific Model?}},
|
||||||
|
year = {2014},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{removedelete,
|
||||||
|
month = {{08}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/7031093/7723859}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {Jonathan R.},
|
||||||
|
title = {{In Django Admin how do I disable the Delete link}},
|
||||||
|
year = {2011},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{readonly,
|
||||||
|
month = {{09}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/46124159/7723859}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {gdlmx},
|
||||||
|
title = {{Display a model field as readonly in Django admin}},
|
||||||
|
year = {2017},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{timezone,
|
||||||
|
month = {{07}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/38239673}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {Antoine Pinsard},
|
||||||
|
title = {{Django: timezone.now vs timezone.now()}},
|
||||||
|
year = {2016},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{usermodel,
|
||||||
|
month = {{07}},
|
||||||
|
note = {{\url{https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {Vitor Freitas},
|
||||||
|
title = {{How to Extend Django User Model}},
|
||||||
|
year = {2016},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{djangogirls,
|
||||||
|
month = {{10}},
|
||||||
|
note = {{\url{https://tutorial.djangogirls.org/en/}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {DjangoGirls},
|
||||||
|
title = {{Django Girls Tutorial}},
|
||||||
|
year = {2017},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{images,
|
||||||
|
month = {{08}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/1235542}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {steve},
|
||||||
|
title = {{How do I include image files in Django templates?}},
|
||||||
|
year = {2009},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{djangodoc,
|
||||||
|
month = {{01}},
|
||||||
|
note = {{\url{https://docs.djangoproject.com/en/1.11/}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {Django Foundation},
|
||||||
|
title = {{Django documentation}},
|
||||||
|
year = {2018},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{upload,
|
||||||
|
month = {{12}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/8542030}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {Akseli Pal{\'{e}}n},
|
||||||
|
title = {{Need a minimal Django file upload example [closed]}},
|
||||||
|
year = {2011},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{tree,
|
||||||
|
month = {{09}},
|
||||||
|
note = {{\url{https://stackoverflow.com/a/39729832}}},
|
||||||
|
Urldate = {{2018-01-15}},
|
||||||
|
author = {ht\_},
|
||||||
|
title = {{Tree view in django template}},
|
||||||
|
year = {2016},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
606
docs/doku.org
606
docs/doku.org
|
@ -5,6 +5,7 @@
|
||||||
#+LATEX_CLASS_OPTIONS: [a4paper,11pt]
|
#+LATEX_CLASS_OPTIONS: [a4paper,11pt]
|
||||||
#+LaTeX_HEADER: \input{style}
|
#+LaTeX_HEADER: \input{style}
|
||||||
#+OPTIONS: H:5 todo:t
|
#+OPTIONS: H:5 todo:t
|
||||||
|
#+LANGUAGE: de
|
||||||
#+STARTUP: align
|
#+STARTUP: align
|
||||||
|
|
||||||
|
|
||||||
|
@ -390,7 +391,7 @@ Abbildung: ([[fig:umweltgrafik]]) grafisch dargestellt.
|
||||||
*** NEXT Risikobewertung
|
*** NEXT Risikobewertung
|
||||||
|
|
||||||
#+CAPTION: Risikobewertung Wahrscheinlichkeit
|
#+CAPTION: Risikobewertung Wahrscheinlichkeit
|
||||||
#+ATTR_LATEX: :align l|l
|
#+ATTR_LATEX: :align l|l :placement [H]
|
||||||
#+NAME: tab:wahrscheinlichkeit
|
#+NAME: tab:wahrscheinlichkeit
|
||||||
| *Bewertung* | *Beschreibung: Warscheinlichkeit (W)* |
|
| *Bewertung* | *Beschreibung: Warscheinlichkeit (W)* |
|
||||||
|-------------+---------------------------------------|
|
|-------------+---------------------------------------|
|
||||||
|
@ -399,7 +400,7 @@ Abbildung: ([[fig:umweltgrafik]]) grafisch dargestellt.
|
||||||
| 3 = hoch | Hohe warscheinlichkeit > 50% |
|
| 3 = hoch | Hohe warscheinlichkeit > 50% |
|
||||||
|
|
||||||
#+CAPTION: Risikobewertung Auswirkung
|
#+CAPTION: Risikobewertung Auswirkung
|
||||||
#+ATTR_LATEX: :align l|l
|
#+ATTR_LATEX: :align l|l :placement [H]
|
||||||
#+NAME: tab:auswirkung
|
#+NAME: tab:auswirkung
|
||||||
| *Bewertung* | *Beschreibung: Auswirkung (A)* |
|
| *Bewertung* | *Beschreibung: Auswirkung (A)* |
|
||||||
|-------------+-------------------------------------------------|
|
|-------------+-------------------------------------------------|
|
||||||
|
@ -408,7 +409,7 @@ Abbildung: ([[fig:umweltgrafik]]) grafisch dargestellt.
|
||||||
| 3 = hoch | Projekt erfüllt nicht alle Anforderungen |
|
| 3 = hoch | Projekt erfüllt nicht alle Anforderungen |
|
||||||
|
|
||||||
#+CAPTION: Grafische Darstellung der Risikoanalyse
|
#+CAPTION: Grafische Darstellung der Risikoanalyse
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+NAME: fig:risk
|
#+NAME: fig:risk
|
||||||
[[file:diagrammes/risk_analysis.eps]]
|
[[file:diagrammes/risk_analysis.eps]]
|
||||||
|
|
||||||
|
@ -475,7 +476,7 @@ Als Interessent möchte ich...
|
||||||
- die Preise in einer anderen Währung anzeigen können um die
|
- die Preise in einer anderen Währung anzeigen können um die
|
||||||
Preise in einer mir bekannten Währung vergleichen zu können.
|
Preise in einer mir bekannten Währung vergleichen zu können.
|
||||||
|
|
||||||
*** TODO Use Cases
|
*** Use Cases
|
||||||
|
|
||||||
Ein Use Case sammelt alle möglichen Szenarien, die eintreten können,
|
Ein Use Case sammelt alle möglichen Szenarien, die eintreten können,
|
||||||
wenn ein Akteur versucht, mit Hilfe des betrachteten Systems ein
|
wenn ein Akteur versucht, mit Hilfe des betrachteten Systems ein
|
||||||
|
@ -506,158 +507,617 @@ Webshops beschränkt.
|
||||||
#+LATEX:\end{landscape}
|
#+LATEX:\end{landscape}
|
||||||
#+LATEX:\newpage
|
#+LATEX:\newpage
|
||||||
|
|
||||||
**** NEXT Use Case Detailbeschreibung
|
**** Use Case Detailbeschreibung
|
||||||
|
|
||||||
#+CAPTION: Use Case
|
Use Cases werden in der Regel mit Hilfe einer sogenannten Use Case
|
||||||
#+ATTR_LATEX: :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}|
|
Schablone im Detail beschrieben damit klar ist wie der Ablauf jeweils
|
||||||
|
genau aussieht. Die von uns verwendete Schablone wurde von Alistair
|
||||||
|
Cockburn definiert.
|
||||||
|
|
||||||
|
Da ein Web-Shop eine sehr umfangreiche Applikation ist gibt es sehr
|
||||||
|
viele Use Cases welche beschrieben und umgesetzt werden müssen. Aus
|
||||||
|
zeitlichen Gründen haben wir nur einen kleinen Teil der Use Cases im
|
||||||
|
Detail ausgearbeitet. Insbesondere diese welche wir selber
|
||||||
|
ausprogrammiert haben. Die gesamte Liste an Use Cases sieht wie folgt
|
||||||
|
aus, die Use Cases mit den Nummern wurden dabei im Detail ausgearbeitet:
|
||||||
|
|
||||||
|
#+LATEX: {\footnotesize
|
||||||
|
| - [[*Artikel durchst%C3%B6bern][1.0 Artikel durchstöbern]] | - Kategorie erfassen (Admin Funktion) |
|
||||||
|
| - [[Registration][2.0 Registration]] | - Kategorie ändern (Admin Funktion) |
|
||||||
|
| - [[User Login][2.1 User Login]] | - Kategorie löschen (Admin Funktion) |
|
||||||
|
| - User Profil ansehen | - Bild hochladen (Admin Funktion) |
|
||||||
|
| - [[Artikel in Warenkorb legen][3.0 Artikel in Warenkorb legen]] | - Bild ändern (Admin Funktion) |
|
||||||
|
| - [[W%C3%A4hrung %C3%A4ndern][3.1 Währung ändern]] | - Bild löschen (Admin Funktion) |
|
||||||
|
| - Währung aktualisieren (Admin Funktion) | - Bestellung erfassen (Admin Funktion) |
|
||||||
|
| - [[Checkout][3.2 Checkout]] | - [[Bestellung %C3%A4ndern/korrigieren][7.0 Bestellung ändern/korrigieren (Admin Funktion)]] |
|
||||||
|
| - [[User Passwort %C3%A4ndern][4.0 User Passwort ändern (Admin Funktion)]] | - Bestellung löschen (Admin Funktion) |
|
||||||
|
| - [[Artikel erfassen][5.0 Artikel erfassen (Admin Funktion)]] | - [[max_pictures Option anpassen][6.0 max_pictures Option anpassen (Admin Funktion)]] |
|
||||||
|
| - Artikel ändern (Admin Funktion) | - max_pictures Option deaktivieren (Admin Funktion) |
|
||||||
|
| - Artikel löschen (Admin Funktion) | - User erfassen (Admin Funktion) |
|
||||||
|
| - Materialbestellung erfassen (Admin Funktion) | - User/Personen Daten ändern (Admin Funktion) |
|
||||||
|
| - Materialbestellung ändern/korrigieren (Admin Funktion) | - User löschen (Admin Funktion) |
|
||||||
|
| - Materialbestellung löschen (Admin Funktion) | - User Berechtigungen anpassen (Admin Funktion) |
|
||||||
|
| - Stadt hinzufügen (Admin Funktion) | |
|
||||||
|
| - Stadt ändern (Admin Funktion) | |
|
||||||
|
| - Stadt löschen (Admin Funktion) | |
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Artikel durchstöbern
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use 1.0 Artikel durchstöbern
|
||||||
|
#+ATTR_LATEX::environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:browse_article
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 1.0 Artikel durchstöbern |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Durchklicken der verschiedenen Kategorieren und ansehen der Artikel Details und Bilder. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Kunden, Interessenten |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigegeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | User möchte Artikel einsehen |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | Website aufgerufen |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Website aufrufen |
|
||||||
|
| | 2. Kategorienen durchsehen |
|
||||||
|
| | 3. Artikel anklicken |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Registration
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 2.0 Registration
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:registration
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 2.0 Registration |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein User registriert sich einen Account. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Interessent |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigebgen |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | User möchte einen Account erstellen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | Email Adresse vorhanden |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Account wurde erfolgreich erstellt. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. User klickt auf den Link "Go to registration.". |
|
||||||
|
| | 2. User füllt das Registrations Formular aus. |
|
||||||
|
| | 3. User schliesst die Registrierung mit Klick auf "Register" ab. |
|
||||||
|
| | 4. Die Website leitet ihn in den Login Bereich um. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | 1. User klickt auf den Link "Go to registration.". |
|
||||||
|
| | 2. User füllt das Registrations Formular mir falschen Daten aus. |
|
||||||
|
| | 3. Die Website gibt die entsprechenden Fehler aus. |
|
||||||
|
| | 4. Der User korrigiert die Angaben. |
|
||||||
|
| | 5. User schliesst die Registrierung mit Klick auf "Register" ab. |
|
||||||
|
| | 6. Die Website leitet ihn in den Login Bereich um. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** User Login
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 2.1 User Login
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
#+NAME: tab:login
|
#+NAME: tab:login
|
||||||
|---------------------+-----------------------------|
|
|---------------------+--------------------------------|
|
||||||
| *Identifier + Name* | |
|
| | <30> |
|
||||||
|---------------------+-----------------------------|
|
| *Identifier + Name* | 2.1 User Login |
|
||||||
| *Description* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Description* | Ein Kunde logt sich auf der Website ein. |
|
||||||
| *Actors* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Actors* | Kunde |
|
||||||
| *Status* | Freigegeben |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Status* | Freigeben |
|
||||||
| *Includes* | - |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Includes* | - |
|
||||||
| *Trigger* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Trigger* | Ein Kunde möchte sich einloggen. |
|
||||||
| *Preconditions* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Preconditions* | UC 2.0 erfolgreich abgeschlossen. |
|
||||||
| *Postconditions* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Postconditions* | User hat sich erfolgreich eingeloggt. |
|
||||||
| *Normal Flow* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Normal Flow* | 1. User klickt in der Navigation auf "Login". |
|
||||||
| *Alternative Flow* | - |
|
| | 2. User gibt Zugangsdaten ein. |
|
||||||
|---------------------+-----------------------------|
|
| | 3. User beendet Login mit Klick auf "Login". |
|
||||||
| *Notes* | - |
|
| | 4. Die Website leitet ihn auf die Index Seite um und zeigt neu eine "Profil" und "Logout" Schaltfläche. |
|
||||||
|---------------------+-----------------------------|
|
|---------------------+--------------------------------|
|
||||||
| *UC History* | 1.0 Darft erstellt durch AZ |
|
| *Alternative Flow* | 1. User klickt in der Navigation auf "Login". |
|
||||||
|---------------------+-----------------------------|
|
| | 2. User gibt falsche Zugangsdaten ein. |
|
||||||
| *Author* | A. Zweili & I. |
|
| | 3. User beendet Login mit Klick auf "Login". |
|
||||||
|---------------------+-----------------------------|
|
| | 4. Die Website gibt entsprechende Fehlermeldungen aus. |
|
||||||
| *Date* | |
|
|---------------------+--------------------------------|
|
||||||
|---------------------+-----------------------------|
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Artikel in Warenkorb legen
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 3.0 Artikel in Warenkorb legen
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:cart
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 3.0 Artikel in Warenkorb legen |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein Kunde legt einen Artikel in den Warenkorb. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Kunde |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Ein Kunde möchte einen Artikel kaufen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | UC2.1 erfolgreich abgeschlossen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Artikel wurde im Warenkorb gespeichert. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. User klickt einen Artikel an. |
|
||||||
|
| | 2. User klickt auf "Add to cart". |
|
||||||
|
| | 3. Die Website speichert den Artikel im Warenkorb. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | 1. User klickt einen Artikel mit Stock "0.0" an. |
|
||||||
|
| | 2. User klickt auf "Add to cart". |
|
||||||
|
| | 3. Die Website meldet "We are sorry but this item is out of stock.". |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Währung ändern
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 3.1 Währung ändern
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:currency
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 3.1 Währung ändern |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein User ändert die Währung für die Preise. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Kunde, Interessent |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Ein User möchte sich die Preise in einer anderen Währung anzeigen lassen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Die Preise werden in der gewünschten Währung angezeigt. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Der User wählt im Drop-Down die gewünschte Währung aus. |
|
||||||
|
| | 2. Die Website aktualisiert und zeigt die neu berechneten Preise an. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Checkout
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 3.2 Checkout
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:checkout
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 3.2 Checkout |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | User gibt seinen Warenkorb als Bestellung auf. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Kunde |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Ein Kunde möchte seine Artikel im Warenkorb bestellen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | UC2.1 und UC3.0 erfolgreich abgeschlossen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Die Bestellung wurde von der Website gespeichert. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Der User klickt in der Navigation auf "Cart". |
|
||||||
|
| | 2. Die Website leitet ihn zum Warenkorb um. |
|
||||||
|
| | 3. Der User klickt dort auf "Checkout". |
|
||||||
|
| | 4. Die Website gibt ihm eine komplette Übersicht der Bestellung sowie der Empfängeradresse. |
|
||||||
|
| | 5. User klickt auf "Send order". |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | 1. Der User klickt in der Navigation auf "Cart". |
|
||||||
|
| | 2. Die Website leitet ihn zum Warenkorb um. |
|
||||||
|
| | 3. Der User klickt dort auf "Checkout". |
|
||||||
|
| | 4. Die Website gibt ihm eine komplette Übersicht der Bestellung sowie der Empfängeradresse. |
|
||||||
|
| | 5. Der User bricht die Bestellung mit Klick auf "Cancel" ab. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** User Passwort ändern
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: 4.0 User Passwort ändern
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:password
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 4.0 User Passwort ändern |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein Administrator ändert ein User Kennwort. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Verwaltung |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Ein Administrator möchte ein Passwort zurücksetzen weil es vergessen wurde. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | Account mit Administrationsrechten vorhanden. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Auf dem User Account wurde ein neues Passwort gesetzt. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klickt auf "Users". |
|
||||||
|
| | 3. Admin wählt den passenden Account aus. |
|
||||||
|
| | 4. Klickt unterhalb des Passwort Hashes auf "this form". |
|
||||||
|
| | 5. Gibt zweimal das neue Passwort ein und klickt "Change password". |
|
||||||
|
| | 6. Die Website leitet den Admin zurück zu den User Details. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klicht auf "Users". |
|
||||||
|
| | 3. Admin wählt den passenden Account aus. |
|
||||||
|
| | 4. Klickt unterhalb des Passwort Hashes auf "this form". |
|
||||||
|
| | 5. Gibt zweimal ein invalides Passwort ein und klickt "Change password". |
|
||||||
|
| | 6. Die Website gibt eine entsprechende Fehlermeldung aus. |
|
||||||
|
| | 7. Der Admin korrigiert die Passwörter und klickt auf "Change password". |
|
||||||
|
| | 8. Die Website leitet den Admin zurück zu den User Details. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Artikel erfassen
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: 5.0 Artikel erfassen
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:create_article
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 5.0 Artikel erfassen |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein Administrator erfasst einen neuen Artikel mit Bildern. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Verwaltung |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Um das Sortiment zu erweitern möchte der Administrator einen neuen Artikel erfassen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | Account mit Administrationsrechten vorhanden. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Der Artikel wir im Webshop angezeigt. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klickt neben "Articles" auf "+ Add". |
|
||||||
|
| | 3. Admin füllt das Formular aus und lädt ein Bild hoch. |
|
||||||
|
| | 4. Klickt unten rechts auf "Save". |
|
||||||
|
| | 5. Die Website speichert den Artikel in der Datenbank. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klickt neben "Articles" auf "+ Add". |
|
||||||
|
| | 3. Admin füllt das Formular aus und lädt zuviele Bilder hoch. |
|
||||||
|
| | 4. Klickt unten rechts auf "Save". |
|
||||||
|
| | 5. Die Website gibt eine entsprechende Fehlermeldung aus. |
|
||||||
|
| | 6. Der Admin entfernt die überzähligen Bilder. |
|
||||||
|
| | 7. Die Website speichert den Artikel in der Datenbank. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** max_pictures Option anpassen
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 6.0 max_pictures Option anpassen
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:max_pictures
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 6.0 max_pictures Option anpassen |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein Administrator ändert die max_pictures Option. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Verwaltung |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Ein Administrator möchte die maximale Anzahl Bilder pro Artikel anpassen. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | Account mit Administrationsrechten vorhanden. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Der neue Wert wurde von der Website gespeichert. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klickt auf "Options" und anschliessend auf "max_pictures". |
|
||||||
|
| | 3. Admin ändert den Wert "Value" zu einer Ganzzahl seiner Wahl. |
|
||||||
|
| | 4. Klickt unten rechts auf "Save". |
|
||||||
|
| | 5. Die Website speichert den Wert in der Datenbank. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klickt auf "Options" und anschliessend auf "max_pictures". |
|
||||||
|
| | 3. Admin ändert den Wert "Value" zu einer Gleitzahl seiner Wahl. |
|
||||||
|
| | 4. Klickt unten rechts auf "Save". |
|
||||||
|
| | 5. Die Website gibt eine entsprechende Fehlermeldung aus. |
|
||||||
|
| | 6. Der Admin korrigiert den Wert und klickt "Save". |
|
||||||
|
| | 7. Die Website speichert den Wert in der Datenbank. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
|
***** Bestellung ändern/korrigieren
|
||||||
|
|
||||||
|
#+LATEX:{\footnotesize
|
||||||
|
#+CAPTION: Use Case 7.0 Bestellung ändern/korrigieren
|
||||||
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{.25\textwidth}|p{.7\textwidth}| :placement [H]
|
||||||
|
#+NAME: tab:change_order
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| | <30> |
|
||||||
|
| *Identifier + Name* | 7.0 Bestellung ändern/korrigieren |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Description* | Ein Administrator korrigiert eine Bestellung. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Actors* | Verwaltung |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Status* | Freigeben |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Includes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Trigger* | Administrator ändert auf Wunsch eines Kunden eine Bestellung. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Preconditions* | Account mit Administrationsrechten vorhanden. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Postconditions* | Die Bestellung hat eine angepasste Artikel Menge. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Normal Flow* | 1. Der Administrator loggt sich unter https://didgeridoo.ml/admin ein. |
|
||||||
|
| | 2. Admin klickt auf "Orders" und anschliessend auf die passende Order ID. |
|
||||||
|
| | 3. Admin ändert den Wert "Amount" des ersten Artikels zu 0. |
|
||||||
|
| | 4. Klickt unten rechts auf "Save". |
|
||||||
|
| | 5. Die Website speichert die Bestellung in der Datenbank. |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Alternative Flow* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Notes* | - |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *UC History* | 1.0 Darft erstellt durch AZ |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Author* | A. Zweili & I. Hörler |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
| *Date* | 16.01.2018 |
|
||||||
|
|---------------------+--------------------------------|
|
||||||
|
#+LATEX:}
|
||||||
|
|
||||||
*** NEXT Mockup
|
*** NEXT Mockup
|
||||||
|
|
||||||
#+CAPTION: Ein frühes Mockup des Shop
|
#+CAPTION: Ein frühes Mockup des Shop
|
||||||
#+ATTR_LATEX: :width \textwidth
|
#+ATTR_LATEX: :width \textwidth
|
||||||
#+NAME: mockup
|
#+NAME: mockup
|
||||||
[[file:pictures/mockup-full-snipet.png][file:pictures/mockup-full-snipet.png]]
|
[[./pictures/mockup-full-snipet.png]]
|
||||||
|
|
||||||
|
*** TODO Models
|
||||||
|
|
||||||
|
\footcite{djangoextensions}
|
||||||
|
|
||||||
*** TODO Klassendiagramme der Models
|
|
||||||
**** NEXT Category
|
**** NEXT Category
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
\footcite{tree}
|
||||||
|
|
||||||
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Kategorien
|
#+CAPTION: Klassenmodel für Kategorien
|
||||||
#+NAME: fig:category
|
#+NAME: fig:category
|
||||||
[[file:pictures/class_category.png]]
|
[[./pictures/class_category.png]]
|
||||||
|
|
||||||
|
|
||||||
**** NEXT Option
|
**** NEXT Option
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
\footcite{readonly}
|
||||||
|
\footcite{removeadd}
|
||||||
|
\footcite{removedelete}
|
||||||
|
|
||||||
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Optionen
|
#+CAPTION: Klassenmodel für Optionen
|
||||||
#+NAME: fig:option
|
#+NAME: fig:option
|
||||||
[[file:pictures/class_option.png][file:pictures/class_option.png]]
|
[[./pictures/class_option.png]]
|
||||||
|
|
||||||
**** NEXT Setting
|
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
|
||||||
#+CAPTION: Klassenmodel für Einstellungen
|
|
||||||
#+NAME: fig:umweltgrafik
|
|
||||||
[[file:pictures/class_setting.png][file:pictures/class_setting.png]]
|
|
||||||
|
|
||||||
**** NEXT ArticleStatus
|
**** NEXT ArticleStatus
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Artikelstatus
|
#+CAPTION: Klassenmodel für Artikelstatus
|
||||||
#+NAME: fig:articlestatus
|
#+NAME: fig:articlestatus
|
||||||
[[file:pictures/class_articlestatus.png][file:pictures/class_articlestatus.png]]
|
[[./pictures/class_articlestatus.png]]
|
||||||
|
|
||||||
**** TODO ExchangeRate
|
**** TODO ExchangeRate
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
\footcite{timezone}
|
||||||
|
|
||||||
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Wechselkurse
|
#+CAPTION: Klassenmodel für Wechselkurse
|
||||||
#+NAME: fig:exchangerate
|
#+NAME: fig:exchangerate
|
||||||
[[file:pictures/class_exchangerate.png][file:pictures/class_exchangerate.png]]
|
[[./pictures/class_exchangerate.png]]
|
||||||
|
|
||||||
**** NEXT Article
|
**** NEXT Article
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Artikel
|
#+CAPTION: Klassenmodel für Artikel
|
||||||
#+NAME: fig:article
|
#+NAME: fig:article
|
||||||
[[file:pictures/class_article.png][file:pictures/class_article.png]]
|
[[./pictures/class_article.png]]
|
||||||
|
|
||||||
**** NEXT OrderStatus
|
**** NEXT OrderStatus
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Bestellstatus
|
#+CAPTION: Klassenmodel für Bestellstatus
|
||||||
#+NAME: fig:orderstatus
|
#+NAME: fig:orderstatus
|
||||||
[[file:pictures/class_orderstatus.png][file:pictures/class_orderstatus.png]]
|
[[./pictures/class_orderstatus.png]]
|
||||||
|
|
||||||
**** NEXT OrderOfGoods
|
**** NEXT OrderOfGoods
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Warenbestellungen
|
#+CAPTION: Klassenmodel für Warenbestellungen
|
||||||
#+NAME: fig:orderofgoods
|
#+NAME: fig:orderofgoods
|
||||||
[[file:pictures/class_orderofgoods.png][file:pictures/class_orderofgoods.png]]
|
[[./pictures/class_orderofgoods.png]]
|
||||||
|
|
||||||
**** NEXT Picture
|
**** NEXT Picture
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
\footcite{upload}
|
||||||
|
\footcite{images}
|
||||||
|
|
||||||
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Bilder
|
#+CAPTION: Klassenmodel für Bilder
|
||||||
#+NAME: fig:picture
|
#+NAME: fig:picture
|
||||||
[[file:pictures/class_picture.png][file:pictures/class_picture.png]]
|
[[./pictures/class_picture.png]]
|
||||||
|
|
||||||
**** NEXT Order
|
**** NEXT Order
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Bestellungen
|
#+CAPTION: Klassenmodel für Bestellungen
|
||||||
#+NAME: fig:order
|
#+NAME: fig:order
|
||||||
[[file:pictures/class_order.png][file:pictures/class_order.png]]
|
[[./pictures/class_order.png]]
|
||||||
|
|
||||||
**** NEXT ShoppingCart
|
**** NEXT ShoppingCart
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Warenkörbe
|
#+CAPTION: Klassenmodel für Warenkörbe
|
||||||
#+NAME: fig:shoppingcart
|
#+NAME: fig:shoppingcart
|
||||||
[[file:pictures/class_shoppingcart.png][file:pictures/class_shoppingcart.png]]
|
[[./pictures/class_shoppingcart.png]]
|
||||||
|
|
||||||
**** NEXT City
|
**** NEXT City
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Städte
|
#+CAPTION: Klassenmodel für Städte
|
||||||
#+NAME: fig:city
|
#+NAME: fig:city
|
||||||
[[file:pictures/class_city.png][file:pictures/class_city.png]]
|
[[./pictures/class_city.png]]
|
||||||
|
|
||||||
**** NEXT Salutation
|
**** NEXT Salutation
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Anreden
|
#+CAPTION: Klassenmodel für Anreden
|
||||||
#+NAME: fig:salutation
|
#+NAME: fig:salutation
|
||||||
[[file:pictures/class_salutation.png][file:pictures/class_salutation.png]]
|
[[./pictures/class_salutation.png]]
|
||||||
|
|
||||||
**** NEXT Person
|
**** NEXT Person
|
||||||
|
|
||||||
#+ATTR_LATEX: :width 9cm
|
\footcite{usermodel}
|
||||||
|
|
||||||
|
#+ATTR_LATEX: :width 9cm :placement [H]
|
||||||
#+CAPTION: Klassenmodel für Personen
|
#+CAPTION: Klassenmodel für Personen
|
||||||
#+NAME: fig:person
|
#+NAME: fig:person
|
||||||
[[file:pictures/class_person.png][file:pictures/class_person.png]]
|
[[./pictures/class_person.png]]
|
||||||
|
|
||||||
** Benutzerinterface
|
** Benutzerinterface
|
||||||
*** Mockup skizzieren
|
*** Mockup skizzieren
|
||||||
*** Frontend Umsetzung
|
*** Frontend Umsetzung
|
||||||
*** Backend Umsetzung
|
*** Backend Umsetzung
|
||||||
|
|
||||||
** Testfälle
|
** Testing
|
||||||
|
|
||||||
|
*** Fixtures
|
||||||
|
|
||||||
#+LATEX:\newpage
|
#+LATEX:\newpage
|
||||||
#+LATEX:\begin{landscape}
|
#+LATEX:\begin{landscape}
|
||||||
|
*** Testfälle
|
||||||
|
|
||||||
#+CAPTION: Testfälle
|
#+CAPTION: Testfälle
|
||||||
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{1.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|
|
#+ATTR_LATEX: :environment longtable :align |>{\columncolor[HTML]{EFEFEF}}p{1.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}| :placement [H]
|
||||||
#+NAME: tab:testcases
|
#+NAME: tab:testcases
|
||||||
|----------------------+----------------------+----------------------+----------------------+----------------------+----------------------+----------------------+----------------------|
|
|----------------------+----------------------+----------------------+----------------------+----------------------+----------------------+----------------------+----------------------|
|
||||||
| <20> | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
| <20> | <20> | <20> | <20> | <20> | <20> | <20> | <20> |
|
||||||
|
|
Loading…
Reference in New Issue