Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

21537 - Shortname Refunds - PUT and GET methods #1758

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
45 changes: 45 additions & 0 deletions pay-api/migrations/versions/2024_09_20_75a39e02c746_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Fix audit columns for eft_refunds.

Revision ID: 75a39e02c746
Revises: 29f59e6f147b
Create Date: 2024-09-20 13:45:35.132557

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
# Note you may see foreign keys with distribution_codes_history
# For disbursement_distribution_code_id, service_fee_distribution_code_id
# Please ignore those lines and don't include in migration.

revision = '75a39e02c746'
down_revision = '29f59e6f147b'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('eft_refunds', schema=None) as batch_op:
batch_op.add_column(sa.Column('created_name', sa.String(length=100), nullable=True))
batch_op.add_column(sa.Column('updated_name', sa.String(length=50), nullable=True))
batch_op.alter_column('updated_by',
existing_type=sa.VARCHAR(length=100),
type_=sa.String(length=50),
existing_nullable=True)
batch_op.drop_column('updated_by_name')
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('eft_refunds', schema=None) as batch_op:
batch_op.add_column(sa.Column('updated_by_name', sa.VARCHAR(length=100), autoincrement=False, nullable=True))
batch_op.alter_column('updated_by',
existing_type=sa.String(length=50),
type_=sa.VARCHAR(length=100),
existing_nullable=True)
batch_op.drop_column('updated_name')
batch_op.drop_column('created_name')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions pay-api/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ notes=FIXME,XXX,TODO
ignored-modules=flask_sqlalchemy,sqlalchemy,SQLAlchemy,alembic,scoped_session
ignored-classes=scoped_session
min-similarity-lines=15
max-attributes=15
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 7 was a bit too low, 15 is reasonable.. for some of our larger search dataclasses

disable=C0301,W0511,R0903
good-names=
b,
Expand Down
1 change: 1 addition & 0 deletions pay-api/src/pay_api/dtos/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Init."""
93 changes: 93 additions & 0 deletions pay-api/src/pay_api/dtos/eft_shortname.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""Rationale behind creating these DTOS below.

1. To ensure that the request and response payloads are validated before they are passed to the service layer.
2. To ensure that the request and response payloads are consistent across the application.
3. To ensure that the request and response payloads are consistent with the API documentation.

In the near future, will find a library that generates our API spec based off of these DTOs.
"""
from decimal import Decimal
from typing import List
from attrs import define

from pay_api.utils.converter import Converter


@define
class EFTShortNameGetRequest:
"""EFT Short name search."""

short_name: str = None
short_name_id: int = None
short_name_type: str = None
amount_owing: Decimal = None
statement_id: int = None
state: str = None
page: int = 1
limit: int = 10
account_id: int = None
account_name: str = None
account_branch: str = None
account_id_list: str = None

@classmethod
def from_dict(cls, data: dict):
"""Convert from request args to EFTShortNameSearchDTO."""
dto = Converter(camel_to_snake_case=True).structure(data, EFTShortNameGetRequest)
# In the future, we'll need a cleaner way to handle this.
dto.state = dto.state.split(',') if dto.state else None
dto.account_id_list = dto.account_id_list.split(',') if dto.account_id_list else None
return dto


@define
class EFTShortNameSummaryGetRequest:
"""EFT Short name summary search."""

short_name: str = None
short_name_id: int = None
short_name_type: str = None
credits_remaining: Decimal = None
linked_accounts_count: int = None
payment_received_start_date: str = None
payment_received_end_date: str = None
page: int = 1
limit: int = 10

@classmethod
def from_dict(cls, data: dict):
"""Convert from request args to EFTShortNameSummarySearchDTO."""
dto = Converter(camel_to_snake_case=True).structure(data, EFTShortNameSummaryGetRequest)
return dto


@define
class EFTShortNameRefundPatchRequest:
"""EFT Short name refund DTO."""

comment: str
decline_reason: str
status: str

@classmethod
def from_dict(cls, data: dict):
"""Convert from request json to EFTShortNameRefundDTO."""
return Converter(camel_to_snake_case=True).structure(data, EFTShortNameRefundPatchRequest)

def to_dict(self):
"""Convert from EFTShortNameRefundDTO to request json."""
return Converter(snake_case_to_camel=True).unstructure(self)


@define
class EFTShortNameRefundGetRequest:
"""EFT Short name refund DTO."""

statuses: List[str]

@classmethod
def from_dict(cls, data: dict):
"""Convert from request json to EFTShortNameRefundDTO."""
input_string = data.get('status', '')
statuses = input_string.split(',') if input_string else []
return EFTShortNameRefundGetRequest(statuses=statuses)
10 changes: 5 additions & 5 deletions pay-api/src/pay_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@
from .eft_credit_invoice_link import EFTCreditInvoiceLink
from .eft_file import EFTFile
from .eft_process_status_code import EFTProcessStatusCode
from .eft_short_names import EFTShortnames, EFTShortnameSchema, EFTShortnameSummarySchema
from .eft_short_names_historical import EFTShortnamesHistorical
from .eft_refund import EFTRefund
from .eft_refund_email_list import EFTRefundEmailList
from .eft_short_name_links import EFTShortnameLinks, EFTShortnameLinkSchema
from .eft_short_names import EFTShortnames, EFTShortnameSchema, EFTShortnameSummarySchema
from .eft_short_names_historical import EFTShortnameHistorySchema, EFTShortNamesHistorical
from .eft_transaction import EFTTransaction, EFTTransactionSchema
from .ejv_file import EjvFile
from .ejv_header import EjvHeader
Expand All @@ -61,13 +62,12 @@
from .refunds_partial import RefundPartialLine, RefundsPartial
from .routing_slip import RoutingSlip, RoutingSlipSchema
from .routing_slip_status_code import RoutingSlipStatusCode, RoutingSlipStatusCodeSchema
from .statement import StatementDTO, Statement, StatementSchema
from .statement import Statement, StatementDTO, StatementSchema
from .statement_invoices import StatementInvoices, StatementInvoicesSchema # noqa: I005
from .statement_recipients import StatementRecipients, StatementRecipientsSchema
from .statement_settings import StatementSettings, StatementSettingsSchema
from .transaction_status_code import TransactionStatusCode, TransactionStatusCodeSchema
from .comment import Comment, CommentSchema
from .eft_refund_email_list import EFTRefundEmailList
from .comment import Comment, CommentSchema # This has to be at the bottom otherwise FeeSchedule errors


event.listen(Engine, 'before_cursor_execute', DBTracing.query_tracing)
5 changes: 5 additions & 0 deletions pay-api/src/pay_api/models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ def delete(self):
db.session.delete(self)
db.session.commit()

def to_dict(self):
"""Quick and easy way to convert to a dict."""
# We need a better way to do this in the future.
return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns if getattr(self, c.name) is not None}

@staticmethod
def rollback():
"""RollBack."""
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/models/cfs_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from .db import db


class CfsAccount(Versioned, BaseModel): # pylint:disable=too-many-instance-attributes
class CfsAccount(Versioned, BaseModel):
"""This class manages all of the base data about PayBC Account."""

__tablename__ = 'cfs_accounts'
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/models/credit.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from .db import db, ma


class Credit(BaseModel): # pylint:disable=too-many-instance-attributes
class Credit(BaseModel):
"""This class manages all of the base data about Credit."""

__tablename__ = 'credits'
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/models/distribution_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def bulk_save_links(cls, links: list):
BaseModel.commit()


class DistributionCode(Audit, Versioned, BaseModel): # pylint:disable=too-many-instance-attributes
class DistributionCode(Audit, Versioned, BaseModel):
"""This class manages all of the base data about distribution code.

Distribution code holds details on the codes for how the collected payment is going to be distributed.
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/models/eft_credit.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .db import db


class EFTCredit(BaseModel): # pylint:disable=too-many-instance-attributes
class EFTCredit(BaseModel):
"""This class manages all of the base data for EFT credits."""

__tablename__ = 'eft_credits'
Expand Down
21 changes: 13 additions & 8 deletions pay-api/src/pay_api/models/eft_refund.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model to handle EFT REFUNDS, this is picked up by the AP job to mail out."""
from datetime import datetime, timezone
from typing import List

from sqlalchemy import ForeignKey

from .base_model import BaseModel
from .audit import Audit
from .db import db


class EFTRefund(BaseModel): # pylint: disable=too-many-instance-attributes
class EFTRefund(Audit):
"""This class manages the file data for EFT Refunds."""

__tablename__ = 'eft_refunds'
Expand All @@ -40,15 +40,16 @@ class EFTRefund(BaseModel): # pylint: disable=too-many-instance-attributes
'cas_supplier_number',
'comment',
'created_by',
'created_name'
'created_on',
'decline_reason',
'id',
'refund_amount',
'refund_email',
'short_name_id',
'status',
'updated_by_name',
'updated_by',
'updated_name',
'updated_on'
]
}
Expand All @@ -57,12 +58,16 @@ class EFTRefund(BaseModel): # pylint: disable=too-many-instance-attributes
comment = db.Column(db.String(), nullable=False)
decline_reason = db.Column(db.String(), nullable=True)
created_by = db.Column('created_by', db.String(100), nullable=True)
created_on = db.Column('created_on', db.DateTime, nullable=False, default=lambda: datetime.now(tz=timezone.utc))
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
refund_amount = db.Column(db.Numeric(), nullable=False)
refund_email = db.Column(db.String(100), nullable=False)
short_name_id = db.Column(db.Integer, ForeignKey('eft_short_names.id'), nullable=False)
status = db.Column(db.String(25), nullable=True)
updated_by = db.Column('updated_by', db.String(100), nullable=True)
updated_by_name = db.Column('updated_by_name', db.String(100), nullable=True)
updated_on = db.Column('updated_on', db.DateTime, nullable=True)

@classmethod
def find_refunds(cls, statuses: List[str]):
"""Return all refunds by status."""
query = cls.query
if statuses:
query = cls.query.filter(EFTRefund.status.in_(statuses))
return query.all()
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/models/eft_short_names_historical.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .db import db


class EFTShortnamesHistorical(BaseModel): # pylint:disable=too-many-instance-attributes
class EFTShortNamesHistorical(BaseModel):
"""This class manages all EFT Short name historical data."""

__tablename__ = 'eft_short_names_historical'
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/models/refund.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from .db import db, ma


class Refund(BaseModel): # pylint:disable=too-many-instance-attributes
class Refund(BaseModel):
"""This class manages all of the base data about Refunds."""

__tablename__ = 'refunds'
Expand Down
Loading
Loading