Ejemplo n.º 1
0
def generate_invoices(based_on_date=None):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = get_previous_month_date_range(today)
    log_accounting_info(
        "Starting up invoices for %(start)s - %(end)s" % {
            'start': invoice_start.strftime(USER_DATE_FORMAT),
            'end': invoice_end.strftime(USER_DATE_FORMAT),
        })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain = Domain.wrap(domain_doc)
        try:
            invoice_factory = DomainInvoiceFactory(invoice_start, invoice_end,
                                                   domain)
            invoice_factory.create_invoices()
            log_accounting_info("Sent invoices for domain %s" % domain.name)
        except CreditLineError as e:
            log_accounting_error("There was an error utilizing credits for "
                                 "domain %s: %s" % (domain.name, e))
        except InvoiceError as e:
            log_accounting_error("Could not create invoice for domain %s: %s" %
                                 (domain.name, e))
        except InvoiceAlreadyCreatedError as e:
            log_accounting_error("Invoice already existed for domain %s: %s" %
                                 (domain.name, e))
        except Exception as e:
            log_accounting_error("Error occurred while creating invoice for "
                                 "domain %s: %s" % (domain.name, e))

    if not settings.UNIT_TESTING:
        _invoicing_complete_soft_assert(False, "Invoicing is complete!")
Ejemplo n.º 2
0
def generate_invoices(based_on_date=None, check_existing=False, is_test=False):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = utils.get_previous_month_date_range(today)
    logger.info("[Billing] Starting up invoices for %(start)s - %(end)s" % {
        'start': invoice_start.strftime("%d %B %Y"),
        'end': invoice_end.strftime("%d %B %Y"),
    })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain = Domain.wrap(domain_doc)
        if (check_existing and
            Invoice.objects.filter(
                subscription__subscriber__domain=domain,
                date_created__gte=today).count() != 0):
            pass
        elif is_test:
            logger.info("[Billing] Ready to create invoice for domain %s"
                        % domain.name)
        else:
            try:
                invoice_factory = DomainInvoiceFactory(
                    invoice_start, invoice_end, domain)
                invoice_factory.create_invoices()
                logger.info("[BILLING] Sent invoices for domain %s"
                            % domain.name)
            except CreditLineError as e:
                logger.error(
                    "[BILLING] There was an error utilizing credits for "
                    "domain %s: %s" % (domain.name, e)
                )
            except BillingContactInfoError as e:
                subject = "[%s] Invoice Generation Issue" % domain.name
                email_content = render_to_string(
                    'accounting/invoice_error_email.html', {
                        'project': domain.name,
                        'error_msg': 'BillingContactInfoError: %s' % e,
                    }
                )
                send_HTML_email(
                    subject, settings.BILLING_EMAIL, email_content,
                    email_from="Dimagi Billing Bot <%s>" % settings.DEFAULT_FROM_EMAIL
                )
            except InvoiceError as e:
                logger.error(
                    "[BILLING] Could not create invoice for domain %s: %s" % (
                    domain.name, e
                ))
            except Exception as e:
                logger.error(
                    "[BILLING] Error occurred while creating invoice for "
                    "domain %s: %s" % (domain.name, e)
                )
    # And finally...
    if not is_test:
        send_bookkeeper_email()
Ejemplo n.º 3
0
def generate_invoices(based_on_date=None, check_existing=False, is_test=False):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = utils.get_previous_month_date_range(today)
    logger.info(
        "[Billing] Starting up invoices for %(start)s - %(end)s" % {
            'start': invoice_start.strftime("%d %B %Y"),
            'end': invoice_end.strftime("%d %B %Y"),
        })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain = Domain.wrap(domain_doc)
        if (check_existing and
                Invoice.objects.filter(subscription__subscriber__domain=domain,
                                       date_created__gte=today).count() != 0):
            pass
        elif is_test:
            logger.info("[Billing] Ready to create invoice for domain %s" %
                        domain.name)
        else:
            try:
                invoice_factory = DomainInvoiceFactory(invoice_start,
                                                       invoice_end, domain)
                invoice_factory.create_invoices()
                logger.info("[BILLING] Sent invoices for domain %s" %
                            domain.name)
            except CreditLineError as e:
                logger.error(
                    "[BILLING] There was an error utilizing credits for "
                    "domain %s: %s" % (domain.name, e))
            except BillingContactInfoError as e:
                subject = "[%s] Invoice Generation Issue" % domain.name
                email_content = render_to_string(
                    'accounting/invoice_error_email.html', {
                        'project': domain.name,
                        'error_msg': 'BillingContactInfoError: %s' % e,
                    })
                send_HTML_email(subject,
                                settings.BILLING_EMAIL,
                                email_content,
                                email_from="Dimagi Billing Bot <%s>" %
                                settings.DEFAULT_FROM_EMAIL)
            except InvoiceError as e:
                logger.error(
                    "[BILLING] Could not create invoice for domain %s: %s" %
                    (domain.name, e))
            except Exception as e:
                logger.error(
                    "[BILLING] Error occurred while creating invoice for "
                    "domain %s: %s" % (domain.name, e))
    # And finally...
    if not is_test:
        send_bookkeeper_email()
Ejemplo n.º 4
0
    def setUp(self):
        super(TestDomainInvoiceFactory, self).setUp()
        self.invoice_start, self.invoice_end = get_previous_month_date_range()

        self.domain = generator.arbitrary_domain()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain=self.domain.name, created_by="TEST")[0]
        self.community = DefaultProductPlan.get_default_plan_version()
        generator.arbitrary_commcare_users_for_domain(
            self.domain.name, self.community.user_limit + 1)

        self.invoice_factory = DomainInvoiceFactory(self.invoice_start,
                                                    self.invoice_end,
                                                    self.domain)
Ejemplo n.º 5
0
def generate_invoices(based_on_date=None, check_existing=False, is_test=False):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = utils.get_previous_month_date_range(today)
    logger.info("[Billing] Starting up invoices for %(start)s - %(end)s" % {
        'start': invoice_start.strftime(USER_DATE_FORMAT),
        'end': invoice_end.strftime(USER_DATE_FORMAT),
    })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain = Domain.wrap(domain_doc)
        if (check_existing and
            Invoice.objects.filter(
                subscription__subscriber__domain=domain,
                date_created__gte=today).count() != 0):
            pass
        elif is_test:
            logger.info("[Billing] Ready to create invoice for domain %s"
                        % domain.name)
        else:
            try:
                invoice_factory = DomainInvoiceFactory(
                    invoice_start, invoice_end, domain)
                invoice_factory.create_invoices()
                logger.info("[BILLING] Sent invoices for domain %s"
                            % domain.name)
            except CreditLineError as e:
                logger.error(
                    "[BILLING] There was an error utilizing credits for "
                    "domain %s: %s" % (domain.name, e)
                )
            except BillingContactInfoError as e:
                logger.info("BillingContactInfoError: %s" % e)
            except InvoiceError as e:
                logger.error(
                    "[BILLING] Could not create invoice for domain %s: %s" % (
                    domain.name, e
                ))
            except InvoiceAlreadyCreatedError as e:
                logger.error(
                    "[BILLING] Invoice already existed for domain %s: %s" % (
                    domain.name, e
                ))
            except Exception as e:
                logger.error(
                    "[BILLING] Error occurred while creating invoice for "
                    "domain %s: %s" % (domain.name, e)
                )
Ejemplo n.º 6
0
def generate_invoices(based_on_date=None):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = get_previous_month_date_range(today)
    log_accounting_info("Starting up invoices for %(start)s - %(end)s" % {
        'start': invoice_start.strftime(USER_DATE_FORMAT),
        'end': invoice_end.strftime(USER_DATE_FORMAT),
    })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain = Domain.wrap(domain_doc)
        try:
            invoice_factory = DomainInvoiceFactory(
                invoice_start, invoice_end, domain)
            invoice_factory.create_invoices()
            log_accounting_info("Sent invoices for domain %s" % domain.name)
        except CreditLineError as e:
            log_accounting_error(
                "There was an error utilizing credits for "
                "domain %s: %s" % (domain.name, e)
            )
        except InvoiceError as e:
            log_accounting_error(
                "Could not create invoice for domain %s: %s" % (domain.name, e)
            )
        except InvoiceAlreadyCreatedError as e:
            log_accounting_error(
                "Invoice already existed for domain %s: %s" % (domain.name, e)
            )
        except Exception as e:
            log_accounting_error(
                "Error occurred while creating invoice for "
                "domain %s: %s" % (domain.name, e)
            )

    if not settings.UNIT_TESTING:
        _invoicing_complete_soft_assert(False, "Invoicing is complete!")
Ejemplo n.º 7
0
    def _test_specified_recipients(self):
        DomainInvoiceFactory(
            self.subscription.date_start,
            utils.months_from_date(self.subscription.date_start, 1) -
            datetime.timedelta(days=1),
            self.subscription.subscriber.domain,
            recipients=['*****@*****.**',
                        '*****@*****.**']).create_invoices()

        self.assertEqual(len(mail.outbox), 2)
        self.assertListEqual(mail.outbox[0].to, ['*****@*****.**'])
        self.assertListEqual(mail.outbox[0].cc, [])
        self.assertListEqual(mail.outbox[1].to, ['*****@*****.**'])
        self.assertListEqual(mail.outbox[1].cc, [])
    def setUp(self):
        super(TestDomainInvoiceFactory, self).setUp()
        self.invoice_start, self.invoice_end = get_previous_month_date_range()

        self.domain = generator.arbitrary_domain()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain=self.domain.name, created_by="TEST"
        )[0]
        self.community = DefaultProductPlan.get_default_plan().plan.get_version()
        generator.arbitrary_commcare_users_for_domain(
            self.domain.name, self.community.user_limit + 1
        )

        self.invoice_factory = DomainInvoiceFactory(
            self.invoice_start, self.invoice_end, self.domain
        )
class TestDomainInvoiceFactory(BaseAccountingTest):
    def setUp(self):
        super(TestDomainInvoiceFactory, self).setUp()
        self.invoice_start, self.invoice_end = get_previous_month_date_range()

        self.domain = generator.arbitrary_domain()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain=self.domain.name, created_by="TEST")[0]
        self.community = DefaultProductPlan.get_default_plan_by_domain(
            self.domain).plan.get_version()
        generator.arbitrary_commcare_users_for_domain(
            self.domain.name, self.community.user_limit + 1)

        self.invoice_factory = DomainInvoiceFactory(self.invoice_start,
                                                    self.invoice_end,
                                                    self.domain)

    def _clean_subs(self):
        SubscriptionAdjustment.objects.all().delete()
        Subscription.objects.all().delete()

    def test_feature_charges(self):
        domain_under_limits = generator.arbitrary_domain()
        self.assertTrue(
            self.community.feature_charges_exist_for_domain(self.domain))
        self.assertFalse(
            self.community.feature_charges_exist_for_domain(
                domain_under_limits))

    def test_incomplete_starting_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain,
            some_plan,
            date_start=self.invoice_start + datetime.timedelta(days=3))
        subscriptions = self.invoice_factory.get_subscriptions()
        community_ranges = self.invoice_factory.get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 1)
        self.assertEqual(community_ranges[0][0], self.invoice_start)
        self.assertEqual(community_ranges[0][1], subscription.date_start)
        self._clean_subs()

    def test_incomplete_ending_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain,
            some_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end - datetime.timedelta(days=3))
        subscriptions = self.invoice_factory.get_subscriptions()
        community_ranges = self.invoice_factory.get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 1)
        self.assertEqual(community_ranges[0][0], subscription.date_end)
        self.assertEqual(community_ranges[0][1],
                         self.invoice_end + datetime.timedelta(days=1))
        self._clean_subs()

    def test_patchy_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        middle_date = self.invoice_end - datetime.timedelta(days=15)
        Subscription.new_domain_subscription(self.account,
                                             self.domain,
                                             some_plan,
                                             date_start=self.invoice_start +
                                             datetime.timedelta(days=1),
                                             date_end=middle_date)
        next_start = middle_date + datetime.timedelta(days=2)
        next_end = next_start + datetime.timedelta(days=2)
        Subscription.new_domain_subscription(
            self.account,
            self.domain,
            some_plan,
            date_start=next_start,
            date_end=next_end,
        )
        final_start = next_end + datetime.timedelta(days=2)
        Subscription.new_domain_subscription(
            self.account,
            self.domain,
            some_plan,
            date_start=final_start,
            date_end=self.invoice_end - datetime.timedelta(days=1),
        )
        subscriptions = self.invoice_factory.get_subscriptions()
        self.assertEqual(len(subscriptions), 3)
        community_ranges = self.invoice_factory.get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 4)
        self._clean_subs()

    def test_full_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        Subscription.new_domain_subscription(
            self.account,
            self.domain,
            some_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end + datetime.timedelta(days=1),
        )
        subscriptions = self.invoice_factory.get_subscriptions()
        community_ranges = self.invoice_factory.get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 0)
        self._clean_subs()

    def test_no_coverage(self):
        subscriptions = self.invoice_factory.get_subscriptions()
        self.assertEqual(len(subscriptions), 0)
        community_ranges = self.invoice_factory.get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 1)
Ejemplo n.º 10
0
class TestDomainInvoiceFactory(BaseAccountingTest):

    def setUp(self):
        super(TestDomainInvoiceFactory, self).setUp()
        self.invoice_start, self.invoice_end = get_previous_month_date_range()

        self.domain = generator.arbitrary_domain()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain=self.domain.name, created_by="TEST"
        )[0]
        self.community = DefaultProductPlan.get_default_plan_by_domain(
            self.domain).plan.get_version()
        generator.arbitrary_commcare_users_for_domain(
            self.domain.name, self.community.user_limit + 1
        )

        self.invoice_factory = DomainInvoiceFactory(
            self.invoice_start, self.invoice_end, self.domain
        )

    def _clean_subs(self):
        SubscriptionAdjustment.objects.all().delete()
        Subscription.objects.all().delete()

    def test_feature_charges(self):
        domain_under_limits = generator.arbitrary_domain()
        self.assertTrue(self.community.feature_charges_exist_for_domain(self.domain))
        self.assertFalse(self.community.feature_charges_exist_for_domain(domain_under_limits))

    def test_incomplete_starting_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        subscription = Subscription.new_domain_subscription(
            self.account, self.domain, some_plan,
            date_start=self.invoice_start + datetime.timedelta(days=3)
        )
        subscriptions = self.invoice_factory.get_subscriptions()
        community_ranges = self.invoice_factory.get_community_ranges(subscriptions)
        self.assertEqual(len(community_ranges), 1)
        self.assertEqual(community_ranges[0][0], self.invoice_start)
        self.assertEqual(community_ranges[0][1], subscription.date_start)
        self._clean_subs()

    def test_incomplete_ending_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        subscription = Subscription.new_domain_subscription(
            self.account, self.domain, some_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end - datetime.timedelta(days=3)
        )
        subscriptions = self.invoice_factory.get_subscriptions()
        community_ranges = self.invoice_factory.get_community_ranges(subscriptions)
        self.assertEqual(len(community_ranges), 1)
        self.assertEqual(community_ranges[0][0], subscription.date_end)
        self.assertEqual(community_ranges[0][1],
                         self.invoice_end + datetime.timedelta(days=1))
        self._clean_subs()

    def test_patchy_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        middle_date = self.invoice_end - datetime.timedelta(days=15)
        Subscription.new_domain_subscription(
            self.account, self.domain, some_plan,
            date_start=self.invoice_start + datetime.timedelta(days=1),
            date_end=middle_date
        )
        next_start = middle_date + datetime.timedelta(days=2)
        next_end = next_start + datetime.timedelta(days=2)
        Subscription.new_domain_subscription(
            self.account, self.domain, some_plan,
            date_start=next_start,
            date_end=next_end,
        )
        final_start = next_end + datetime.timedelta(days=2)
        Subscription.new_domain_subscription(
            self.account, self.domain, some_plan,
            date_start=final_start,
            date_end=self.invoice_end - datetime.timedelta(days=1),
        )
        subscriptions = self.invoice_factory.get_subscriptions()
        self.assertEqual(len(subscriptions), 3)
        community_ranges = self.invoice_factory.get_community_ranges(subscriptions)
        self.assertEqual(len(community_ranges), 4)
        self._clean_subs()

    def test_full_coverage(self):
        some_plan = generator.arbitrary_subscribable_plan()
        Subscription.new_domain_subscription(
            self.account, self.domain, some_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end + datetime.timedelta(days=1),
        )
        subscriptions = self.invoice_factory.get_subscriptions()
        community_ranges = self.invoice_factory.get_community_ranges(subscriptions)
        self.assertEqual(len(community_ranges), 0)
        self._clean_subs()

    def test_no_coverage(self):
        subscriptions = self.invoice_factory.get_subscriptions()
        self.assertEqual(len(subscriptions), 0)
        community_ranges = self.invoice_factory.get_community_ranges(subscriptions)
        self.assertEqual(len(community_ranges), 1)
Ejemplo n.º 11
0
def generate_invoices(based_on_date=None):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = get_previous_month_date_range(today)
    log_accounting_info(
        "Starting up invoices for %(start)s - %(end)s" % {
            'start': invoice_start.strftime(USER_DATE_FORMAT),
            'end': invoice_end.strftime(USER_DATE_FORMAT),
        })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain_obj = Domain.wrap(domain_doc)
        if not domain_obj.is_active:
            continue
        try:
            invoice_factory = DomainInvoiceFactory(invoice_start, invoice_end,
                                                   domain_obj)
            invoice_factory.create_invoices()
            log_accounting_info("Sent invoices for domain %s" %
                                domain_obj.name)
        except CreditLineError as e:
            log_accounting_error(
                "There was an error utilizing credits for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
        except InvoiceError as e:
            log_accounting_error(
                "Could not create invoice for domain %s: %s" %
                (domain_obj.name, e),
                show_stack_trace=True,
            )
        except Exception as e:
            log_accounting_error(
                "Error occurred while creating invoice for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
    all_customer_billing_accounts = BillingAccount.objects.filter(
        is_customer_billing_account=True)
    for account in all_customer_billing_accounts:
        try:
            if account.invoicing_plan == InvoicingPlan.QUARTERLY:
                customer_invoice_start = invoice_start - relativedelta(
                    months=2)
            elif account.invoicing_plan == InvoicingPlan.YEARLY:
                customer_invoice_start = invoice_start - relativedelta(
                    months=11)
            else:
                customer_invoice_start = invoice_start
            invoice_factory = CustomerAccountInvoiceFactory(
                account=account,
                date_start=customer_invoice_start,
                date_end=invoice_end)
            invoice_factory.create_invoice()
        except CreditLineError as e:
            log_accounting_error(
                "There was an error utilizing credits for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
        except InvoiceError as e:
            log_accounting_error(
                "Could not create invoice for domain %s: %s" %
                (domain_obj.name, e),
                show_stack_trace=True,
            )
        except Exception as e:
            log_accounting_error(
                "Error occurred while creating invoice for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )

    if not settings.UNIT_TESTING:
        _invoicing_complete_soft_assert(False, "Invoicing is complete!")
Ejemplo n.º 12
0
class TestDomainInvoiceFactory(BaseAccountingTest):
    @classmethod
    def setUpClass(cls):
        super(TestDomainInvoiceFactory, cls).setUpClass()
        generator.bootstrap_test_software_plan_versions()

    def setUp(self):
        super(TestDomainInvoiceFactory, self).setUp()
        self.invoice_start, self.invoice_end = get_previous_month_date_range()

        self.domain = generator.arbitrary_domain()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain=self.domain.name, created_by="TEST")[0]
        self.community = DefaultProductPlan.get_default_plan_version()
        generator.arbitrary_commcare_users_for_domain(
            self.domain.name, self.community.user_limit + 1)

        self.invoice_factory = DomainInvoiceFactory(self.invoice_start,
                                                    self.invoice_end,
                                                    self.domain)

    def tearDown(self):
        self.domain.delete()
        super(TestDomainInvoiceFactory, self).tearDown()

    @classmethod
    def tearDownClass(cls):
        clear_plan_version_cache()
        super(TestDomainInvoiceFactory, cls).tearDownClass()

    def test_feature_charges(self):
        domain_under_limits = generator.arbitrary_domain()
        self.assertTrue(
            self.community.feature_charges_exist_for_domain(self.domain))
        self.assertFalse(
            self.community.feature_charges_exist_for_domain(
                domain_under_limits))
        domain_under_limits.delete()

    def test_incomplete_starting_coverage(self):
        some_plan = generator.subscribable_plan_version()
        subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            some_plan,
            date_start=self.invoice_start + datetime.timedelta(days=3))
        subscriptions = self.invoice_factory._get_subscriptions()
        community_ranges = self.invoice_factory._get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 1)
        self.assertEqual(community_ranges[0][0], self.invoice_start)
        self.assertEqual(community_ranges[0][1], subscription.date_start)

    def test_incomplete_ending_coverage(self):
        some_plan = generator.subscribable_plan_version()
        subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            some_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end - datetime.timedelta(days=3))
        subscriptions = self.invoice_factory._get_subscriptions()
        community_ranges = self.invoice_factory._get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 1)
        self.assertEqual(community_ranges[0][0], subscription.date_end)
        self.assertEqual(community_ranges[0][1],
                         self.invoice_end + datetime.timedelta(days=1))

    def test_patchy_coverage(self):
        some_plan = generator.subscribable_plan_version()
        middle_date = self.invoice_end - datetime.timedelta(days=15)
        Subscription.new_domain_subscription(self.account,
                                             self.domain.name,
                                             some_plan,
                                             date_start=self.invoice_start +
                                             datetime.timedelta(days=1),
                                             date_end=middle_date)
        next_start = middle_date + datetime.timedelta(days=2)
        next_end = next_start + datetime.timedelta(days=2)
        Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            some_plan,
            date_start=next_start,
            date_end=next_end,
        )
        final_start = next_end + datetime.timedelta(days=2)
        Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            some_plan,
            date_start=final_start,
            date_end=self.invoice_end - datetime.timedelta(days=1),
        )
        subscriptions = self.invoice_factory._get_subscriptions()
        self.assertEqual(len(subscriptions), 3)
        community_ranges = self.invoice_factory._get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 4)

    def test_full_coverage(self):
        some_plan = generator.subscribable_plan_version()
        Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            some_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end + datetime.timedelta(days=1),
        )
        subscriptions = self.invoice_factory._get_subscriptions()
        community_ranges = self.invoice_factory._get_community_ranges(
            subscriptions)
        self.assertEqual(len(community_ranges), 0)

    def test_no_coverage(self):
        subscriptions = self.invoice_factory._get_subscriptions()
        self.assertEqual(len(subscriptions), 0)
        community_ranges = self.invoice_factory._get_community_ranges(
            subscriptions)
        self.assertEqual(community_ranges, [
            (self.invoice_start, self.invoice_end + datetime.timedelta(days=1))
        ])

    def test_paused_plan_generates_no_invoice(self):
        """
        Ensure that paused plans do not generate invoices.
        """
        paused_plan = generator.subscribable_plan_version(
            edition=SoftwarePlanEdition.PAUSED)
        Subscription.new_domain_subscription(
            self.account,
            self.domain.name,
            paused_plan,
            date_start=self.invoice_start,
            date_end=self.invoice_end + datetime.timedelta(days=1),
        )
        self.assertListEqual(self.invoice_factory._get_subscriptions(), [])
Ejemplo n.º 13
0
def generate_invoices(based_on_date=None):
    """
    Generates all invoices for the past month.
    """
    today = based_on_date or datetime.date.today()
    invoice_start, invoice_end = get_previous_month_date_range(today)
    log_accounting_info("Starting up invoices for %(start)s - %(end)s" % {
        'start': invoice_start.strftime(USER_DATE_FORMAT),
        'end': invoice_end.strftime(USER_DATE_FORMAT),
    })
    all_domain_ids = [d['id'] for d in Domain.get_all(include_docs=False)]
    for domain_doc in iter_docs(Domain.get_db(), all_domain_ids):
        domain_obj = Domain.wrap(domain_doc)
        if not domain_obj.is_active:
            continue
        try:
            invoice_factory = DomainInvoiceFactory(invoice_start, invoice_end, domain_obj)
            invoice_factory.create_invoices()
            log_accounting_info("Sent invoices for domain %s" % domain_obj.name)
        except CreditLineError as e:
            log_accounting_error(
                "There was an error utilizing credits for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
        except InvoiceError as e:
            log_accounting_error(
                "Could not create invoice for domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
        except Exception as e:
            log_accounting_error(
                "Error occurred while creating invoice for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
    all_customer_billing_accounts = BillingAccount.objects.filter(is_customer_billing_account=True)
    for account in all_customer_billing_accounts:
        try:
            if account.invoicing_plan == InvoicingPlan.QUARTERLY:
                customer_invoice_start = invoice_start - relativedelta(months=2)
            elif account.invoicing_plan == InvoicingPlan.YEARLY:
                customer_invoice_start = invoice_start - relativedelta(months=11)
            else:
                customer_invoice_start = invoice_start
            invoice_factory = CustomerAccountInvoiceFactory(
                account=account,
                date_start=customer_invoice_start,
                date_end=invoice_end
            )
            invoice_factory.create_invoice()
        except CreditLineError as e:
            log_accounting_error(
                "There was an error utilizing credits for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
        except InvoiceError as e:
            log_accounting_error(
                "Could not create invoice for domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )
        except Exception as e:
            log_accounting_error(
                "Error occurred while creating invoice for "
                "domain %s: %s" % (domain_obj.name, e),
                show_stack_trace=True,
            )

    if not settings.UNIT_TESTING:
        _invoicing_complete_soft_assert(False, "Invoicing is complete!")