0010_new_billing_system_data.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. import sys
  4. from django.db import migrations
  5. from coin.members.models import Member
  6. from coin.billing.models import Invoice, InvoiceDetail, Payment
  7. def check_current_state(apps, schema_editor):
  8. for invoice in Invoice.objects.all():
  9. invoice_name = invoice.__unicode__()
  10. related_payments = invoice.payments.all()
  11. total_related_payments = sum([p.amount for p in related_payments])
  12. if total_related_payments > invoice.amount:
  13. error = "For invoice, current sum of payment is higher than total of invoice. Please fix this before running this migration" % invoice_name
  14. raise AssertionError(error.encode('utf-8'))
  15. if total_related_payments != 0 and not invoice.validated:
  16. error = "Invoice %s is not validated but already has allocated payments. Please remove them before running this migration" % invoice_name
  17. raise AssertionError(error.encode('utf-8'))
  18. def forwards(apps, schema_editor):
  19. # Create allocation for all payment to their respective invoice
  20. for payment in Payment.objects.all():
  21. payment.member = payment.invoice.member
  22. payment.allocate_to_invoice(payment.invoice)
  23. # Update balance for all members
  24. for member in Member.objects.all():
  25. this_member_invoices = [i for i in member.invoices.filter(validated=True).order_by("date")]
  26. this_member_payments = [p for p in member.payments.order_by("date")]
  27. member.balance = compute_balance(this_member_invoices,
  28. this_member_payments)
  29. member.save()
  30. def compute_balance(invoices, payments):
  31. active_payments = [p for p in payments if p.amount_not_allocated() > 0]
  32. active_invoices = [i for i in invoices if i.amount_remaining_to_pay() > 0]
  33. s = 0
  34. s -= sum([i.amount_remaining_to_pay() for i in active_invoices])
  35. s += sum([p.amount_not_allocated() for p in active_payments])
  36. return s
  37. class Migration(migrations.Migration):
  38. dependencies = [
  39. ('billing', '0009_new_billing_system_schema'),
  40. ('members', '0014_member_balance'),
  41. ]
  42. operations = [
  43. migrations.RunPython(check_current_state),
  44. migrations.RunPython(forwards),
  45. ]