diff --git a/pay-api/src/pay_api/models/custom_query.py b/pay-api/src/pay_api/models/custom_query.py index f3fcb08eb..c9c40dcee 100644 --- a/pay-api/src/pay_api/models/custom_query.py +++ b/pay-api/src/pay_api/models/custom_query.py @@ -35,3 +35,14 @@ def filter_conditionally(self, search_criteria, model_attribute, is_like: bool = return self.filter(func.lower(model_attribute).ilike(f'%{search_criteria}%')) return self.filter(model_attribute == search_criteria) + + def filter_conditional_date_range(self, start_date: date, end_date: date, model_attribute): + """Add query filter for a date range if present.""" + query = self + if start_date: + query = query.filter(func.DATE(model_attribute) >= start_date) + + if end_date: + query = query.filter(func.DATE(model_attribute) <= end_date) + + return query diff --git a/pay-api/src/pay_api/models/eft_short_names.py b/pay-api/src/pay_api/models/eft_short_names.py index fd6aa29f4..bae3ccc00 100644 --- a/pay-api/src/pay_api/models/eft_short_names.py +++ b/pay-api/src/pay_api/models/eft_short_names.py @@ -41,7 +41,10 @@ class EFTShortnames(VersionedModel): # pylint: disable=too-many-instance-attrib 'id', 'auth_account_id', 'created_on', - 'short_name' + 'short_name', + 'linked_by', + 'linked_by_name', + 'linked_on' ] } diff --git a/pay-api/src/pay_api/resources/v1/eft_short_names.py b/pay-api/src/pay_api/resources/v1/eft_short_names.py index 40f7afd75..e4a9a13fa 100644 --- a/pay-api/src/pay_api/resources/v1/eft_short_names.py +++ b/pay-api/src/pay_api/resources/v1/eft_short_names.py @@ -44,9 +44,11 @@ def get_eft_shortnames(): state = request.args.get('state', None) page: int = int(request.args.get('page', '1')) limit: int = int(request.args.get('limit', '10')) - transaction_date = request.args.get('transactionDate', None) + transaction_start_date = request.args.get('transactionStartDate', None) + transaction_end_date = request.args.get('transactionEndDate', None) deposit_amount = request.args.get('depositAmount', None) - deposit_date = request.args.get('depositDate', None) + deposit_start_date = request.args.get('depositStartDate', None) + deposit_end_date = request.args.get('depositEndDate', None) short_name = request.args.get('shortName', None) account_id = request.args.get('accountId', None) account_id_list = request.args.get('accountIdList', None) @@ -59,10 +61,12 @@ def get_eft_shortnames(): account_id_list=account_id_list, account_name=account_name, account_branch=account_branch, - deposit_date=string_to_date(deposit_date), + deposit_start_date=string_to_date(deposit_start_date), + deposit_end_date=string_to_date(deposit_end_date), deposit_amount=Decimal(deposit_amount) * Decimal(100) if deposit_amount else None, short_name=short_name, - transaction_date=string_to_date(transaction_date), + transaction_start_date=string_to_date(transaction_start_date), + transaction_end_date=string_to_date(transaction_end_date), state=state, page=page, limit=limit)), HTTPStatus.OK @@ -83,7 +87,7 @@ def get_eft_shortname(short_name_id: int): response, status = {'message': 'The requested EFT short name could not be found.'}, \ HTTPStatus.NOT_FOUND else: - response, status = eft_short_name.asdict(), HTTPStatus.OK + response, status = eft_short_name, HTTPStatus.OK current_app.logger.debug('>get_eft_shortname') return jsonify(response), status @@ -103,7 +107,7 @@ def patch_eft_shortname(short_name_id: int): HTTPStatus.NOT_FOUND else: account_id = request_json.get('accountId', None) - response, status = EFTShortnameService.patch(short_name_id, account_id).asdict(), HTTPStatus.OK + response, status = EFTShortnameService.patch(short_name_id, account_id), HTTPStatus.OK except BusinessException as exception: return exception.response() diff --git a/pay-api/src/pay_api/services/eft_short_names.py b/pay-api/src/pay_api/services/eft_short_names.py index 3530e527d..6316f8d6e 100644 --- a/pay-api/src/pay_api/services/eft_short_names.py +++ b/pay-api/src/pay_api/services/eft_short_names.py @@ -42,12 +42,15 @@ class EFTShortnamesSearch: # pylint: disable=too-many-instance-attributes """Used for searching EFT short name records.""" + id: Optional[int] = None account_id_list: Optional[List[str]] = None account_id: Optional[str] = None account_name: Optional[str] = None account_branch: Optional[str] = None - transaction_date: Optional[date] = None - deposit_date: Optional[date] = None + transaction_start_date: Optional[date] = None + transaction_end_date: Optional[date] = None + deposit_start_date: Optional[date] = None + deposit_end_date: Optional[date] = None deposit_amount: Optional[Decimal] = None short_name: Optional[str] = None state: Optional[str] = None @@ -64,6 +67,9 @@ def __init__(self): self._id: Optional[int] = None self._auth_account_id: Optional[str] = None self._short_name: Optional[str] = None + self._linked_by: Optional[str] = None + self._linked_by_name: Optional[str] = None + self._linked_on: Optional[datetime] = None @property def _dao(self): @@ -77,6 +83,9 @@ def _dao(self, value: EFTShortnameModel): self.id: int = self._dao.id self.auth_account_id: str = self._dao.auth_account_id self.short_name: str = self._dao.short_name + self.linked_by: str = self._dao.linked_by + self.linked_by_name: str = self._dao.linked_by_name + self.linked_on: datetime = self._dao.linked_on @property def id(self): @@ -122,6 +131,39 @@ def created_on(self, value: datetime): self._created_on = value self._dao.created_on = value + @property + def linked_by(self): + """Return the linked by user name.""" + return self._linked_by + + @linked_by.setter + def linked_by(self, value: str): + """Set the linked by user name.""" + self._linked_by = value + self._dao.linked_by = value + + @property + def linked_by_name(self): + """Return the linked by name.""" + return self._linked_by + + @linked_by_name.setter + def linked_by_name(self, value: str): + """Set the linked by name.""" + self._linked_by_name = value + self._dao.linked_by_name = value + + @property + def linked_on(self): + """Return the linked on date.""" + return self._linked_on + + @linked_on.setter + def linked_on(self, value: str): + """Set the linked on date.""" + self._linked_on = value + self._dao.linked_on = value + def save(self): """Save the information to the DB.""" return self._dao.save() @@ -216,13 +258,12 @@ def get_invoices_owing(auth_account_id: str) -> [InvoiceModel]: def find_by_short_name_id(cls, short_name_id: int) -> EFTShortnames: """Find payment account by corp number, corp type and payment system code.""" current_app.logger.debug('find_by_short_name_id') - return short_name_service + short_name_model: EFTShortnameModel = cls.get_search_query(EFTShortnamesSearch(id=short_name_id)).one_or_none() + converter = Converter() + result = converter.unstructure(EFTShortnameSchema.from_row(short_name_model)) + + current_app.logger.debug('>find_by_short_name_id') + return result @classmethod def search(cls, search_criteria: EFTShortnamesSearch): @@ -306,12 +347,20 @@ def get_search_query(cls, search_criteria: EFTShortnamesSearch, is_count: bool = .outerjoin(PaymentAccountModel, PaymentAccountModel.auth_account_id == EFTShortnameModel.auth_account_id) - # Sub query filters for EFT transaction dates - query = query.filter_conditionally(search_criteria.transaction_date, sub_query.c.transaction_date) - query = query.filter_conditionally(search_criteria.deposit_date, sub_query.c.deposit_date) + # Sub query filters for EFT dates + query = query.filter_conditional_date_range(start_date=search_criteria.transaction_start_date, + end_date=search_criteria.transaction_end_date, + model_attribute=sub_query.c.transaction_date) + + query = query.filter_conditional_date_range(start_date=search_criteria.deposit_start_date, + end_date=search_criteria.deposit_end_date, + model_attribute=sub_query.c.deposit_date) + + # Sub query filters query = query.filter_conditionally(search_criteria.deposit_amount, sub_query.c.deposit_amount_cents) query = query.filter_conditionally(search_criteria.account_id, EFTShortnameModel.auth_account_id, is_like=True) + # Payment account filters query = query.filter_conditionally(search_criteria.account_name, PaymentAccountModel.name, is_like=True) query = query.filter_conditionally(search_criteria.account_branch, PaymentAccountModel.branch_name, is_like=True) @@ -326,7 +375,8 @@ def get_search_query(cls, search_criteria: EFTShortnamesSearch, is_count: bool = if search_criteria.account_id_list: query = query.filter(EFTShortnameModel.auth_account_id.in_(search_criteria.account_id_list)) - # Short name free text search + # Short name filters + query = query.filter_conditionally(search_criteria.id, EFTShortnameModel.id) query = query.filter_conditionally(search_criteria.short_name, EFTShortnameModel.short_name, is_like=True) query = cls.get_order_by(search_criteria, query, sub_query) diff --git a/pay-api/src/pay_api/version.py b/pay-api/src/pay_api/version.py index b34c5a526..3a9ddb853 100644 --- a/pay-api/src/pay_api/version.py +++ b/pay-api/src/pay_api/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '1.20.7' # pylint: disable=invalid-name +__version__ = '1.20.8' # pylint: disable=invalid-name diff --git a/pay-api/tests/unit/api/test_eft_short_names.py b/pay-api/tests/unit/api/test_eft_short_names.py index 08fb8ef21..458804c14 100755 --- a/pay-api/tests/unit/api/test_eft_short_names.py +++ b/pay-api/tests/unit/api/test_eft_short_names.py @@ -341,7 +341,8 @@ def test_search_eft_short_names(session, client, jwt, app): assert_short_name(result_dict['items'][0], short_name_1, s1_transaction1) # Assert search transaction date - rv = client.get('/api/v1/eft-shortnames?transactionDate=2024-01-05', headers=headers) + rv = client.get('/api/v1/eft-shortnames?transactionStartDate=2024-01-04&transactionEndDate=2024-01-14', + headers=headers) assert rv.status_code == 200 result_dict = rv.json @@ -355,7 +356,23 @@ def test_search_eft_short_names(session, client, jwt, app): assert_short_name(result_dict['items'][0], short_name_1, s1_transaction1) # Assert search transaction date - rv = client.get('/api/v1/eft-shortnames?depositDate=2024-01-16', headers=headers) + rv = client.get('/api/v1/eft-shortnames?transactionStartDate=2024-01-04&transactionEndDate=2024-01-15', + headers=headers) + assert rv.status_code == 200 + + result_dict = rv.json + assert result_dict is not None + assert result_dict['page'] == 1 + assert result_dict['stateTotal'] == 2 + assert result_dict['total'] == 2 + assert result_dict['limit'] == 10 + assert result_dict['items'] is not None + assert len(result_dict['items']) == 2 + assert_short_name(result_dict['items'][0], short_name_1, s1_transaction1) + assert_short_name(result_dict['items'][1], short_name_2, s2_transaction1) + + # Assert search transaction date + rv = client.get('/api/v1/eft-shortnames?depositStartDate=2024-01-16&depositEndDate=2024-01-16', headers=headers) assert rv.status_code == 200 result_dict = rv.json