<commit_before>from urllib import urlencode
from StringIO import StringIO
from celery.schedules import crontab
from celery.task import periodic_task, task
from celery.utils.log import get_task_logger
import datetime
from couchdbkit import ResourceNotFound
from django.conf import settings
from django.db import transaction
from django.http import HttpRequest, QueryDict
from django.template.loader import render_to_string
from django.utils.translation import ugettext

from corehq.apps.domain.models import Domain
from corehq.apps.accounting import utils
from corehq.apps.accounting.exceptions import (
    InvoiceError, CreditLineError,
    BillingContactInfoError,
    InvoiceAlreadyCreatedError
)
from corehq.apps.accounting.invoicing import DomainInvoiceFactory

from corehq.apps.accounting.models import (
    Subscription, Invoice,
    SubscriptionAdjustment, SubscriptionAdjustmentReason,
    SubscriptionAdjustmentMethod,
    BillingAccount, WirePrepaymentInvoice, WirePrepaymentBillingRecord
)
from corehq.apps.accounting.utils import (
    has_subscription_already_ended, get_dimagi_from_email_by_product,
    fmt_dollar_amount,
    get_change_status,
)
from corehq.apps.accounting.payment_handlers import AutoPayInvoicePaymentHandler
from corehq.apps.users.models import FakeUser, WebUser
from corehq.const import USER_DATE_FORMAT, USER_MONTH_FORMAT
from couchexport.export import export_from_tables
from couchexport.models import Format
from dimagi.utils.couch.database import iter_docs
from dimagi.utils.django.email import send_HTML_email
import corehq.apps.accounting.filters as filters

logger = get_task_logger('accounting')


def activate_subscriptions(based_on_date=None):
    """
    Activates all subscriptions starting today (or, for testing, based on the date specified)
    """
    starting_date = based_on_date or datetime.date.today()
    starting_subscriptions = Subscription.objects.filter(date_start=starting_date)
    for subscription in starting_subscriptions:
        if not has_subscription_already_ended(subscription) and not subscription.is_active:
            with transaction.atomic():
                subscription.is_active = True
                subscription.save()
                upgraded_privs = get_change_status(None, subscription.plan_version).upgraded_privs
                subscription.subscriber.activate_subscription(
                    upgraded_privileges=upgraded_privs,
                    subscription=subscription,
                )


def deactivate_subscriptions(based_on_date=None):
    """
    Deactivates all subscriptions ending today (or, for testing, based on the date specified)
    """
    ending_date = based_on_date or datetime.date.today()
    ending_subscriptions = Subscription.objects.filter(date_end=ending_date)
    for subscription in ending_subscriptions:
        with transaction.atomic():
            subscription.is_active = False
            subscription.save()
            next_subscription = subscription.next_subscription
            if next_subscription and next_subscription.date_start == ending_date:
                new_plan_version = next_subscription.plan_version
                next_subscription.is_active = True
                next_subscription.save()
            else:
                new_plan_version = None
            _, downgraded_privs, upgraded_privs = get_change_status(subscription.plan_version, new_plan_version)
            subscription.subscriber.deactivate_subscription(
                downgraded_privileges=downgraded_privs,
                upgraded_privileges=upgraded_privs,
                old_subscription=subscription,
                new_subscription=next_subscription,
            )


@periodic_task(run_every=crontab(minute=0, hour=0))
def update_subscriptions():
    deactivate_subscriptions()
    activate_subscriptions()<commit_msg>only send new subscription email when it's starting<commit_after>from urllib import urlencode
from StringIO import StringIO
from celery.schedules import crontab
from celery.task import periodic_task, task
from celery.utils.log import get_task_logger
import datetime
from couchdbkit import ResourceNotFound
from django.conf import settings
from django.db import transaction
from django.http import HttpRequest, QueryDict
from django.template.loader import render_to_string
from django.utils.translation import ugettext

from corehq.apps.domain.models import Domain
from corehq.apps.accounting import utils
from corehq.apps.accounting.exceptions import (
    InvoiceError, CreditLineError,
    BillingContactInfoError,
    InvoiceAlreadyCreatedError
)
from corehq.apps.accounting.invoicing import DomainInvoiceFactory

from corehq.apps.accounting.models import (
    Subscription, Invoice,
    SubscriptionAdjustment, SubscriptionAdjustmentReason,
    SubscriptionAdjustmentMethod,
    BillingAccount, WirePrepaymentInvoice, WirePrepaymentBillingRecord
)
from corehq.apps.accounting.utils import (
    has_subscription_already_ended, get_dimagi_from_email_by_product,
    fmt_dollar_amount,
    get_change_status,
)
from corehq.apps.accounting.payment_handlers import AutoPayInvoicePaymentHandler
from corehq.apps.users.models import FakeUser, WebUser
from corehq.const import USER_DATE_FORMAT, USER_MONTH_FORMAT
from couchexport.export import export_from_tables
from couchexport.models import Format
from dimagi.utils.couch.database import iter_docs
from dimagi.utils.django.email import send_HTML_email
import corehq.apps.accounting.filters as filters

logger = get_task_logger('accounting')


def activate_subscriptions(based_on_date=None):
    """
    Activates all subscriptions starting today (or, for testing, based on the date specified)
    """
    starting_date = based_on_date or datetime.date.today()
    starting_subscriptions = Subscription.objects.filter(date_start=starting_date)
    for subscription in starting_subscriptions:
        if not has_subscription_already_ended(subscription) and not subscription.is_active:
            with transaction.atomic():
                subscription.is_active = True
                subscription.save()
                upgraded_privs = get_change_status(None, subscription.plan_version).upgraded_privs
                subscription.subscriber.activate_subscription(
                    upgraded_privileges=upgraded_privs,
                    subscription=subscription,
                )


def deactivate_subscriptions(based_on_date=None):
    """
    Deactivates all subscriptions ending today (or, for testing, based on the date specified)
    """
    ending_date = based_on_date or datetime.date.today()
    ending_subscriptions = Subscription.objects.filter(date_end=ending_date)
    for subscription in ending_subscriptions:
        with transaction.atomic():
            subscription.is_active = False
            subscription.save()
            next_subscription = subscription.next_subscription
            activate_next_subscription = next_subscription and next_subscription.date_start == ending_date
            if activate_next_subscription:
                new_plan_version = next_subscription.plan_version
                next_subscription.is_active = True
                next_subscription.save()
            else:
                new_plan_version = None
            _, downgraded_privs, upgraded_privs = get_change_status(subscription.plan_version, new_plan_version)
            subscription.subscriber.deactivate_subscription(
                downgraded_privileges=downgraded_privs,
                upgraded_privileges=upgraded_privs,
                old_subscription=subscription,
                new_subscription=next_subscription if activate_next_subscription else None,
            )


@periodic_task(run_every=crontab(minute=0, hour=0))
def update_subscriptions():
    deactivate_subscriptions()
    activate_subscriptions()
{'fraction_non_alphanumeric': 0.05532891381947986, 'fraction_numerical': 0.0005099439061703213, 'mean_word_length': 3.8276923076923075, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5693402', 'n_tokens_mistral': 2093, 'n_tokens_neox': 2084, 'n_words': 458}