예제 #1
0
    def should_be_billed(self, billing_date, generate_documents_datetime=None):
        if self.state not in [self.STATES.ACTIVE, self.STATES.CANCELED]:
            return False

        if not generate_documents_datetime:
            generate_documents_datetime = timezone.now()

        if self.cycle_billing_duration:
            if self.start_date > first_day_of_month(billing_date) + self.cycle_billing_duration:
                # There was nothing to bill on the last day of the first cycle billing duration
                return False

            # We need the full cycle here (ignoring trial ends)
            cycle_start_datetime_ignoring_trial = self._cycle_start_date(billing_date,
                                                                         ignore_trial=False)
            latest_possible_billing_datetime = (
                cycle_start_datetime_ignoring_trial + self.cycle_billing_duration
            )

            billing_date = min(billing_date, latest_possible_billing_datetime)

        if billing_date > generate_documents_datetime.date():
            return False

        cycle_start_date = self.cycle_start_date(billing_date)

        if not cycle_start_date:
            return False

        if self.state == self.STATES.CANCELED:
            if billing_date <= self.cancel_date:
                return False

            cycle_start_date = self.cancel_date + ONE_DAY

        cycle_start_datetime = datetime.combine(cycle_start_date,
                                                datetime.min.time()).replace(tzinfo=utc)

        generate_after = timedelta(seconds=self.plan.generate_after)

        if generate_documents_datetime < cycle_start_datetime + generate_after:
            return False

        billed_up_to_dates = self.billed_up_to_dates
        plan_billed_up_to = billed_up_to_dates['plan_billed_up_to']
        metered_features_billed_up_to = billed_up_to_dates['metered_features_billed_up_to']

        # We want to bill the subscription if the plan hasn't been billed for this cycle or
        # if the subscription has been canceled and the plan won't be billed for this cycle.
        if self.prebill_plan or self.state == self.STATES.CANCELED:
            plan_should_be_billed = plan_billed_up_to < cycle_start_date

            if self.state == self.STATES.CANCELED:
                return metered_features_billed_up_to < cycle_start_date or plan_should_be_billed

            return plan_should_be_billed

        # wait until the cycle that is going to be billed ends:
        billed_cycle_end_date = self.cycle_end_date(plan_billed_up_to + ONE_DAY)
        return billed_cycle_end_date < cycle_start_date
예제 #2
0
    def should_be_billed(self, billing_date, generate_documents_datetime=None):
        if self.state not in [self.STATES.ACTIVE, self.STATES.CANCELED]:
            return False

        if not generate_documents_datetime:
            generate_documents_datetime = timezone.now()

        if self.cycle_billing_duration:
            if self.start_date > first_day_of_month(billing_date) + self.cycle_billing_duration:
                # There was nothing to bill on the last day of the first cycle billing duration
                return False

            # We need the full cycle here (ignoring trial ends)
            cycle_start_datetime_ignoring_trial = self._cycle_start_date(billing_date,
                                                                         ignore_trial=False)
            latest_possible_billing_datetime = (
                cycle_start_datetime_ignoring_trial + self.cycle_billing_duration
            )

            billing_date = min(billing_date, latest_possible_billing_datetime)

        if billing_date > generate_documents_datetime.date():
            return False

        cycle_start_date = self.cycle_start_date(billing_date)

        if not cycle_start_date:
            return False

        if self.state == self.STATES.CANCELED:
            if billing_date <= self.cancel_date:
                return False

            cycle_start_date = self.cancel_date + ONE_DAY

        cycle_start_datetime = datetime.combine(cycle_start_date,
                                                datetime.min.time()).replace(tzinfo=utc)

        generate_after = timedelta(seconds=self.plan.generate_after)

        if generate_documents_datetime < cycle_start_datetime + generate_after:
            return False

        billed_up_to_dates = self.billed_up_to_dates
        plan_billed_up_to = billed_up_to_dates['plan_billed_up_to']
        metered_features_billed_up_to = billed_up_to_dates['metered_features_billed_up_to']

        # We want to bill the subscription if the plan hasn't been billed for this cycle or
        # if the subscription has been canceled and the plan won't be billed for this cycle.
        if self.prebill_plan or self.state == self.STATES.CANCELED:
            plan_should_be_billed = plan_billed_up_to < cycle_start_date

            if self.state == self.STATES.CANCELED:
                return metered_features_billed_up_to < cycle_start_date or plan_should_be_billed

            return plan_should_be_billed

        # wait until the cycle that is going to be billed ends:
        billed_cycle_end_date = self.cycle_end_date(plan_billed_up_to + ONE_DAY)
        return billed_cycle_end_date < cycle_start_date