Commit 26087f22 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki
Browse files

Merge branch '0.6.4' into dev

parents 8441dbf1 46b08a57
......@@ -149,7 +149,7 @@ form+p:first-child, form legend + p { margin-bottom:2em; }
.form-row .dk_options a:hover,
.form-row .dk_option_current a { text-shadow:none; background-color: #E7E7E3; text-decoration:none;}
form.link-like { display:inline-block; margin:0 5px; }
form.link-like { display:inline-block; margin:0 5px; float:right;}
form.link-like input[type="submit"] { margin:0; padding:0 5px; background:transparent; color:#F89A1C; cursor:pointer; height:auto; }
form.link-like input[type="submit"]:hover { text-decoration:underline; }
.projects form.withlabels .checkbox-widget { margin-top:5px; }
......
......@@ -3,4 +3,3 @@
@import url(colorbox.css);
@import url(browser-fixes.css);
@import url(forms.css);
@import url(dropkick.css);
\ No newline at end of file
......@@ -296,7 +296,7 @@ dl.alt-style dt:nth-child(2n) { background:black; }
.alt-style .table-div { border:1px dashed #000; }
.billing table.complex tr:nth-child(2n) td { background:transparent; }
.billing table.alt-style tr.zebra td { background:#F2F2F2; }
.billing .highlight { text-align:center; padding:10px; border:1px dashed #000; font-size:1.231em; margin:0 0 2em;}
.billing .highlight { text-align:center; padding:10px; border:1px dashed #000; font-size:1.231em; margin:0 0 2em; position:relative;}
.billing .highlight em { color:#3582AC; font-style:normal; font-weight:bold; }
.billing table.marginless { margin-bottom:0; }
.billing .sum { background:#5A97B8; padding:5px 5px 5px 10px; color:#fff; }
......@@ -321,6 +321,16 @@ dl.alt-style dt:nth-child(2n) { background:black; }
.billing .resource-cat-1.filter-item a:hover { color:#ff6f00 }
.billing .resource-cat-2.filter-item a,
.billing .resource-cat-2.filter-item a:hover { color:#4085A5 }
.billing span.info { position:absolute;z-index:10; bottom:32px; right:40px; }
.billing span.info em { display:block; overflow:hidden; position:absolute; left:0; text-indent:-110px; top:0; height:21px; width:21px; background:url(../images/symbols.png) no-repeat -4px -31px;cursor:pointer; }
.billing span.info:hover em { background-position:-4px -3px; }
.billing span.info span { position:absolute; left:29px; top:-2px; width:120px; padding-left:30px; background:url(../images/black-line.jpg ) no-repeat left 12px ; min-height:50px; display:none; font-size:12px;}
.billing span.info:hover span { display:block; }
.billing span.info.foo span { padding:0; background:transparent; left:-48px; top:22px; font-size:12px;}
.billing .highlight a { float:right; }
.billing .highlight .popup { position:absolute;right:20px; top:40px; width: 100px; border:1px solid #000; }
.billing table.alt-style tr td { border-top:10px solid #fff; }
.billing table.alt-style .last { text-align:right; }
.table_sorting tr th { cursor:pointer; }
......@@ -332,7 +342,7 @@ table.alt-style tr.tr2 td,
table.alt-style tr.tmore2 td { background:#fff }
table.alt-style tr td.info-td { padding:5px; }
table.alt-style tr td.info-td div { padding:15px; border:1px dashed #000 }
table.alt-style tr td a.more-info { display:block; float:left; width:17px; height:16px; background:url(../images/plus-minus.png) no-repeat 0 0; margin-right:5px; }
table.alt-style tr td a.more-info { display:inline-block; width:17px; height:16px; background:url(../images/plus-minus.png) no-repeat 0 0; margin-left:10px; }
table.alt-style tr td a.more-info:hover { background-image:url(../images/plus-minus-hover.png); text-decoration:none;}
table.alt-style tr td a.open { background-position:-16px 0}
......
......@@ -113,7 +113,7 @@ $(document).ready(function() {
$('select').dropkick();
//$('select').dropkick();
$('.top-msg .success').parents('.top-msg').addClass('success');
......
......@@ -2,14 +2,145 @@
{% load filters %}
{% block page.body %}
{% if data %}
{{ data }}
{% endif %}
<form action="{% url astakos.im.views.billing %}">{% csrf_token %}
{% for m in user.date_joined|months_since %}
{{ m|date:"M Y" }}
{% endfor %}
</form>
<div class="billing list">
<div class="highlight">
<em>{{ data.remainingCredits|floatformat:2 }}</em> credits remaining
<span class="info foo">
<em>more info</em>
<span>|<br>Each month you are given 4.000 new credits.</span>
</span>
</div>
<h2><span>Billing statement for </span><em>[ {{ today.month|month_name|upper }} {{ today.year }} ]</em></h2>
{% if data.bill|length %}
<p>
<em>
This page shows billing report for the period 1 {{ today.month|month_name }} {{ today.year }}- {{ month_last_day }} {{ today.month|month_name }} {{ today.year }}
</em>
</p>
<br><br>
<table class="alt-style">
<tr>
<th>Service</th>
<th>Monthly Usage</th>
<th class="last">Charged Credits</th>
</tr>
<tr>
<td>Cyclades
{% with data|lookup:'bill_vmtime' as bill_vmtime %}
{% if bill_vmtime.0.totalCredits != '0.0' %}
<a href="" class="more-info">&nbsp;</a>
{% endif%}
{% endwith %}
</td>
<td>
{% with data|lookup:'bill_vmtime' as bill_vmtime %}
{{ bill_vmtime.0.totalUnits|floatformat:0}} Hr
{% endwith %}
</td>
<td class="last">
{% with data|lookup:'bill_vmtime' as bill_vmtime %}
{{ bill_vmtime.0.totalCredits|floatformat:2}}
{% endwith %}
</td>
</tr>
<tr class="innertable" style="display:none">
<td colspan="3">
<div class="table-div">
<table class="alt-style">
<tr>
<th>VM</th>
<th>Flavor</th>
<th>Vmtime</th>
<th class="last">Charged Credits</th>
</tr>
{% with data|lookup:'bill_vmtime' as bill_vmtime %}
{% for d in bill_vmtime %}
{% for vm in d.details %}
<tr>
<td>{{ vm.resourceName }}</td>
<td>flavor?</td>
<td>{{ vm.totalElapsedTime|todate|timeuntil:zerodate }}</td>
<td class="last">{{ vm.totalUnits }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endwith %}
</table>
</div>
</td>
</tr>
<tr>
<td>Pithos +</td>
<td>
{% with data|lookup:'bill_diskspace' as bill_diskspace %}
{{ bill_diskspace.0.totalUnits|floatformat:0}} {{ bill_diskspace.0.unitName }}
{% endwith %}
</td>
<td class="last">
{% with data|lookup:'bill_diskspace' as bill_diskspace %}
{{ bill_diskspace.0.totalCredits|floatformat:2}}
{% endwith %}
</td>
</tr>
<tr>
<td>Total Credits</td>
<td>&nbsp;</td>
<td class="sum last">{{ data.deductedCredits|floatformat:2 }}</td>
</tr>
</table>
{% else %}
<p>
<em>
There is no billing statement for this month.
</em>
</p>
{% endif %}
<form action={% url astakos.im.views.billing %} class="withlabels" method="POST">{% csrf_token %}
<div class="form-row">
<label for="month">Choose another month</label>
<select name="datefrom">
{% with user.date_joined|monthssince as periods %}
{% for period in periods %}
<option value="{{ period.2 }}" {% if period.2 == start %}selected="selected"{% endif%}>
{{ period.1|month_name }} {{period.0}}
</option>
{% endfor %}
{% endwith %}
</select>
</div>
<div class="form-row submit">
<input type="submit" value="VIEW">
</div>
</form>
<br><br><br>
<p>You can download a detailed activity report in Comma Separated Value (CSV) format or as txt file for AUGUST 2012.<br />
<a href="#">Download CSV</a>, <a href="#">Download .txt</a>
</p>
</div>
{% endblock %}
......@@ -32,12 +32,36 @@
# or implied, of GRNET S.A.
from django import template
from datetime import datetime
from dateutil.relativedelta import relativedelta
import calendar
import datetime
register = template.Library()
@register.filter
def monthssince(joined_date):
now = datetime.datetime.now()
date = datetime.datetime(year=joined_date.year, month=joined_date.month, day=1)
months = []
month = date.month
year = date.year
timestamp=calendar.timegm( date.utctimetuple() )
while date < now:
months.append((year, month, timestamp))
if date.month < 12:
month = date.month + 1
year = date.year
else:
month = 1
year = date.year + 1
date = datetime.datetime(year=year, month=month, day=1)
timestamp=calendar.timegm( date.utctimetuple() )
return months
@register.filter
def lookup(d, key):
return d.get(key)
......@@ -67,9 +91,11 @@ def split(object_list, user):
@register.filter
def months_since(start_date, end_date=datetime.now()):
delta = relativedelta(months=+1)
d = start_date
while d < end_date:
d += delta
yield d
\ No newline at end of file
def month_name(month_number):
return calendar.month_name[month_number]
@register.filter
def todate(value, arg = ''):
secs = int(value) / 1000
return datetime.datetime.fromtimestamp(secs)
......@@ -53,8 +53,7 @@ from django.template import RequestContext, loader
from django.utils.http import urlencode
from django.utils.translation import ugettext as _
from django.views.generic.create_update import (create_object, delete_object,
get_model_and_form_class
)
get_model_and_form_class)
from django.views.generic.list_detail import object_list, object_detail
from django.http import HttpResponseBadRequest
......@@ -845,34 +844,32 @@ def group_leave(request, group_id):
)
def handle_membership():
def decorator(func):
@wraps(func)
def wrapper(request, group_id, user_id):
try:
m = Membership.objects.select_related().get(
group__id=group_id,
person__id=user_id
)
except Membership.DoesNotExist:
return HttpResponseBadRequest(_('Invalid membership.'))
else:
if request.user not in m.group.owner.all():
return HttpResponseForbidden(_('User is not a group owner.'))
func(request, m)
return render_response(
template='im/astakosgroup_detail.html',
context_instance=get_context(request),
object=m.group,
quota=m.group.quota
)
return wrapper
return decorator
def handle_membership(func):
@wraps(func)
def wrapper(request, group_id, user_id):
try:
m = Membership.objects.select_related().get(
group__id=group_id,
person__id=user_id
)
except Membership.DoesNotExist:
return HttpResponseBadRequest(_('Invalid membership.'))
else:
if request.user not in m.group.owner.all():
return HttpResponseForbidden(_('User is not a group owner.'))
func(request, m)
return render_response(
template='im/astakosgroup_detail.html',
context_instance=get_context(request),
object=m.group,
quota=m.group.quota
)
return wrapper
@signed_terms_required
@login_required
@handle_membership()
@handle_membership
def approve_member(request, membership):
try:
membership.approve()
......@@ -887,7 +884,7 @@ def approve_member(request, membership):
@signed_terms_required
@login_required
@handle_membership()
@handle_membership
def disapprove_member(request, membership):
try:
membership.disapprove()
......@@ -946,23 +943,59 @@ def group_create_list(request):
@signed_terms_required
@login_required
def billing(request):
today = datetime.today()
month_last_day = calendar.monthrange(today.year, today.month)[1]
month_last_day= calendar.monthrange(today.year, today.month)[1]
start = request.POST.get('datefrom', None)
if start:
today = datetime.fromtimestamp(int(start))
month_last_day= calendar.monthrange(today.year, today.month)[1]
start = datetime(today.year, today.month, 1).strftime("%s")
end = datetime(today.year, today.month, month_last_day).strftime("%s")
r = request_billing.apply(args=(request.user.email,
int(start) * 1000,
int(end) * 1000)
)
data = None
int(end) * 1000))
data = {}
try:
status, data = r.result
data=clear_billing_data(data)
if status != 200:
messages.error(request, _('Service response status: %d' % status))
except:
messages.error(request, r.result)
print type(start)
return render_response(
template='im/billing.html',
context_instance=get_context(request),
data=data
)
data=data,
zerodate=datetime(month=1,year=1970, day=1),
today=today,
start=int(start),
month_last_day=month_last_day)
def clear_billing_data(data):
# remove addcredits entries
def isnotcredit(e):
return e['serviceName'] != "addcredits"
# separate services
def servicefilter(service_name):
service = service_name
def fltr(e):
return e['serviceName'] == service
return fltr
data['bill_nocredits'] = filter(isnotcredit, data['bill'])
data['bill_vmtime'] = filter(servicefilter('vmtime'), data['bill'])
data['bill_diskspace'] = filter(servicefilter('diskspace'), data['bill'])
return data
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment