Exemplo n.º 1
0
def redeem(order_number, user, allocations):
    """
    Settle payment for the passed set of account allocations

    Will raise UnableToTakePayment if any of the transfers is invalid
    """
    # First, we need to check if the allocations are still valid.  The accounts
    # may have changed status since the allocations were written to the
    # session.
    transfers = []
    destination = core.redemptions_account()
    for code, amount in allocations.items():
        try:
            account = Account.active.get(code=code)
        except Account.DoesNotExist:
            raise UnableToTakePayment(
                _("No active account found with code %s") % code)

        # We verify each transaction
        try:
            Transfer.objects.verify_transfer(
                account, destination, amount, user)
        except exceptions.AccountException as e:
            raise UnableToTakePayment(str(e))

        transfers.append((account, destination, amount))

    # All transfers verified, now redeem
    for account, destination, amount in transfers:
        facade.transfer(account, destination, amount,
                        user=user, merchant_reference=order_number,
                        description="Redeemed to pay for order %s" % order_number)
Exemplo n.º 2
0
def redeem(order_number, user, allocations):
    """
    Settle payment for the passed set of account allocations

    Will raise UnableToTakePayment if any of the transfers is invalid
    """
    # First, we need to check if the allocations are still valid.  The accounts
    # may have changed status since the allocations were written to the
    # session.
    transfers = []
    destination = core.redemptions_account()
    for code, amount in allocations.items():
        try:
            account = Account.active.get(code=code)
        except Account.DoesNotExist:
            raise UnableToTakePayment(
                _("No active account found with code %s") % code)

        # We verify each transaction
        try:
            Transfer.objects.verify_transfer(
                account, destination, amount, user)
        except exceptions.AccountException as e:
            raise UnableToTakePayment(str(e))

        transfers.append((account, destination, amount))

    # All transfers verified, now redeem
    for account, destination, amount in transfers:
        facade.transfer(account, destination, amount,
                        user=user, merchant_reference=order_number,
                        description="Redeemed to pay for order %s" % order_number)
Exemplo n.º 3
0
def create_giftcard(order_number, user, amount):
    source = core.paid_source_account()
    code = codes.generate()
    destination = Account.objects.create(
        code=code
    )
    facade.transfer(source, destination, amount, user,
                    "Create new account")
Exemplo n.º 4
0
def create_giftcard(order_number, user, amount):
    source = core.paid_source_account()
    code = codes.generate()
    destination = Account.objects.create(
        code=code
    )
    facade.transfer(source, destination, amount, user,
                    "Create new account")
Exemplo n.º 5
0
 def test_account_exception_raised_for_runtime_error(self):
     user = UserFactory()
     source = AccountFactory(credit_limit=None)
     destination = AccountFactory()
     with mock.patch('oscar_accounts.abstract_models.PostingManager._wrap') as mock_method:
         mock_method.side_effect = RuntimeError()
         with self.assertRaises(exceptions.AccountException):
             facade.transfer(source, destination, D('100'), user)
 def test_account_exception_raised_for_runtime_error(self):
     user = UserFactory()
     source = AccountFactory(credit_limit=None)
     destination = AccountFactory()
     with mock.patch('oscar_accounts.abstract_models.PostingManager._wrap') as mock_method:
         mock_method.side_effect = RuntimeError()
         with self.assertRaises(exceptions.AccountException):
             facade.transfer(source, destination, D('100'), user)
 def test_no_transaction_created_when_exception_raised(self):
     user = UserFactory()
     source = AccountFactory(credit_limit=None)
     destination = AccountFactory()
     with mock.patch('oscar_accounts.abstract_models.PostingManager._wrap') as mock_method:
         mock_method.side_effect = RuntimeError()
         try:
             facade.transfer(source, destination, D('100'), user)
         except Exception:
             pass
     self.assertEqual(0, Transfer.objects.all().count())
     self.assertEqual(0, Transaction.objects.all().count())
Exemplo n.º 8
0
 def test_no_transaction_created_when_exception_raised(self):
     user = UserFactory()
     source = AccountFactory(credit_limit=None)
     destination = AccountFactory()
     with mock.patch('oscar_accounts.abstract_models.PostingManager._wrap') as mock_method:
         mock_method.side_effect = RuntimeError()
         try:
             facade.transfer(source, destination, D('100'), user)
         except Exception:
             pass
     self.assertEqual(0, Transfer.objects.all().count())
     self.assertEqual(0, Transaction.objects.all().count())
Exemplo n.º 9
0
 def form_valid(self, form):
     account = self.object
     amount = form.cleaned_data['amount']
     try:
         facade.transfer(form.get_source_account(), account, amount,
                         user=self.request.user,
                         description=_("Top-up account"))
     except exceptions.AccountException as e:
         messages.error(self.request,
                        _("Unable to top-up account: %s") % e)
     else:
         messages.success(
             self.request, _("%s added to account") % currency(amount))
     return http.HttpResponseRedirect(reverse('accounts_dashboard:accounts-detail',
                                              kwargs={'pk': account.id}))
 def form_valid(self, form):
     account = self.object
     amount = form.cleaned_data['amount']
     try:
         facade.transfer(form.get_source_account(), account, amount,
                         user=self.request.user,
                         description=_("Top-up account"))
     except exceptions.AccountException as e:
         messages.error(self.request,
                        _("Unable to top-up account: %s") % e)
     else:
         messages.success(
             self.request, _("%s added to account") % currency(amount))
     return http.HttpResponseRedirect(reverse('accounts-detail',
                                              kwargs={'pk': account.id}))
 def setUp(self):
     self.user = UserFactory()
     self.source = AccountFactory(credit_limit=None, primary_user=None)
     self.destination = AccountFactory()
     self.transfer = facade.transfer(
         self.source, self.destination, D('100'),
         user=self.user, description="Give money to customer")
Exemplo n.º 12
0
 def setUp(self):
     self.user = UserFactory()
     self.source = AccountFactory(credit_limit=None, primary_user=None)
     self.destination = AccountFactory()
     self.transfer = facade.transfer(
         self.source, self.destination, D('100'),
         user=self.user, description="Give money to customer")
Exemplo n.º 13
0
    def form_valid(self, form):
        # O formulario foi validado e o obj do type ferramenta foi criado
        self.object = form.save()
        ferramenta = self.object

        account = self._get_user_account(form)
        amount = ferramenta.value
        try:
            transfer = facade.transfer(
                self._get_source_account(),
                account,
                amount,
                user=form.cleaned_data.get("user"),
                description=_(f"Inserção da Ferramenta: {ferramenta.name}"),
            )
            ferramenta.transfer = transfer
            ferramenta.save()
        except exceptions.AccountException as e:
            messages.error(
                self.request,
                _("Tive um problema para inserir a sua ferramenta, procure o mario: %s"
                  ) % e,
            )
        else:
            messages.success(
                self.request,
                _("%s adicionado ao seu saldo") % currency(amount))

        return HttpResponseRedirect(self.get_success_url())
Exemplo n.º 14
0
    def valid_payload(self, payload):
        """
        Redeem an amount from the selected giftcard
        """
        account = get_object_or_404(Account, code=self.kwargs['code'])
        if not account.is_active():
            raise ValidationError(errors.ACCOUNT_INACTIVE)
        amt = payload['amount']
        if not account.is_debit_permitted(amt):
            raise ValidationError(errors.INSUFFICIENT_FUNDS)

        redemptions = Account.objects.get(code=names.REDEMPTIONS_CODE)
        try:
            transfer = facade.transfer(account,
                                       redemptions,
                                       amt,
                                       merchant_reference=payload.get(
                                           'merchant_reference', None))
        except exceptions.AccountException as e:
            return self.forbidden(code=errors.CANNOT_CREATE_TRANSFER,
                                  msg=e.message)
        return self.created(
            reverse('oscar_accounts_api:transfer',
                    kwargs={'reference': transfer.reference}),
            transfer.as_dict())
Exemplo n.º 15
0
def form_valid(form, request):
    # O formulario foi validado e o obj do type ferramenta foi criado
    object = form.save()
    ferramenta = object

    account = get_imported_user_account(form)
    amount = ferramenta.value
    try:
        transfer = facade.transfer(
            get_imported_source_account(),
            account,
            amount,
            user=form.cleaned_data.get("user"),
            description=
            _(f"Inserção da Ferramenta via arquivo de solicitações: {ferramenta.name}"
              ),
        )
        ferramenta.transfer = transfer
        ferramenta.save()
    except exceptions.AccountException as e:
        messages.error(
            resquest,
            _("Tive um problema para processar o arquivo de solicitação, procure o mario: %s"
              ) % e,
        )
    else:
        messages.success(
            request,
            _("%s adicionado ao seu saldo via arquivo de solicitações") %
            currency(amount))

    return render(request, 'import.html')
Exemplo n.º 16
0
 def valid_payload(self, payload):
     to_refund = get_object_or_404(Transfer,
                                   reference=self.kwargs['reference'])
     amount = payload['amount']
     max_refund = to_refund.max_refund()
     if amount > max_refund:
         return self.forbidden(
             ("Refund not permitted: maximum refund permitted "
              "is %.2f") % max_refund)
     if not to_refund.source.is_active():
         raise ValidationError(errors.ACCOUNT_INACTIVE)
     try:
         transfer = facade.transfer(to_refund.destination,
                                    to_refund.source,
                                    payload['amount'],
                                    parent=to_refund,
                                    merchant_reference=payload.get(
                                        'merchant_reference', None))
     except exceptions.AccountException as e:
         return self.forbidden(code=errors.CANNOT_CREATE_TRANSFER,
                               msg=e.message)
     return self.created(
         reverse('oscar_accounts_api:transfer',
                 kwargs={'reference': transfer.reference}),
         transfer.as_dict())
Exemplo n.º 17
0
 def form_valid(self, form):
     account = self.object
     amount = form.cleaned_data['amount']
     try:
         facade.transfer(account,
                         form.get_source_account(),
                         amount,
                         user=self.request.user,
                         description=_("Return funds to source account"))
     except exceptions.AccountException as e:
         messages.error(self.request,
                        _("Unable to withdraw funds from account: %s") % e)
     else:
         messages.success(self.request,
                          _("%s withdrawn from account") % currency(amount))
     return http.HttpResponseRedirect(
         reverse('accounts-detail', kwargs={'pk': account.id}))
Exemplo n.º 18
0
    def form_valid(self, form):
        account = form.save()

        # Load transaction
        source = form.get_source_account()
        amount = form.cleaned_data['initial_amount']
        try:
            facade.transfer(source, account, amount,
                            user=self.request.user,
                            description=_("Creation of account"))
        except exceptions.AccountException as e:
            messages.error(
                self.request,
                _("Account created but unable to load funds onto new "
                  "account: %s") % e)
        else:
            messages.success(
                self.request,
                _("New account created with code '%s'") % account.code)
        return http.HttpResponseRedirect(
            reverse('accounts_dashboard:accounts-detail', kwargs={'pk': account.id}))
    def form_valid(self, form):
        account = form.save()

        # Load transaction
        source = form.get_source_account()
        amount = form.cleaned_data['initial_amount']
        try:
            facade.transfer(source, account, amount,
                            user=self.request.user,
                            description=_("Creation of account"))
        except exceptions.AccountException as e:
            messages.error(
                self.request,
                _("Account created but unable to load funds onto new "
                  "account: %s") % e)
        else:
            messages.success(
                self.request,
                _("New account created with code '%s'") % account.code)
        return http.HttpResponseRedirect(
            reverse('accounts-detail', kwargs={'pk': account.id}))
Exemplo n.º 20
0
    def reconcile(self, user=None):
        # Perform a transfer to make the account balance match WF. This will overtime
        # mirror customer payments into Wells Fargo (that we don't have notifications of)
        balance_wf = -(self.balance)
        balance_us = self.account.balance
        balance_change = balance_wf - balance_us
        if balance_change != Decimal('0.00'):
            logger.info('Reconciling balance offset of %s on account %s' % (balance_change, self.account))
            facade.transfer(
                description=_('Automatic compensating transaction during reconciliation with Wells Fargo Retail Services.'),
                source=Account.objects.get(name=names.BANK),
                destination=self.account,
                amount=balance_change,
                user=user)
        else:
            logger.info('Reconciliation not needed. Recorded balance matches WFRS records for account %s' % (self.account))

        assert self.account.balance == balance_wf

        # Adjust the credit limit to match WF. Should be equal to the sum of `balance` and `open_to_buy`
        self.account.credit_limit = (self.balance + self.open_to_buy)
        self.account.save()
Exemplo n.º 21
0
 def valid_payload(self, payload):
     account = get_object_or_404(Account, code=self.kwargs['code'])
     if not account.is_active():
         raise ValidationError(errors.ACCOUNT_INACTIVE)
     redemptions = Account.objects.get(name=names.REDEMPTIONS)
     try:
         transfer = facade.transfer(
             redemptions, account, payload['amount'],
             merchant_reference=payload.get('merchant_reference', None))
     except exceptions.AccountException as e:
         return self.forbidden(
             code=errors.CANNOT_CREATE_TRANSFER,
             msg=e.message)
     return self.created(
         reverse('transfer', kwargs={'reference': transfer.reference}),
         transfer.as_dict())
Exemplo n.º 22
0
def submit_transaction(trans_request):
    client = soap.get_client(WFRS_TRANSACTION_WSDL, 'WFRS')

    request = client.factory.create('ns2:Transaction')
    request.userName = WFRS_USER_NAME
    request.setupPassword = WFRS_PASSWORD
    request.merchantNumber = WFRS_MERCHANT_NUM
    request.uuid = uuid.uuid1()
    request.transactionCode = trans_request.type_code
    request.localeString = trans_request.source_account.wfrs_metadata.locale
    request.accountNumber = trans_request.source_account.wfrs_metadata.account_number
    request.planNumber = trans_request.plan_number
    request.amount = _as_decimal(trans_request.amount)
    request.authorizationNumber = trans_request.auth_number
    request.ticketNumber = trans_request.ticket_number

    # Submit
    resp = client.service.submitTransaction(request)

    # Check for faults
    if resp.faults:
        for fault in resp.faults:
            logger.error(fault.faultDetailString)
            raise ValidationError(fault.faultDetailString)

    # Check for approval
    if resp.transactionStatus != TRANS_APPROVED:
        raise TransactionDenied('%s: %s' % (resp.transactionStatus, resp.transactionMessage))

    # Persist transaction data and WF specific metadata
    with transaction.atomic():
        transfer = facade.transfer(
            source=trans_request.source_account,
            destination=trans_request.dest_account,
            amount=_as_decimal(resp.amount),
            user=trans_request.user,
            merchant_reference=resp.uuid)
        TransferMetadata.objects.create(
            transfer=transfer,
            type_code=resp.transactionCode,
            ticket_number=resp.ticketNumber,
            plan_number=resp.planNumber,
            auth_number=resp.authorizationNumber,
            status=resp.transactionStatus,
            message=resp.transactionMessage,
            disclosure=resp.disclosure)
    return transfer
Exemplo n.º 23
0
def debit_tokens_from_user(user, amount):
    """Tranfer from user account to sink account."""
    # staff_member = User.objects.get(username="******")
    no_credit_limit_account_sink = None
    try:
        no_credit_limit_account_sink = models.Account.objects.get(
            name="sink_2016_no_limit")
    except models.Account.DoesNotExist:
        no_credit_limit_account_sink = create_no_limit_account(
            "sink_2016_no_limit")

    user_account = models.Account.objects.get(
        primary_user=user, account_type__name=django_settings.TOKEN_ACCOUNT)

    trans = facade.transfer(
        source=user_account,
        destination=no_credit_limit_account_sink,
        amount=amount,
    )

    return trans
Exemplo n.º 24
0
def credit_to_reimbursement_account(user, amount, merchant_reference=None):

    no_credit_limit_account_source = None
    try:
        no_credit_limit_account_source = models.Account.objects.get(
            name="source_2016_no_limit")
    except models.Account.DoesNotExist:
        no_credit_limit_account_source = create_no_limit_account(
            "source_2016_no_limit")

    user_account = models.Account.objects.get(
        primary_user=user,
        account_type__name=django_settings.REIMBURSEMENT_ACCOUNT)
    if not Transfer.objects.filter(
            merchant_reference=merchant_reference).exists():
        trans = facade.transfer(source=no_credit_limit_account_source,
                                destination=user_account,
                                amount=amount,
                                merchant_reference=merchant_reference)

        return trans
Exemplo n.º 25
0
    def valid_payload(self, payload):
        """
        Redeem an amount from the selected giftcard
        """
        account = get_object_or_404(Account, code=self.kwargs['code'])
        if not account.is_active():
            raise ValidationError(errors.ACCOUNT_INACTIVE)
        amt = payload['amount']
        if not account.is_debit_permitted(amt):
            raise ValidationError(errors.INSUFFICIENT_FUNDS)

        redemptions = Account.objects.get(name=names.REDEMPTIONS)
        try:
            transfer = facade.transfer(
                account, redemptions, amt,
                merchant_reference=payload.get('merchant_reference', None))
        except exceptions.AccountException as e:
            return self.forbidden(
                code=errors.CANNOT_CREATE_TRANSFER,
                msg=e.message)
        return self.created(
            reverse('transfer', kwargs={'reference': transfer.reference}),
            transfer.as_dict())
Exemplo n.º 26
0
 def valid_payload(self, payload):
     to_refund = get_object_or_404(Transfer,
                                   reference=self.kwargs['reference'])
     amount = payload['amount']
     max_refund = to_refund.max_refund()
     if amount > max_refund:
         return self.forbidden(
             ("Refund not permitted: maximum refund permitted "
              "is %.2f") % max_refund)
     if not to_refund.source.is_active():
         raise ValidationError(errors.ACCOUNT_INACTIVE)
     try:
         transfer = facade.transfer(
             to_refund.destination, to_refund.source,
             payload['amount'], parent=to_refund,
             merchant_reference=payload.get('merchant_reference', None))
     except exceptions.AccountException as e:
         return self.forbidden(
             code=errors.CANNOT_CREATE_TRANSFER,
             msg=e.message)
     return self.created(
         reverse('transfer', kwargs={'reference': transfer.reference}),
         transfer.as_dict())
Exemplo n.º 27
0
def credit_tokens_for_user(user, amount):
    """Tranfer from system wide accoutn to user account.

    Ideally this wiil be called after payment success by user.
    """
    # staff_member = User.objects.get(username="******")
    no_credit_limit_account_source = None
    try:
        no_credit_limit_account_source = models.Account.objects.get(
            name="source_2016_no_limit")
    except models.Account.DoesNotExist:
        no_credit_limit_account_source = create_no_limit_account(
            "source_2016_no_limit")

    user_account = models.Account.objects.get(
        primary_user=user, account_type__name=django_settings.TOKEN_ACCOUNT)

    trans = facade.transfer(
        source=no_credit_limit_account_source,
        destination=user_account,
        amount=amount,
    )

    return trans
Exemplo n.º 28
0
 def load_account(self, account, payload):
     bank = Account.objects.get(name=names.BANK)
     facade.transfer(bank, account, payload['amount'],
                     description="Load from bank")
Exemplo n.º 29
0
    def test_reconcilation(self):
        source = self._build_account('9999999999999991')
        dest = core.redemptions_account()

        # Test initial state of the account
        self.assertEqual(source.credit_limit, Decimal('7500.00'))
        self.assertEqual(source.balance, Decimal('0.00'))

        # Buy something
        facade.transfer(
            source=source,
            destination=dest,
            amount=Decimal('999.99'))

        # Check account balance
        self.assertEqual(source.credit_limit, Decimal('7500.00'))
        self.assertEqual(source.balance, Decimal('-999.99'))

        # Build a fake inquiry response that shows they haven't paid anything yet
        inquiry = AccountInquiryResult()
        inquiry.account = source
        inquiry.balance = Decimal('999.99')
        inquiry.open_to_buy = Decimal('6500.01')
        inquiry.reconcile()

        # Check account balance
        self.assertEqual(source.credit_limit, Decimal('7500.00'))
        self.assertEqual(source.balance, Decimal('-999.99'))

        # Customer made a payment
        inquiry = AccountInquiryResult()
        inquiry.account = source
        inquiry.balance = Decimal('800.00')
        inquiry.open_to_buy = Decimal('6700.00')
        inquiry.reconcile()

        # Check account balance
        self.assertEqual(source.credit_limit, Decimal('7500.00'))
        self.assertEqual(source.balance, Decimal('-800.00'))

        # Wells Fargo lowered the Customer's credit limit
        inquiry = AccountInquiryResult()
        inquiry.account = source
        inquiry.balance = Decimal('800.00')
        inquiry.open_to_buy = Decimal('6000.00')
        inquiry.reconcile()

        # Check account balance
        self.assertEqual(source.credit_limit, Decimal('6800.00'))
        self.assertEqual(source.balance, Decimal('-800.00'))

        # Wells Fargo lowered the Customer's credit limit again and the customer made a payment
        inquiry = AccountInquiryResult()
        inquiry.account = source
        inquiry.balance = Decimal('700.00')
        inquiry.open_to_buy = Decimal('5000.00')
        inquiry.reconcile()

        # Check account balance
        self.assertEqual(source.credit_limit, Decimal('5700.00'))
        self.assertEqual(source.balance, Decimal('-700.00'))
Exemplo n.º 30
0
 def test_account_exception_raised_for_invalid_transfer(self):
     user = UserFactory()
     source = AccountFactory(credit_limit=D('0.00'))
     destination = AccountFactory()
     with self.assertRaises(exceptions.AccountException):
         facade.transfer(source, destination, D('100'), user)
Exemplo n.º 31
0
 def test_doesnt_explode(self):
     source = AccountFactory(credit_limit=None)
     destination = AccountFactory()
     facade.transfer(source, destination, D('1'))
 def test_account_exception_raised_for_invalid_transfer(self):
     user = UserFactory()
     source = AccountFactory(credit_limit=D('0.00'))
     destination = AccountFactory()
     with self.assertRaises(exceptions.AccountException):
         facade.transfer(source, destination, D('100'), user)
 def test_doesnt_explode(self):
     source = AccountFactory(credit_limit=None)
     destination = AccountFactory()
     facade.transfer(source, destination, D('1'))