admin.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. from django.contrib import admin, messages
  2. from django.core.urlresolvers import reverse
  3. from django.utils.encoding import force_text
  4. from django.utils.safestring import mark_safe
  5. from .models import (
  6. Document, Cost, Good, CostUse, GoodUse, Service, ServiceUse)
  7. class GoodInline(admin.TabularInline):
  8. model = Good
  9. extra = 0
  10. exclude = ['description_html']
  11. class CostInline(admin.TabularInline):
  12. model = Cost
  13. extra = 0
  14. exclude = ['description_html']
  15. class ServiceInline(admin.TabularInline):
  16. model = Service
  17. fields = (
  18. 'name', 'subscriptions_count',
  19. 'monthly_unit_cost', 'new_subscriber_cost')
  20. readonly_fields = (
  21. 'subscriptions_count',
  22. 'monthly_unit_cost', 'new_subscriber_cost')
  23. show_change_link = True
  24. extra = 0
  25. verbose_name = 'Service proposé'
  26. verbose_name_plural = 'Services proposés'
  27. def monthly_unit_cost(self, obj):
  28. return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price'])
  29. monthly_unit_cost.short_description = "Coût de revient mensuel"
  30. def new_subscriber_cost(self, obj):
  31. return '{:.2f}€'.format(obj.get_prices()['unit_goods_value_share'])
  32. new_subscriber_cost.short_description = "Coût nouv. abo"
  33. @admin.register(Document)
  34. class DocumentAdmin(admin.ModelAdmin):
  35. list_display = ('name', 'date', 'type')
  36. actions = ['copy']
  37. inlines = [ServiceInline, GoodInline, CostInline]
  38. save_on_top = True
  39. def copy(self, request, queryset):
  40. for i in queryset.all():
  41. new = i.copy()
  42. edit_url = reverse('admin:costs_document_change', args=(new.pk,))
  43. self.message_user(
  44. request, mark_safe(
  45. "{} a été créé, en tant que brouillon, pensez à <a href=\"{}\">l'éditer</a>.".format(
  46. new, edit_url)))
  47. copy.short_description = 'Copier'
  48. class AbstractUseInline(admin.TabularInline):
  49. """ An inline with some knowledge of the currently edited Document
  50. """
  51. def formfield_for_foreignkey(self, db_field, request, **kwargs):
  52. if db_field.name == "resource" and getattr(request, 'document', None):
  53. kwargs["queryset"] = db_field.related_model.objects.filter(
  54. document=request.document)
  55. return super().formfield_for_foreignkey(
  56. db_field, request, **kwargs)
  57. class GoodUseInline(AbstractUseInline):
  58. model = GoodUse
  59. extra = 1
  60. class CostUseInline(AbstractUseInline):
  61. model = CostUse
  62. extra = 1
  63. class ServiceUseInline(AbstractUseInline):
  64. model = ServiceUse
  65. extra = 1
  66. fk_name = 'service'
  67. class DirectDocumentFilter(admin.SimpleListFilter):
  68. title = 'Rapport'
  69. parameter_name = 'document'
  70. def queryset(self, request, queryset):
  71. document = self.value()
  72. if not document:
  73. return queryset.none()
  74. else:
  75. return queryset.filter(document=document)
  76. def lookups(self, request, model_admin):
  77. for i in Document.objects.all():
  78. yield i.pk, str(i)
  79. def choices(self, changelist):
  80. """ Same as base SimpleListFilter but do not display the "All" choice
  81. """
  82. for lookup, title in self.lookup_choices:
  83. yield {
  84. 'selected': self.value() == force_text(lookup),
  85. 'query_string': changelist.get_query_string(
  86. {self.parameter_name: lookup}, []),
  87. 'display': title,
  88. }
  89. @admin.register(Service)
  90. class ServiceAdmin(admin.ModelAdmin):
  91. list_display = (
  92. 'name', 'subscriptions_count', 'document',
  93. 'monthly_unit_cost', 'new_subscriber_cost')
  94. inlines = (CostUseInline, GoodUseInline, ServiceUseInline)
  95. list_filter = [DirectDocumentFilter]
  96. fieldsets = (
  97. (None, {
  98. 'fields': (
  99. ('name', 'document'), 'description', 'subscriptions_count'),
  100. }),
  101. ('Utilisation', {
  102. 'fields': ('reusable', 'internal')
  103. })
  104. )
  105. save_on_top = True
  106. def get_form(self, request, obj=None, **kwargs):
  107. if obj:
  108. # anotate the request with some context
  109. request.document = obj.document
  110. else:
  111. doc_pk = request.GET.get('document')
  112. if doc_pk:
  113. request.document = Document.objects.get(pk=doc_pk)
  114. else:
  115. request.document = None
  116. if request.method == 'GET':
  117. self.message_user(
  118. request,
  119. 'Il est nécessaire de faire "Enregistrer et continuer"'
  120. ' pour ajouter des ressources au service',
  121. messages.WARNING)
  122. return super().get_form(request, obj, **kwargs)
  123. def get_inline_instances(self, request, obj=None):
  124. if getattr(request, 'document', None):
  125. return super().get_inline_instances(request, obj)
  126. else:
  127. return []
  128. def monthly_unit_cost(self, obj):
  129. return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price'])
  130. def new_subscriber_cost(self, obj):
  131. return '{:.2f}€'.format(obj.get_prices()['total_goods_value_share'])
  132. @admin.register(Good)
  133. class GoodAdmin(admin.ModelAdmin):
  134. list_filter = [DirectDocumentFilter]
  135. exclude = ['description_html']
  136. @admin.register(Cost)
  137. class CostAdmin(admin.ModelAdmin):
  138. list_filter = [DirectDocumentFilter]
  139. exclude = ['description_html']