async def _create_payment_record(amount, ejv_header, receipt_number): """Create payment record.""" PaymentModel(payment_system_code=PaymentSystem.CGI.value, payment_account_id=ejv_header.payment_account_id, payment_method_code=PaymentMethod.EJV.value, payment_status_code=PaymentStatus.COMPLETED.value, receipt_number=receipt_number, invoice_amount=amount, paid_amount=amount, completed_on=datetime.now()).flush()
def _save_payment( payment_date, inv_number, invoice_amount, # pylint: disable=too-many-arguments paid_amount, row, status, payment_method, receipt_number): # pylint: disable=import-outside-toplevel from pay_api.factory.payment_system_factory import PaymentSystemFactory payment_account = _get_payment_account(row) pay_service = PaymentSystemFactory.create_from_payment_method( payment_method) # If status is failed, which means NSF. We already have a COMPLETED payment record, find and update iit. payment: PaymentModel = None if status == PaymentStatus.FAILED.value: payment = _get_payment_by_inv_number_and_status( inv_number, PaymentStatus.COMPLETED.value) # Just to handle duplicate rows in settlement file, # pull out failed payment record if it exists and no COMPLETED payments are present. if not payment: payment = _get_payment_by_inv_number_and_status( inv_number, PaymentStatus.FAILED.value) elif status == PaymentStatus.COMPLETED.value: # if the payment status is COMPLETED, then make sure there are # no other COMPLETED payment for same invoice_number.If found, return. This is to avoid duplicate entries. payment = _get_payment_by_inv_number_and_status( inv_number, PaymentStatus.COMPLETED.value) if payment: return if not payment: payment = PaymentModel() payment.payment_method_code = pay_service.get_payment_method_code() payment.payment_status_code = status payment.payment_system_code = pay_service.get_payment_system_code() payment.invoice_number = inv_number payment.invoice_amount = invoice_amount payment.payment_account_id = payment_account.id payment.payment_date = payment_date payment.paid_amount = paid_amount payment.receipt_number = receipt_number db.session.add(payment)
def _dao(self): if not self.__dao: self.__dao = PaymentModel() return self.__dao
def create(cls, request_json: Dict[str, any], **kwargs): """Search for routing slip.""" # 1. Create customer profile in CFS and store it in payment_account and cfs_accounts # 2. Create receipt in CFS # 3. Create routing slip and payment records. rs_number = request_json.get('number') # Validate Routing slip digits and if slip number is unique. if cls.validate_and_find_by_number(rs_number): raise BusinessException(Error.FAS_INVALID_ROUTING_SLIP_NUMBER) payment_methods: [str] = [payment.get('paymentMethod') for payment in request_json.get('payments')] # all the payment should have the same payment method if len(set(payment_methods)) != 1: raise BusinessException(Error.FAS_INVALID_PAYMENT_METHOD) # If payment method is cheque and then there is no payment date then raise error if payment_methods[0] == PaymentMethod.CHEQUE.value: for payment in request_json.get('payments'): if payment.get('paymentDate') is None: raise BusinessException(Error.INVALID_REQUEST) pay_account: PaymentAccountModel = PaymentAccountModel( name=request_json.get('paymentAccount').get('accountName'), payment_method=payment_methods[0], ).flush() CfsAccountModel( account_id=pay_account.id, status=CfsAccountStatus.PENDING.value ).flush() total = get_quantized(sum(float(payment.get('paidAmount')) for payment in request_json.get('payments'))) # Calculate Total USD total_usd = get_quantized(sum(float(payment.get('paidUsdAmount', 0)) for payment in request_json.get('payments'))) # Create a routing slip record. routing_slip: RoutingSlipModel = RoutingSlipModel( number=rs_number, payment_account_id=pay_account.id, status=RoutingSlipStatus.ACTIVE.value, total=total, remaining_amount=total, routing_slip_date=string_to_date(request_json.get('routingSlipDate')), total_usd=total_usd ).flush() for payment in request_json.get('payments'): PaymentModel( payment_system_code=PaymentSystem.FAS.value, payment_account_id=pay_account.id, payment_method_code=payment.get('paymentMethod'), payment_status_code=PaymentStatus.COMPLETED.value, receipt_number=rs_number, cheque_receipt_number=payment.get('chequeReceiptNumber'), is_routing_slip=True, paid_amount=payment.get('paidAmount'), payment_date=string_to_date(payment.get('paymentDate')) if payment.get('paymentDate') else None, created_by=kwargs['user'].user_name, paid_usd_amount=payment.get('paidUsdAmount', None) ).flush() routing_slip.commit() return cls.find_by_number(rs_number)
async def test_credits(session, app, stan_server, event_loop, client_id, events_stan, future, mock_publish, monkeypatch): """Test Reconciliations worker.""" # Call back for the subscription from reconciliations.worker import cb_subscription_handler # Create a Credit Card Payment # register the handler to test it await subscribe_to_queue( events_stan, current_app.config.get('SUBSCRIPTION_OPTIONS').get('subject'), current_app.config.get('SUBSCRIPTION_OPTIONS').get('queue'), current_app.config.get('SUBSCRIPTION_OPTIONS').get('durable_name'), cb_subscription_handler) # 1. Create payment account. # 2. Create EFT/WIRE payment db record. # 3. Create a credit memo db record. # 4. Publish credit in settlement file. # 5. Mock CFS Response for the receipt and credit memo. # 6. Confirm the credit matches the records. cfs_account_number = '1234' pay_account: PaymentAccountModel = factory_create_online_banking_account( status=CfsAccountStatus.ACTIVE.value, cfs_account=cfs_account_number) pay_account_id = pay_account.id # invoice_number = '1234567890' # Create a payment for EFT Wire eft_wire_receipt = 'RCPT0012345' onac_amount = 100 cm_identifier = 1000 cm_amount = 100 cm_used_amount = 50 PaymentModel(payment_method_code=PaymentMethod.EFT.value, payment_status_code=PaymentStatus.CREATED.value, payment_system_code='PAYBC', payment_account_id=pay_account.id, completed_on=datetime.now(), paid_amount=onac_amount, receipt_number=eft_wire_receipt).save() credit = CreditModel(cfs_identifier=cm_identifier, is_credit_memo=True, amount=cm_amount, remaining_amount=cm_amount, account_id=pay_account_id).save() credit_id = credit.id # Mock up the Receipt look up def mock_receipt(cfs_account: CfsAccountModel, receipt_number: str): # pylint: disable=unused-argument; mocks of library methods return {'receipt_amount': onac_amount} # Mock up the Receipt look up def mock_cms(cfs_account: CfsAccountModel, cms_number: str): # pylint: disable=unused-argument; mocks of library methods return {'amount_due': cm_amount - cm_used_amount} monkeypatch.setattr('pay_api.services.cfs_service.CFSService.get_receipt', mock_receipt) monkeypatch.setattr('pay_api.services.cfs_service.CFSService.get_cms', mock_cms) # Create a settlement file and publish. file_name: str = 'cas_settlement_file.csv' # Settlement row date = datetime.now().strftime('%d-%b-%y') row = [ RecordType.ONAC.value, SourceTransaction.EFT_WIRE.value, eft_wire_receipt, 100001, date, onac_amount, cfs_account_number, TargetTransaction.RECEIPT.value, eft_wire_receipt, onac_amount, 0, Status.ON_ACC.value ] create_and_upload_settlement_file(file_name, [row]) await helper_add_event_to_queue(events_stan, file_name=file_name) # Look up credit file and make sure the credits are recorded. pay_account = PaymentAccountModel.find_by_id(pay_account_id) assert pay_account.credit == onac_amount + cm_amount - cm_used_amount credit = CreditModel.find_by_id(credit_id) assert credit.remaining_amount == cm_amount - cm_used_amount
async def test_eft_wire_reconciliations(session, app, stan_server, event_loop, client_id, events_stan, future, mock_publish): """Test Reconciliations worker.""" # Call back for the subscription from reconciliations.worker import cb_subscription_handler # Create a Credit Card Payment # register the handler to test it await subscribe_to_queue( events_stan, current_app.config.get('SUBSCRIPTION_OPTIONS').get('subject'), current_app.config.get('SUBSCRIPTION_OPTIONS').get('queue'), current_app.config.get('SUBSCRIPTION_OPTIONS').get('durable_name'), cb_subscription_handler) # 1. Create payment account # 2. Create invoice and related records # 3. Create CFS Invoice records # 4. Create a CFS settlement file, and verify the records cfs_account_number = '1234' pay_account: PaymentAccountModel = factory_create_online_banking_account( status=CfsAccountStatus.ACTIVE.value, cfs_account=cfs_account_number) invoice: InvoiceModel = factory_invoice( payment_account=pay_account, total=100, service_fees=10.0, payment_method_code=PaymentMethod.ONLINE_BANKING.value) factory_payment_line_item(invoice_id=invoice.id, filing_fees=90.0, service_fees=10.0, total=90.0) invoice_number = '1234567890' factory_invoice_reference(invoice_id=invoice.id, invoice_number=invoice_number) invoice.invoice_status_code = InvoiceStatus.SETTLEMENT_SCHEDULED.value invoice = invoice.save() invoice_id = invoice.id total = invoice.total # Create a payment for EFT Wire eft_wire_receipt = 'RCPT0012345' paid_amount = 100 PaymentModel(payment_method_code=PaymentMethod.EFT.value, payment_status_code=PaymentStatus.CREATED.value, payment_system_code='PAYBC', payment_account_id=pay_account.id, completed_on=datetime.now(), paid_amount=paid_amount, receipt_number=eft_wire_receipt).save() # Create a settlement file and publish. file_name: str = 'cas_settlement_file.csv' # Settlement row date = datetime.now().strftime('%d-%b-%y') row = [ RecordType.EFTP.value, SourceTransaction.EFT_WIRE.value, eft_wire_receipt, 100001, date, total, cfs_account_number, TargetTransaction.INV.value, invoice_number, total, 0, Status.PAID.value ] create_and_upload_settlement_file(file_name, [row]) await helper_add_event_to_queue(events_stan, file_name=file_name) # The invoice should be in PAID status and Payment should be completed updated_invoice = InvoiceModel.find_by_id(invoice_id) assert updated_invoice.invoice_status_code == InvoiceStatus.PAID.value payment: PaymentModel = PaymentModel.find_payment_by_receipt_number( eft_wire_receipt) assert payment.payment_status_code == PaymentStatus.COMPLETED.value assert payment.paid_amount == paid_amount assert payment.receipt_number == eft_wire_receipt