Skip to content

Instantly share code, notes, and snippets.

@razum2um
Created July 5, 2011 14:48
Show Gist options
  • Save razum2um/1064975 to your computer and use it in GitHub Desktop.
Save razum2um/1064975 to your computer and use it in GitHub Desktop.
django CBV
# -*- coding: utf-8 -*-
from django.conf import settings
from django.views.generic import TemplateView, DetailView, CreateView, UpdateView
from django.shortcuts import get_object_or_404
from django.forms.models import inlineformset_factory
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.utils.decorators import classonlymethod
from django.utils import simplejson
from django.http import HttpResponse, HttpResponseForbidden
from cabinet.views import BaseListViewJSONMixin
from cabinet.views import BaseListView as ListView # fake generic
from cabinet.helpers import DjangoJSONEncoder
from directory.models import Nomenclature
from cabinet.helpers import UrlPaginator
from documents.models import Bill, Sale, Order, Invoice, BillNomenclature, SaleNomenclature, InvoiceNomenclature
from documents.forms import (OrderForm, NomenclatureInlineFormSet,
BillForm, BillNomenclatureForm,
SaleForm, SaleNomenclatureForm,
InvoiceForm, InvoiceNomenclatureForm,
DocFilterForm)
from documents import consts as doc_consts
from directory import consts as dir_consts
from directory.models import Contractor, Folder
class DocumentDetailViewBase(DetailView): # base class for all document details view
def get_context_data(self, **kwargs):
context = super(DocumentDetailViewBase, self).get_context_data(**kwargs)
context['in_documents'] = True
return context
class DocumentFormsetMixin(object):
""" mixin class. adds formset usage """
formset_class = NomenclatureInlineFormSet
def post(self, request, *args, **kwargs):
if not hasattr(self, 'object'):
try:
self.object = self.get_object()
except AttributeError:
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
FormSet = inlineformset_factory(self.formset_parent_model, self.formset_model,
formset=self.formset_class, form=self.formset_form, extra=0)
formset = FormSet(request.POST, instance=self.object)
self.formset = formset
if form.is_valid() and formset.is_valid():
return self.form_valid(form, formset)
else:
return self.form_invalid(form, formset)
def form_valid(self, form, formset):
obj = form.save()
formset.instance = obj
obj_list = formset.save()
return super(DocumentFormsetMixin, self).form_valid(form)
def form_invalid(self, form, formset):
return super(DocumentFormsetMixin, self).form_invalid(form)
def get_context_data(self, **kwargs):
context = super(DocumentFormsetMixin, self).get_context_data(**kwargs)
if hasattr(self, 'formset'):
# formset already submitted
formset = self.formset
else:
FormSet = inlineformset_factory(self.formset_parent_model, self.formset_model,
formset=self.formset_class, form=self.formset_form, extra=0)
if self.object:
formset = FormSet(instance=self.object)
else:
# if bill id found in the url, fill new documents formset with forms containing nomenclature from bill
initial = None
bill_id = self.kwargs.get('bill_id')
if bill_id:
bill_obj = Bill.objects.get(id=bill_id)
initial = bill_obj.get_nomenclature_initial()
sale_id = self.kwargs.get('sale_id')
if sale_id:
sale_obj = Sale.objects.get(id=sale_id)
initial = sale_obj.get_nomenclature_initial()
formset = FormSet(initial=initial)
context['formset'] = formset
return context
class DocumentCreateViewBase(CreateView): # base class for all document details view
def get_context_data(self, **kwargs):
context = super(DocumentCreateViewBase, self).get_context_data(**kwargs)
context['in_documents'] = True
# select nomenclature popup needs need services and products in every document
MAX_ROWS = 10
service_paginator = UrlPaginator(self.request.user.nomenclature_set.filter(kind=dir_consts.SERVICE), MAX_ROWS, url=reverse("services_list"))
service_pages = service_paginator.page(1)
context['service_pages'] = service_pages
product_paginator = UrlPaginator(self.request.user.nomenclature_set.filter(kind=dir_consts.PRODUCT), MAX_ROWS, url=reverse("products_list"))
product_pages = product_paginator.page(1)
context['product_pages'] = product_pages
context['contractor_kinds'] = Contractor.KIND_CHOICES
return context
class DocumentUpdateViewBase(UpdateView): # base class for all document details view
def get(self, request, **kwargs):
obj = self.get_object()
if obj.user != self.request.user:
return HttpResponseForbidden("You have no permission to edit this document")
return super(DocumentUpdateViewBase, self).get(request, **kwargs)
def post(self, request, *args, **kwargs):
obj = self.get_object()
if obj.user != self.request.user:
return HttpResponseForbidden("You have no permission to edit this document")
return super(DocumentUpdateViewBase, self).post(request, *args, **kwargs)
# put uses post
def get_context_data(self, **kwargs):
context = super(DocumentUpdateViewBase, self).get_context_data(**kwargs)
context['in_documents'] = True
# select nomenclature popup needs need services and products in every document
MAX_ROWS = 10
service_paginator = UrlPaginator(self.request.user.nomenclature_set.filter(kind=dir_consts.SERVICE), MAX_ROWS, url=reverse("services_list"))
service_pages = service_paginator.page(1)
context['service_pages'] = service_pages
product_paginator = UrlPaginator(self.request.user.nomenclature_set.filter(kind=dir_consts.PRODUCT), MAX_ROWS, url=reverse("products_list"))
product_pages = product_paginator.page(1)
context['product_pages'] = product_pages
return context
class DocumentListViewBase(ListView): # base class for all documents list view
paginate_by = 20
def get_queryset(self):
queryset = super(DocumentListViewBase, self).get_queryset() # sorted
queryset = queryset.filter(user=self.request.user)
if self.request.GET:
form = DocFilterForm(self.request.GET, user=self.request.user)
if form.is_valid():
cd = form.cleaned_data
date_from = cd.get('date_from')
date_to = cd.get('date_to')
contractor = cd.get('contractor')
if date_from:
queryset = queryset.filter(created__gte=date_from)
if date_to:
queryset = queryset.filter(created__lte=date_to)
if contractor:
queryset = queryset.filter(contractor=contractor)
return queryset
return queryset
def get_context_data(self, **kwargs):
context = super(DocumentListViewBase, self).get_context_data(**kwargs)
context['in_documents'] = True
context['contractor_kinds'] = Contractor.KIND_CHOICES
context['show_create'] = True # forces to show link to contractor create page
context['filter_form'] = DocFilterForm(user=self.request.user)
return context
class BillUpdateView(DocumentFormsetMixin, DocumentUpdateViewBase):
queryset = Bill.objects.all()
template_name = "documents/bill_detail.html"
form_class = BillForm
formset_form = BillNomenclatureForm
formset_parent_model = Bill
formset_model = BillNomenclature
def get_context_data(self, **kwargs):
context = super(BillUpdateView, self).get_context_data(**kwargs)
context['contractor'] = self.object.contractor
context['contractor_account'] = self.object.contractor_account
MAX_ROWS = 10
service_paginator = UrlPaginator(self.request.user.nomenclature_set.filter(kind=dir_consts.SERVICE), MAX_ROWS, url=reverse("services_list"))
service_pages = service_paginator.page(1)
context['service_pages'] = service_pages
product_paginator = UrlPaginator(self.request.user.nomenclature_set.filter(kind=dir_consts.PRODUCT), MAX_ROWS, url=reverse("products_list"))
product_pages = product_paginator.page(1)
context['product_pages'] = product_pages
return context
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(BillUpdateView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
class JSONResponseMixin(BaseListViewJSONMixin):
def object_list_to_jsonable(self, object_list):
return [{'id': x.id, 'url': x.get_absolute_url(), 'number': x.number,
'type_name': x.get_type_name(), 'date': x.created,
'pdf_report_url': x.get_pdf_report_url(), 'xls_report_url': x.get_xls_report_url(),
'basis_bill_number': x.get_basis_bill_number(), 'basis_bill_url': x.get_basis_bill_url(),
'summ': x.summ, 'contractor_name': x.contractor.name, 'contractor_url': x.contractor.get_absolute_url(),
'accepted': x.get_accepted_name()} for x in object_list]
class BillCreateView(DocumentFormsetMixin, DocumentCreateViewBase):
queryset = Bill.objects.all()
template_name = "documents/bill_detail.html"
form_class = BillForm
formset_form = BillNomenclatureForm
formset_parent_model = Bill
formset_model = BillNomenclature
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(BillCreateView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_context_data(self, **kwargs):
context = super(BillCreateView, self).get_context_data(**kwargs)
return context
class UserBillListView(JSONResponseMixin, DocumentListViewBase):
context_object_name = "bills_list"
template_name = "documents/user_bills.html"
queryset = Bill.objects.all()
paginate_by=20
def render_to_response(self, context):
""" returns json or html response """
if self.request.is_ajax():
return JSONResponseMixin.render_to_response(self, context)
else:
return DocumentListViewBase.render_to_response(self, context)
def get_context_data(self, **kwargs):
context = super(UserBillListView, self).get_context_data(**kwargs)
context['in_bills'] = True
return context
def get_queryset(self):
queryset = super(UserBillListView, self).get_queryset()
if self.request.GET.get('c', None):
queryset = queryset.filter(contractor__id=self.request.GET['c'])
if self.request.GET.get('bill_number', None):
queryset = queryset.filter(number__icontains=self.request.GET['bill_number'])
return queryset
class UserSaleListView(JSONResponseMixin, DocumentListViewBase):
context_object_name = "sales_list"
template_name = "documents/user_sales.html"
queryset = Sale.objects.all()
def get_context_data(self, **kwargs):
context = super(UserSaleListView, self).get_context_data(**kwargs)
context['in_sales'] = True
return context
def render_to_response(self, context):
""" returns json or html response """
if self.request.is_ajax():
return JSONResponseMixin.render_to_response(self, context)
else:
return DocumentListViewBase.render_to_response(self, context)
class SaleCreateView(DocumentFormsetMixin, DocumentCreateViewBase):
queryset = Sale.objects.all()
template_name = "documents/sale_detail.html"
form_class = SaleForm
formset_form = SaleNomenclatureForm
formset_parent_model = Sale
formset_model = SaleNomenclature
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(SaleCreateView, self).get_form_kwargs()
kwargs['request'] = self.request
bill_id = self.kwargs.get('bill_id')
contractor_id = self.kwargs.get('contractor_id')
kind = self.kwargs.get('kind')
if bill_id:
kwargs['from_bill'] = Bill.objects.get(id=bill_id)
if contractor_id:
kwargs['for_contractor'] = Contractor.objects.get(id=contractor_id)
# user choosed waybill creation, pass is_waybill to form initial
if kind == doc_consts.WAYBILL:
kwargs['is_waybill'] = True
return kwargs
def get_context_data(self, **kwargs):
context = super(SaleCreateView, self).get_context_data(**kwargs)
kind = self.kwargs.get('kind')
sale_title = None
if kind:
if kind == doc_consts.WAYBILL:
sale_title = u"Создание накладной"
is_waybill = True
elif kind == doc_consts.ACT:
sale_title = u"Создание акта"
is_waybill = False
contractor_id = self.kwargs.get('contractor_id')
if contractor_id:
context['contractor'] = self.request.user.contractor_set.get(id=contractor_id)
# user creates sale from bill
bill_id = self.kwargs.get('bill_id')
if bill_id:
bill = self.request.user.bill_set.get(id=bill_id)
context['contractor'] = bill.contractor
# pass all bills between user and contractor for select bill popup
context['bills'] = self.request.user.bill_set.filter(contractor=bill.contractor)
context['base_obj'] = bill # object in wich base document is creating
context['sale_title'] = sale_title
context['is_waybill'] = is_waybill
return context
class SaleUpdateView(DocumentFormsetMixin, DocumentUpdateViewBase):
queryset = Sale.objects.all()
template_name = "documents/sale_detail.html"
form_class = SaleForm
formset_form = SaleNomenclatureForm
formset_parent_model = Sale
formset_model = SaleNomenclature
def get_context_data(self, **kwargs):
context = super(SaleUpdateView, self).get_context_data(**kwargs)
context['bills'] = Bill.objects.filter(user=self.request.user, contractor=self.object.contractor)
if self.object.is_waybill:
sale_title = u"Создание накладной"
else:
sale_title = u"Создание акта"
context['sale_title'] = sale_title
return context
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(SaleUpdateView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
class OrderCreateView(DocumentCreateViewBase):
queryset = Order.objects.all()
template_name = "documents/order_detail.html"
form_class = OrderForm
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(OrderCreateView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
class UserOrderListView(JSONResponseMixin, DocumentListViewBase):
context_object_name = "orders_list"
template_name = "documents/user_orders.html"
queryset = Order.objects.all()
def render_to_response(self, context):
""" returns json or html response """
if self.request.is_ajax():
return JSONResponseMixin.render_to_response(self, context)
else:
return DocumentListViewBase.render_to_response(self, context)
def get_context_data(self, **kwargs):
context = super(UserOrderListView, self).get_context_data(**kwargs)
context['in_orders'] = True
return context
class OrderUpdateView(DocumentUpdateViewBase):
queryset = Order.objects.all()
template_name = "documents/order_detail.html"
form_class = OrderForm
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(OrderUpdateView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
class InvoiceCreateView(DocumentFormsetMixin, DocumentCreateViewBase):
queryset = Invoice.objects.all()
template_name = "documents/invoice_detail.html"
form_class = InvoiceForm
formset_form = InvoiceNomenclatureForm
formset_parent_model = Invoice
formset_model = InvoiceNomenclature
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(InvoiceCreateView, self).get_form_kwargs()
kwargs['request'] = self.request
sale_id = self.kwargs.get('sale_id')
if sale_id:
kwargs['from_sale'] = Sale.objects.get(id=sale_id)
return kwargs
def get_context_data(self, **kwargs):
context = super(InvoiceCreateView, self).get_context_data(**kwargs)
sale_id = self.kwargs.get('sale_id')
if sale_id:
sale = self.request.user.sale_set.get(id=sale_id)
context['base_obj'] = sale
context['contractor'] = sale.contractor
# pass all bills between user and contractor for select bill popup
context['bills'] = self.request.user.bill_set.filter(contractor=sale.contractor)
return context
class UserInvoiceListView(JSONResponseMixin, DocumentListViewBase):
context_object_name = "invoices_list"
template_name = "documents/user_invoices.html"
queryset = Invoice.objects.all()
def render_to_response(self, context):
""" returns json or html response """
if self.request.is_ajax():
return JSONResponseMixin.render_to_response(self, context)
else:
return DocumentListViewBase.render_to_response(self, context)
def get_context_data(self, **kwargs):
context = super(UserInvoiceListView, self).get_context_data(**kwargs)
context['in_invoices'] = True
return context
class InvoiceUpdateView(DocumentFormsetMixin, DocumentUpdateViewBase):
queryset = Invoice.objects.all()
template_name = "documents/invoice_detail.html"
form_class = InvoiceForm
formset_form = InvoiceNomenclatureForm
formset_parent_model = Invoice
formset_model = InvoiceNomenclature
def get_context_data(self, **kwargs):
context = super(InvoiceUpdateView, self).get_context_data(**kwargs)
context['bills'] = Bill.objects.filter(user=self.request.user, contractor=self.object.contractor)
return context
def get_form_kwargs(self):
"""
Returns the keyword arguments for instanciating the form.
"""
kwargs = super(InvoiceUpdateView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
class BillNomenclatureView(TemplateView):
template = None # json only. without template
def get_json_response(self, content, **httpresponse_kwargs):
""" Constructs an `HttpResponse` object. """
return HttpResponse(content,
content_type='application/json',
**httpresponse_kwargs)
def render_to_response(self, context):
""" Returns a JSON response containing 'context' as payload """
return self.get_json_response(self.convert_context_to_json(context))
def convert_context_to_json(self, context):
""" Converts the context dictionary into a JSON object """
bill_id = self.kwargs.get('bill_id')
queryset = BillNomenclature.objects.filter(bill__id=bill_id)
data = [{'unit_id': x.nomenclature.id,
'unit_name': x.nomenclature.name,
'unit_price': x.price,
'unit_kind': x.nomenclature.kind} for x in queryset.all()]
resp = simplejson.dumps({'code': 1, 'nomenclature': data}, cls=DjangoJSONEncoder)
return resp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment