Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0294d5a
fix - Add dataclass-based dynamic attribute initialization
hfekete Jan 14, 2026
754373a
test - Add unit tests for `PaymentToken` and `ReceiptResponse` datacl…
hfekete Jan 15, 2026
8a26afb
ruff fixes
hfekete Jan 15, 2026
728982b
refactor - Replace `from_dict` methods with Pydantic-based dataclass …
hfekete Jan 15, 2026
823cec2
test - Add unit tests for `PaymentInvoice` dataclass and refactor to …
hfekete Jan 15, 2026
936e997
refactor - Update `links` field in Pydantic model to use alias "_link…
hfekete Jan 15, 2026
18ee73e
ruff fixes
hfekete Jan 15, 2026
27bd39b
test/refactor - Add `invoice` field support in `ReceiptResponse` with…
hfekete Jan 15, 2026
6f4b49e
Merge branch 'main' of github.com:hfekete/namex
hfekete Jan 15, 2026
8c13881
refactor/tests - Update DB connection logic, add refund field, and im…
hfekete Jan 16, 2026
7842c84
ruff cleanup
hfekete Jan 16, 2026
a509085
test - Enhance `PaymentInvoice` tests to validate numeric types and u…
hfekete Jan 16, 2026
c702f9e
test/refactor - Replace hardcoded assertions in `test_payment_invoice…
hfekete Jan 16, 2026
633ce59
Merge pull request #1945 from hfekete/feature-serialization-updates
hfekete Jan 19, 2026
ea5a73c
test - Add `PaymentRefundInvoice` dataclass, update `refund_payment` …
hfekete Jan 19, 2026
23ff0fb
wMerge branch 'main' of github.com:hfekete/namex into feature-seriali…
hfekete Jan 19, 2026
fc9b0c5
Merge branch 'main' of github.com:bcgov/namex
hfekete Jan 28, 2026
46db317
refactor - Comment out replacements for 'british columbia' variations…
hfekete Jan 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ class TestConfig(Config): # pylint: disable=too-few-public-methods
DB_NAME = os.getenv('DATABASE_TEST_NAME', 'unittesting')
DB_HOST = os.getenv('DATABASE_TEST_HOST', 'localhost')
DB_PORT = os.getenv('DATABASE_TEST_PORT', '54345')
SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}'
if os.getenv('TEST_USE_LOCAL_DB', False):
SQLALCHEMY_DATABASE_URI = f'postgresql+psycopg2://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}'
else:
SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{int(DB_PORT)}/{DB_NAME}'

# Ensure SQLAlchemy is properly configured for Flask-Marshmallow compatibility
SQLALCHEMY_TRACK_MODIFICATIONS = False
Expand Down
16 changes: 8 additions & 8 deletions api/namex/analytics/solr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1279,14 +1279,14 @@ def name_pre_processing(cls, name):
.replace('$', 's')
.replace(' ¢ ', 'cent')
.replace('¢', 'c')
.replace('britishcolumbia', 'bc')
.replace('britishcolumbias', 'bc')
.replace('britishcolumbian', 'bc')
.replace('britishcolumbians', 'bc')
.replace('british columbia', 'bc')
.replace('british columbias', 'bc')
.replace('british columbian', 'bc')
.replace('british columbians', 'bc')
# .replace('britishcolumbia', 'bc')
# .replace('britishcolumbias', 'bc')
# .replace('britishcolumbian', 'bc')
# .replace('britishcolumbians', 'bc')
# .replace('british columbia', 'bc')
# .replace('british columbias', 'bc')
# .replace('british columbian', 'bc')
# .replace('british columbians', 'bc')
)
return processed_name.strip()

Expand Down
63 changes: 38 additions & 25 deletions api/namex/services/payment/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import dataclasses
from dataclasses import dataclass, field
from typing import Optional, Union
from decimal import Decimal

from pydantic.dataclasses import dataclass as pydantic_dataclass
from pydantic import Field
from datetime import date

from .abstract import Serializable
Expand Down Expand Up @@ -118,7 +122,21 @@ class PaymentRequest(Serializable):
details: list = field(default_factory=PaymentDetailItem)


@dataclass
class PydanticConfig:
"""Pydantic config to ignore extra fields."""
extra = 'ignore'
underscore_attrs_are_private = False


@pydantic_dataclass(config=PydanticConfig)
class PaymentRefundInvoice:
refundId: int
refundAmount: Decimal
message: str
isPartialRefund: bool


@pydantic_dataclass(config=PydanticConfig)
class PaymentInvoice(Serializable):
id: int
serviceFees: float
Expand All @@ -140,25 +158,20 @@ class PaymentInvoice(Serializable):
routingSlip: str = ''
datNumber: str = ''
folioNumber: str = ''
lineItems: list = field(default_factory=list)
receipts: list = field(default_factory=list)
references: list = field(default_factory=list)
details: list = field(default_factory=list)
_links: list = field(default_factory=list)
paymentAccount: dict = field(default_factory=dict)

def __init__(self, **kwargs):
"""Set the attributes only if the field is defined."""
self.lineItems = []
self.receipts = []
self.references = []
self.details = []
self._links = []
self.paymentAccount = {}
names = {f.name for f in dataclasses.fields(self)}
for k, v in kwargs.items():
if k in names:
setattr(self, k, v)
lineItems: list = Field(default_factory=list)
receipts: list = Field(default_factory=list)
references: list = Field(default_factory=list)
details: list = Field(default_factory=list)
links: list = Field(default_factory=list)
paymentAccount: dict = Field(default_factory=dict)

@property
def _links(self) -> list:
return self.links

@_links.setter
def _links(self, value: list) -> None:
self.links = value


@dataclass
Expand All @@ -180,11 +193,11 @@ class Receipt(Serializable):
receiptNumber: str = ''


@dataclass
@pydantic_dataclass(config=PydanticConfig)
class ReceiptResponse(Serializable):
bcOnlineAccountNumber: str = None
filingIdentifier: str = None
invoice: PaymentInvoice = field(default=PaymentInvoice)
bcOnlineAccountNumber: Optional[str] = None
filingIdentifier: Optional[str] = None
invoice: Optional[Union[PaymentInvoice, dict]] = None
invoiceNumber: str = ''
paymentMethod: str = ''
receiptNumber: str = ''
Expand Down
10 changes: 7 additions & 3 deletions api/namex/services/payment/payments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .client import SBCPaymentClient
from .exceptions import SBCPaymentException
from .models import PaymentInvoice
from .models import PaymentInvoice, PaymentRefundInvoice


def get_payment(payment_identifier):
Expand Down Expand Up @@ -38,8 +38,12 @@ def refund_payment(payment_identifier, model=None):
data = model
api_instance = SBCPaymentClient()
api_response = api_instance.refund_payment(payment_identifier, data)
current_app.logger.debug(api_response)
return PaymentInvoice(**api_response) if api_response else None
current_app.logger.debug(
"services refund_payment response",
payment_identifier=payment_identifier,
api_response=api_response,
)
return PaymentRefundInvoice(**api_response) if api_response else None

except Exception as err:
raise SBCPaymentException(err)
Expand Down
1 change: 0 additions & 1 deletion api/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ def client_ctx(app):
with app.test_client() as c:
yield c


@pytest.fixture(scope='session')
def db(app, request):
"""
Expand Down
20 changes: 20 additions & 0 deletions api/tests/python/end_points/payments/test_payments.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,26 @@ def mock_publish(topic: str, payload: bytes):
'total': 31.5,
},
)

# Mock the get_payment API call that happens during payment completion
mocker.patch.object(
SBCPaymentClient,
'get_payment',
return_value={
'id': 1,
'serviceFees': 1.5,
'paid': 31.5,
'refund': 0.0,
'total': 31.5,
'isPaymentActionRequired': False,
'statusCode': 'CREATED',
'businessIdentifier': 'NR L000001',
'createdOn': '2021-01-14T23:52:05.531317+00:00',
'lineItems': [{'filingTypeCode': 'NM620', 'priority': False, 'waiveFees': False}],
'references': [],
},
)

payment = execute_payment(client, jwt, create_payment_request, action)
assert payment['action'] == action
if complete_payment:
Expand Down
Loading