Moved account service management object-tools to cl filters

This commit is contained in:
Marc 2014-09-08 10:03:42 +00:00
parent cc85956e7b
commit fc44c8bfc0
12 changed files with 65 additions and 33 deletions

View File

@ -89,6 +89,4 @@ at + clock time, midnight, noon- At 3:30 p.m., At 4:01, At noon
* help_text on readonly_fields specialy Bill.state. (eg. A bill is in OPEN state when bla bla ) * help_text on readonly_fields specialy Bill.state. (eg. A bill is in OPEN state when bla bla )
* Account link and "show all" button on the filters secction instead of object-tools
* Create ProForma from orders orders.bill(proforma=True) * Create ProForma from orders orders.bill(proforma=True)

View File

@ -37,8 +37,8 @@ class AdminFormSet(BaseModelFormSet):
return template.render(Context({'inline_admin_formset': inline_admin_formset})) return template.render(Context({'inline_admin_formset': inline_admin_formset}))
def adminmodelformset_factory(modeladmin, form): def adminmodelformset_factory(modeladmin, form, formset=AdminFormSet, **kwargs):
formset = modelformset_factory(modeladmin.model, extra=0, formset = modelformset_factory(modeladmin.model, form=form, formset=formset,
form=form, formset=AdminFormSet) **kwargs)
formset.modeladmin = modeladmin formset.modeladmin = modeladmin
return formset return formset

View File

@ -198,19 +198,25 @@ class AccountAdminMixin(object):
def changelist_view(self, request, extra_context=None): def changelist_view(self, request, extra_context=None):
account_id = request.GET.get('account') account_id = request.GET.get('account')
context = { context = {}
'from_account': False
}
if account_id: if account_id:
opts = self.model._meta opts = self.model._meta
account = Account.objects.get(pk=account_id) account = Account.objects.get(pk=account_id)
context = { context = {
'from_account': True,
'title': _("Select %s to change for %s") % (
opts.verbose_name, account.name),
'account': not account_id or Account.objects.get(pk=account_id), 'account': not account_id or Account.objects.get(pk=account_id),
'account_opts': Account._meta, 'account_opts': Account._meta,
'all_selected': True,
} }
if not request.GET.get('all'):
context.update({
'all_selected': False,
'title': _("Select %s to change for %s") % (
opts.verbose_name, account.name),
})
else:
request_copy = request.GET.copy()
request_copy.pop('account')
request.GET = request_copy
context.update(extra_context or {}) context.update(extra_context or {})
return super(AccountAdminMixin, self).changelist_view(request, return super(AccountAdminMixin, self).changelist_view(request,
extra_context=context) extra_context=context)

View File

@ -1,4 +1,5 @@
from django.contrib.admin import SimpleListFilter from django.contrib.admin import SimpleListFilter
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _

View File

@ -1,11 +1,11 @@
{% extends "admin/change_list.html" %} {% extends "admin/change_list.html" %}
{% load i18n admin_urls %} {% load i18n admin_urls admin_list %}
{% block breadcrumbs %} {% block breadcrumbs %}
<div class="breadcrumbs"> <div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a> <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
{% if from_account %} {% if account %}
&rsaquo; <a href="{% url 'admin:app_list' app_label=account_opts.app_label %}">{{ account_opts.app_config.verbose_name }}</a> &rsaquo; <a href="{% url 'admin:app_list' app_label=account_opts.app_label %}">{{ account_opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url account_opts|admin_urlname:'changelist' %}">{{ account_opts.verbose_name_plural|capfirst }}</a> &rsaquo; <a href="{% url account_opts|admin_urlname:'changelist' %}">{{ account_opts.verbose_name_plural|capfirst }}</a>
&rsaquo; <a href="{% url account_opts|admin_urlname:'change' account.pk|admin_urlquote %}">{{ account|truncatewords:"18" }}</a> &rsaquo; <a href="{% url account_opts|admin_urlname:'change' account.pk|admin_urlquote %}">{{ account|truncatewords:"18" }}</a>
@ -18,18 +18,32 @@
{% block object-tools-items %} {% block object-tools-items %}
{% if from_account %}
<li>
<a href="{% url account_opts|admin_urlname:'change' account.pk|admin_urlquote %}" class="historylink">{{ account|truncatewords:"18" }}</a>
</li>
<li>
<a href="./" class="historylink">{% trans 'Show all' %}</a>
</li>
{% endif %}
<li> <li>
{% url cl.opts|admin_urlname:'add' as add_url %} {% url cl.opts|admin_urlname:'add' as add_url %}
<a href="{% add_preserved_filters add_url is_popup to_field %}" class="addlink"> <a href="{% add_preserved_filters add_url is_popup to_field %}" class="addlink">
{% if all_selected %}
{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %} {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
{% else %}
{% blocktrans with cl.opts.verbose_name as name and account|truncatewords:"18" as account %}Add {{ account }} {{ name }}{% endblocktrans %}
{% endif %}
</a> </a>
</li> </li>
{% endblock %} {% endblock %}
{% block filters %}
{% if cl.has_filters %}
<div id="changelist-filter">
<h2>{% trans 'Filter' %}</h2>
{% if account %}
<h3>{% trans 'By account' %}</h3>
<ul>
<li {% if not all_selected %}class="selected"{% endif %}><a href="?account={{ account.pk }}">{{ account|truncatewords:"18" }}</a></li>
<li {% if all_selected %}class="selected"{% endif %}><a href="?account={{ account.pk }}&all=True">All</a></li>
</ul>
{% endif %}
{% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
</div>
{% endif %}
{% endblock %}

View File

@ -45,7 +45,8 @@ def close_bills(modeladmin, request, queryset):
if not queryset: if not queryset:
messages.warning(request, _("Selected bills should be in open state")) messages.warning(request, _("Selected bills should be in open state"))
return return
SelectSourceFormSet = adminmodelformset_factory(modeladmin, SelectSourceForm) SelectSourceFormSet = adminmodelformset_factory(modeladmin, SelectSourceForm,
extra=0)
formset = SelectSourceFormSet(queryset=queryset) formset = SelectSourceFormSet(queryset=queryset)
if request.POST.get('post') == 'yes': if request.POST.get('post') == 'yes':
formset = SelectSourceFormSet(request.POST, request.FILES, queryset=queryset) formset = SelectSourceFormSet(request.POST, request.FILES, queryset=queryset)
@ -66,6 +67,7 @@ def close_bills(modeladmin, request, queryset):
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
'formset': formset, 'formset': formset,
} }
# TODO use generic confirmation template
return render(request, 'admin/bills/close_confirmation.html', context) return render(request, 'admin/bills/close_confirmation.html', context)
close_bills.verbose_name = _("Close") close_bills.verbose_name = _("Close")
close_bills.url_name = 'close' close_bills.url_name = 'close'

View File

@ -39,7 +39,7 @@
{% block summary %} {% block summary %}
<div id="bill-number"> <div id="bill-number">
{{ bill.get_type_display }}<br> {{ bill.get_type_display.capitalize }}<br>
<span class="value">{{ bill.number }}</span><br> <span class="value">{{ bill.number }}</span><br>
</div> </div>
<div id="bill-summary"> <div id="bill-summary">
@ -125,14 +125,14 @@
{% if payment.message %} {% if payment.message %}
{{ payment.message | safe }} {{ payment.message | safe }}
{% else %} {% else %}
You can pay our invoice by bank transfer. <br> You can pay our {{ bill.get_type_display.lower }} by bank transfer. <br>
Please make sure to state your name and the invoice number. Please make sure to state your name and the {{ bill.get_type_display.lower}} number.
Our bank account number is <br> Our bank account number is <br>
<strong>{{ seller_info.bank_account }}</strong> <strong>{{ seller_info.bank_account }}</strong>
{% endif %} {% endif %}
</div> </div>
<div id="questions"> <div id="questions">
<span class="title">QUESTIONS</span> If you have any question about your bill, please <span class="title">QUESTIONS</span> If you have any question about your {{ bill.get_type_display.lower}}, please
feel free to contact us at your convinience. We will reply as soon as we get feel free to contact us at your convinience. We will reply as soon as we get
your message. your message.
</div> </div>

View File

@ -13,6 +13,7 @@ from django.utils.translation import ugettext_lazy as _
from orchestra.core import caches, services, accounts from orchestra.core import caches, services, accounts
from orchestra.models import queryset from orchestra.models import queryset
from orchestra.utils.apps import autodiscover from orchestra.utils.apps import autodiscover
from orchestra.utils.python import import_class
from . import settings, helpers from . import settings, helpers
from .handlers import ServiceHandler from .handlers import ServiceHandler
@ -315,9 +316,7 @@ class Order(models.Model):
@classmethod @classmethod
def get_bill_backend(cls): def get_bill_backend(cls):
# TODO return import_class(settings.ORDERS_BILLING_BACKEND)()
from .backends import BillsBackend
return BillsBackend()
def cancel(self): def cancel(self):
self.cancelled_on = timezone.now() self.cancelled_on = timezone.now()

View File

@ -12,3 +12,7 @@ ORDERS_SERVICE_DEFAUL_TAX = getattr(settings, 'ORDERS_SERVICE_DFAULT_TAX', 0)
ORDERS_SERVICE_ANUAL_BILLING_MONTH = getattr(settings, 'ORDERS_SERVICE_ANUAL_BILLING_MONTH', 4) ORDERS_SERVICE_ANUAL_BILLING_MONTH = getattr(settings, 'ORDERS_SERVICE_ANUAL_BILLING_MONTH', 4)
ORDERS_BILLING_BACKEND = getattr(settings, 'ORDERS_BILLING_BACKEND',
'orchestra.apps.orders.billing.BillsBackend')

View File

@ -1,4 +1,5 @@
from .methods import PaymentMethod
def process_transactions(modeladmin, request, queryset): def process_transactions(modeladmin, request, queryset):
for source, transactions in queryset.group_by('source'): for method, transactions in queryset.group_by('source__method'):
if source: if method is not None:
source.method_class().process(transactions) PaymentMethod.get_plugin(method)().process(transactions)

View File

@ -1,3 +1,6 @@
from .utils import get_field_value
def group_by(qset, *fields, **kwargs): def group_by(qset, *fields, **kwargs):
""" group_by iterator with support for multiple nested fields """ """ group_by iterator with support for multiple nested fields """
ix = kwargs.get('ix', 0) ix = kwargs.get('ix', 0)
@ -6,7 +9,11 @@ def group_by(qset, *fields, **kwargs):
group = [] group = []
first = True first = True
for obj in qset: for obj in qset:
current = getattr(obj, fields[ix]) try:
current = get_field_value(obj, fields[ix])
except AttributeError:
# Intermediary relation does not exists
current = None
if first or current == previous: if first or current == previous:
group.append(obj) group.append(obj)
else: else: