Example #1
0
    def advance_invoice_link(self, obj):
        """
        Display advance invoice link.

        If there are any other invoices, number of remaining (not displayed)
        invoices is displayed as well.
        """
        advance_invoice = obj.advance_invoice
        invoices_count = obj.invoices.count()
        if advance_invoice is not None:
            processor = get_processor_instance(obj.processor)
            if hasattr(processor, 'get_invoice_url'):
                link = format_html('<a href="{}">{}</a>',
                                   processor.get_invoice_url(advance_invoice),
                                   advance_invoice.number)
            else:
                link = advance_invoice.number

            if invoices_count > 1:
                link = format_html('{}&nbsp;(+{})', link, invoices_count - 1)

            return link
        else:
            if invoices_count > 0:
                return '(+{})'.format(invoices_count)
            else:
                return ''
Example #2
0
    def _process_card_payments(payments):
        """Process the payments made by card."""
        if not payments:
            return

        LOGGER.info('Processing card payments.')
        # We sort the names for easier testing.
        processor_names = sorted(
            set(payment['processor']
                for payment in payments.values('processor')))
        for processor_name in processor_names:

            processor = get_processor_instance(processor_name)
            processors_payments = payments.filter(processor=processor_name)

            LOGGER.info('Processing card payments with processor %s.',
                        processor_name)
            results = processor.process_payments(
                deepcopy(payment) for payment in processors_payments)

            for payment, processed in zip_longest(processors_payments,
                                                  results):
                if processed.result:
                    payment.state = PaymentState.PROCESSED
                    payment.processing_error = processed.error
                    payment.save()
                else:
                    LOGGER.info('Saving payment %s as DEFERRED with error %s.',
                                payment.uuid, processed.error)
                    payment.state = PaymentState.DEFERRED
                    payment.processing_error = processed.error
                    payment.save()
Example #3
0
    def clean(self):
        """
        Check whether payment processor has been set.

        If so, assign payment to chosen payment processor and note the result.
        """
        cleaned_data = super().clean()
        if cleaned_data.get('processor'):
            # The only valid choices are those from PAIN_PROCESSORS settings.
            # Those are already validated during startup.
            processor = get_processor_instance(cleaned_data['processor'])
            kwargs = {}
            if processor.manual_tax_date:
                tax_date = cleaned_data.get('tax_date')
                if tax_date is None:
                    if 'tax_date' not in self.errors:
                        self.add_error('tax_date', _('This field is required'))
                    return
                kwargs['tax_date'] = tax_date
            try:
                result = processor.assign_payment(self.instance,
                                                  cleaned_data['client_id'],
                                                  **kwargs)
            except InvalidTaxDateError as error:
                self.add_error('tax_date', str(error))
            else:
                if result.result:
                    cleaned_data['state'] = PaymentState.PROCESSED
                    return cleaned_data
                else:
                    raise forms.ValidationError(_('Unable to assign payment'),
                                                code='unable_to_assign')
Example #4
0
 def objective_choices(self):
     """Return payment processor default objectives choices."""
     choices = BLANK_CHOICE_DASH.copy()
     for proc_name in SETTINGS.processors:
         proc = get_processor_instance(proc_name)
         choices.append((proc_name, proc.default_objective))
     return choices
Example #5
0
 def invoice_link(self, obj):
     """Return invoice link."""
     processor = get_processor_instance(obj.bankpayment.processor)
     if hasattr(processor, 'get_invoice_url'):
         return format_html('<a href="{}">{}</a>',
                            processor.get_invoice_url(obj.invoice),
                            obj.invoice.number)
     else:
         return obj.invoice.number
Example #6
0
def load_processor_client_choices(request):
    """Load client choices from the appropriate payment processor."""
    try:
        processor = get_processor_instance(request.GET.get('processor', ''))
    except ValueError:
        raise Http404

    if hasattr(processor, 'get_client_choices'):
        return JsonResponse(processor.get_client_choices())
    else:
        raise Http404
Example #7
0
def get_processors_options(request):
    """
    Get following processors options.

      * manual_tax_date
    """
    options = {}  # type: dict
    for proc_name in SETTINGS.processors:
        options[proc_name] = {}
        proc = get_processor_instance(proc_name)
        options[proc_name]['manual_tax_date'] = proc.manual_tax_date
    return JsonResponse(options)
Example #8
0
 def _process_payment(self, payment):
     processor = get_processor_instance(payment.processor)
     LOGGER.info('Processing card payment with processor %s.', processor)
     result = list(processor.process_payments([deepcopy(payment)]))[0]
     if result.result:
         payment.state = PaymentState.PROCESSED
     else:
         LOGGER.info('Saving payment %s as DEFERRED with error %s.',
                     payment.uuid, result.error)
         payment.state = PaymentState.DEFERRED
     payment.processing_error = result.error
     payment.save()
Example #9
0
 def client_link(self, obj):
     """Client link."""
     client = getattr(obj, 'client', None)
     if client is not None:
         processor = get_processor_instance(obj.processor)
         if hasattr(processor, 'get_client_url'):
             return format_html('<a href="{}">{}</a>',
                                processor.get_client_url(client),
                                client.handle)
         else:
             return client.handle
     else:
         return ''
Example #10
0
def create_permissions(app_config, **kwargs):
    """
    Create payment processor specific permissions.

    These permission depend on application settings.
    For every payment processor in PAIN_PROCESSORS
    there is one permission to manually assign payments to this processor.
    Codename of this permission is dependent on payment processor label in PAIN_PROCESSORS.
    """
    ContentType = apps.get_model('contenttypes', 'ContentType')
    Permission = apps.get_model('auth', 'Permission')
    BankPayment = app_config.get_model('BankPayment')
    content_type = ContentType.objects.get_for_model(BankPayment)

    for proc_name in SETTINGS.processors:
        proc = get_processor_instance(proc_name)
        Permission.objects.update_or_create(
            codename='can_manually_assign_to_{}'.format(proc_name),
            content_type=content_type,
            defaults={
                'name': 'Can manually assign to {}'.format(proc.default_objective),
            },
        )
Example #11
0
    def _process_transfer_payments(payments):
        """Process the payments made by bank transfer."""
        for processor_name in SETTINGS.processors:
            processor = get_processor_instance(processor_name)
            if not payments:
                break

            LOGGER.info('Processing payments with processor %s.',
                        processor_name)
            results = processor.process_payments(
                deepcopy(payment) for payment in payments)
            unprocessed_payments = []

            for payment, processed in zip_longest(payments, results):
                if processed.result:
                    payment.state = PaymentState.PROCESSED
                    payment.processor = processor_name
                    payment.processing_error = processed.error
                    payment.save()
                elif processed.error is not None:
                    LOGGER.info('Saving payment %s as DEFERRED with error %s.',
                                payment.uuid, processed.error)
                    payment.state = PaymentState.DEFERRED
                    payment.processor = processor_name
                    payment.processing_error = processed.error
                    payment.save()
                else:
                    unprocessed_payments.append(payment)

            payments = unprocessed_payments

        LOGGER.info('Marking %s unprocessed payments as DEFERRED.',
                    len(payments))
        for unprocessed_payment in payments:
            unprocessed_payment.state = PaymentState.DEFERRED
            unprocessed_payment.save()
Example #12
0
 def test_success(self):
     """Test success."""
     self.assertIsInstance(
         get_processor_instance('dummy'),
         DummyPaymentProcessor
     )