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
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
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
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", )
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
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
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
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
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
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