from django.contrib import admin, messages from django.core.urlresolvers import reverse from django.utils.encoding import force_text from django.utils.safestring import mark_safe from .models import ( Document, Cost, Good, CostUse, GoodUse, Service, ServiceUse) class GoodInline(admin.TabularInline): model = Good extra = 0 exclude = ['description_html'] class CostInline(admin.TabularInline): model = Cost extra = 0 exclude = ['description_html'] class ServiceInline(admin.TabularInline): model = Service fields = ( 'name', 'subscriptions_count', 'monthly_unit_cost', 'new_subscriber_cost') readonly_fields = ( 'subscriptions_count', 'monthly_unit_cost', 'new_subscriber_cost') show_change_link = True extra = 0 verbose_name = 'Service proposé' verbose_name_plural = 'Services proposés' def monthly_unit_cost(self, obj): return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price']) monthly_unit_cost.short_description = "Coût de revient mensuel" def new_subscriber_cost(self, obj): return '{:.2f}€'.format(obj.get_prices()['unit_goods_value_share']) new_subscriber_cost.short_description = "Coût nouv. abo" @admin.register(Document) class DocumentAdmin(admin.ModelAdmin): list_display = ('name', 'date', 'type') actions = ['copy'] inlines = [ServiceInline, GoodInline, CostInline] save_on_top = True def copy(self, request, queryset): for i in queryset.all(): new = i.copy() edit_url = reverse('admin:costs_document_change', args=(new.pk,)) self.message_user( request, mark_safe( "{} a été créé, en tant que brouillon, pensez à l'éditer.".format( new, edit_url))) copy.short_description = 'Copier' class AbstractUseInline(admin.TabularInline): """ An inline with some knowledge of the currently edited Document """ def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "resource" and getattr(request, 'document', None): kwargs["queryset"] = db_field.related_model.objects.filter( document=request.document) return super().formfield_for_foreignkey( db_field, request, **kwargs) class GoodUseInline(AbstractUseInline): model = GoodUse extra = 1 class CostUseInline(AbstractUseInline): model = CostUse extra = 1 class ServiceUseInline(AbstractUseInline): model = ServiceUse extra = 1 fk_name = 'service' class DirectDocumentFilter(admin.SimpleListFilter): title = 'Rapport' parameter_name = 'document' def queryset(self, request, queryset): document = self.value() if not document: return queryset.none() else: return queryset.filter(document=document) def lookups(self, request, model_admin): for i in Document.objects.all(): yield i.pk, str(i) def choices(self, changelist): """ Same as base SimpleListFilter but do not display the "All" choice """ for lookup, title in self.lookup_choices: yield { 'selected': self.value() == force_text(lookup), 'query_string': changelist.get_query_string( {self.parameter_name: lookup}, []), 'display': title, } @admin.register(Service) class ServiceAdmin(admin.ModelAdmin): list_display = ( 'name', 'subscriptions_count', 'document', 'monthly_unit_cost', 'new_subscriber_cost') inlines = (CostUseInline, GoodUseInline, ServiceUseInline) list_filter = [DirectDocumentFilter] fieldsets = ( (None, { 'fields': ( ('name', 'document'), 'description', 'subscriptions_count'), }), ('Utilisation', { 'fields': ('reusable', 'internal') }) ) save_on_top = True def get_form(self, request, obj=None, **kwargs): if obj: # anotate the request with some context request.document = obj.document else: doc_pk = request.GET.get('document') if doc_pk: request.document = Document.objects.get(pk=doc_pk) else: request.document = None if request.method == 'GET': self.message_user( request, 'Il est nécessaire de faire "Enregistrer et continuer"' ' pour ajouter des ressources au service', messages.WARNING) return super().get_form(request, obj, **kwargs) def get_inline_instances(self, request, obj=None): if getattr(request, 'document', None): return super().get_inline_instances(request, obj) else: return [] def monthly_unit_cost(self, obj): return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price']) def new_subscriber_cost(self, obj): return '{:.2f}€'.format(obj.get_prices()['total_goods_value_share']) @admin.register(Good) class GoodAdmin(admin.ModelAdmin): list_filter = [DirectDocumentFilter] exclude = ['description_html'] @admin.register(Cost) class CostAdmin(admin.ModelAdmin): list_filter = [DirectDocumentFilter] exclude = ['description_html']