transparence.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. from django.core.management.base import BaseCommand, CommandError
  2. from django.db.models import Q
  3. from adhesions.models import Adhesion
  4. from services.models import Service, ServiceType, IPResource, Route
  5. from banking.models import RecurringPayment, PaymentUpdate
  6. from operator import add
  7. from djadhere.utils import get_active_filter
  8. class Command(BaseCommand):
  9. help = 'Afficher les statistiques financières'
  10. def add_arguments(self, parser):
  11. parser.add_argument('--services', action='store_true')
  12. parser.add_argument('--adhesions', action='store_true')
  13. def handle(self, *args, **options):
  14. if options['services']:
  15. self.handle_services()
  16. if options['adhesions']:
  17. self.handle_adhesions()
  18. def handle_services(self):
  19. ttnn = Adhesion.objects.get(id=100)
  20. total = [0, 0, 0, 0, 0, 0, 0]
  21. lines = []
  22. for service_type in ServiceType.objects.exclude(name='Contribution'):
  23. ntotal = ninf = nadh = npay = nfree = nmiss = income = 0
  24. for service in service_type.services.filter(get_active_filter('allocation')).order_by('pk').distinct():
  25. ntotal += 1
  26. if service.adhesion == ttnn:
  27. ninf += 1
  28. continue
  29. nadh += 1
  30. contrib = service.contribution.current
  31. if not contrib or contrib.payment_method == PaymentUpdate.STOP:
  32. nmiss += 1
  33. elif contrib.payment_method == PaymentUpdate.FREE:
  34. nfree += 1
  35. else:
  36. npay += 1
  37. income += float(contrib.amount) / contrib.period
  38. assert(ntotal == ninf + nadh)
  39. assert(nadh == npay + nfree + nmiss)
  40. total = list(map(add, total, [ntotal, ninf, nadh, npay, nfree, nmiss, income]))
  41. lines += [(str(service_type), ntotal, ninf, nadh, npay, nfree, nmiss, income)]
  42. self.stdout.write("%-18s%12s%12s%12s%12s%12s%12s%12s%12s%12s" % ('Service', 'total', 'infra', 'adhérents', 'gratuits', 'manquants', 'payés', 'euros', 'moyenne', 'pourcent'))
  43. lines += [('TOTAL',) + tuple(total)]
  44. total_income = total[6]
  45. for service_type, ntotal, ninf, nadh, npay, nfree, nmiss, income in lines:
  46. if total_income:
  47. percent = income / total_income * 100
  48. else:
  49. percent = 0
  50. if npay:
  51. moy = income / npay
  52. else:
  53. moy = float('nan')
  54. self.stdout.write("%-18s%12d%12d%12d%12d%12d%12d%12.2f%12.2f%12.1f" % (service_type, ntotal, ninf, nadh, nfree, nmiss, npay, income, moy, percent))
  55. def handle_adhesions(self):
  56. adhesions = Adhesion.objects.filter(Q(active__isnull=True) | Q(active=True))
  57. nadh = adhesions.count()
  58. pmiss, pgra, ppay, income = 0, 0, 0, 0
  59. payments = map(lambda adh: adh.membership.current, adhesions)
  60. for payment in payments:
  61. if payment is None:
  62. pmiss += 1
  63. elif payment.payment_method == PaymentUpdate.FREE:
  64. pgra += 1
  65. else:
  66. assert(payment.payment_method != PaymentUpdate.STOP)
  67. ppay += 1
  68. income += float(payment.amount) / payment.period
  69. self.stdout.write("%12s%12s%12s%12s%12s%12s" % ('Adhesions', 'gratuites', 'manquantes', 'payées', 'euros', 'moyenne'))
  70. self.stdout.write("%12d%12d%12d%12d%12.2f%12.2f" % (nadh, pgra, pmiss, ppay, income, 12 * income / ppay))