예제 #1
0
 def response_later_subscription(self):
     """
     Makes sure that subscriptions beginning in the future are ended.
     """
     from corehq.apps.accounting.models import (Subscription,
                                                SubscriptionAdjustment,
                                                SubscriptionAdjustmentReason
                                                )
     try:
         for later_subscription in Subscription.objects.filter(
                 subscriber__domain=self.domain.name,
                 date_start__gt=self.date_start).order_by(
                     'date_start').all():
             later_subscription.date_start = datetime.date.today()
             later_subscription.date_end = datetime.date.today()
             later_subscription.save()
             SubscriptionAdjustment.record_adjustment(
                 later_subscription,
                 reason=SubscriptionAdjustmentReason.CANCEL,
                 web_user=self.web_user,
                 note="Cancelled due to changing subscription",
             )
     except Subscription.DoesNotExist:
         pass
     return True
예제 #2
0
    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
                )

        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)
        date_due = self.date_end + datetime.timedelta(days_until_due)

        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,
            date_due=date_due,
            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()

        record = BillingRecord.generate_record(invoice)
        try:
            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
예제 #3
0
 def create(self):
     invoice = super(CommunityInvoiceFactory, self).create()
     if invoice is None:
         # no charges were created, so delete the temporary subscription to the community plan for this
         # invoicing period
         self.subscription.delete()
         try:
             # delete the account too (is only successful if no other subscriptions reference it)
             self.account.delete()
         except ProtectedError:
             pass
     else:
         SubscriptionAdjustment.record_adjustment(
             self.subscription, method=SubscriptionAdjustmentMethod.TASK, invoice=invoice
         )
     return invoice
예제 #4
0
def cancel_future_subscriptions(domain_name, from_date, web_user):
    from corehq.apps.accounting.models import (
        Subscription,
        SubscriptionAdjustment,
        SubscriptionAdjustmentReason,
    )
    for later_subscription in Subscription.visible_objects.filter(
            subscriber__domain=domain_name,
            date_start__gt=from_date,
    ).order_by('date_start').all():
        later_subscription.date_end = later_subscription.date_start
        later_subscription.save()
        SubscriptionAdjustment.record_adjustment(
            later_subscription,
            reason=SubscriptionAdjustmentReason.CANCEL,
            web_user=web_user,
            note="Cancelled due to changing subscription",
        )
예제 #5
0
파일: utils.py 프로젝트: dimagi/commcare-hq
def cancel_future_subscriptions(domain_name, from_date, web_user):
    from corehq.apps.accounting.models import (
        Subscription,
        SubscriptionAdjustment,
        SubscriptionAdjustmentReason,
    )
    for later_subscription in Subscription.visible_objects.filter(
        subscriber__domain=domain_name,
        date_start__gt=from_date,
    ).order_by('date_start').all():
        later_subscription.date_end = later_subscription.date_start
        later_subscription.save()
        SubscriptionAdjustment.record_adjustment(
            later_subscription,
            reason=SubscriptionAdjustmentReason.CANCEL,
            web_user=web_user,
            note="Cancelled due to changing subscription",
        )
예제 #6
0
    def _generate_invoice(self, subscription, invoice_start, invoice_end):
        invoice, is_new_invoice = Invoice.objects.get_or_create(
            subscription=subscription,
            date_start=invoice_start,
            date_end=invoice_end,
            is_hidden=subscription.do_not_invoice,
        )

        if not is_new_invoice:
            raise InvoiceAlreadyCreatedError(
                "invoice id: {id}".format(id=invoice.id))

        if subscription.subscriptionadjustment_set.count() == 0:
            # record that the subscription was created
            SubscriptionAdjustment.record_adjustment(
                subscription,
                method=SubscriptionAdjustmentMethod.TASK,
                invoice=invoice,
            )

        DomainInvoiceFactory._generate_line_items(invoice, subscription)
        invoice.calculate_credit_adjustments()
        invoice.update_balance()
        invoice.save()
        visible_domain_invoices = Invoice.objects.filter(
            is_hidden=False,
            subscription__subscriber__domain=invoice.get_domain(),
        )
        total_balance = sum(invoice.balance
                            for invoice in visible_domain_invoices)

        should_set_date_due = (total_balance > SMALL_INVOICE_THRESHOLD
                               or (invoice.account.auto_pay_enabled
                                   and total_balance > Decimal(0)))
        if should_set_date_due:
            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()

        return invoice
예제 #7
0
    def _generate_invoice(self, subscription, invoice_start, invoice_end):
        invoice, is_new_invoice = Invoice.objects.get_or_create(
            subscription=subscription,
            date_start=invoice_start,
            date_end=invoice_end,
            is_hidden=subscription.do_not_invoice,
        )

        if not is_new_invoice:
            raise InvoiceAlreadyCreatedError("invoice id: {id}".format(id=invoice.id))

        if subscription.subscriptionadjustment_set.count() == 0:
            # record that the subscription was created
            SubscriptionAdjustment.record_adjustment(
                subscription,
                method=SubscriptionAdjustmentMethod.TASK,
                invoice=invoice,
            )

        DomainInvoiceFactory._generate_line_items(invoice, subscription)
        invoice.calculate_credit_adjustments()
        invoice.update_balance()
        invoice.save()
        visible_domain_invoices = Invoice.objects.filter(
            is_hidden=False,
            subscription__subscriber__domain=invoice.get_domain(),
        )
        total_balance = sum(invoice.balance for invoice in visible_domain_invoices)

        should_set_date_due = (
            total_balance > SMALL_INVOICE_THRESHOLD or
            (invoice.account.auto_pay_enabled and total_balance > Decimal(0))
        )
        if should_set_date_due:
            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()

        return invoice
예제 #8
0
 def response_later_subscription(self):
     """
     Makes sure that subscriptions beginning in the future are ended.
     """
     from corehq.apps.accounting.models import (
         Subscription, SubscriptionAdjustment, SubscriptionAdjustmentReason
     )
     try:
         for later_subscription in Subscription.objects.filter(
             subscriber__domain=self.domain.name,
             date_start__gt=self.date_start
         ).order_by('date_start').all():
             later_subscription.date_start = datetime.date.today()
             later_subscription.date_end = datetime.date.today()
             later_subscription.save()
             SubscriptionAdjustment.record_adjustment(
                 later_subscription,
                 reason=SubscriptionAdjustmentReason.CANCEL,
                 web_user=self.web_user,
                 note="Cancelled due to changing subscription",
             )
     except Subscription.DoesNotExist:
         pass
     return True
예제 #9
0
    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.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, is_new_invoice = Invoice.objects.get_or_create(
            subscription=subscription,
            date_start=invoice_start,
            date_end=invoice_end,
            is_hidden=subscription.do_not_invoice,
        )

        if not is_new_invoice:
            raise InvoiceAlreadyCreatedError("invoice id: {id}".format(id=invoice.id))

        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:
            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
예제 #10
0
    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,
                )

        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)
        date_due = self.date_end + datetime.timedelta(days_until_due)

        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,
            date_due=date_due,
            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()

        record = BillingRecord.generate_record(invoice)
        try:
            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
예제 #11
0
    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.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, is_new_invoice = Invoice.objects.get_or_create(
            subscription=subscription,
            date_start=invoice_start,
            date_end=invoice_end,
            is_hidden=subscription.do_not_invoice,
        )

        if not is_new_invoice:
            raise InvoiceAlreadyCreatedError(
                "invoice id: {id}".format(id=invoice.id))

        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:
            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