Merge branch 'master' into backoffice_invoice_scanning

This commit is contained in:
Víðir Valberg Guðmundsson 2019-07-23 21:55:31 +02:00
commit 04d858adf3
59 changed files with 327 additions and 151 deletions

View file

@ -128,6 +128,7 @@ You can also specify details like:
* Kasper Christensen https://github.com/fALKENdk * Kasper Christensen https://github.com/fALKENdk
* klarstrup https://github.com/klarstrup * klarstrup https://github.com/klarstrup
* kugg https://github.com/kugg * kugg https://github.com/kugg
* lgandersen https://github.com/lgandersen
* RadicalPet https://github.com/RadicalPet * RadicalPet https://github.com/RadicalPet
* Reynir Björnsson https://github.com/reynir * Reynir Björnsson https://github.com/reynir
* Ronni Elken Lindsgaard https://github.com/rlindsgaard * Ronni Elken Lindsgaard https://github.com/rlindsgaard

View file

@ -9,14 +9,22 @@
</div> </div>
</div> </div>
<div class="row center-block">
<div class="col-md-4 col-md-offset-4">
<a class="btn btn-primary btn-lg" href="{% url 'shop:index' %}?category=tickets" role="button">
Tickets still available! Get yours today!
</a>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
<b>BornHack</b> is a 7 day outdoor tent camp where hackers, makers and people with an interest in technology or security come together to celebrate technology, socialise, learn and <b>have fun</b>. <b>BornHack</b> is a 7 day <b>outdoor tent camp</b> where hackers, makers and people with an interest in technology or security come together to celebrate technology, socialise, learn and <b>have fun</b>.
</div> </div>
</div> </div>
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2610.jpg' 'The family area at BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9961_cropped.jpg' 'BornHack banners from previous camps.' %}
</div> </div>
</div> </div>
@ -49,7 +57,7 @@
<div class="row"> <div class="row">
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5149.JPG' 'Danish politicians debating at BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9970_cropped.JPG' 'Danish politicians, government officals and IT-developers debating at BornHack 2018' %}
</div> </div>
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead">We want to encourage <strong>hackers, makers, politicians, activists, developers, artists, sysadmins, engineers</strong> with something to say to read our <a href="{% url 'program:call_for_participation' camp_slug=camp.slug %}">call for participation</a>.</div> <div class="lead">We want to encourage <strong>hackers, makers, politicians, activists, developers, artists, sysadmins, engineers</strong> with something to say to read our <a href="{% url 'program:call_for_participation' camp_slug=camp.slug %}">call for participation</a>.</div>
@ -65,7 +73,7 @@
</div> </div>
</div> </div>
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5265.JPG' 'Organisers thanking the BornHack 2016 sponsors' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7675_cropped.jpg' 'Organisers thanking the BornHack 2017 sponsors' %}
</div> </div>
</div> </div>
@ -78,16 +86,16 @@
</div> </div>
</div> </div>
<p align="center"> <p align="center">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1983.JPG' 'Happy organisers welcoming people at the entrance to BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9947_cropped.JPG' 'Speakers of all ages at BornHack 2018' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1986.JPG' 'A bus full of hackers arrive at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %} {% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %}
{% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7724_cropped.jpg' 'A welcoming hug upon arrival at BornHack 2017! <3' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %} {% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2452.jpg' 'Soldering the BornHack 2016 badge' %} {% thumbnail 'img/bornhack-2018/flummer' 'DSC_7054_cropped.jpg' 'The BornHack 2018 badge' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2608.jpg' 'Colored lights at night' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7510_cropped.jpg' 'Colored speakers tent ready for use!' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1961.JPG' 'BornHack' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9916_cropped.JPG' 'Wanna take a ride? Borrow a bike for free!' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2485.jpg' 'Colored light in the grass' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_7518_cropped.JPG' 'Colored light in a tree' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2624.jpg' 'Working on decorations' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB2_0020_cropped.JPG' 'Colourful chairs!' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2604.jpg' 'Sitting around the campfire at BornHack 2016' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7521_cropped.jpg' 'Amelia Andersdotter presenting at BornHack 2017' %}
</p> </p>
{% endblock content %} {% endblock content %}

View file

@ -9,14 +9,15 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
<b>BornHack</b> is a 7 day outdoor tent camp where hackers, makers and people with an interest in technology or security come together to celebrate technology, socialise, learn and <b>have fun</b>. <b>BornHack</b> is a 7 day <b>outdoor tent camp</b> where hackers, makers and people with an interest in technology or security come together to celebrate technology, socialise, learn and <b>have fun</b>.
</div> </div>
</div> </div>
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2610.jpg' 'The family area at BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9961_cropped.jpg' 'BornHack banners from previous camps.' %}
</div> </div>
</div> </div>
@ -27,7 +28,7 @@
</div> </div>
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
<strong>Bornhack 2020</strong> will be the fifth BornHack. It will take place from <strong>Tuesday the 11th of August to Tuesday the 18th of August 2020</strong> on the Danish island of Funen. <strong>Bornhack 2019</strong> will be the fourth BornHack. It will take place from <strong>Thursday the 8th of August to Thursday the 15th of August 2019</strong> at a our new venue on the Danish island of Funen.
</div> </div>
</div> </div>
</div> </div>
@ -49,7 +50,7 @@
<div class="row"> <div class="row">
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5149.JPG' 'Danish politicians debating at BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9970_cropped.JPG' 'Danish politicians, government officals and IT-developers debating at BornHack 2018' %}
</div> </div>
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead">We want to encourage <strong>hackers, makers, politicians, activists, developers, artists, sysadmins, engineers</strong> with something to say to read our <a href="{% url 'program:call_for_participation' camp_slug=camp.slug %}">call for participation</a>.</div> <div class="lead">We want to encourage <strong>hackers, makers, politicians, activists, developers, artists, sysadmins, engineers</strong> with something to say to read our <a href="{% url 'program:call_for_participation' camp_slug=camp.slug %}">call for participation</a>.</div>
@ -65,7 +66,7 @@
</div> </div>
</div> </div>
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5265.JPG' 'Organisers thanking the BornHack 2016 sponsors' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7675_cropped.jpg' 'Organisers thanking the BornHack 2017 sponsors' %}
</div> </div>
</div> </div>
@ -78,16 +79,16 @@
</div> </div>
</div> </div>
<p align="center"> <p align="center">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1983.JPG' 'Happy organisers welcoming people at the entrance to BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9947_cropped.JPG' 'Speakers of all ages at BornHack 2018' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1986.JPG' 'A bus full of hackers arrive at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %} {% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %}
{% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7724_cropped.jpg' 'A welcoming hug upon arrival at BornHack 2017! <3' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %} {% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2452.jpg' 'Soldering the BornHack 2016 badge' %} {% thumbnail 'img/bornhack-2018/flummer' 'DSC_7054_cropped.jpg' 'The BornHack 2018 badge' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2608.jpg' 'Colored lights at night' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7510_cropped.jpg' 'Colored speakers tent ready for use!' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1961.JPG' 'BornHack' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9916_cropped.JPG' 'Wanna take a ride? Borrow a bike for free!' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2485.jpg' 'Colored light in the grass' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_7518_cropped.JPG' 'Colored light in a tree' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2624.jpg' 'Working on decorations' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB2_0020_cropped.JPG' 'Colourful chairs!' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2604.jpg' 'Sitting around the campfire at BornHack 2016' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7521_cropped.jpg' 'Amelia Andersdotter presenting at BornHack 2017' %}
</p> </p>
{% endblock content %} {% endblock content %}

View file

@ -9,14 +9,15 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
<b>BornHack</b> is a 7 day outdoor tent camp where hackers, makers and people with an interest in technology or security come together to celebrate technology, socialise, learn and <b>have fun</b>. <b>BornHack</b> is a 7 day <b>outdoor tent camp</b> where hackers, makers and people with an interest in technology or security come together to celebrate technology, socialise, learn and <b>have fun</b>.
</div> </div>
</div> </div>
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2610.jpg' 'The family area at BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9961_cropped.jpg' 'BornHack banners from previous camps.' %}
</div> </div>
</div> </div>
@ -27,7 +28,7 @@
</div> </div>
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
<strong>Bornhack 2021</strong> will be the sixth BornHack. It will take place from <strong>Thursday the 19th of August to Thursday the 26th of August 2021</strong> on the Danish island of Funen. <strong>Bornhack 2019</strong> will be the fourth BornHack. It will take place from <strong>Thursday the 8th of August to Thursday the 15th of August 2019</strong> at a our new venue on the Danish island of Funen.
</div> </div>
</div> </div>
</div> </div>
@ -49,7 +50,7 @@
<div class="row"> <div class="row">
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5149.JPG' 'Danish politicians debating at BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9970_cropped.JPG' 'Danish politicians, government officals and IT-developers debating at BornHack 2018' %}
</div> </div>
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead">We want to encourage <strong>hackers, makers, politicians, activists, developers, artists, sysadmins, engineers</strong> with something to say to read our <a href="{% url 'program:call_for_participation' camp_slug=camp.slug %}">call for participation</a>.</div> <div class="lead">We want to encourage <strong>hackers, makers, politicians, activists, developers, artists, sysadmins, engineers</strong> with something to say to read our <a href="{% url 'program:call_for_participation' camp_slug=camp.slug %}">call for participation</a>.</div>
@ -65,7 +66,7 @@
</div> </div>
</div> </div>
<div class="col-md-3 col-sm-3"> <div class="col-md-3 col-sm-3">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5265.JPG' 'Organisers thanking the BornHack 2016 sponsors' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7675_cropped.jpg' 'Organisers thanking the BornHack 2017 sponsors' %}
</div> </div>
</div> </div>
@ -78,16 +79,16 @@
</div> </div>
</div> </div>
<p align="center"> <p align="center">
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1983.JPG' 'Happy organisers welcoming people at the entrance to BornHack 2016' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9947_cropped.JPG' 'Speakers of all ages at BornHack 2018' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1986.JPG' 'A bus full of hackers arrive at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %} {% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5126.JPG' 'Late night hacking at Baconsvin village at BornHack 2016' %}
{% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7724_cropped.jpg' 'A welcoming hug upon arrival at BornHack 2017! <3' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %} {% thumbnail 'img/bornhack-2016/fonsmark' 'FB1_5168.JPG' '#irl_bar by night at BornHack 2016' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2452.jpg' 'Soldering the BornHack 2016 badge' %} {% thumbnail 'img/bornhack-2018/flummer' 'DSC_7054_cropped.jpg' 'The BornHack 2018 badge' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2608.jpg' 'Colored lights at night' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7510_cropped.jpg' 'Colored speakers tent ready for use!' %}
{% thumbnail 'img/bornhack-2016/fonsmark' 'FA0_1961.JPG' 'BornHack' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_9916_cropped.JPG' 'Wanna take a ride? Borrow a bike for free!' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2485.jpg' 'Colored light in the grass' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB1_7518_cropped.JPG' 'Colored light in a tree' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x988-B12A2624.jpg' 'Working on decorations' %} {% thumbnail 'img/bornhack-2018/fonsmark' 'FB2_0020_cropped.JPG' 'Colourful chairs!' %}
{% thumbnail 'img/bornhack-2016/esbjerg' '1600x900-B12A2604.jpg' 'Sitting around the campfire at BornHack 2016' %} {% thumbnail 'img/bornhack-2017/fonsmark' 'FB1_7521_cropped.jpg' 'Amelia Andersdotter presenting at BornHack 2017' %}
</p> </p>
{% endblock content %} {% endblock content %}

View file

@ -25,11 +25,19 @@ Info | {{ block.super }}
margin-top: -94px; /*same height as header*/ margin-top: -94px; /*same height as header*/
visibility: hidden; visibility: hidden;
} }
@media (min-width: 992px) {
.sticky {
position: sticky;
top: 100px;
}
}
</style> </style>
{% if categories %} {% if categories %}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-3 sticky">
<h3>Table of Contents</h3> <h3>Table of Contents</h3>
<p class="list-group"> <p class="list-group">
{% for category in categories %} {% for category in categories %}
@ -37,13 +45,10 @@ Info | {{ block.super }}
{% endfor %} {% endfor %}
</p> </p>
</div> </div>
</div>
<div class="col-md-9">
{% for category in categories %} {% for category in categories %}
<span class="anchor" id="{{ category.anchor }}"></span>
<span class="anchor" id="{{ category.anchor }}"></span>
<div class="row">
<div class="col-md-12">
<h2>{{ category.headline }} {% if category.team %}<small>Info by the {{ category.team.name }} team</small>{% endif %}</h2> <h2>{{ category.headline }} {% if category.team %}<small>Info by the {{ category.team.name }} team</small>{% endif %}</h2>
<div class="panel-group"> <div class="panel-group">
{% for item in category.infoitems.all %} {% for item in category.infoitems.all %}
@ -69,9 +74,9 @@ Info | {{ block.super }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div>
</div>
{% endfor %} {% endfor %}
</div>
</div>
{% else %} {% else %}
<h3>No info found for {{ camp.title }}</h3> <h3>No info found for {{ camp.title }}</h3>
{% endif %} {% endif %}

View file

@ -12,70 +12,66 @@ def add_new_speakerproposal_email(speakerproposal):
try: try:
content_team = Team.objects.get(camp=speakerproposal.camp, name="Content") content_team = Team.objects.get(camp=speakerproposal.camp, name="Content")
return add_outgoing_email(
text_template="emails/new_speakerproposal.txt",
html_template="emails/new_speakerproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="New speaker proposal for {}".format(speakerproposal.camp.title),
)
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
logger.info("There is no team with name Content: {}".format(e)) logger.info("There is no team with name Content: {}".format(e))
return False return False
return add_outgoing_email(
text_template="emails/new_speakerproposal.txt",
html_template="emails/new_speakerproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="New speaker proposal '%s' was just submitted" % speakerproposal.name,
)
def add_new_eventproposal_email(eventproposal): def add_new_eventproposal_email(eventproposal):
formatdict = {"proposal": eventproposal} formatdict = {"proposal": eventproposal}
try: try:
content_team = Team.objects.get(camp=eventproposal.camp, name="Content") content_team = Team.objects.get(camp=eventproposal.camp, name="Content")
return add_outgoing_email(
text_template="emails/new_eventproposal.txt",
html_template="emails/new_eventproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="New event proposal for {}".format(eventproposal.camp.title),
)
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
logger.info("There is no team with name Content: {}".format(e)) logger.info("There is no team with name Content: {}".format(e))
return False return False
return add_outgoing_email(
text_template="emails/new_eventproposal.txt",
html_template="emails/new_eventproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="New event proposal '%s' was just submitted" % eventproposal.title,
)
def add_speakerproposal_updated_email(speakerproposal): def add_speakerproposal_updated_email(speakerproposal):
formatdict = {"proposal": speakerproposal} formatdict = {"proposal": speakerproposal}
try: try:
content_team = Team.objects.get(camp=speakerproposal.camp, name="Content") content_team = Team.objects.get(camp=speakerproposal.camp, name="Content")
return add_outgoing_email(
text_template="emails/update_speakerproposal.txt",
html_template="emails/update_speakerproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="Updated speaker proposal for {}".format(
speakerproposal.camp.title
),
)
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
logger.info("There is no team with name Content: {}".format(e)) logger.info("There is no team with name Content: {}".format(e))
return False return False
return add_outgoing_email(
text_template="emails/update_speakerproposal.txt",
html_template="emails/update_speakerproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="Speaker proposal '%s' was just updated" % speakerproposal.name,
)
def add_eventproposal_updated_email(eventproposal): def add_eventproposal_updated_email(eventproposal):
formatdict = {"proposal": eventproposal} formatdict = {"proposal": eventproposal}
try: try:
content_team = Team.objects.get(camp=eventproposal.camp, name="Content") content_team = Team.objects.get(camp=eventproposal.camp, name="Content")
return add_outgoing_email(
text_template="emails/update_eventproposal.txt",
html_template="emails/update_eventproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="New event proposal for {}".format(eventproposal.camp.title),
)
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
logger.info("There is no team with name Content: {}".format(e)) logger.info("There is no team with name Content: {}".format(e))
return False return False
return add_outgoing_email(
text_template="emails/update_eventproposal.txt",
html_template="emails/update_eventproposal.html",
to_recipients=content_team.mailing_list,
formatdict=formatdict,
subject="Event proposal '%s' was just updated" % eventproposal.title,
)

View file

@ -1,6 +1,6 @@
Hello!<br> Hello!<br>
<br> <br>
Event {{ proposal.title }} was just submitted as a new proposal for {{ proposal.camp }}. Event "{{ proposal.title }}" was just submitted as a new proposal for {{ proposal.camp }}.
<br> <br>
<br> <br>
More info <a href="https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/">here</a>. More info <a href="https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/">here</a>.

View file

@ -1,6 +1,6 @@
Hello! Hello!
Event {{ proposal.title }} was just submitted as a new proposal for {{ proposal.camp }}. Event "{{ proposal.title }}" was just submitted as a new proposal for {{ proposal.camp }}.
More info: https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/ More info: https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/

View file

@ -1,6 +1,6 @@
Hello!<br> Hello!<br>
<br> <br>
Speaker {{ proposal.name }} was just submitted as a new proposal for {{ proposal.camp }}. Speaker "{{ proposal.name }}" was just submitted as a new proposal for {{ proposal.camp }}.
<br> <br>
<br> <br>
More info <a href="https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/">here</a>. More info <a href="https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/">here</a>.

View file

@ -1,6 +1,6 @@
Hello! Hello!
Speaker {{ proposal.name }} was just submitted as a new proposal for {{ proposal.camp }}. Speaker "{{ proposal.name }}" was just submitted as a new proposal for {{ proposal.camp }}.
More info: https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/ More info: https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/

View file

@ -1,6 +1,6 @@
Hello!<br> Hello!<br>
<br> <br>
Event {{ proposal.name }} for {{ proposal.camp }} was just updated! Event "{{ proposal.name }}" for {{ proposal.camp }} was just updated!
<br> <br>
<br> <br>
More info <a href="https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/">here</a>. More info <a href="https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/">here</a>.

View file

@ -1,6 +1,6 @@
Hello! Hello!
Event {{ proposal.name }} for {{ proposal.camp }} was just updated! Event "{{ proposal.name }}" for {{ proposal.camp }} was just updated!
More info: https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/ More info: https://bornhack.dk/admin/program/eventproposal/{{ proposal.uuid }}/change/

View file

@ -1,6 +1,6 @@
Hello!<br> Hello!<br>
<br> <br>
Speaker {{ proposal.name }} for {{ proposal.camp }} was just updated! Speaker "{{ proposal.name }}" for {{ proposal.camp }} was just updated!
<br> <br>
<br> <br>
More info <a href="https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/">here</a>. More info <a href="https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/">here</a>.

View file

@ -1,6 +1,6 @@
Hello! Hello!
Speaker {{ proposal.name }} was just submitted as a new speaker proposal for {{ proposal.camp }}. Speaker "{{ proposal.name }}" was just submitted as a new speaker proposal for {{ proposal.camp }}.
More info: https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/ More info: https://bornhack.dk/admin/program/speakerproposal/{{ proposal.uuid }}/change/

View file

@ -212,7 +212,8 @@ class SpeakerProposalUpdateView(
for ep in self.get_object().eventproposals.all(): for ep in self.get_object().eventproposals.all():
eventtypes.add(ep.event_type) eventtypes.add(ep.event_type)
if len(eventtypes) == 1: if len(eventtypes) == 1:
eventtype = self.get_object().eventproposals.get().event_type # only one eventtype found
eventtype = ep.event_type
else: else:
# more than one type of event for this person, return the generic speakerproposal form # more than one type of event for this person, return the generic speakerproposal form
eventtype = None eventtype = None

View file

@ -12,13 +12,13 @@ defusedxml==0.6.0
django-allauth==0.39.1 django-allauth==0.39.1
django-allauth-2fa==0.6 django-allauth-2fa==0.6
django-bleach==0.5.3 django-bleach==0.5.3
django-bootstrap3==11.0.0 django-bootstrap3==11.1.0
django-extensions==2.1.9 django-extensions==2.1.9
django-wkhtmltopdf==3.2.0 django-wkhtmltopdf==3.2.0
django-reversion==3.0.4 django-reversion==3.0.4
django-betterforms==1.2 django-betterforms==1.2
django-cors-headers==3.0.2 django-cors-headers==3.0.2
django-filter==2.1.0 django-filter==2.2.0
docopt==0.6.2 docopt==0.6.2
future==0.17.1 future==0.17.1
html5lib==1.0.1 html5lib==1.0.1
@ -38,4 +38,4 @@ six==1.12.0
sqlparse==0.3.0 sqlparse==0.3.0
venusian==1.2.0 venusian==1.2.0
webencodings==0.5.1 webencodings==0.5.1
graphene-django==2.3.2 graphene-django==2.4.0

View file

@ -5,5 +5,5 @@ from .models import Ride
@admin.register(Ride) @admin.register(Ride)
class RideModelAdmin(admin.ModelAdmin): class RideModelAdmin(admin.ModelAdmin):
list_display = ("location", "when", "seats", "user") list_display = ("camp", "user", "from_location", "to_location", "when", "seats")
list_filter = ("camp", "user") list_filter = ("camp", "user")

View file

@ -0,0 +1,18 @@
# Generated by Django 2.1.7 on 2019-07-11 18:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rideshare', '0002_auto_20180814_1942'),
]
operations = [
migrations.AddField(
model_name='ride',
name='has_car',
field=models.BooleanField(default=True, help_text='Leave checked if you are offering a ride, uncheck if you need a ride'),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 2.1.7 on 2019-07-11 18:36
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('rideshare', '0003_ride_has_car'),
]
operations = [
migrations.RenameField(
model_name='ride',
old_name='location',
new_name='from_location',
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.1.7 on 2019-07-11 18:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rideshare', '0004_auto_20190711_2036'),
]
operations = [
migrations.AddField(
model_name='ride',
name='to_location',
field=models.CharField(default='BornHack', max_length=100),
preserve_default=False,
),
]

View file

@ -0,0 +1,43 @@
# Generated by Django 2.1.7 on 2019-07-13 06:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rideshare', '0005_ride_to_location'),
]
operations = [
migrations.AlterField(
model_name='ride',
name='description',
field=models.TextField(help_text='Include any details you want, like luggage space/requirements, contact info and so on.'),
),
migrations.AlterField(
model_name='ride',
name='from_location',
field=models.CharField(help_text='Where does this ride begin?', max_length=100),
),
migrations.AlterField(
model_name='ride',
name='has_car',
field=models.BooleanField(default=True, help_text='Leave checked if you are offering a ride, uncheck if you need a ride.'),
),
migrations.AlterField(
model_name='ride',
name='seats',
field=models.PositiveIntegerField(help_text='How many seats are you offering/how many seats do you need?'),
),
migrations.AlterField(
model_name='ride',
name='to_location',
field=models.CharField(help_text='What is the destination of this ride?', max_length=100),
),
migrations.AlterField(
model_name='ride',
name='when',
field=models.DateTimeField(help_text='When does this ride leave? Format is YYYY-MM-DD HH:mm'),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 2.1.7 on 2019-07-13 07:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rideshare', '0006_auto_20190713_0859'),
]
operations = [
migrations.AddField(
model_name='ride',
name='author',
field=models.CharField(default='Unnamed', help_text='Let people know who posted this', max_length=100),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 2.1.7 on 2019-07-13 07:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rideshare', '0007_ride_author'),
]
operations = [
migrations.AlterField(
model_name='ride',
name='author',
field=models.CharField(default='Anonymous', help_text='Let people know who posted this', max_length=100),
),
]

View file

@ -7,10 +7,16 @@ from utils.models import UUIDModel, CampRelatedModel
class Ride(UUIDModel, CampRelatedModel): class Ride(UUIDModel, CampRelatedModel):
camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT)
user = models.ForeignKey("auth.User", on_delete=models.PROTECT) user = models.ForeignKey("auth.User", on_delete=models.PROTECT)
seats = models.PositiveIntegerField() author = models.CharField(max_length=100, help_text="Let people know who posted this", default="Anonymous")
location = models.CharField(max_length=100) has_car = models.BooleanField(
when = models.DateTimeField(help_text="Format is YYYY-MM-DD HH:mm") default=True,
description = models.TextField() help_text="Leave checked if you are offering a ride, uncheck if you need a ride."
)
seats = models.PositiveIntegerField(help_text="How many seats are you offering/how many seats do you need?")
from_location = models.CharField(max_length=100, help_text="Where does this ride begin?")
to_location = models.CharField(max_length=100, help_text="What is the destination of this ride?")
when = models.DateTimeField(help_text="When does this ride leave? Format is YYYY-MM-DD HH:mm")
description = models.TextField(help_text="Include any details you want, like luggage space/requirements, contact info and so on.")
def get_absolute_url(self): def get_absolute_url(self):
return reverse( return reverse(
@ -18,6 +24,6 @@ class Ride(UUIDModel, CampRelatedModel):
) )
def __str__(self): def __str__(self):
return "{} seats from {} at {} by {}".format( return "{} seats from {} to {} at {} by {}".format(
self.seats, self.location, self.when, self.user self.seats, self.from_location, self.to_location, self.when, self.user
) )

View file

@ -14,9 +14,13 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h4> <h4>
<strong>{{ object.author }}</strong>
{% if object.has_car %}has {% else %}needs {% endif %}
<strong>{{ object.seats }}</strong> <strong>{{ object.seats }}</strong>
seats free, going from seats free, going from
<strong>{{ object.location }}</strong> <strong>{{ object.from_location }}</strong>
to
<strong>{{ object.to_location }}</strong>
at at
<strong>{{ object.when|date:"jS \o\f F \a\t H:i T" }}</strong> <strong>{{ object.when|date:"jS \o\f F \a\t H:i T" }}</strong>
</h4> </h4>

View file

@ -1,4 +1,10 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load staticfiles %}
{% block extra_head %}
<script src="{% static "js/jquery.dataTables.min.js" %}"></script>
<link rel="stylesheet" href="{% static 'css/jquery.dataTables.min.css' %}">
{% endblock extra_head %}
{% block content %} {% block content %}
@ -6,8 +12,8 @@
<h1>Ridesharing</h1> <h1>Ridesharing</h1>
</div> </div>
<p> <p class="lead">
On this page participants of {{ camp.title }} can communicate about ridesharing to and from the festival. On this page participants of {{ camp.title }} can communicate about ridesharing to and from the festival. Press "Details" to send a message to the author of the entry.
</p> </p>
<a class="btn btn-success pull-right" href="{% url 'rideshare:create' camp_slug=camp.slug %}"> <a class="btn btn-success pull-right" href="{% url 'rideshare:create' camp_slug=camp.slug %}">
@ -21,24 +27,49 @@ On this page participants of {{ camp.title }} can communicate about ridesharing
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
<thead> <thead>
<th> <th>
When Author
<th> <th>
Location Type
<th> <th>
Seats Leaving When
<th> <th>
From Location
<th>
To Location
<th>
Seats Free/Needed
<th>
Actions
<tbody> <tbody>
{% for ride in ride_list %} {% for ride in ride_list %}
<tr> <tr>
<td>
{{ ride.author }}
<td>
{% if ride.has_car %}
<i class="fas fa-car"></i> Has car
{% else %}
<i class="fas fa-thumbs-up"></i> Needs ride
{% endif %}
<td> <td>
{{ ride.when|date:"c" }} {{ ride.when|date:"c" }}
<td> <td>
{{ ride.location }} {{ ride.from_location }}
<td> <td>
{{ ride.seats }} {{ ride.to_location }}
<td class="text-center">
<span class="badge">{{ ride.seats }}</span>
<td> <td>
<a class="btn btn-primary" href="{% url 'rideshare:detail' camp_slug=camp.slug pk=ride.pk %}"> {% if request.user == ride.user %}
<a class="btn btn-danger pull-right" href="{% url 'rideshare:delete' camp_slug=camp.slug pk=ride.pk %}">
<i class="fas fa-times"></i> Delete
</a>
<a class="btn btn-primary pull-right" href="{% url 'rideshare:update' camp_slug=camp.slug pk=ride.pk %}">
<i class="fas fa-edit"></i> Update
</a>
{% endif %}
<a class="btn btn-primary pull-right" href="{% url 'rideshare:detail' camp_slug=camp.slug pk=ride.pk %}">
<i class="fas fa-eye"></i> Details <i class="fas fa-eye"></i> Details
</a> </a>

View file

@ -22,8 +22,8 @@ class ContactRideForm(forms.Form):
widget=forms.Textarea( widget=forms.Textarea(
attrs={"placeholder": "Remember to include your contact information!"} attrs={"placeholder": "Remember to include your contact information!"}
), ),
label="Write a message to this rideshare", label="Write a message to the author of this rideshare",
help_text="ATTENTION!: Pressing send will send an email with the above text. It is up to you to include your contact information so the person receiving the email can contact you.", help_text="ATTENTION!: Pressing send will send an email to the author with the above text. It is up to you to include your contact information in the message so the person receiving the email can contact you.",
) )
@ -63,9 +63,20 @@ class RideDetail(LoginRequiredMixin, CampViewMixin, DetailView):
class RideCreate(LoginRequiredMixin, CampViewMixin, CreateView): class RideCreate(LoginRequiredMixin, CampViewMixin, CreateView):
model = Ride model = Ride
fields = ["location", "when", "seats", "description"] fields = ["author", "has_car", "from_location", "to_location", "when", "seats", "description"]
def get_initial(self):
"""
Default 'author' to users public_credit_name where relevant
"""
return {
"author": self.request.user.profile.get_public_credit_name
}
def form_valid(self, form, **kwargs): def form_valid(self, form, **kwargs):
"""
Set camp and user before saving
"""
ride = form.save(commit=False) ride = form.save(commit=False)
ride.camp = self.camp ride.camp = self.camp
ride.user = self.request.user ride.user = self.request.user
@ -81,7 +92,7 @@ class IsRideOwnerMixin(UserPassesTestMixin):
class RideUpdate(LoginRequiredMixin, CampViewMixin, IsRideOwnerMixin, UpdateView): class RideUpdate(LoginRequiredMixin, CampViewMixin, IsRideOwnerMixin, UpdateView):
model = Ride model = Ride
fields = ["location", "when", "seats", "description"] fields = ["author", "has_car", "from_location", "to_location", "when", "seats", "description"]
class RideDelete(LoginRequiredMixin, CampViewMixin, IsRideOwnerMixin, DeleteView): class RideDelete(LoginRequiredMixin, CampViewMixin, IsRideOwnerMixin, DeleteView):

View file

@ -20,14 +20,12 @@ of the <strong>full</strong> amount of <b>{{ total|currency }}</b> using the fol
<strong> <strong>
Remember: Remember:
</strong> </strong>
If you transfer from outside of Denmark you <strong>MUST</strong> make sure that If you transfer from outside of Denmark please make sure that you pay the
all transfers fees are <strong>paid by you</strong>. sender fees. Please allow for up to a week before we register your bank transfer,
especially if you are outside of the SEPA region.
</p> </p>
</div> </div>
<p>Also note: Please allow for up to a week before we register your bank
transfer, especially if you are outside of the SEPA region.</p>
<p> <p>
<strong>*</strong> This reference is a message to the payee (BornHack) and <strong>*</strong> This reference is a message to the payee (BornHack) and
enables us to register your payment. enables us to register your payment.

View file

@ -35,7 +35,7 @@
<tr> <tr>
<td align="right"> <td align="right">
{% if invoice.customorder.danish_vat %} {% if invoice.customorder.danish_vat %}
<strong>Danish VAT (25%)</strong> <strong>Included Danish VAT (25%)</strong>
{% else %} {% else %}
<strong>No VAT</strong> <strong>No VAT</strong>
{% endif %} {% endif %}

View file

@ -78,18 +78,10 @@
<li>Please remember to add Order number in the transfer notes, and pay the transfer fees in your end.</li> <li>Please remember to add Order number in the transfer notes, and pay the transfer fees in your end.</li>
</ul> </ul>
<h4>Credit Card</h4> <h4>Other Payment Methods</h4>
<ul> <ul>
<li>https://{{ hostname }}{% url 'shop:epay_form' pk=order.pk %} (requires login)</li> <li><b>Credit Card:</b> https://{{ hostname }}{% url 'shop:epay_form' pk=order.pk %} (requires login)</li>
</ul> <li><b>Blockchain (multiple currencies)</b>: https://{{ hostname }}{% url 'shop:coinify_pay' pk=order.pk %} (requires login)</li>
<li><b>Cash:</b> https://{{ hostname }}{% url 'shop:cash' pk=order.pk %} (requires geographical proximity to an organiser)</li>
<h4>Blockchain (multiple currencies)</h4>
<ul>
<li>https://{{ hostname }}{% url 'shop:coinify_pay' pk=order.pk %} (requires login)</li>
</ul>
<h4>Cash</h4>
<ul>
<li>https://{{ hostname }}{% url 'shop:cash' pk=order.pk %} (requires geographical proximity to an organiser)</li>
</ul> </ul>

View file

@ -16,21 +16,14 @@
{% if user.creditnotes.exists %} {% if user.creditnotes.exists %}
<li class="pull-right"><a href="{% url 'shop:creditnote_list' %}">Credit Notes</a></li> <li class="pull-right"><a href="{% url 'shop:creditnote_list' %}">Credit Notes</a></li>
{% endif %} {% endif %}
<li class="pull-right"><a href="{% url 'shop:order_list' %}">Orders</a></li> {% if current_order %}
<li class="pull-right no-before"> <li class="pull-right no-before">
{% if current_order and current_order.get_number_of_items %}
<a href="{% url 'shop:order_detail' pk=current_order.pk %}"> <a href="{% url 'shop:order_detail' pk=current_order.pk %}">
{% endif %} <i class="glyphicon glyphicon-shopping-cart"></i> Shopping Cart ({{ current_order.get_number_of_items|default:0 }} items)</a>
<i class="glyphicon glyphicon-shopping-cart"></i>
<span class="badge">
{{ current_order.get_number_of_items|default:0 }}
</span>
{% if current_order and current_order.get_number_of_items %}
</a>
{% endif %}
</li> </li>
{% else %}
<li class="pull-right no-before"><a href="{% url 'shop:order_list' %}">Show Orders</a></li>
{% endif %}
{% endif %} {% endif %}
</ol> </ol>
</div> </div>

View file

@ -154,9 +154,7 @@ class TestProductDetailView(TestCase):
order = self.user.orders.get() order = self.user.orders.get()
self.assertRedirects( self.assertRedirects(response, reverse("shop:index"))
response, reverse("shop:order_detail", kwargs={"pk": order.pk})
)
def test_product_is_in_order(self): def test_product_is_in_order(self):
# Put the product in an order owned by the user # Put the product in an order owned by the user
@ -182,9 +180,7 @@ class TestProductDetailView(TestCase):
response = self.client.post(self.path, data={"quantity": 2}) response = self.client.post(self.path, data={"quantity": 2})
self.assertRedirects( self.assertRedirects(response, reverse("shop:index"))
response, reverse("shop:order_detail", kwargs={"pk": opr.order.pk})
)
opr.refresh_from_db() opr.refresh_from_db()
self.assertEquals(opr.quantity, 2) self.assertEquals(opr.quantity, 2)

View file

@ -249,9 +249,7 @@ class ProductDetailView(FormView, DetailView):
return super(ProductDetailView, self).form_valid(form) return super(ProductDetailView, self).form_valid(form)
def get_success_url(self): def get_success_url(self):
return Order.objects.get( return reverse("shop:index")
user=self.request.user, open__isnull=False
).get_absolute_url()
class OrderListView(LoginRequiredMixin, ListView): class OrderListView(LoginRequiredMixin, ListView):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,013 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB