def create_invoice_for_subscription(self, subscription): if subscription.is_trial: # Don't create invoices for trial subscriptions logger.info("[BILLING] Skipping invoicing for Subscription " "%s because it's a trial." % subscription.pk) return if subscription.auto_generate_credits: for product_rate in subscription.plan_version.product_rates.all(): CreditLine.add_credit( product_rate.monthly_fee, subscription=subscription, product_type=product_rate.product.product_type, permit_inactive=True, ) if subscription.date_start > self.date_start: invoice_start = subscription.date_start else: invoice_start = self.date_start if (subscription.date_end is not None and subscription.date_end <= self.date_end): # Since the Subscription is actually terminated on date_end # have the invoice period be until the day before date_end. invoice_end = subscription.date_end - datetime.timedelta(days=1) else: invoice_end = self.date_end invoice = Invoice( subscription=subscription, date_start=invoice_start, date_end=invoice_end, is_hidden=subscription.do_not_invoice, ) invoice.save() if subscription.subscriptionadjustment_set.count() == 0: # record that the subscription was created SubscriptionAdjustment.record_adjustment( subscription, method=SubscriptionAdjustmentMethod.TASK, invoice=invoice, ) self.generate_line_items(invoice, subscription) invoice.calculate_credit_adjustments() invoice.update_balance() invoice.save() total_balance = sum(invoice.balance for invoice in Invoice.objects.filter( is_hidden=False, subscription__subscriber__domain=invoice.get_domain(), )) if total_balance > SMALL_INVOICE_THRESHOLD: days_until_due = DEFAULT_DAYS_UNTIL_DUE if subscription.date_delay_invoicing is not None: td = subscription.date_delay_invoicing - self.date_end days_until_due = max(days_until_due, td.days) invoice.date_due = self.date_end + datetime.timedelta(days_until_due) invoice.save() record = BillingRecord.generate_record(invoice) try: if subscription.auto_generate_credits and not invoice.balance: record.skipped_email = True record.save() else: record.send_email() except InvoiceEmailThrottledError as e: if not self.logged_throttle_error: logger.error("[BILLING] %s" % e) self.logged_throttle_error = True return invoice