def run_billing_processor_one_step(processor: BillingProcessor) -> bool: # Returns True if a row was processed, or if processing was attempted log_row = get_next_billing_log_entry(processor) if log_row is None: if processor.realm is not None: processor.delete() return False try: process_billing_log_entry(processor, log_row) return True except Exception as e: # Possible errors include processing subscription quantity entries # after downgrade, since the downgrade code doesn't check that # billing processor is up to date billing_logger.error( "Error on log_row.realm=%s, event_type=%s, log_row.id=%s, " "processor.id=%s, processor.realm=%s" % (processor.log_row.realm.string_id, processor.log_row.event_type, processor.log_row.id, processor.id, processor.realm)) if isinstance(e, StripeCardError): if processor.realm is None: BillingProcessor.objects.create(log_row=processor.log_row, realm=processor.log_row.realm, state=BillingProcessor.STALLED) processor.state = BillingProcessor.SKIPPED else: processor.state = BillingProcessor.STALLED processor.save() return True raise
def run_billing_processor_one_step(processor: BillingProcessor) -> bool: # Returns True if a row was processed, or if processing was attempted log_row = get_next_billing_log_entry(processor) if log_row is None: if processor.realm is not None: processor.delete() return False try: process_billing_log_entry(processor, log_row) return True except Exception as e: # Possible errors include processing subscription quantity entries # after downgrade, since the downgrade code doesn't check that # billing processor is up to date billing_logger.error("Error on log_row.realm=%s, event_type=%s, log_row.id=%s, " "processor.id=%s, processor.realm=%s" % ( processor.log_row.realm.string_id, processor.log_row.event_type, processor.log_row.id, processor.id, processor.realm)) if isinstance(e, StripeCardError): if processor.realm is None: BillingProcessor.objects.create(log_row=processor.log_row, realm=processor.log_row.realm, state=BillingProcessor.STALLED) processor.state = BillingProcessor.SKIPPED else: processor.state = BillingProcessor.STALLED processor.save() return True raise
def process_billing_log_entry(processor: BillingProcessor, log_row: RealmAuditLog) -> None: processor.state = BillingProcessor.STARTED processor.log_row = log_row processor.save() customer = Customer.objects.get(realm=log_row.realm) timestamp = datetime_to_timestamp(log_row.event_time) idempotency_key = 'process_billing_log_entry:%s' % (log_row.id, ) if settings.TEST_SUITE: idempotency_key += '+' + generate_random_token(10) extra_args = {} # type: Dict[str, Any] if log_row.extra_data is not None: extra_args = ujson.loads(log_row.extra_data) processing_functions = { RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET: do_set_subscription_quantity, RealmAuditLog.USER_CREATED: increment_subscription_quantity, RealmAuditLog.USER_ACTIVATED: increment_subscription_quantity, RealmAuditLog.USER_DEACTIVATED: decrement_subscription_quantity, RealmAuditLog.USER_REACTIVATED: increment_subscription_quantity, } # type: Dict[str, Callable[..., None]] processing_functions[log_row.event_type](customer, timestamp, idempotency_key, **extra_args) processor.state = BillingProcessor.DONE processor.save()
def process_billing_log_entry(processor: BillingProcessor, log_row: RealmAuditLog) -> None: processor.state = BillingProcessor.STARTED processor.log_row = log_row processor.save() customer = Customer.objects.get(realm=log_row.realm) timestamp = datetime_to_timestamp(log_row.event_time) idempotency_key = 'process_billing_log_entry:%s' % (log_row.id,) extra_args = {} # type: Dict[str, Any] if log_row.extra_data is not None: extra_args = ujson.loads(log_row.extra_data) processing_functions = { RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET: do_set_subscription_quantity, RealmAuditLog.USER_CREATED: increment_subscription_quantity, RealmAuditLog.USER_ACTIVATED: increment_subscription_quantity, RealmAuditLog.USER_DEACTIVATED: decrement_subscription_quantity, RealmAuditLog.USER_REACTIVATED: increment_subscription_quantity, } # type: Dict[str, Callable[..., None]] processing_functions[log_row.event_type](customer, timestamp, idempotency_key, **extra_args) processor.state = BillingProcessor.DONE processor.save()