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
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()
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()