コード例 #1
0
ファイル: tasks.py プロジェクト: kkaczmarczyk/commcare-hq
def send_bookkeeper_email(month=None, year=None, emails=None):
    today = datetime.date.today()

    # now, make sure that we send out LAST month's invoices if we did
    # not specify a month or year.
    today = utils.get_previous_month_date_range(today)[0]

    month = month or today.month
    year = year or today.year

    from corehq.apps.accounting.interface import InvoiceInterface
    request = HttpRequest()
    params = urlencode((
        ('report_filter_statement_period_use_filter', 'on'),
        ('report_filter_statement_period_month', month),
        ('report_filter_statement_period_year', year),
    ))
    request.GET = QueryDict(params)
    request.couch_user = FakeUser(
        domain="hqadmin",
        username="******",
    )
    invoice = InvoiceInterface(request)
    invoice.is_rendered_as_email = True
    first_of_month = datetime.date(year, month, 1)
    email_context = {
        'month': first_of_month.strftime("%B"),
    }
    email_content = render_to_string(
        'accounting/bookkeeper_email.html', email_context)
    email_content_plaintext = render_to_string(
        'accounting/bookkeeper_email_plaintext.html', email_context)

    format_dict = Format.FORMAT_DICT[Format.CSV]
    excel_attachment = {
        'title': 'Invoices_%(period)s.%(extension)s' % {
            'period': first_of_month.strftime('%B_%Y'),
            'extension': format_dict['extension'],
        },
        'mimetype': format_dict['mimetype'],
        'file_obj': invoice.excel_response,
    }

    emails = emails or settings.BOOKKEEPER_CONTACT_EMAILS
    for email in emails:
        send_HTML_email(
            "Invoices for %s" % datetime.date(year, month, 1).strftime("%B %Y"),
            email,
            email_content,
            email_from=settings.DEFAULT_FROM_EMAIL,
            text_content=email_content_plaintext,
            file_attachments=[excel_attachment],
        )

    logger.info(
        "[BILLING] Sent Bookkeeper Invoice Summary for %(month)s "
        "to %(emails)s." % {
            'month': first_of_month.strftime("%B %Y"),
            'emails': ", ".join(emails)
        })
コード例 #2
0
def send_bookkeeper_email(month=None, year=None, emails=None):
    today = datetime.date.today()

    # now, make sure that we send out LAST month's invoices if we did
    # not specify a month or year.
    today = utils.get_previous_month_date_range(today)[0]

    month = month or today.month
    year = year or today.year

    from corehq.apps.accounting.interface import InvoiceInterface
    request = HttpRequest()
    params = urlencode((
        ('report_filter_statement_period_use_filter', 'on'),
        ('report_filter_statement_period_month', month),
        ('report_filter_statement_period_year', year),
    ))
    request.GET = QueryDict(params)
    request.couch_user = FakeUser(
        domain="hqadmin",
        username="******",
    )
    invoice = InvoiceInterface(request)
    invoice.is_rendered_as_email = True
    first_of_month = datetime.date(year, month, 1)
    email_context = {
        'month': first_of_month.strftime("%B"),
    }
    email_content = render_to_string(
        'accounting/bookkeeper_email.html', email_context)
    email_content_plaintext = render_to_string(
        'accounting/bookkeeper_email_plaintext.html', email_context)

    format_dict = Format.FORMAT_DICT[Format.CSV]
    excel_attachment = {
        'title': 'Invoices_%(period)s.%(extension)s' % {
            'period': first_of_month.strftime('%B_%Y'),
            'extension': format_dict['extension'],
        },
        'mimetype': format_dict['mimetype'],
        'file_obj': invoice.excel_response,
    }

    emails = emails or settings.BOOKKEEPER_CONTACT_EMAILS
    for email in emails:
        send_HTML_email(
            "Invoices for %s" % datetime.date(year, month, 1).strftime(USER_MONTH_FORMAT),
            email,
            email_content,
            email_from=settings.DEFAULT_FROM_EMAIL,
            text_content=email_content_plaintext,
            file_attachments=[excel_attachment],
        )

    logger.info(
        "[BILLING] Sent Bookkeeper Invoice Summary for %(month)s "
        "to %(emails)s." % {
            'month': first_of_month.strftime(USER_MONTH_FORMAT),
            'emails': ", ".join(emails)
        })
コード例 #3
0
ファイル: daterange.py プロジェクト: ekush/commcare-hq
def get_daterange_start_end_dates(date_range, start_date=None, end_date=None, days=None):
    today = datetime.date.today()
    if date_range == 'since':
        start_date = start_date
        end_date = today
    elif date_range == 'range':
        start_date = start_date
        end_date = end_date
    elif date_range == 'lastmonth':
        start_date, end_date = get_previous_month_date_range()
    elif date_range == 'lastyear':
        last_year = today.year - 1
        return datetime.date(last_year, 1, 1), datetime.date(last_year, 12, 31)
    else:
        end_date = today
        days = {
            'last7': 7,
            'last30': 30,
            'lastn': days
        }.get(date_range)
        if days is None:
            raise InvalidDaterangeException
        start_date = today - datetime.timedelta(days=days)

    if start_date is None or end_date is None:
        raise InvalidDaterangeException

    return start_date, end_date
コード例 #4
0
def get_daterange_start_end_dates(date_range,
                                  start_date=None,
                                  end_date=None,
                                  days=None):
    today = datetime.date.today()
    if date_range == 'since':
        start_date = start_date
        end_date = today
    elif date_range == 'range':
        start_date = start_date
        end_date = end_date
    elif date_range == 'lastmonth':
        start_date, end_date = get_previous_month_date_range()
    elif date_range == 'lastyear':
        last_year = today.year - 1
        return datetime.date(last_year, 1, 1), datetime.date(last_year, 12, 31)
    else:
        end_date = today
        days = {'last7': 7, 'last30': 30, 'lastn': days}.get(date_range)
        if days is None:
            raise InvalidDaterangeException
        start_date = today - datetime.timedelta(days=days)

    if start_date is None or end_date is None:
        raise InvalidDaterangeException

    return start_date, end_date
コード例 #5
0
ファイル: tasks.py プロジェクト: SEL-Columbia/commcare-hq
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()
コード例 #6
0
ファイル: tasks.py プロジェクト: thedevelopermw/commcare-hq
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()
コード例 #7
0
ファイル: models.py プロジェクト: idiene/commcare-hq
    def get_date_range(self):
        """Duplicated in reports.config.js"""
        date_range = self.date_range
        # allow old report email notifications to represent themselves as a
        # report config by leaving the default date range up to the report
        # dispatcher
        if not date_range:
            return {}

        import datetime
        today = datetime.date.today()
        if date_range == 'since':
            start_date = self.start_date
            end_date = today
        elif date_range == 'range':
            start_date = self.start_date
            end_date = self.end_date
        elif date_range == 'lastmonth':
            start_date, end_date = get_previous_month_date_range()
        else:
            end_date = today

            if date_range == 'last7':
                days = 7
            elif date_range == 'last30':
                days = 30
            elif date_range == 'lastn':
                days = self.days
            else:
                raise Exception("Invalid date range")

            start_date = today - datetime.timedelta(days=days)

        if start_date is None or end_date is None:
            # this is due to bad validation. see: http://manage.dimagi.com/default.asp?110906
            logging.error('scheduled report %s is in a bad state (no startdate or enddate)' % self._id)
            return {}

        dates = {
            'startdate': start_date.isoformat(),
            'enddate': end_date.isoformat(),
        }

        if self.is_configurable_report:
            filter_slug = self.datespan_slug
            if filter_slug:
                return {
                    '%s-start' % filter_slug: start_date.isoformat(),
                    '%s-end' % filter_slug: end_date.isoformat(),
                    filter_slug: '%(startdate)s to %(enddate)s' % dates,
                }
        return dates
コード例 #8
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)
                )
コード例 #9
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_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)
コード例 #10
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_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
        )
コード例 #11
0
 def setUp(self):
     super(TestBillingRecord, self).setUp()
     self.billing_contact = generator.arbitrary_web_user()
     self.dimagi_user = generator.arbitrary_web_user(is_dimagi=True)
     self.domain = Domain(name='test')
     self.domain.save()
     self.invoice_start, self.invoice_end = get_previous_month_date_range()
     self.currency = generator.init_default_currency()
     self.account = generator.billing_account(self.dimagi_user, self.billing_contact)
     self.subscription, self.subscription_length = generator.generate_domain_subscription_from_date(
         datetime.date.today(), self.account, self.domain.name
     )
     self.invoice = Invoice(
         subscription=self.subscription,
         date_start=self.invoice_start,
         date_end=self.invoice_end,
         is_hidden=False,
     )
     self.billing_record = BillingRecord(invoice=self.invoice)
コード例 #12
0
    def test_use_prev_billing_account_for_community_invoice(self):
        """
        Make sure that if a billing account was already auto generated for a previous community invoice,
        that a new one is not created.
        """
        domain = generator.arbitrary_domain()
        generator.create_excess_community_users(domain)

        second_invoicing_date = datetime.date.today()
        second_invoice_start, second_invoice_end = utils.get_previous_month_date_range(second_invoicing_date)
        first_invoicing_date = second_invoice_start - datetime.timedelta(days=random.randint(0, 365))

        tasks.generate_invoices(first_invoicing_date)
        tasks.generate_invoices(second_invoicing_date)
        subscriber = Subscriber.objects.get(domain=domain.name)
        invoices = Invoice.objects.filter(subscription__subscriber=subscriber)
        self.assertEqual(invoices.count(), 2)
        invoices = invoices.all()
        self.assertNotEqual(invoices[0].subscription, invoices[1].subscription)
        self.assertEqual(invoices[0].subscription.account, invoices[1].subscription.account)
        for invoice in invoices:
            self.assertEqual(invoice.subscription.subscriber.domain, domain.name)
        domain.delete()
コード例 #13
0
ファイル: tasks.py プロジェクト: pawelreise/commcare-hq
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 = utils.get_previous_month_date_range(today)
    invoiceable_subscriptions = Subscription.objects.filter(date_start__lt=invoice_end,
                                                            date_end__gt=invoice_start).all()

    def _create_invoice(sub):
        invoice_factory = SubscriptionInvoiceFactory(invoice_start, invoice_end, sub)
        invoice_factory.create()

    invoiced_orgs = []
    orgs = Organization.get_db().view('orgs/by_name', group=True, group_level=1).all()
    org_names = [o['key'] for o in orgs]
    for org_name in org_names:
        try:
            subscription = invoiceable_subscriptions.get(subscriber__organization=org_name)
        except ObjectDoesNotExist:
            continue
        _create_invoice(subscription)
        invoiced_orgs.append(org_name)

    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_name = domain_doc['name']
        domain_org = domain_doc['organization']
        try:
            subscription = invoiceable_subscriptions.get(subscriber__domain=domain_name)
        except ObjectDoesNotExist:
            if domain_org not in invoiced_orgs:
                domain = Domain.wrap(domain_doc)
                invoice_factory = CommunityInvoiceFactory(invoice_start, invoice_end, domain)
                invoice_factory.create()
            continue
        _create_invoice(subscription)