diff --git a/pay-api/migrations/versions/44bd57ece7b0_ppr_filing_types.py b/pay-api/migrations/versions/44bd57ece7b0_ppr_filing_types.py new file mode 100644 index 000000000..fc517e881 --- /dev/null +++ b/pay-api/migrations/versions/44bd57ece7b0_ppr_filing_types.py @@ -0,0 +1,70 @@ +"""ppr_filing_types + +Revision ID: 44bd57ece7b0 +Revises: 609b98d87a72 +Create Date: 2021-09-16 16:25:58.618648 + +""" +from alembic import op +import sqlalchemy as sa +from datetime import date + +import sqlalchemy as sa +from alembic import op +from sqlalchemy import Date, Float, String, Boolean +from sqlalchemy.sql import column, table + +# revision identifiers, used by Alembic. +revision = '44bd57ece7b0' +down_revision = '609b98d87a72' +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_index(op.f('ix_invoices_created_on'), 'invoices', ['created_on'], unique=False) + op.alter_column('payment_line_items', 'fee_distribution_id', + existing_type=sa.INTEGER(), + nullable=True) + + filing_type_table = table('filing_types', + column('code', String), + column('description', String) + ) + fee_schedule_table = table('fee_schedules', + column('filing_type_code', String), + column('corp_type_code', String), + column('fee_code', String), + column('fee_start_date', Date), + column('fee_end_date', Date) + ) + + op.bulk_insert( + filing_type_table, + [ + {'code': 'FSDIS', 'description': 'PPR Total Discharge'}, + {'code': 'NCREG', 'description': 'PPR No Charge Registration'}, + {'code': 'NCCHG', 'description': 'PPR No Charge Change or Amendment'} + ] + ) + + op.bulk_insert( + fee_schedule_table, + [ + {'filing_type_code': 'FSDIS', 'corp_type_code': 'PPR', 'fee_code': 'EN107', 'fee_start_date': date.today(), + 'fee_end_date': None}, + {'filing_type_code': 'NCREG', 'corp_type_code': 'PPR', 'fee_code': 'EN107', 'fee_start_date': date.today(), + 'fee_end_date': None}, + {'filing_type_code': 'NCCHG', 'corp_type_code': 'PPR', 'fee_code': 'EN107', 'fee_start_date': date.today(), + 'fee_end_date': None} + ] + ) + + +def downgrade(): + op.execute("DELETE FROM fee_schedules WHERE filing_type_code in ('NCCHG', 'NCREG', 'FSDIS')") + op.execute("DELETE FROM filing_types WHERE code in ('NCCHG', 'NCREG', 'FSDIS')") + op.alter_column('payment_line_items', 'fee_distribution_id', + existing_type=sa.INTEGER(), + nullable=False) + op.drop_index(op.f('ix_invoices_created_on'), table_name='invoices') diff --git a/pay-api/src/pay_api/__init__.py b/pay-api/src/pay_api/__init__.py index e6de6dfba..151880bc9 100755 --- a/pay-api/src/pay_api/__init__.py +++ b/pay-api/src/pay_api/__init__.py @@ -49,7 +49,7 @@ def create_app(run_mode=os.getenv('FLASK_ENV', 'production')): # Configure Sentry if app.config.get('SENTRY_DSN', None): # pragma: no cover - sentry_sdk.init( + sentry_sdk.init( # pylint: disable=abstract-class-instantiated dsn=app.config.get('SENTRY_DSN'), integrations=[FlaskIntegration()] ) diff --git a/pay-api/src/pay_api/config.py b/pay-api/src/pay_api/config.py index 75802f09b..12821ddb8 100755 --- a/pay-api/src/pay_api/config.py +++ b/pay-api/src/pay_api/config.py @@ -82,9 +82,7 @@ class _Config(): # pylint: disable=too-few-public-methods DB_NAME = _get_config('DATABASE_NAME') DB_HOST = _get_config('DATABASE_HOST') DB_PORT = _get_config('DATABASE_PORT', default='5432') - SQLALCHEMY_DATABASE_URI = 'postgresql://{user}:{password}@{host}:{port}/{name}'.format( - user=DB_USER, password=DB_PASSWORD, host=DB_HOST, port=int(DB_PORT), name=DB_NAME - ) + SQLALCHEMY_DATABASE_URI = f'postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}' SQLALCHEMY_ECHO = _get_config('SQLALCHEMY_ECHO', default='False').lower() == 'true' # JWT_OIDC Settings @@ -204,9 +202,7 @@ class TestConfig(_Config): # pylint: disable=too-few-public-methods DB_PORT = _get_config('DATABASE_TEST_PORT', default='5432') SQLALCHEMY_DATABASE_URI = _get_config( 'DATABASE_TEST_URL', - default='postgresql://{user}:{password}@{host}:{port}/{name}'.format( - user=DB_USER, password=DB_PASSWORD, host=DB_HOST, port=int(DB_PORT), name=DB_NAME - ), + default=f'postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}' ) JWT_OIDC_TEST_MODE = True @@ -330,7 +326,5 @@ class MigrationConfig(): # pylint: disable=too-few-public-methods DB_NAME = _get_config('DATABASE_NAME') DB_HOST = _get_config('DATABASE_HOST') DB_PORT = _get_config('DATABASE_PORT', default='5432') - SQLALCHEMY_DATABASE_URI = 'postgresql://{user}:{password}@{host}:{port}/{name}'.format( - user=DB_USER, password=DB_PASSWORD, host=DB_HOST, port=int(DB_PORT), name=DB_NAME - ) + SQLALCHEMY_DATABASE_URI = f'postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}' SQLALCHEMY_TRACK_MODIFICATIONS = False diff --git a/pay-api/src/pay_api/factory/payment_system_factory.py b/pay-api/src/pay_api/factory/payment_system_factory.py index 7df1c9ac0..c3fec703c 100644 --- a/pay-api/src/pay_api/factory/payment_system_factory.py +++ b/pay-api/src/pay_api/factory/payment_system_factory.py @@ -80,7 +80,7 @@ def create(**kwargs): has_bcol_account_number = account_info is not None and account_info.get('bcolAccountNumber') is not None _instance: PaymentSystemService = None - current_app.logger.debug('payment_method: {}'.format(payment_method)) + current_app.logger.debug(f'payment_method: {payment_method}') if not payment_method: raise BusinessException(Error.INVALID_CORP_OR_FILING_TYPE) diff --git a/pay-api/src/pay_api/models/invoice.py b/pay-api/src/pay_api/models/invoice.py index 973714b56..3d546e664 100644 --- a/pay-api/src/pay_api/models/invoice.py +++ b/pay-api/src/pay_api/models/invoice.py @@ -50,6 +50,7 @@ class Invoice(Audit): # pylint: disable=too-many-instance-attributes payment_method_code = db.Column(db.String(15), ForeignKey('payment_methods.code'), nullable=False) corp_type_code = db.Column(db.String(10), ForeignKey('corp_types.code'), nullable=True) disbursement_status_code = db.Column(db.String(20), ForeignKey('disbursement_status_codes.code'), nullable=True) + created_on = db.Column('created_on', db.DateTime, nullable=False, default=datetime.now, index=True) business_identifier = db.Column(db.String(20), nullable=True) total = db.Column(db.Float, nullable=False) diff --git a/pay-api/src/pay_api/models/payment_line_item.py b/pay-api/src/pay_api/models/payment_line_item.py index 9349f4e68..4b57cac66 100644 --- a/pay-api/src/pay_api/models/payment_line_item.py +++ b/pay-api/src/pay_api/models/payment_line_item.py @@ -43,7 +43,7 @@ class PaymentLineItem(BaseModel): # pylint: disable=too-many-instance-attribute waived_by = db.Column(db.String(50), nullable=True, default=None) service_fees = db.Column(db.Float, nullable=True) - fee_distribution_id = db.Column(db.Integer, ForeignKey('distribution_codes.distribution_code_id'), nullable=False) + fee_distribution_id = db.Column(db.Integer, ForeignKey('distribution_codes.distribution_code_id'), nullable=True) fee_schedule = relationship(FeeSchedule, foreign_keys=[fee_schedule_id], lazy='joined', innerjoin=True) diff --git a/pay-api/src/pay_api/resources/account.py b/pay-api/src/pay_api/resources/account.py index 4355a1933..90598043e 100644 --- a/pay-api/src/pay_api/resources/account.py +++ b/pay-api/src/pay_api/resources/account.py @@ -230,7 +230,7 @@ def post(account_number: str): if not valid_format: return error_to_response(Error.INVALID_REQUEST, invalid_params=schema_utils.serialize(errors)) - report_name = 'bcregistry-transactions-{}'.format(datetime.now().strftime('%m-%d-%Y')) + report_name = f"bcregistry-transactions-{datetime.now().strftime('%m-%d-%Y')}" if response_content_type == ContentType.PDF.value: report_name = f'{report_name}.pdf' diff --git a/pay-api/src/pay_api/resources/fas/routing_slip.py b/pay-api/src/pay_api/resources/fas/routing_slip.py index 79acad0a6..415095dda 100644 --- a/pay-api/src/pay_api/resources/fas/routing_slip.py +++ b/pay-api/src/pay_api/resources/fas/routing_slip.py @@ -103,7 +103,7 @@ def post(date: str): pdf, file_name = RoutingSlipService.create_daily_reports(date) response = Response(pdf, 201) - response.headers.set('Content-Disposition', 'attachment', filename='{}.pdf'.format(file_name)) + response.headers.set('Content-Disposition', 'attachment', filename=f'{file_name}.pdf') response.headers.set('Content-Type', 'application/pdf') response.headers.set('Access-Control-Expose-Headers', 'Content-Disposition') diff --git a/pay-api/src/pay_api/resources/invoice.py b/pay-api/src/pay_api/resources/invoice.py index 33a358fb8..be768ae49 100644 --- a/pay-api/src/pay_api/resources/invoice.py +++ b/pay-api/src/pay_api/resources/invoice.py @@ -159,7 +159,7 @@ def post(invoice_id: int = None): try: pdf, file_name = InvoiceService.create_invoice_pdf(invoice_id) response = Response(pdf, 201) - response.headers.set('Content-Disposition', 'attachment', filename='{}.pdf'.format(file_name)) + response.headers.set('Content-Disposition', 'attachment', filename=f'{file_name}.pdf') response.headers.set('Content-Type', 'application/pdf') response.headers.set('Access-Control-Expose-Headers', 'Content-Disposition') return response diff --git a/pay-api/src/pay_api/resources/invoice_receipt.py b/pay-api/src/pay_api/resources/invoice_receipt.py index 6ffcb6fb9..f9b4201a3 100644 --- a/pay-api/src/pay_api/resources/invoice_receipt.py +++ b/pay-api/src/pay_api/resources/invoice_receipt.py @@ -49,7 +49,7 @@ def post(invoice_id): response = Response(pdf, 201) file_name = request_json.get('fileName') file_name = 'Coops-Filing' if not file_name else file_name - response.headers.set('Content-Disposition', 'attachment', filename='{}.pdf'.format(file_name)) + response.headers.set('Content-Disposition', 'attachment', filename=f'{file_name}.pdf') response.headers.set('Content-Type', 'application/pdf') response.headers.set('Access-Control-Expose-Headers', 'Content-Disposition') return response diff --git a/pay-api/src/pay_api/services/base_payment_system.py b/pay-api/src/pay_api/services/base_payment_system.py index 30ff2095d..b4eea3d33 100644 --- a/pay-api/src/pay_api/services/base_payment_system.py +++ b/pay-api/src/pay_api/services/base_payment_system.py @@ -128,5 +128,4 @@ def _release_payment(invoice: Invoice): except Exception as e: # NOQA pylint: disable=broad-except current_app.logger.error(e) current_app.logger.error('Notification to Queue failed for the Payment Event %s', payload) - capture_message('Notification to Queue failed for the Payment Event : {msg}.'.format(msg=payload), - level='error') + capture_message(f'Notification to Queue failed for the Payment Event : {payload}.', level='error') diff --git a/pay-api/src/pay_api/services/cfs_service.py b/pay-api/src/pay_api/services/cfs_service.py index 4e1afbaaf..6c5169071 100644 --- a/pay-api/src/pay_api/services/cfs_service.py +++ b/pay-api/src/pay_api/services/cfs_service.py @@ -156,8 +156,7 @@ def _transform_error_message(param: str) -> str: def _create_paybc_account(access_token, party): """Create account record in PayBC.""" current_app.logger.debug('find_by_id') @@ -321,7 +321,7 @@ def find_by_id(identifier: int): @staticmethod def find_active_by_account_id(account_id: int) -> DistributionCode: """Find active distribution code by account_id.""" - current_app.logger.debug('= 500: raise ServiceUnavailableException(exc) from exc raise exc @@ -85,11 +85,11 @@ def post(endpoint, token, auth_header_type: AuthHeaderType, # pylint: disable=t @staticmethod def __log_response(response): if response is not None: - current_app.logger.info('Response Headers {}'.format(response.headers)) + current_app.logger.info(f'Response Headers {response.headers}') if response.headers and isinstance(response.headers, Iterable) and \ 'Content-Type' in response.headers and \ response.headers['Content-Type'] == ContentType.JSON.value: - current_app.logger.info('response : {}'.format(response.text if response else '')) + current_app.logger.info(f"response : {response.text if response else ''} ") @staticmethod def get(endpoint, token, auth_header_type: AuthHeaderType, # pylint:disable=too-many-arguments @@ -106,8 +106,8 @@ def get(endpoint, token, auth_header_type: AuthHeaderType, # pylint:disable=too if additional_headers is not None: headers.update(additional_headers) - current_app.logger.debug('Endpoint : {}'.format(endpoint)) - current_app.logger.debug('headers : {}'.format(headers)) + current_app.logger.debug(f'Endpoint : {endpoint}') + current_app.logger.debug(f'headers : {headers}') session = requests.Session() if retry_on_failure: session.mount(endpoint, RETRY_ADAPTER) @@ -120,8 +120,7 @@ def get(endpoint, token, auth_header_type: AuthHeaderType, # pylint:disable=too current_app.logger.error(exc) raise ServiceUnavailableException(exc) from exc except HTTPError as exc: - current_app.logger.error( - 'HTTPError on POST with status code {}'.format(response.status_code if response else '')) + current_app.logger.error(f"HTTPError on POST with status code {response.status_code if response else ''}") if response is not None: if response.status_code >= 500: raise ServiceUnavailableException(exc) from exc diff --git a/pay-api/src/pay_api/services/paybc_service.py b/pay-api/src/pay_api/services/paybc_service.py index 7ad6d2401..70891cb7f 100644 --- a/pay-api/src/pay_api/services/paybc_service.py +++ b/pay-api/src/pay_api/services/paybc_service.py @@ -113,8 +113,9 @@ def get_receipt(self, payment_account: PaymentAccount, pay_response_url: str, in current_app.logger.debug('Creating PayBC Adjustment For Invoice: {inv_number}') - adjustment_url = current_app.config.get('CFS_BASE_URL') + '/cfs/parties/{}/accs/{}/sites/{}/invs/{}/adjs/' \ - .format(payment_account.cfs_party, payment_account.cfs_account, payment_account.cfs_site, inv_number) + adjustment_url = current_app.config.get( + 'CFS_BASE_URL') + f'/cfs/parties/{payment_account.cfs_party}/accs/{payment_account.cfs_account}' \ + f'/sites/{payment_account.cfs_site}/invs/{inv_number}/adjs/' current_app.logger.debug(f'>Creating PayBC Adjustment URL {adjustment_url}') adjustment = dict( @@ -172,8 +174,9 @@ def _add_adjustment(self, payment_account: PaymentAccount, # pylint: disable=to def _get_invoice(self, payment_account: PaymentAccount, inv_number: str, access_token: str): """Get invoice from PayBC.""" current_app.logger.debug('<__get_invoice') - invoice_url = current_app.config.get('CFS_BASE_URL') + '/cfs/parties/{}/accs/{}/sites/{}/invs/{}/' \ - .format(payment_account.cfs_party, payment_account.cfs_account, payment_account.cfs_site, inv_number) + invoice_url = current_app.config.get( + 'CFS_BASE_URL') + f'/cfs/parties/{payment_account.cfs_party}/accs/{payment_account.cfs_account}/' \ + f'sites/{payment_account.cfs_site}/invs/{inv_number}/' invoice_response = self.get(invoice_url, access_token, AuthHeaderType.BEARER, ContentType.JSON) current_app.logger.debug('>__get_invoice') diff --git a/pay-api/src/pay_api/services/payment.py b/pay-api/src/pay_api/services/payment.py index c2a1743ee..4535bf8cf 100644 --- a/pay-api/src/pay_api/services/payment.py +++ b/pay-api/src/pay_api/services/payment.py @@ -463,9 +463,8 @@ def _prepare_csv_data(results): total_fees = float(invoice.get('total', 0)) row_value = [ ','.join([line_item.get('description') for line_item in invoice.get('line_items')]), - ','.join(['{} {}'.format( - detail.get('label'), detail.get('value')) for detail in invoice.get('details') - ]) if invoice.get('details') else None, + ','.join([f"{detail.get('label')} {detail.get('value')}" for detail in invoice.get('details')]) + if invoice.get('details') else None, invoice.get('folio_number'), invoice.get('created_name'), get_local_formatted_date_time( diff --git a/pay-api/src/pay_api/services/payment_account.py b/pay-api/src/pay_api/services/payment_account.py index b037e65b4..9c6ba4e4d 100644 --- a/pay-api/src/pay_api/services/payment_account.py +++ b/pay-api/src/pay_api/services/payment_account.py @@ -586,8 +586,8 @@ def publish_account_mailer_event(self): 'Notification to Queue failed for the Account Mailer %s - %s', self.auth_account_id, self.name) capture_message( - 'Notification to Queue failed for the Account Mailer on account creation : {msg}.'.format( - msg=payload), level='error') + f'Notification to Queue failed for the Account Mailer on account creation : {payload}.', + level='error') def _create_account_event_payload(self, event_type: str, include_pay_info: bool = False): """Return event payload for account.""" @@ -639,8 +639,7 @@ def unlock_frozen_accounts(account_id: int): 'Notification to Queue failed for the Unlock Account %s - %s', pay_account.auth_account_id, pay_account.name) capture_message( - 'Notification to Queue failed for the Unlock Account : {msg}.'.format( - msg=payload), level='error') + f'Notification to Queue failed for the Unlock Account : {payload}.', level='error') @classmethod def delete_account(cls, auth_account_id: str) -> PaymentAccount: diff --git a/pay-api/src/pay_api/services/payment_line_item.py b/pay-api/src/pay_api/services/payment_line_item.py index 4a324571b..e4fbc9739 100644 --- a/pay-api/src/pay_api/services/payment_line_item.py +++ b/pay-api/src/pay_api/services/payment_line_item.py @@ -291,9 +291,10 @@ def create(invoice_id: int, fee: FeeSchedule, **kwargs): p.service_fees = fee.service_fees # Set distribution details to line item - distribution_code = DistributionCodeModel.find_by_active_for_fee_schedule(fee.fee_schedule_id) - - p.fee_distribution_id = distribution_code.distribution_code_id + distribution_code = None + if p.total > 0: + distribution_code = DistributionCodeModel.find_by_active_for_fee_schedule(fee.fee_schedule_id) + p.fee_distribution_id = distribution_code.distribution_code_id if fee.waived_fee_amount > 0: if user.has_role(Role.STAFF.value): diff --git a/pay-api/src/pay_api/services/payment_service.py b/pay-api/src/pay_api/services/payment_service.py index 1abea28f6..b643563b9 100644 --- a/pay-api/src/pay_api/services/payment_service.py +++ b/pay-api/src/pay_api/services/payment_service.py @@ -291,7 +291,7 @@ def _calculate_fees(corp_type, filing_info): fees = [] service_fee_applied: bool = False for filing_type_info in filing_info.get('filingTypes'): - current_app.logger.debug('Getting fees for {} '.format(filing_type_info.get('filingTypeCode'))) + current_app.logger.debug(f"Getting fees for {filing_type_info.get('filingTypeCode')} ") fee: FeeSchedule = FeeSchedule.find_by_corp_type_and_filing_type( corp_type=corp_type, filing_type_code=filing_type_info.get('filingTypeCode', None), diff --git a/pay-api/src/pay_api/services/receipt.py b/pay-api/src/pay_api/services/receipt.py index 0df580176..901b512fc 100644 --- a/pay-api/src/pay_api/services/receipt.py +++ b/pay-api/src/pay_api/services/receipt.py @@ -160,7 +160,7 @@ def create_receipt(invoice_identifier: str, filing_data: Dict[str, Any], skip_au receipt_dict['templateVars'] = template_vars current_app.logger.debug( - '