def delete_account(cls, auth_account_id: str) -> PaymentAccount: """Delete the payment account.""" current_app.logger.debug('<delete_account') pay_account: PaymentAccountModel = PaymentAccountModel.find_by_auth_account_id( auth_account_id) cfs_account: CfsAccountModel = CfsAccountModel.find_effective_by_account_id( pay_account.id) # 1 - Check if account have any credits # 2 - Check if account have any PAD transactions done in last N (10) days. if pay_account.credit and pay_account.credit > 0: raise BusinessException(Error.OUTSTANDING_CREDIT) # Check if account is frozen. cfs_status: str = cfs_account.status if cfs_account else None if cfs_status == CfsAccountStatus.FREEZE.value: raise BusinessException(Error.FROZEN_ACCOUNT) if InvoiceModel.find_outstanding_invoices_for_account( pay_account.id, get_outstanding_txns_from_date()): # Check if there is any recent PAD transactions in N days. raise BusinessException(Error.TRANSACTIONS_IN_PROGRESS) # If CFS Account present, mark it as INACTIVE. if cfs_status and cfs_status != CfsAccountStatus.INACTIVE.value: cfs_account.status = CfsAccountStatus.INACTIVE.value # If account is active or pending pad activation stop PAD payments. if pay_account.payment_method == PaymentMethod.PAD.value \ and cfs_status in [CfsAccountStatus.ACTIVE.value, CfsAccountStatus.PENDING_PAD_ACTIVATION.value]: CFSService.suspend_cfs_account(cfs_account) cfs_account.save() if pay_account.statement_notification_enabled: pay_account.statement_notification_enabled = False pay_account.save()
def _process_failed_payments(row): """Handle failed payments.""" # 1. Set the cfs_account status as FREEZE. # 2. Call cfs api to Stop further PAD on this account. # 3. Reverse the invoice_reference status to ACTIVE, invoice status to SETTLEMENT_SCHED, and delete receipt. # 4. Create an NSF invoice for this account. # 5. Create invoice reference for the newly created NSF invoice. # 6. Adjust invoice in CFS to include NSF fees. inv_number = _get_row_value(row, Column.TARGET_TXN_NO) # If there is a FAILED payment record for this; it means it's a duplicate event. Ignore it. payment: PaymentModel = PaymentModel.find_payment_by_invoice_number_and_status( inv_number, PaymentStatus.FAILED.value) if payment: logger.info('Ignoring duplicate NSF message for invoice : %s ', inv_number) return # Set CFS Account Status. payment_account: PaymentAccountModel = _get_payment_account(row) cfs_account: CfsAccountModel = CfsAccountModel.find_effective_by_account_id( payment_account.id) logger.info('setting payment account id : %s status as FREEZE', payment_account.id) cfs_account.status = CfsAccountStatus.FREEZE.value # Call CFS to stop any further PAD transactions on this account. CFSService.suspend_cfs_account(cfs_account) # Find the invoice_reference for this invoice and mark it as ACTIVE. inv_references: List[InvoiceReferenceModel] = db.session.query(InvoiceReferenceModel). \ filter(InvoiceReferenceModel.status_code == InvoiceReferenceStatus.COMPLETED.value). \ filter(InvoiceReferenceModel.invoice_number == inv_number). \ all() # Update status to ACTIVE, if it was marked COMPLETED for inv_reference in inv_references: inv_reference.status_code = InvoiceReferenceStatus.ACTIVE.value # Find receipt and delete it. receipt: ReceiptModel = ReceiptModel.find_by_invoice_id_and_receipt_number( invoice_id=inv_reference.invoice_id) if receipt: db.session.delete(receipt) # Find invoice and update the status to SETTLEMENT_SCHED invoice: InvoiceModel = InvoiceModel.find_by_id( identifier=inv_reference.invoice_id) invoice.invoice_status_code = InvoiceStatus.SETTLEMENT_SCHEDULED.value invoice.paid = 0 # Create an invoice for NSF for this account invoice = _create_nsf_invoice(cfs_account, inv_number, payment_account) # Adjust CFS invoice CFSService.add_nsf_adjustment(cfs_account=cfs_account, inv_number=inv_number, amount=invoice.total)