Random stuff
This commit is contained in:
parent
157fd54ce5
commit
4e3105194c
|
@ -55,7 +55,7 @@ def action_with_confirmation(action_name, extra_context={},
|
|||
(action_name, objects_name),
|
||||
"action_name": action_name.capitalize(),
|
||||
"action_value": action_value,
|
||||
"deletable_objects": queryset,
|
||||
"display_objects": queryset,
|
||||
'queryset': queryset,
|
||||
"opts": opts,
|
||||
"app_label": app_label,
|
||||
|
|
|
@ -3,7 +3,7 @@ from django.core.urlresolvers import reverse
|
|||
from django.utils.text import capfirst
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.core import services
|
||||
from orchestra.core import services, accounts
|
||||
from orchestra.utils.apps import isinstalled
|
||||
|
||||
|
||||
|
@ -28,47 +28,39 @@ def api_link(context):
|
|||
|
||||
|
||||
def get_services():
|
||||
result = []
|
||||
childrens = []
|
||||
for model, options in services.get().iteritems():
|
||||
if options.get('menu', True):
|
||||
opts = model._meta
|
||||
url = reverse('admin:{}_{}_changelist'.format(
|
||||
opts.app_label, opts.model_name))
|
||||
name = capfirst(options.get('verbose_name_plural'))
|
||||
result.append(items.MenuItem(name, url))
|
||||
return sorted(result, key=lambda i: i.title)
|
||||
childrens.append(items.MenuItem(name, url))
|
||||
return sorted(childrens, key=lambda i: i.title)
|
||||
|
||||
|
||||
def get_account_items():
|
||||
def get_accounts():
|
||||
childrens = [
|
||||
items.MenuItem(_("Accounts"),
|
||||
reverse('admin:accounts_account_changelist'))
|
||||
]
|
||||
if isinstalled('orchestra.apps.contacts'):
|
||||
url = reverse('admin:contacts_contact_changelist')
|
||||
childrens.append(items.MenuItem(_("Contacts"), url))
|
||||
if isinstalled('orchestra.apps.users'):
|
||||
url = reverse('admin:users_user_changelist')
|
||||
childrens.append(items.MenuItem(_("Users"), url))
|
||||
if isinstalled('orchestra.apps.orders'):
|
||||
url = reverse('admin:orders_plan_changelist')
|
||||
childrens.append(items.MenuItem(_("Plans"), url))
|
||||
url = reverse('admin:orders_order_changelist')
|
||||
childrens.append(items.MenuItem(_("Orders"), url))
|
||||
if isinstalled('orchestra.apps.bills'):
|
||||
url = reverse('admin:bills_bill_changelist')
|
||||
childrens.append(items.MenuItem(_("Bills"), url))
|
||||
if isinstalled('orchestra.apps.payments'):
|
||||
url = reverse('admin:payments_transaction_changelist')
|
||||
childrens.append(items.MenuItem(_("Transactions"), url))
|
||||
url = reverse('admin:payments_transactionprocess_changelist')
|
||||
childrens.append(items.MenuItem(_("Transaction processes"), url))
|
||||
url = reverse('admin:payments_paymentsource_changelist')
|
||||
childrens.append(items.MenuItem(_("Payment sources"), url))
|
||||
if isinstalled('orchestra.apps.issues'):
|
||||
url = reverse('admin:issues_ticket_changelist')
|
||||
childrens.append(items.MenuItem(_("Tickets"), url))
|
||||
return childrens
|
||||
for model, options in accounts.get().iteritems():
|
||||
if options.get('menu', True):
|
||||
opts = model._meta
|
||||
url = reverse('admin:{}_{}_changelist'.format(
|
||||
opts.app_label, opts.model_name))
|
||||
name = capfirst(options.get('verbose_name_plural'))
|
||||
childrens.append(items.MenuItem(name, url))
|
||||
return sorted(childrens, key=lambda i: i.title)
|
||||
|
||||
|
||||
def get_administration_items():
|
||||
|
@ -128,7 +120,7 @@ class OrchestraMenu(Menu):
|
|||
items.MenuItem(
|
||||
_("Accounts"),
|
||||
reverse('admin:accounts_account_changelist'),
|
||||
children=get_account_items()
|
||||
children=get_accounts()
|
||||
),
|
||||
items.MenuItem(
|
||||
_("Administration"),
|
||||
|
|
|
@ -48,7 +48,7 @@ def close_bills(modeladmin, request, queryset):
|
|||
SelectSourceFormSet = adminmodelformset_factory(modeladmin, SelectSourceForm,
|
||||
extra=0)
|
||||
formset = SelectSourceFormSet(queryset=queryset)
|
||||
if request.POST.get('post') == 'yes':
|
||||
if request.POST.get('post') == 'generic_confirmation':
|
||||
formset = SelectSourceFormSet(request.POST, request.FILES, queryset=queryset)
|
||||
if formset.is_valid():
|
||||
for form in formset.forms:
|
||||
|
@ -58,17 +58,19 @@ def close_bills(modeladmin, request, queryset):
|
|||
return
|
||||
opts = modeladmin.model._meta
|
||||
context = {
|
||||
'title': "Are you sure?",
|
||||
'title': _("Are you sure about closing the following bills?"),
|
||||
'content_message': _("Once a bill is closed it can not be further modified.</p>"
|
||||
"<p>Please select a payment source for the selected bills"),
|
||||
'action_name': 'Close bills',
|
||||
'action_value': 'close_bills',
|
||||
'deletable_objects': queryset,
|
||||
'display_objects': [],
|
||||
'queryset': queryset,
|
||||
'opts': opts,
|
||||
'app_label': opts.app_label,
|
||||
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
|
||||
'formset': formset,
|
||||
}
|
||||
# TODO use generic confirmation template
|
||||
return render(request, 'admin/bills/close_confirmation.html', context)
|
||||
return render(request, 'admin/orchestra/generic_confirmation.html', context)
|
||||
close_bills.verbose_name = _("Close")
|
||||
close_bills.url_name = 'close'
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ class BudgetLineInline(admin.TabularInline):
|
|||
fields = ('description', 'rate', 'amount', 'tax', 'total')
|
||||
|
||||
|
||||
# TODO hide raw when status = oPen
|
||||
class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||
list_display = (
|
||||
'number', 'status', 'type_link', 'account_link', 'created_on_display',
|
||||
|
@ -83,9 +82,10 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
num_lines.short_description = _("lines")
|
||||
|
||||
def display_total(self, bill):
|
||||
return "%s &%s;" % (bill.get_total(), settings.BILLS_CURRENCY.lower())
|
||||
return "%s &%s;" % (bill.total, settings.BILLS_CURRENCY.lower())
|
||||
display_total.allow_tags = True
|
||||
display_total.short_description = _("total")
|
||||
display_total.admin_order_field = 'total'
|
||||
|
||||
def type_link(self, bill):
|
||||
bill_type = bill.type.lower()
|
||||
|
@ -101,6 +101,12 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
fields += self.add_fields
|
||||
return fields
|
||||
|
||||
def get_fieldsets(self, request, obj=None):
|
||||
fieldsets = super(BillAdmin, self).get_fieldsets(request, obj=obj)
|
||||
if obj and obj.status == obj.OPEN:
|
||||
fieldsets = (fieldsets[0],)
|
||||
return fieldsets
|
||||
|
||||
def get_change_view_actions(self, obj=None):
|
||||
actions = super(BillAdmin, self).get_change_view_actions(obj)
|
||||
discard = []
|
||||
|
|
|
@ -26,7 +26,7 @@ class SelectSourceForm(forms.ModelForm):
|
|||
bill = kwargs.get('instance')
|
||||
if bill:
|
||||
sources = bill.account.paymentsources.filter(is_active=True)
|
||||
recharge = bool(bill.get_total() < 0)
|
||||
recharge = bool(bill.total < 0)
|
||||
choices = [(None, '-----------')]
|
||||
for source in sources:
|
||||
if not recharge or source.method_class().allow_recharge:
|
||||
|
|
20
orchestra/apps/bills/migrations/0003_bill_total.py
Normal file
20
orchestra/apps/bills/migrations/0003_bill_total.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bills', '0002_bill_closed_on'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='bill',
|
||||
name='total',
|
||||
field=models.DecimalField(default=10, max_digits=12, decimal_places=2),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -57,10 +57,8 @@ class Bill(models.Model):
|
|||
closed_on = models.DateTimeField(_("closed on"), blank=True, null=True)
|
||||
due_on = models.DateField(_("due on"), null=True, blank=True)
|
||||
last_modified_on = models.DateTimeField(_("last modified on"), auto_now=True)
|
||||
#base = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
#tax = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
total = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
comments = models.TextField(_("comments"), blank=True)
|
||||
# TODO rename to HTML-agnostic term like.. RAW ?
|
||||
html = models.TextField(_("HTML"), blank=True)
|
||||
|
||||
objects = BillManager()
|
||||
|
@ -121,10 +119,9 @@ class Bill(models.Model):
|
|||
payment = self.account.paymentsources.get_default()
|
||||
if not self.due_on:
|
||||
self.due_on = self.get_due_date(payment=payment)
|
||||
self.total = self.get_total()
|
||||
self.html = self.render(payment=payment)
|
||||
self.transactions.create(
|
||||
bill=self, source=payment, amount=self.get_total()
|
||||
)
|
||||
self.transactions.create(bill=self, source=payment, amount=self.total)
|
||||
self.closed_on = timezone.now()
|
||||
self.status = self.CLOSED
|
||||
self.save()
|
||||
|
@ -173,6 +170,8 @@ class Bill(models.Model):
|
|||
def save(self, *args, **kwargs):
|
||||
if not self.type:
|
||||
self.type = self.get_type()
|
||||
if self.status == self.OPEN:
|
||||
self.total = self.get_total()
|
||||
if not self.number or (self.number.startswith('O') and self.status != self.OPEN):
|
||||
self.set_number()
|
||||
super(Bill, self).save(*args, **kwargs)
|
||||
|
@ -190,7 +189,6 @@ class Bill(models.Model):
|
|||
|
||||
@cached
|
||||
def get_total(self):
|
||||
# TODO self.total = self.get_total on self.save()
|
||||
total = 0
|
||||
for tax, subtotal in self.get_subtotals().iteritems():
|
||||
subtotal, taxes = subtotal
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n l10n staticfiles admin_urls %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
|
||||
<link rel="stylesheet" type="text/css" href="{% static "orchestra/css/hide-inline-id.css" %}" />
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<h1>Are you sure you want to close selected bills</h1>
|
||||
<p>Once a bill is closed it can not be further modified.</p>
|
||||
<p>Please select a payment source for the selected bills </p>
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<div>
|
||||
<div style="margin:20px;">
|
||||
|
||||
{{ formset.as_admin }}
|
||||
|
||||
|
||||
</div>
|
||||
{% 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="yes"/>
|
||||
<input type="submit" value="{% trans "Yes, close bills" %}" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ class DomainAdmin(ChangeListDefaultFilter, AccountAdminMixin, ExtendedModelAdmin
|
|||
def get_queryset(self, request):
|
||||
""" Order by structured name and imporve performance """
|
||||
qs = super(DomainAdmin, self).get_queryset(request)
|
||||
qs = qs.select_related('top', 'account__user')
|
||||
qs = qs.select_related('top')
|
||||
# qs = qs.select_related('top')
|
||||
# For some reason if we do this we know for sure that join table will be called T4
|
||||
__ = str(qs.query)
|
||||
|
|
|
@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
|
|||
from django.shortcuts import render, redirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.admin.utils import admin_colored, admin_link
|
||||
from orchestra.admin.utils import admin_colored, admin_link, wrap_admin_view
|
||||
from orchestra.apps.accounts.admin import AccountAdminMixin
|
||||
|
||||
from .actions import process_transactions
|
||||
|
@ -82,9 +82,8 @@ class PaymentSourceAdmin(AccountAdminMixin, admin.ModelAdmin):
|
|||
opts = self.model._meta
|
||||
info = opts.app_label, opts.model_name
|
||||
select_urls = patterns("",
|
||||
# TODO wrap for authentication
|
||||
url("/select-method/$",
|
||||
self.select_method_view,
|
||||
wrap_admin_view(self, self.select_method_view),
|
||||
name='%s_%s_select_method' % info),
|
||||
)
|
||||
return select_urls + urls
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n l10n staticfiles admin_urls %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block breadcrumbs %}
|
||||
TODO
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<h1>Select a method for the new payment source</h1>
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<div>
|
||||
<div style="margin:20px;">
|
||||
<ul>
|
||||
{% for name, verbose in methods %}
|
||||
<li><a href="../?method={{ name }}&{{ request.META.QUERY_STRING }}">{{ verbose }}</<a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -64,8 +64,7 @@ class AutoresponseInline(admin.StackedInline):
|
|||
# def queryset(self, request):
|
||||
# """ Select related for performance """
|
||||
# qs = super(AddressAdmin, self).queryset(request)
|
||||
# # TODO django 1.7 account__user is not needed
|
||||
# return qs.select_related('domain', 'account__user')
|
||||
# return qs.select_related('domain')
|
||||
|
||||
|
||||
class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||
|
@ -114,8 +113,7 @@ class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
def get_queryset(self, request):
|
||||
""" Select related for performance """
|
||||
qs = super(AddressAdmin, self).get_queryset(request)
|
||||
# TODO django 1.7 account__user is not needed
|
||||
return qs.select_related('domain', 'account__user')
|
||||
return qs.select_related('domain')
|
||||
|
||||
|
||||
class MailRoleAdmin(RoleAdmin):
|
||||
|
|
Loading…
Reference in a new issue