def retry_failed_orders(max_retries=1): failed_orders = orders.list_orders_with_failed_items() for order in failed_orders: if order.retries < max_retries: logger.info('Going to retry failed %r after %r retries', order, order.retries) order.retries = order.retries + 1 order.save() orders.execute_order(order)
def test_refresh_order_domain_transfer_pending_to_processed( self, mock_domain_transfer_request): tester_domain = testsupport.prepare_tester_domain( domain_name='testdomain.%s' % settings.ZENAIDA_SUPPORTED_ZONES[0], add_contacts=[ 'registrant', 'admin', ], epp_id_dict={ 'registrant': 'ThisIDNotExist1', 'admin': 'ThisIDNotExist2', }, nameservers=[ 'notexist1.com', 'notexist2.com', ], ) tester_domain.owner.balance = 1000.0 tester_domain.owner.save() mock_domain_transfer_request.return_value = True order_object = orders.order_single_item( owner=tester_domain.owner, item_type='domain_transfer', item_price=100.0, item_name='testdomain.ai', item_details={ 'transfer_code': 'abcd1234', }, ) assert len(order_object.items.all()) == 1 order_item = order_object.items.first() assert order_item.status == 'started' assert order_object.status == 'started' orders.execute_order(order_object) order_item.refresh_from_db() assert order_item.status == 'pending' assert order_object.status == 'processing' assert tester_domain.owner.balance == 1000.0 orders.update_order_item(order_item, new_status='processed', charge_user=True) order_item.refresh_from_db() assert order_item.status == 'processed' orders.refresh_order(order_object) assert order_object.status == 'processed' tester_domain.owner.refresh_from_db() assert tester_domain.owner.balance == 900.0
def test_order_domain_renew_processed( self, mock_domain_check_create_update_renew, mock_domain_synchronize_from_backend): tester_domain = testsupport.prepare_tester_domain( domain_name='testdomain.%s' % settings.ZENAIDA_SUPPORTED_ZONES[0], add_contacts=[ 'registrant', 'admin', ], epp_id_dict={ 'registrant': 'ThisIDNotExist1', 'admin': 'ThisIDNotExist2', }, nameservers=[ 'notexist1.com', 'notexist2.com', ], ) tester_domain.owner.balance = 1000.0 tester_domain.owner.save() mock_domain_synchronize_from_backend.return_value = True mock_domain_check_create_update_renew.return_value = True order_object = orders.order_single_item( owner=tester_domain.owner, item_type='domain_renew', item_price=100.0, item_name='testdomain.ai', item_details={ 'some': 'details', }, ) assert len(order_object.items.all()) == 1 order_item = order_object.items.first() assert order_item.status == 'started' assert order_object.status == 'started' orders.execute_order(order_object) order_item.refresh_from_db() assert order_item.status == 'processed' assert order_object.status == 'processed' tester_domain.owner.refresh_from_db() assert tester_domain.owner.balance == 900.0
def _do_renew_on_behalf_of_customer(self, queryset): report = [] for domain_object in queryset: renewal_order = billing_orders.order_single_item( owner=domain_object.owner, item_type='domain_renew', item_price=settings.ZENAIDA_DOMAIN_PRICE, item_name=domain_object.name, ) if renewal_order.total_price > renewal_order.owner.balance: report.append('"%s": %s' % (domain_object.name, 'not enough funds')) continue new_status = billing_orders.execute_order(renewal_order) report.append('"%s": %s' % (domain_object.name, new_status)) return report
def post(self, request, *args, **kwargs): existing_order = billing_orders.get_order_by_id_and_owner( order_id=kwargs.get('order_id'), owner=request.user, log_action='execute') if existing_order.total_price > existing_order.owner.balance: messages.error(request, self.error_message_balance) return shortcuts.redirect('billing_new_payment') new_status = billing_orders.execute_order(existing_order) if new_status == 'processed': messages.success(request, self.success_message) elif new_status == 'processing': messages.success(request, self.processing_message) else: messages.error(request, self.error_message_technical) return shortcuts.redirect('account_domains')
def order_retry(self, request, queryset): results = [] for order_object in queryset: results.append('{}: {}'.format(order_object, orders.execute_order(order_object))) self.message_user(request, ', '.join(results))
def auto_renew_expiring_domains(dry_run=True, min_days_before_expire=60, max_days_before_expire=90): """ When customer enables "domain auto-renew" feature on "My Profile" page and possess enough account balance Zenaida must take care of his expiring domains and automatically renew them 3 months before the expiration date. The task is checking all expiring domains and for those which has enabled `auto_renew_enabled` flag performs such actions: 1. create a renew order on behalf of customer 2. execute the order right away if customer possess enough account balance 3. send a email notification to customer 4. if user do not have enough account balance, will send a "low_balance" notification 5. checks notifications history to keep only one "low_balance" email per 30 days if `dry_run` is True will only return a list of domains to be automatically renewed. """ moment_now = timezone.now() moment_min_days_before_expire = timezone.now() + datetime.timedelta( days=min_days_before_expire) moment_max_days_before_expire = timezone.now() + datetime.timedelta( days=max_days_before_expire) expiring_active_domains = Domain.domains.filter( expiry_date__gte=moment_min_days_before_expire, expiry_date__lte=moment_max_days_before_expire, status='active', ).exclude(epp_id=None, ) report = [] users_on_low_balance = {} for expiring_domain in expiring_active_domains: if not expiring_domain.auto_renew_enabled: continue if not expiring_domain.owner.profile.automatic_renewal_enabled: continue logger.debug('domain %r is expiring, going to start auto-renew now', expiring_domain.name) current_expiry_date = expiring_domain.expiry_date if expiring_domain.owner.balance < settings.ZENAIDA_DOMAIN_PRICE: # step 4: user is on low balance report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('not enough funds'), )) if expiring_domain.owner.email not in users_on_low_balance: users_on_low_balance[expiring_domain.owner.email] = [] users_on_low_balance[expiring_domain.owner.email].append( expiring_domain.name) logger.debug('not enough funds to auto-renew domain %r', expiring_domain.name) continue if billing_orders.find_pending_domain_renew_order_items( expiring_domain.name): logger.debug('domain renew order already started for %r', expiring_domain.name) continue if dry_run: report.append(( expiring_domain.name, expiring_domain.owner.email, current_expiry_date, )) continue # step 1: create domain renew order renewal_order = billing_orders.order_single_item( owner=expiring_domain.owner, item_type='domain_renew', item_price=settings.ZENAIDA_DOMAIN_PRICE, item_name=expiring_domain.name, item_details={ 'created_automatically': moment_now.isoformat(), }, ) # step 2: execute the order new_status = billing_orders.execute_order(renewal_order) expiring_domain.refresh_from_db() if new_status != 'processed': report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('renew order status is %s' % new_status, ), )) logger.info('for account %r renew order status is %r', expiring_domain.owner, new_status) continue if not expiring_domain.owner.profile.email_notifications_enabled: report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('email notifications are disabled', ), )) logger.info( 'skip "domain_renewed" notification, email notifications are disabled for account %r', expiring_domain.owner) continue # step 3: send a notification to the customer notifications.start_email_notification_domain_renewed( user=expiring_domain.owner, domain_name=expiring_domain.name, expiry_date=expiring_domain.expiry_date, old_expiry_date=current_expiry_date, ) report.append(( expiring_domain.name, expiring_domain.owner.email, expiring_domain.expiry_date, )) for one_user_email, user_domain_names in users_on_low_balance.items(): one_user = zusers.find_account(one_user_email) if not one_user.profile.email_notifications_enabled: report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('email notifications are disabled', ), )) logger.debug( 'skip "low_balance" notification, email notifications are disabled for account %r', expiring_domain.owner) continue recent_low_balance_notification = one_user.notifications.filter( subject='low_balance', created_at__gte=(moment_now - datetime.timedelta(days=30)), ).first() if recent_low_balance_notification: # step 5: found recent notification, skip report.append(( None, one_user.email, Exception('notification already sent recently'), )) logger.debug( 'skip "low_balance" notification, notification already sent recently for account %r', expiring_domain.owner) continue if dry_run: report.append(( None, one_user.email, True, )) continue notifications.start_email_notification_low_balance( one_user, expiring_domains_list=user_domain_names) return report