admin.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. class CostInline(admin.TabularInline):
  11. model = Cost
  12. extra = 0
  13. @admin.register(Document)
  14. class DocumentAdmin(admin.ModelAdmin):
  15. list_display = ('name', 'date', 'type')
  16. actions = ['copy']
  17. inlines = [GoodInline, CostInline]
  18. def copy(self, request, queryset):
  19. for i in queryset.all():
  20. new = i.copy()
  21. edit_url = reverse('admin:costs_document_change', args=(new.pk,))
  22. self.message_user(
  23. request, mark_safe(
  24. "{} copié, pensez à <a href=\"{}\">L'éditer</a>".format(
  25. new, edit_url)))
  26. copy.short_description = 'Copier'
  27. class AbstractUseInline(admin.TabularInline):
  28. """ An inline with some knowledge of the currently edited Document
  29. """
  30. def formfield_for_foreignkey(self, db_field, request, **kwargs):
  31. if db_field.name == "resource" and getattr(request, 'document', None):
  32. kwargs["queryset"] = db_field.related_model.objects.filter(
  33. document=request.document)
  34. return super().formfield_for_foreignkey(
  35. db_field, request, **kwargs)
  36. class GoodUseInline(AbstractUseInline):
  37. model = GoodUse
  38. extra = 1
  39. class CostUseInline(AbstractUseInline):
  40. model = CostUse
  41. extra = 1
  42. class ServiceUseInline(AbstractUseInline):
  43. model = ServiceUse
  44. extra = 1
  45. fk_name = 'service'
  46. class DirectDocumentFilter(admin.SimpleListFilter):
  47. title = 'Document'
  48. parameter_name = 'document'
  49. def queryset(self, request, queryset):
  50. document = self.value()
  51. if not document:
  52. return queryset.none()
  53. else:
  54. return queryset.filter(document=document)
  55. def lookups(self, request, model_admin):
  56. for i in Document.objects.all():
  57. yield i.pk, str(i)
  58. def choices(self, changelist):
  59. """ Same as base SimpleListFilter but do not display the "All" choice
  60. """
  61. for lookup, title in self.lookup_choices:
  62. yield {
  63. 'selected': self.value() == force_text(lookup),
  64. 'query_string': changelist.get_query_string(
  65. {self.parameter_name: lookup}, []),
  66. 'display': title,
  67. }
  68. @admin.register(Service)
  69. class ServiceAdmin(admin.ModelAdmin):
  70. list_display = (
  71. 'name', 'subscriptions_count', 'document',
  72. 'monthly_unit_cost', 'new_subscriber_cost')
  73. inlines = (CostUseInline, GoodUseInline, ServiceUseInline)
  74. list_filter = [DirectDocumentFilter]
  75. fieldsets = (
  76. (None, {
  77. 'fields': (
  78. ('name', 'document'), 'description', 'subscriptions_count'),
  79. }),
  80. ('Ré-utilisabilité', {
  81. 'fields': ('reusable',)
  82. })
  83. )
  84. def get_form(self, request, obj=None, **kwargs):
  85. if obj:
  86. # anotate the request with some context
  87. request.document = obj.document
  88. else:
  89. doc_pk = request.GET.get('document')
  90. if doc_pk:
  91. request.document = Document.objects.get(pk=doc_pk)
  92. else:
  93. request.document = None
  94. if request.method == 'GET':
  95. self.message_user(
  96. request,
  97. 'Il est nécessaire de faire "Enregistrer et continuer"'
  98. ' pour ajouter des ressources au service',
  99. messages.WARNING)
  100. return super().get_form(request, obj, **kwargs)
  101. def get_inline_instances(self, request, obj=None):
  102. if getattr(request, 'document', None):
  103. return super().get_inline_instances(request, obj)
  104. else:
  105. return []
  106. def monthly_unit_cost(self, obj):
  107. return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price'])
  108. def new_subscriber_cost(self, obj):
  109. return '{:.2f}€'.format(obj.get_prices()['total_goods_value_share'])