Added update orders confirmation page
This commit is contained in:
parent
0e65c65433
commit
e669dcf926
4
TODO.md
4
TODO.md
|
@ -154,3 +154,7 @@ textwrap.dedent( \\)
|
|||
|
||||
|
||||
* parmiko write to a channel instead of transfering files? http://sysadmin.circularvale.com/programming/paramiko-channel-hangs/
|
||||
|
||||
* strip leading and trailing whitre spaces of most input fields
|
||||
* Examples of service.match and service.metric
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ def admin_field(method):
|
|||
kwargs['field'] = args[0] if args else ''
|
||||
kwargs['order'] = kwargs.get('order', kwargs['field'])
|
||||
kwargs['popup'] = kwargs.get('popup', False)
|
||||
# TODO get field verbose name
|
||||
kwargs['short_description'] = kwargs.get('short_description',
|
||||
kwargs['field'].split('__')[-1].replace('_', ' ').capitalize())
|
||||
admin_method = partial(method, **kwargs)
|
||||
|
|
|
@ -13,7 +13,7 @@ def create_account_creation_form():
|
|||
for model, key, kwargs, help_text in settings.ACCOUNTS_CREATE_RELATED:
|
||||
model = get_model(model)
|
||||
field_name = 'create_%s' % model._meta.model_name
|
||||
label = _("Create related %s") % model._meta.verbose_name
|
||||
label = _("Create %s") % model._meta.verbose_name
|
||||
fields[field_name] = forms.BooleanField(initial=True, required=False, label=label,
|
||||
help_text=help_text)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import zipfile
|
|||
from django.contrib import messages
|
||||
from django.contrib.admin import helpers
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.utils.safestring import mark_safe
|
||||
|
@ -45,6 +46,7 @@ view_bill.verbose_name = _("View")
|
|||
view_bill.url_name = 'view'
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def close_bills(modeladmin, request, queryset):
|
||||
queryset = queryset.filter(is_open=True)
|
||||
if not queryset:
|
||||
|
|
|
@ -59,6 +59,7 @@ class OrderQuerySet(models.QuerySet):
|
|||
return self.filter(**qs)
|
||||
|
||||
def get_related(self, **options):
|
||||
""" returns related orders that could have a pricing effect """
|
||||
Service = get_model(settings.ORDERS_SERVICE_MODEL)
|
||||
conflictive = self.filter(service__metric='')
|
||||
conflictive = conflictive.exclude(service__billing_period=Service.NEVER)
|
||||
|
@ -66,6 +67,8 @@ class OrderQuerySet(models.QuerySet):
|
|||
qs = Q()
|
||||
for account_id, services in conflictive.iteritems():
|
||||
for service, orders in services.iteritems():
|
||||
if not service.rates.exists():
|
||||
continue
|
||||
end = datetime.date.min
|
||||
bp = None
|
||||
for order in orders:
|
||||
|
@ -107,7 +110,7 @@ class Order(models.Model):
|
|||
related_name='orders')
|
||||
registered_on = models.DateField(_("registered"), default=lambda: timezone.now())
|
||||
cancelled_on = models.DateField(_("cancelled"), null=True, blank=True)
|
||||
billed_on = models.DateField(_("billed on"), null=True, blank=True)
|
||||
billed_on = models.DateField(_("billed"), null=True, blank=True)
|
||||
billed_until = models.DateField(_("billed until"), null=True, blank=True)
|
||||
ignore = models.BooleanField(_("ignore"), default=False)
|
||||
description = models.TextField(_("description"), blank=True)
|
||||
|
@ -122,7 +125,8 @@ class Order(models.Model):
|
|||
return str(self.service)
|
||||
|
||||
@classmethod
|
||||
def update_orders(cls, instance, service=None):
|
||||
def update_orders(cls, instance, service=None, commit=True):
|
||||
updates = []
|
||||
if service is None:
|
||||
Service = get_model(settings.ORDERS_SERVICE_MODEL)
|
||||
services = Service.get_services(instance)
|
||||
|
@ -140,14 +144,23 @@ class Order(models.Model):
|
|||
account = getattr(instance, 'account', instance)
|
||||
if account.is_superuser:
|
||||
ignore = service.ignore_superusers
|
||||
order = cls.objects.create(content_object=instance, service=service,
|
||||
order = cls(content_object=instance, service=service,
|
||||
account_id=account_id, ignore=ignore)
|
||||
if commit:
|
||||
order.save()
|
||||
updates.append((order, 'created'))
|
||||
logger.info("CREATED new order id: {id}".format(id=order.id))
|
||||
else:
|
||||
order = orders.get()
|
||||
order.update()
|
||||
updates.append((order, 'updated'))
|
||||
if commit:
|
||||
order.update()
|
||||
elif orders:
|
||||
orders.get().cancel()
|
||||
order = orders.get()
|
||||
if commit:
|
||||
order.cancel()
|
||||
updates.append((order, 'cancelled'))
|
||||
return updates
|
||||
|
||||
@classmethod
|
||||
def get_bill_backend(cls):
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
{% for line in lines %}
|
||||
<tr class="form-row {% if forloop.counter|divisibleby:2 %}row2{% else %}row1{% endif %}">
|
||||
<td>
|
||||
<a href="{{ line.order | admin_link }}">{{ line.order.description }}</a>
|
||||
<a href="{{ line.order | admin_url }}">{{ line.order.description }}</a>
|
||||
{% for discount in line.discounts %}
|
||||
<br> Discount per {{ discount.type }}
|
||||
{% endfor %}
|
||||
|
|
|
@ -1,15 +1,50 @@
|
|||
from django.contrib.admin import helpers
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import transaction
|
||||
from django.shortcuts import render
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.admin.utils import get_object_from_url
|
||||
|
||||
@transaction.atomic
|
||||
def update_orders(modeladmin, request, queryset):
|
||||
def update_orders(modeladmin, request, queryset, extra_context=None):
|
||||
if not queryset:
|
||||
return
|
||||
if request.POST.get('post') == 'confirmation':
|
||||
num = 0
|
||||
services = []
|
||||
for service in queryset:
|
||||
updates = service.update_orders()
|
||||
num += len(updates)
|
||||
services.append(str(service.pk))
|
||||
modeladmin.log_change(request, service, _("Orders updated"))
|
||||
if num == 1:
|
||||
url = reverse('admin:orders_order_change', args=(updates[0][0].pk,))
|
||||
msg = _('<a href="%s">One related order</a> has benn updated') % url
|
||||
else:
|
||||
url = reverse('admin:orders_order_changelist')
|
||||
url += '?service__in=%s' % ','.join(services)
|
||||
msg = _('<a href="%s">%s related orders</a> have been updated') % (url, num)
|
||||
modeladmin.message_user(request, mark_safe(msg))
|
||||
return
|
||||
updates = []
|
||||
for service in queryset:
|
||||
service.update_orders()
|
||||
modeladmin.log_change(request, service, 'Update orders')
|
||||
msg = _("Orders for %s selected services have been updated.") % queryset.count()
|
||||
modeladmin.message_user(request, msg)
|
||||
updates += service.update_orders(commit=False)
|
||||
opts = modeladmin.model._meta
|
||||
context = {
|
||||
'title': _("Update orders will cause the following."),
|
||||
'action_name': 'Update orders',
|
||||
'action_value': 'update_orders',
|
||||
'updates': updates,
|
||||
'queryset': queryset,
|
||||
'opts': opts,
|
||||
'app_label': opts.app_label,
|
||||
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
|
||||
'obj': get_object_from_url(modeladmin, request),
|
||||
}
|
||||
return render(request, 'admin/services/service/update_orders.html', context)
|
||||
update_orders.url_name = 'update-orders'
|
||||
update_orders.verbose_name = _("Update orders")
|
||||
|
||||
|
|
|
@ -272,11 +272,13 @@ class Service(models.Model):
|
|||
def rate_method(self):
|
||||
return self.RATE_METHODS[self.rate_algorithm]
|
||||
|
||||
def update_orders(self):
|
||||
def update_orders(self, commit=True):
|
||||
order_model = get_model(settings.SERVICES_ORDER_MODEL)
|
||||
related_model = self.content_type.model_class()
|
||||
updates = []
|
||||
for instance in related_model.objects.all().select_related('account'):
|
||||
order_model.update_orders(instance, service=self)
|
||||
updates += order_model.update_orders(instance, service=self, commit=commit)
|
||||
return updates
|
||||
|
||||
|
||||
accounts.register(ContractedPlan)
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
{% extends "admin/orchestra/generic_confirmation.html" %}
|
||||
{% load i18n l10n %}
|
||||
{% load url from future %}
|
||||
{% load admin_urls static utils %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="inline-group" id="rates-group">
|
||||
<div class="tabular inline-related last-related">
|
||||
<fieldset class="module">
|
||||
<table id="result_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><div class="text"><span>Action</span</div></th>
|
||||
<th scope="col"><div class="text"><span>ID</span</div></th>
|
||||
<th scope="col"><div class="text"><span>Service</span</div></th>
|
||||
<th scope="col"><div class="text"><span>Account</span</div></th>
|
||||
<th scope="col"><div class="text"><span>Content object</span</div></th>
|
||||
<th scope="col"><div class="text"><span>Registered on</span</div></th>
|
||||
<th scope="col"><div class="text"><span>Billed until</span</div></th>
|
||||
<th scope="col"><div class="text"><span>Cancelled on</span</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order, action in updates %}
|
||||
<tr class="{% if forloop.counter|divisibleby:2 %}row2{% else %}row1{% endif %}">
|
||||
<th>{{ action }}</th>
|
||||
<td>{% if order.pk %}<a href="{{ order | admin_url }}">{{ order.id }}</a>{% endif %}</td>
|
||||
<td><a href="{{ order.service | admin_url }}">{{ order.service }}</a></td>
|
||||
<td><a href="{{ order.account | admin_url }}">{{ order.account }}</a></td>
|
||||
<td><a href="{{ order.content_object | admin_url }}">{{ order.content_object }}</a></td>
|
||||
<td><span title="{{ order.registered_on }}">{{ order.registered_on }}</span></td>
|
||||
<td><span title="{{ order.billed_unitl }}">{{ order.billed_unitl }}</span></td>
|
||||
<td>{{ order.canncelled_on }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
{% for obj in queryset %}
|
||||
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}" />
|
||||
{% endfor %}
|
||||
<input type="hidden" name="action" value="{{ action_value }}" />
|
||||
<input type="hidden" name="post" value="confirmation" />
|
||||
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -54,5 +54,5 @@ def is_checkbox(field):
|
|||
|
||||
|
||||
@register.filter
|
||||
def admin_link(obj):
|
||||
def admin_url(obj):
|
||||
return change_url(obj)
|
||||
|
|
Loading…
Reference in New Issue