def test_get_payment_system_url_service_fees(session, public_user_mock): """Assert that the url returned is correct.""" today = current_local_time().strftime(PAYBC_DATE_FORMAT) payment_account = factory_payment_account() payment = factory_payment() payment_account.save() payment.save() invoice = factory_invoice(payment_account) invoice.save() invoice_ref = factory_invoice_reference(invoice.id).save() fee_schedule = FeeSchedule.find_by_filing_type_and_corp_type('CP', 'OTANN') distribution_code = DistributionCodeModel.find_by_active_for_fee_schedule(fee_schedule.fee_schedule_id) distribution_code_svc = DistributionCode() distribution_code_payload = get_distribution_code_payload() # Set service fee distribution distribution_code_payload.update({'serviceFeeDistributionCodeId': distribution_code.distribution_code_id}) # update the existing gl code with new values distribution_code_svc.save_or_update(distribution_code_payload, distribution_code.distribution_code_id) service_fee = 100 line = factory_payment_line_item(invoice.id, fee_schedule_id=fee_schedule.fee_schedule_id, service_fees=service_fee) line.save() direct_pay_service = DirectPayService() payment_response_url = direct_pay_service.get_payment_system_url_for_invoice(invoice, invoice_ref, 'google.com') url_param_dict = dict(urllib.parse.parse_qsl(urllib.parse.urlsplit(payment_response_url).query)) assert url_param_dict['trnDate'] == today assert url_param_dict['glDate'] == today assert url_param_dict['description'] == 'Direct_Sale' assert url_param_dict['pbcRefNumber'] == current_app.config.get('PAYBC_DIRECT_PAY_REF_NUMBER') assert url_param_dict['trnNumber'] == generate_transaction_number(invoice.id) assert url_param_dict['trnAmount'] == str(invoice.total) assert url_param_dict['paymentMethod'] == 'CC' assert url_param_dict['redirectUri'] == 'google.com' revenue_str = f"1:{distribution_code_payload['client']}." \ f"{distribution_code_payload['responsibilityCentre']}." \ f"{distribution_code_payload['serviceLine']}." \ f"{distribution_code_payload['stob']}." \ f"{distribution_code_payload['projectCode']}." \ f'000000.0000:10.00' revenue_str_service_fee = f"2:{distribution_code_payload['client']}." \ f"{distribution_code_payload['responsibilityCentre']}." \ f"{distribution_code_payload['serviceLine']}." \ f"{distribution_code_payload['stob']}." \ f"{distribution_code_payload['projectCode']}." \ f'000000.0000:{format(service_fee, DECIMAL_PRECISION)}' assert url_param_dict['revenue'] == f'{revenue_str}|{revenue_str_service_fee}' urlstring = f"trnDate={today}&pbcRefNumber={current_app.config.get('PAYBC_DIRECT_PAY_REF_NUMBER')}&" \ f'glDate={today}&description=Direct_Sale&' \ f'trnNumber={generate_transaction_number(invoice.id)}&' \ f'trnAmount={invoice.total}&' \ f'paymentMethod=CC&' \ f'redirectUri=google.com&' \ f'currency=CAD&' \ f'revenue={revenue_str}|' \ f'{revenue_str_service_fee}' expected_hash_str = HashingService.encode(urlstring) assert expected_hash_str == url_param_dict['hashValue']
def _handle_payment_details(cls, account_request, is_sandbox, pay_system, payment_account, payment_info): # pylint: disable=too-many-arguments cfs_account: CfsAccountModel = CfsAccountModel.find_effective_by_account_id(payment_account.id) \ if payment_account.id else None if pay_system.get_payment_system_code() == PaymentSystem.PAYBC.value: if cfs_account is None: cfs_account = pay_system.create_account( # pylint:disable=assignment-from-none identifier=payment_account.auth_account_id, contact_info=account_request.get('contactInfo'), payment_info=account_request.get('paymentInfo')) if cfs_account: cfs_account.payment_account = payment_account cfs_account.flush() # If the account is PAD and bank details changed, then update bank details else: # Update details in CFS pay_system.update_account(name=payment_account.name, cfs_account=cfs_account, payment_info=payment_info) cls._update_pad_activation_date(cfs_account, is_sandbox, payment_account) elif pay_system.get_payment_system_code() == PaymentSystem.CGI.value: # if distribution code exists, put an end date as previous day and create new. dist_code_svc: DistributionCode = DistributionCode.find_active_by_account_id( payment_account.id) if dist_code_svc and dist_code_svc.distribution_code_id: end_date: datetime = datetime.now() - timedelta(days=1) dist_code_svc.end_date = end_date.date() dist_code_svc.save() # Create distribution code details. if revenue_account := payment_info.get('revenueAccount'): revenue_account.update( dict( accountId=payment_account.id, name=payment_account.name, )) DistributionCode.save_or_update(revenue_account)
def asdict(self, **kwargs): """Return the Account as a python dict.""" user: UserContext = kwargs['user'] account_schema = PaymentAccountSchema() d = account_schema.dump(self._dao) # Add cfs account values based on role and payment method. For system roles, return bank details. is_ob_or_pad = self.payment_method in ( PaymentMethod.PAD.value, PaymentMethod.ONLINE_BANKING.value) # to handle PAD 3 day period..UI needs bank details even if PAD is not activated is_future_pad = (self.payment_method == PaymentMethod.DRAWDOWN.value ) and (self._is_pad_in_pending_activation()) show_cfs_details = is_ob_or_pad or is_future_pad if show_cfs_details: cfs_account = { 'cfsAccountNumber': self.cfs_account, 'cfsPartyNumber': self.cfs_party, 'cfsSiteNumber': self.cfs_site, 'status': self.cfs_account_status } if user.is_system() or user.can_view_bank_info(): mask_len = 0 if not user.can_view_bank_account_number( ) else current_app.config['MASK_LEN'] cfs_account['bankAccountNumber'] = mask( self.bank_account_number, mask_len) cfs_account['bankInstitutionNumber'] = self.bank_number cfs_account['bankTransitNumber'] = self.bank_branch_number d['cfsAccount'] = cfs_account if is_future_pad: d['futurePaymentMethod'] = PaymentMethod.PAD.value if self.payment_method == PaymentMethod.EJV.value: # include JV details dist_code = DistributionCode.find_active_by_account_id(self.id) d['revenueAccount'] = dist_code.asdict() if account_fees := AccountFeeModel.find_by_account_id(self.id): d['accountFees'] = AccountFeeSchema().dump(account_fees, many=True)
def _save_account(cls, account_request: Dict[str, any], payment_account: PaymentAccountModel): """Update and save payment account and CFS account model.""" # pylint:disable=cyclic-import, import-outside-toplevel from pay_api.factory.payment_system_factory import PaymentSystemFactory # If the payment method is CC, set the payment_method as DIRECT_PAY payment_method: str = get_str_by_path(account_request, 'paymentInfo/methodOfPayment') if not payment_method or payment_method == PaymentMethod.CC.value: payment_method = PaymentMethod.DIRECT_PAY.value payment_account.payment_method = payment_method payment_account.auth_account_id = account_request.get('accountId') payment_account.auth_account_name = account_request.get( 'accountName', None) payment_account.bcol_account = account_request.get( 'bcolAccountNumber', None) payment_account.bcol_user_id = account_request.get('bcolUserId', None) payment_account.pad_tos_accepted_by = account_request.get( 'padTosAcceptedBy', None) if payment_account.pad_tos_accepted_by is not None: payment_account.pad_tos_accepted_date = datetime.now() payment_info = account_request.get('paymentInfo') billable = payment_info.get('billable', True) payment_account.billable = billable payment_account.flush() # Steps to decide on creating CFS Account or updating CFS bank account. # Updating CFS account apart from bank details not in scope now. # Create CFS Account IF: # 1. New payment account # 2. Existing payment account: # - If the account was on DIRECT_PAY and switching to Online Banking, and active CFS account is not present. # - If the account was on DRAWDOWN and switching to PAD, and active CFS account is not present cfs_account: CfsAccountModel = CfsAccountModel.find_effective_by_account_id(payment_account.id) \ if payment_account.id else None pay_system = PaymentSystemFactory.create_from_payment_method( payment_method=payment_method) if pay_system.get_payment_system_code() == PaymentSystem.PAYBC.value: if cfs_account is None: cfs_account = pay_system.create_account( name=payment_account.auth_account_name, contact_info=account_request.get('contactInfo'), payment_info=account_request.get('paymentInfo')) if cfs_account: cfs_account.payment_account = payment_account cfs_account.flush() # If the account is PAD and bank details changed, then update bank details else: # Update details in CFS pay_system.update_account( name=payment_account.auth_account_name, cfs_account=cfs_account, payment_info=payment_info) is_pad = payment_method == PaymentMethod.PAD.value if is_pad: # override payment method for since pad has 3 days wait period effective_pay_method, activation_date = PaymentAccount._get_payment_based_on_pad_activation( payment_account) payment_account.pad_activation_date = activation_date payment_account.payment_method = effective_pay_method elif pay_system.get_payment_system_code() == PaymentSystem.CGI.value: # if distribution code exists, put an end date as previous day and create new. dist_code_svc: DistributionCode = DistributionCode.find_active_by_account_id( payment_account.id) if dist_code_svc and dist_code_svc.distribution_code_id: end_date: datetime = datetime.now() - timedelta(days=1) dist_code_svc.end_date = end_date.date() dist_code_svc.save() # Create distribution code details. if revenue_account := payment_info.get('revenueAccount'): revenue_account.update( dict( accountId=payment_account.id, name=payment_account.auth_account_name, )) DistributionCode.save_or_update(revenue_account)