123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- # -*- coding: utf-8 -*-
- import datetime
- from dateutil.relativedelta import relativedelta
- from django.http import HttpResponse
- from django.db.models import Q
- from coin.offers.models import Offer, OfferSubscription
- from coin.members.models import Member
- from coin.billing.models import Invoice, InvoiceDetail
- def create_all_members_invoices_for_a_period(date):
- """
- Pour chaque membre ayant au moins un abonnement actif, génère les factures
- en prenant la date comme premier mois de la période de facturation
- """
- members = Member.objects.filter(
- Q(offersubscription__resign_date__isnull=True) |
- Q(offersubscription__resign_date__gte=datetime.date.today()))
- for member in members:
- create_member_invoice_for_a_period(member,date)
- def create_member_invoice_for_a_period(member, date):
- """
- Créé si necessaire une facture pour un membre en prenant la date passée
- en paramètre comme premier mois de période. Renvoi la facture générée
- ou None si aucune facture n'était pas necessaire.
- """
- invoice = None
- # Récupère les abonnements en cours du membre
- offer_subscriptions = member.get_active_subscriptions(date)
- # Pour chaque abonnement
- for offer_subscription in offer_subscriptions:
- # Récupère l'offre de l'abonnement
- offer = offer_subscription.offer
- # Recherche dans les factures déjà existantes de ce membre des items
- # ayant cet abonnement pour lesquels la période de facturation englobe
- # la date
- invoicedetail_test_before = InvoiceDetail.objects.filter(
- offersubscription__exact=offer_subscription.pk,
- period_from__lte=date,
- period_to__gte=date,
- invoice__member__exact=member.pk)
- # Si une telle facture n'existe pas, alors ajout l'item à facturer à la
- # facture à générer
- if not invoicedetail_test_before.exists():
- # Si l'object facture n'a pas encore été créé, le créé
- if invoice is None:
- invoice = Invoice.objects.create(
- date_due=datetime.date.today(),
- member=member
- )
- # Vérifie s'il s'agit de la première facture d'un abonnement,
- # Alors facture en plus les frais de mise en service
- invoicedetail_test_first = InvoiceDetail.objects.filter(
- offersubscription__exact=offer_subscription.pk,
- invoice__member__exact=member.pk)
- if not invoicedetail_test_first.exists():
- invoice.details.create(
- label=offer.name + " - Frais de mise en service",
- amount=offer.initial_fees,
- offersubscription=offer_subscription,
- period_from=None,
- period_to=None)
- # Période de facturation de l'item par defaut
- # - Du début du mois de la date passée en paramètre
- # - Jusqu'à la fin du mois de la période de facturation de l'offre
- period_from = datetime.date(date.year, date.month, 1)
- period_to = (datetime.date(date.year, date.month, 1) +
- relativedelta(months=+offer.billing_period) -
- relativedelta(days=+1))
- # Recherche dans les factures déjà existantes de ce membre des
- # items ayant cet abonnement pour lesquels la période de
- # facturation commence avant la fin de notre période de facturation
- # actuelle
- invoicedetail_test_after = InvoiceDetail.objects.filter(
- offersubscription__exact=offer_subscription.pk,
- period_from__lte=period_to,
- period_from__gte=period_from,
- invoice__member__exact=member.pk)
- # Si une telle facture existe, récupère la date de début de
- # facturation pour en faire la date de fin de facturation
- if invoicedetail_test_after.exists():
- invoicedetail_after = invoicedetail_test_after.first()
- period_to = (
- datetime.date(invoicedetail_after.period_from.year,
- invoicedetail_after.period_from.month, 1) -
- relativedelta(days=+1))
- # Ajout l'item de l'offre correspondant à l'abonnement à la facture
- invoice.details.create(label=offer.name,
- amount=offer.period_fees,
- offersubscription=offer_subscription,
- period_from=period_from,
- period_to=period_to)
- invoice.save()
- return invoice
|