Implemented payments source selection
This commit is contained in:
parent
4c603bf584
commit
cc85956e7b
6
TODO.md
6
TODO.md
|
@ -86,3 +86,9 @@ at + clock time, midnight, noon- At 3:30 p.m., At 4:01, At noon
|
|||
from django.utils import translation
|
||||
with translation.override('en'):
|
||||
* Plurals!
|
||||
|
||||
* 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)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.contrib.admin import helpers
|
||||
from django.forms.models import modelformset_factory, BaseModelFormSet
|
||||
from django.template import Template, Context
|
||||
from django.contrib.admin.helpers import AdminForm
|
||||
|
||||
|
||||
class AdminFormMixin(object):
|
||||
|
@ -9,10 +10,35 @@ class AdminFormMixin(object):
|
|||
fieldsets = [
|
||||
(None, {'fields': self.fields.keys()})
|
||||
]
|
||||
adminform = AdminForm(self, fieldsets, prepopulated_fields)
|
||||
adminform = helpers.AdminForm(self, fieldsets, prepopulated_fields)
|
||||
template = Template(
|
||||
'{% for fieldset in adminform %}'
|
||||
' {% include "admin/includes/fieldset.html" %}'
|
||||
'{% endfor %}'
|
||||
)
|
||||
return template.render(Context({'adminform': adminform}))
|
||||
|
||||
|
||||
class AdminFormSet(BaseModelFormSet):
|
||||
def as_admin(self):
|
||||
prepopulated = {}
|
||||
fieldsets = [
|
||||
(None, {'fields': self.form().fields.keys()})
|
||||
]
|
||||
readonly = getattr(self.form.Meta, 'readonly_fields', ())
|
||||
if not hasattr(self.modeladmin, 'verbose_name_plural'):
|
||||
opts = self.modeladmin.model._meta
|
||||
self.modeladmin.verbose_name_plural = opts.verbose_name_plural
|
||||
inline_admin_formset = helpers.InlineAdminFormSet(self.modeladmin, self,
|
||||
fieldsets, prepopulated, readonly, model_admin=self.modeladmin)
|
||||
template = Template(
|
||||
'{% include "admin/edit_inline/tabular.html" %}'
|
||||
)
|
||||
return template.render(Context({'inline_admin_formset': inline_admin_formset}))
|
||||
|
||||
|
||||
def adminmodelformset_factory(modeladmin, form):
|
||||
formset = modelformset_factory(modeladmin.model, extra=0,
|
||||
form=form, formset=AdminFormSet)
|
||||
formset.modeladmin = modeladmin
|
||||
return formset
|
||||
|
|
|
@ -2,11 +2,16 @@ import StringIO
|
|||
import zipfile
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.admin import helpers
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.admin.forms import adminmodelformset_factory
|
||||
from orchestra.utils.html import html_to_pdf
|
||||
|
||||
from .forms import SelectSourceForm
|
||||
|
||||
|
||||
def download_bills(modeladmin, request, queryset):
|
||||
if queryset.count() > 1:
|
||||
|
@ -35,29 +40,33 @@ view_bill.verbose_name = _("View")
|
|||
view_bill.url_name = 'view'
|
||||
|
||||
|
||||
from django import forms
|
||||
from django.forms.models import BaseModelFormSet
|
||||
from django.forms.formsets import formset_factory
|
||||
from django.forms.models import modelformset_factory
|
||||
from django.shortcuts import render
|
||||
|
||||
from .forms import SelectPaymentSourceForm
|
||||
|
||||
def close_bills(modeladmin, request, queryset):
|
||||
queryset = queryset.filter(status=queryset.model.OPEN)
|
||||
if not queryset:
|
||||
messages.warning(request, _("Selected bills should be in open state"))
|
||||
return
|
||||
SelectPaymentSourceFormSet = modelformset_factory(queryset.model, form=SelectPaymentSourceForm, extra=0)
|
||||
if request.POST.get('action') == 'close_selected_bills':
|
||||
formset = SelectPaymentSourceFormSet(request.POST, queryset=queryset)
|
||||
SelectSourceFormSet = adminmodelformset_factory(modeladmin, SelectSourceForm)
|
||||
formset = SelectSourceFormSet(queryset=queryset)
|
||||
if request.POST.get('post') == 'yes':
|
||||
formset = SelectSourceFormSet(request.POST, request.FILES, queryset=queryset)
|
||||
if formset.is_valid():
|
||||
for form in formset.forms:
|
||||
form.save()
|
||||
source = form.cleaned_data['source']
|
||||
form.instance.close(payment=source)
|
||||
messages.success(request, _("Selected bills have been closed"))
|
||||
return
|
||||
formset = SelectPaymentSourceFormSet(queryset=queryset)
|
||||
return render(request, 'admin/bills/close_confirmation.html', {'formset': formset})
|
||||
opts = modeladmin.model._meta
|
||||
context = {
|
||||
'title': "Are you sure?",
|
||||
'action_value': 'close_bills',
|
||||
'deletable_objects': queryset,
|
||||
'queryset': queryset,
|
||||
'opts': opts,
|
||||
'app_label': opts.app_label,
|
||||
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
|
||||
'formset': formset,
|
||||
}
|
||||
return render(request, 'admin/bills/close_confirmation.html', context)
|
||||
close_bills.verbose_name = _("Close")
|
||||
close_bills.url_name = 'close'
|
||||
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.admin.utils import admin_link
|
||||
from orchestra.forms.widgets import ShowTextWidget
|
||||
|
||||
class SelectPaymentSourceForm(forms.ModelForm):
|
||||
|
||||
class SelectSourceForm(forms.ModelForm):
|
||||
bill_link = forms.CharField(label=_("Number"), required=False,
|
||||
widget=ShowTextWidget())
|
||||
account_link = forms.CharField(label=_("Account"), required=False)
|
||||
display_total = forms.CharField(label=_("Total"), required=False)
|
||||
display_type = forms.CharField(label=_("Type"), required=False,
|
||||
widget=ShowTextWidget())
|
||||
source = forms.ChoiceField(label=_("Source"), required=False)
|
||||
|
||||
class Meta:
|
||||
fields = ('number', 'source')
|
||||
fields = (
|
||||
'bill_link', 'display_type', 'account_link', 'display_total',
|
||||
'source'
|
||||
)
|
||||
readonly_fields = ('account_link', 'display_total')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SelectPaymentSourceForm, self).__init__(*args, **kwargs)
|
||||
super(SelectSourceForm, self).__init__(*args, **kwargs)
|
||||
bill = kwargs.get('instance')
|
||||
if bill:
|
||||
sources = bill.account.paymentsources.filter(is_active=True)
|
||||
|
@ -19,6 +32,9 @@ class SelectPaymentSourceForm(forms.ModelForm):
|
|||
if not recharge or source.method_class().allow_recharge:
|
||||
choices.append((source.pk, str(source)))
|
||||
self.fields['source'].choices = choices
|
||||
self.fields['source'].initial = choices[-1][0]
|
||||
self.fields['bill_link'].initial = admin_link('__unicode__')(bill)
|
||||
self.fields['display_type'].initial = bill.get_type_display()
|
||||
|
||||
def clean_source(self):
|
||||
source_id = self.cleaned_data['source']
|
||||
|
@ -27,8 +43,8 @@ class SelectPaymentSourceForm(forms.ModelForm):
|
|||
source_model = self.instance.account.paymentsources.model
|
||||
return source_model.objects.get(id=source_id)
|
||||
|
||||
def has_changed(self):
|
||||
return False
|
||||
|
||||
def save(self, commit=True):
|
||||
if commit:
|
||||
source = self.cleaned_data['source']
|
||||
self.instance.close(payment=source)
|
||||
return self.instance
|
||||
pass
|
||||
|
|
|
@ -180,7 +180,7 @@ class Bill(models.Model):
|
|||
@cached
|
||||
def get_subtotals(self):
|
||||
subtotals = {}
|
||||
for line in self.lines.all().prefetch_related('sublines'):
|
||||
for line in self.lines.all():
|
||||
subtotal, taxes = subtotals.get(line.tax, (0, 0))
|
||||
subtotal += line.total
|
||||
for subline in line.sublines.all():
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{% 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 %}
|
||||
|
||||
|
||||
|
@ -18,12 +19,16 @@
|
|||
<form action="" method="post">{% csrf_token %}
|
||||
<div>
|
||||
<div style="margin:20px;">
|
||||
{{ formset }}
|
||||
|
||||
{{ 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="close_selected_bills"/>
|
||||
<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>
|
||||
|
|
|
@ -82,6 +82,7 @@ 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,
|
||||
name='%s_%s_select_method' % info),
|
||||
|
|
|
@ -55,11 +55,18 @@ class PaymentSource(models.Model):
|
|||
class TransactionQuerySet(models.QuerySet):
|
||||
group_by = group_by
|
||||
|
||||
def create(self, **kwargs):
|
||||
source = kwargs.get('source')
|
||||
if source is None or not hasattr(source.method_class, 'process'):
|
||||
# Manual payments don't need processing
|
||||
kwargs['state']=self.model.WAITTING_CONFIRMATION
|
||||
return super(TransactionQuerySet, self).create(**kwargs)
|
||||
|
||||
|
||||
# TODO lock transaction in waiting confirmation
|
||||
class Transaction(models.Model):
|
||||
WAITTING_PROCESSING = 'WAITTING_PROCESSING'
|
||||
WAITTING_CONFIRMATION = 'WAITTING_CONFIRMATION'
|
||||
WAITTING_PROCESSING = 'WAITTING_PROCESSING' # CREATED
|
||||
WAITTING_CONFIRMATION = 'WAITTING_CONFIRMATION' # PROCESSED
|
||||
CONFIRMED = 'CONFIRMED'
|
||||
REJECTED = 'REJECTED'
|
||||
DISCARTED = 'DISCARTED'
|
||||
|
|
Loading…
Reference in a new issue