Example #1
0
def create_cfs_account(cfs_account: CfsAccountModel,
                       pay_account: PaymentAccountModel):
    """Create CFS account for routing slip."""
    routing_slip: RoutingSlipModel = RoutingSlipModel.find_by_payment_account_id(
        pay_account.id)
    try:
        # TODO add status check so that LINKED etc can be skipped.
        # for RS , entity/business number=party name ; RS Number=site name
        cfs_account_details: Dict[str, any] = CFSService.create_cfs_account(
            identifier=pay_account.name,
            contact_info={},
            site_name=routing_slip.number,
            is_fas=True)
        cfs_account.cfs_account = cfs_account_details.get('account_number')
        cfs_account.cfs_party = cfs_account_details.get('party_number')
        cfs_account.cfs_site = cfs_account_details.get('site_number')
        cfs_account.status = CfsAccountStatus.ACTIVE.value
        # Create receipt in CFS for the payment.
        CFSService.create_cfs_receipt(
            cfs_account=cfs_account,
            rcpt_number=routing_slip.number,
            rcpt_date=routing_slip.routing_slip_date.strftime('%Y-%m-%d'),
            amount=routing_slip.total,
            payment_method=pay_account.payment_method,
            access_token=CFSService.get_fas_token().json().get('access_token'))
        cfs_account.commit()
        return

    except Exception as e:  # NOQA # pylint: disable=broad-except

        capture_message(
            f'Error on creating Routing Slip CFS Account: account id={pay_account.id}, '
            f'auth account : {pay_account.auth_account_id}, ERROR : {str(e)}',
            level='error')
        current_app.logger.error(e)
        cfs_account.rollback()
        return
Example #2
0
    def create_accounts(cls):  # pylint: disable=too-many-locals
        """Find all pending accounts to be created in CFS.

        Steps:
        1. Find all pending CFS accounts.
        2. Create CFS accounts.
        3. Publish a message to the queue if successful.
        """
        # Pass payment method if offline account creation has be restricted based on payment method.
        pending_accounts: List[
            CfsAccountModel] = CfsAccountModel.find_all_pending_accounts()
        current_app.logger.info(
            f'Found {len(pending_accounts)} CFS Accounts to be created.')
        if len(pending_accounts) == 0:
            return

        auth_token = get_token()

        for pending_account in pending_accounts:
            # Find the payment account and create the pay system instance.
            pay_account: PaymentAccountModel = PaymentAccountModel.find_by_id(
                pending_account.account_id)

            # If PAD Account creation in CFS is paused, then just continue
            # TODO Remove once PAD account bugs are fixed and stable on CAS side.
            if current_app.config.get('CFS_STOP_PAD_ACCOUNT_CREATION') and \
                    pay_account.payment_method == PaymentMethod.PAD.value:
                current_app.logger.info(
                    'Continuing to next record as CFS PAD account creation is stopped.'
                )
                continue

            current_app.logger.info(
                f'Creating pay system instance for {pay_account.payment_method} for account {pay_account.id}.'
            )

            account_contact = cls._get_account_contact(
                auth_token, pay_account.auth_account_id)

            contact_info: Dict[str, str] = {
                'city': account_contact.get('city'),
                'postalCode': account_contact.get('postalCode'),
                'province': account_contact.get('region'),
                'addressLine1': account_contact.get('street'),
                'country': account_contact.get('country')
            }

            payment_info: Dict[str, any] = {
                'bankInstitutionNumber': pending_account.bank_number,
                'bankTransitNumber': pending_account.bank_branch_number,
                'bankAccountNumber': pending_account.bank_account_number,
            }

            account_name = pay_account.auth_account_name
            # For an existing CFS Account, call update.. This is to handle PAD update when CFS is offline
            try:
                if pending_account.cfs_account and pending_account.cfs_party and pending_account.cfs_site:
                    # This means, PAD account details have changed. So update banking details for this CFS account
                    bank_details = CFSService.update_bank_details(
                        name=account_name,
                        party_number=pending_account.cfs_party,
                        account_number=pending_account.cfs_account,
                        site_number=pending_account.cfs_site,
                        payment_info=payment_info)
                    pending_account.payment_instrument_number = bank_details.get(
                        'payment_instrument_number', None)
                else:  # It's a new account, now create
                    # If the account have banking information, then create a PAD account else a regular account.
                    if pending_account.bank_number and pending_account.bank_branch_number \
                            and pending_account.bank_account_number:
                        cfs_account_details = CFSService.create_cfs_account(
                            name=account_name,
                            contact_info=contact_info,
                            payment_info=payment_info,
                            receipt_method=RECEIPT_METHOD_PAD_DAILY)
                    else:
                        cfs_account_details = CFSService.create_cfs_account(
                            name=account_name,
                            contact_info=contact_info,
                            receipt_method=None)

                    pending_account.payment_instrument_number = cfs_account_details.get(
                        'payment_instrument_number', None)
                    pending_account.cfs_account = cfs_account_details.get(
                        'account_number')
                    pending_account.cfs_site = cfs_account_details.get(
                        'site_number')
                    pending_account.cfs_party = cfs_account_details.get(
                        'party_number')

            except Exception as e:  # NOQA # pylint: disable=broad-except
                # publish to mailer queue.
                mailer.publish_mailer_events('PadSetupFailed', pay_account)
                capture_message(
                    f'Error on creating CFS Account: account id={pay_account.id}, '
                    f'auth account : {pay_account.auth_account_id}, ERROR : {str(e)}',
                    level='error')
                current_app.logger.error(e)
                pending_account.rollback()
                # pending_account.status = CfsAccountStatus.INACTIVE.value
                # pending_account.save()
                continue

            # If the account has an activation time set ,
            # before that it shud be set to the  PENDING_PAD_ACTIVATION status.
            is_account_in_pad_confirmation_period = pay_account.pad_activation_date is not None and \
                pay_account.pad_activation_date > datetime.today()
            pending_account.status = CfsAccountStatus.PENDING_PAD_ACTIVATION.value if \
                is_account_in_pad_confirmation_period else CfsAccountStatus.ACTIVE.value
            pending_account.save()
Example #3
0
    def _create_cfs_account(cls, pending_account: CfsAccountModel,
                            pay_account: PaymentAccountModel, auth_token: str):
        # If PAD Account creation in CFS is paused, then just continue
        # TODO Remove once PAD account bugs are fixed and stable on CAS side.
        if current_app.config.get('CFS_STOP_PAD_ACCOUNT_CREATION') and \
                pay_account.payment_method == PaymentMethod.PAD.value:
            current_app.logger.info(
                'Continuing to next record as CFS PAD account creation is stopped.'
            )
            return

        current_app.logger.info(
            f'Creating pay system instance for {pay_account.payment_method} for account {pay_account.id}.'
        )

        # For an existing CFS Account, call update.. This is to handle PAD update when CFS is offline
        try:
            account_contact = cls._get_account_contact(
                auth_token, pay_account.auth_account_id)

            contact_info: Dict[str, str] = {
                'city': account_contact.get('city'),
                'postalCode': account_contact.get('postalCode'),
                'province': account_contact.get('region'),
                'addressLine1': account_contact.get('street'),
                'country': account_contact.get('country')
            }

            payment_info: Dict[str, any] = {
                'bankInstitutionNumber': pending_account.bank_number,
                'bankTransitNumber': pending_account.bank_branch_number,
                'bankAccountNumber': pending_account.bank_account_number,
                'bankAccountName': pay_account.name
            }

            if pending_account.cfs_account and pending_account.cfs_party and pending_account.cfs_site:
                # This means, PAD account details have changed. So update banking details for this CFS account
                bank_details = CFSService.update_bank_details(
                    name=pay_account.auth_account_id,
                    party_number=pending_account.cfs_party,
                    account_number=pending_account.cfs_account,
                    site_number=pending_account.cfs_site,
                    payment_info=payment_info)
                pending_account.payment_instrument_number = bank_details.get(
                    'payment_instrument_number', None)
            else:  # It's a new account, now create
                # If the account have banking information, then create a PAD account else a regular account.
                if pending_account.bank_number and pending_account.bank_branch_number \
                        and pending_account.bank_account_number:
                    cfs_account_details = CFSService.create_cfs_account(
                        identifier=pay_account.auth_account_id,
                        contact_info=contact_info,
                        payment_info=payment_info,
                        receipt_method=RECEIPT_METHOD_PAD_DAILY)
                else:
                    cfs_account_details = CFSService.create_cfs_account(
                        identifier=pay_account.auth_account_id,
                        contact_info=contact_info,
                        receipt_method=None)

                pending_account.payment_instrument_number = cfs_account_details.get(
                    'payment_instrument_number', None)
                pending_account.cfs_account = cfs_account_details.get(
                    'account_number')
                pending_account.cfs_site = cfs_account_details.get(
                    'site_number')
                pending_account.cfs_party = cfs_account_details.get(
                    'party_number')

        except Exception as e:  # NOQA # pylint: disable=broad-except
            # publish to mailer queue.
            is_user_error = False
            if pay_account.payment_method == PaymentMethod.PAD.value:
                is_user_error = CreateAccountTask._check_user_error(e.response)  # pylint: disable=no-member
            capture_message(
                f'Error on creating CFS Account: account id={pay_account.id}, '
                f'auth account : {pay_account.auth_account_id}, ERROR : {str(e)}',
                level='error')
            current_app.logger.error(e)
            pending_account.rollback()

            if is_user_error:
                capture_message(
                    f'User Input needed for creating CFS Account: account id={pay_account.id}, '
                    f'auth account : {pay_account.auth_account_id}, ERROR : Invalid Bank Details',
                    level='error')
                mailer.publish_mailer_events('PadSetupFailed', pay_account)
                pending_account.status = CfsAccountStatus.INACTIVE.value
                pending_account.save()
            return

        # If the account has an activation time set ,
        # before that it shud be set to the  PENDING_PAD_ACTIVATION status.
        is_account_in_pad_confirmation_period = pay_account.pad_activation_date is not None and \
            pay_account.pad_activation_date > datetime.today()
        pending_account.status = CfsAccountStatus.PENDING_PAD_ACTIVATION.value if \
            is_account_in_pad_confirmation_period else CfsAccountStatus.ACTIVE.value
        pending_account.save()