예제 #1
0
    def check_order(self, order):
        max_transaction = self.get_transaction_from_order(order=order)
        manual_review_score = getattr(order.client.billing_settings,
                                      'maxmind_manual_review_score', 30)
        maxmind_fraud_score = getattr(order.client.billing_settings,
                                      'maxmind_fraud_score', 60)
        insights_enabled = getattr(order.client.billing_settings,
                                   'enable_maxmind_insights', True)
        try:
            if insights_enabled:
                max_score = self.maxclient.insights(
                    transaction=max_transaction)
            else:
                max_score = self.maxclient.score(transaction=max_transaction)
        except errors.InvalidRequestError as e:
            LOG.exception(e)
            return FraudResultStatus.ACCEPT
        else:
            # Add fraud check results to order as key value pairs
            if insights_enabled:
                order.fraud_check_result = self.get_fraud_results_from_insights(
                    max_score)
            else:
                order.fraud_check_result = self.get_fraud_results_from_score(
                    max_score)
            order.save(update_fields=['fraud_check_result'])
            # Check disposition (custom maxmind rules):
            if max_score.disposition and max_score.disposition.action is not None:
                if max_score.disposition.action == DispositionResult.ACCEPT:
                    return FraudResultStatus.ACCEPT
                elif max_score.disposition.action == DispositionResult.MANUAL_REVIEW:
                    plugin_dispatcher.call_function(
                        'todo',
                        'create_todo',
                        title=_('Manual review needed for order {}').format(
                            order),
                        description=
                        _('Order {} may be fraudulent. Manual review is needed.'
                          ).format(order),
                    )
                    return FraudResultStatus.MANUAL_REVIEW
                elif max_score.disposition.action == DispositionResult.REJECT:
                    plugin_dispatcher.call_function(
                        'todo',
                        'create_todo',
                        title=_('Order {} rejected').format(order),
                        description=
                        _('Order {} may be fraudulent. Manual review is needed.'
                          ).format(order),
                    )
                    return FraudResultStatus.REJECT

            # Check main risk score
            elif max_score.risk_score >= manual_review_score < maxmind_fraud_score:
                return FraudResultStatus.MANUAL_REVIEW
            elif max_score.risk_score >= maxmind_fraud_score:
                return FraudResultStatus.REJECT
            return FraudResultStatus.ACCEPT
    def update_nameservers(domain: Domain):
        plugin_dispatcher.call_function(
            'todo',
            'create_todo',
            title=_('Nameservers updated for domain {}').format(domain.name),
            description=_('Nameservers have been updated for domain {}.').format(domain.name),
        )

        return True
    def set_whois_data(self, domain: Domain, whois_data: List[WhoisField]) -> Tuple[bool, str]:
        plugin_dispatcher.call_function(
            'todo',
            'create_todo',
            title=_('Whois data updated for domain {}').format(domain.name),
            description=_('Whois data for domain {} was updated to: \n{}.').format(
                domain.name,
                '\n'.join([str(whois_field) for whois_field in whois_data])
            ),
        )

        return True, _('Whois data updated')
    def registrar_unlock(domain: Domain):
        if domain.status != DomainStatus.active and domain.registrar_locked:
            return False

        domain.registrar_locked = False
        domain.save()

        plugin_dispatcher.call_function(
            'todo',
            'create_todo',
            title=_('Registrar lock deactivated for domain {}').format(domain.name),
            description=_('Registrar lock has been deactivated for domain {}.').format(domain.name),
        )

        return True
    def transfer_domain(domain: Domain):
        if domain.status != DomainStatus.pending_transfer:
            return False

        domain.status = DomainStatus.active
        domain.save()

        plugin_dispatcher.call_function(
            'todo',
            'create_todo',
            title=_('New domain transfer {} order').format(domain.name),
            description=_('A new order to transfer domain {} has been placed.').format(domain.name),
        )

        return True
    def renew_domain(domain: Domain):
        if domain.status != DomainStatus.active:
            return False

        domain.expiry_date = domain.expiry_date + relativedelta(years=domain.registration_period)
        domain.status = DomainStatus.active
        domain.save()

        plugin_dispatcher.call_function(
            'todo',
            'create_todo',
            title=_('New domain renew {} order').format(domain.name),
            description=_('A new order to renew domain {} has been placed.').format(domain.name),
        )

        return True
예제 #7
0
def process_paid_invoice(invoice_id, **kwargs):
    """When an invoice is completely paid, we process all items"""
    with transaction.atomic():
        invoice = Invoice.objects.select_for_update().get(id=invoice_id)
        # TODO(tomo): Check if invoice.processed_at is not None and raise (meaning it was already processed) ?
        services_tasks = list()
        for item in invoice.items.prefetch_related(
                'service',
                'service__product').filter(item_type=BillingItemTypes.service,
                                           service__isnull=False):
            # Update the next due date on active services
            if item.service.status == ServiceStatus.active:
                item.service.update_next_due_date()
            # Run create on new services if enabled or just update the next due date
            elif item.service.status == ServiceStatus.pending:
                item.service.update_next_due_date()
                # FIXME(tomo): if the service remains in pending for 1 cycle, what happens with it if unpaid
                # or if paid after 2 cycles ?
                if (item.service.product.auto_setup
                        == ProductAutoSetup.on_first_payment
                        and item.service.activated_at is None):
                    services_tasks.append(
                        create_service.s(item.service.pk,
                                         user_id=kwargs.get('user_id')))
                elif (item.service.product.auto_setup
                      == ProductAutoSetup.on_order
                      and item.service.activated_at is None):
                    # Create services for items that have auto setup on order
                    services_tasks.append(
                        create_service.s(item.service.pk,
                                         user_id=kwargs.get('user_id')))
            # Resume suspended services
            elif (item.service.status == ServiceStatus.suspended
                  and item.service.suspend_type == ServiceSuspendType.overdue):
                # NOTE(tomo): Make sure the service does not have any other unpaid invoices before calling resume
                if Invoice.objects.for_service(
                        service=item.service).unpaid().count() == 0:
                    item.service.update_next_due_date()
                    services_tasks.append(
                        resume_service.s(item.service.id,
                                         user_id=kwargs.get('user_id')))
        # Process upgrade service items
        for item in invoice.items.prefetch_related(
                'service', 'product',
                'cycle').filter(item_type=BillingItemTypes.serviceUpgrade,
                                service__isnull=False):
            item.service.task = ServiceTask.changeInProgress
            item.service.save(update_fields=['task'])
            configurable_options = item.configurable_options.values(
                'option', 'option_value', 'quantity', 'has_price', 'taxable',
                'unit_price', 'price', 'setup_fee')

            if item.service.product == item.product:
                services_tasks.append(
                    change_cycle_service.s(
                        service_id=item.service.id,
                        cycle_id=item.cycle.pk,
                        configurable_options=configurable_options))
            else:
                services_tasks.append(
                    change_product_service.s(
                        service_id=item.service.id,
                        product_id=item.product.pk,
                        cycle_id=item.cycle.pk,
                        configurable_options=configurable_options))

        if len(services_tasks):
            transaction.on_commit(
                lambda: celery.group(services_tasks).apply_async())

        # Add to credit balance
        for item in invoice.items.filter(item_type=BillingItemTypes.credit):
            # NOTE(tomo): Process all items containing credit balance additions
            item_total = item.amount
            client_credit_account = invoice.client.credits.deposit(
                client=invoice.client,
                currency=invoice.currency,
                amount=item_total)
            invoice.journalentries.create(
                client_credit=client_credit_account,
                transaction=None,
                source=JournalSources.invoice,
                destination=JournalSources.credit,
                source_currency=invoice.currency,
                destination_currency=invoice.currency,
                destination_amount=item_total,
                source_amount=item_total,
                partial=False)
        invoice.processed_at = now()
        invoice.save()

        InvoiceUtils.settle_dynamic_price_for_invoice(invoice)

        if kwargs.get('create_todo', False):
            plugin_dispatcher.call_function(
                'todo',
                'create_todo',
                title=_('Invoice {} payment added').format(invoice.id),
                description=_(
                    'Invoice {} for client {} has been paid.').format(
                        invoice.id,
                        invoice.client.id,
                    ),
            )