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

19163 & 19165 - Credits implementation to assist customers where their credits have been spent #1767

Merged
merged 22 commits into from
Oct 7, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Add in CFS credit invoices table which is parsed from the CSV feedback.

Revision ID: f78095de8cfc
Revises: 56c4542db0d7
Create Date: 2024-10-04 14:21:55.600886

"""
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 = 'f78095de8cfc'
down_revision = '56c4542db0d7'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('cfs_credit_invoices',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('account_id', sa.Integer(), nullable=True),
sa.Column('application_id', sa.Integer(), nullable=True, unique=True),
sa.Column('amount_applied', sa.Numeric(), nullable=False),
sa.Column('cfs_account', sa.String(length=50), nullable=False),
sa.Column('cfs_identifier', sa.String(length=50), nullable=False),
sa.Column('credit_id', sa.Integer(), nullable=True),
sa.Column('created_on', sa.DateTime(), nullable=False),
sa.Column('invoice_amount', sa.Numeric(), nullable=False),
sa.Column('invoice_number', sa.String(length=50), nullable=False),
sa.ForeignKeyConstraint(['account_id'], ['payment_accounts.id'], ),
sa.ForeignKeyConstraint(['credit_id'], ['credits.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('cfs_credit_invoices', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_cfs_credit_invoices_account_id'), ['account_id'], unique=False)
batch_op.create_index(batch_op.f('ix_cfs_credit_invoices_application_id'), ['application_id'], unique=True)
batch_op.create_index(batch_op.f('ix_cfs_credit_invoices_cfs_account'), ['cfs_account'], unique=False)
batch_op.create_index(batch_op.f('ix_cfs_credit_invoices_cfs_identifier'), ['cfs_identifier'], unique=False)
batch_op.create_index(batch_op.f('ix_cfs_credit_invoices_credit_id'), ['credit_id'], unique=False)

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('cfs_credit_invoices', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_cfs_credit_invoices_credit_id'))
batch_op.drop_index(batch_op.f('ix_cfs_credit_invoices_cfs_identifier'))
batch_op.drop_index(batch_op.f('ix_cfs_credit_invoices_cfs_account'))
batch_op.drop_index(batch_op.f('ix_cfs_credit_invoices_application_id'))
batch_op.drop_index(batch_op.f('ix_cfs_credit_invoices_account_id'))

op.drop_table('cfs_credit_invoices')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions pay-api/src/pay_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from .cfs_account_status_code import CfsAccountStatusCode, CfsAccountStatusCodeSchema
from .corp_type import CorpType, CorpTypeSchema # noqa: I001
from .credit import Credit
from .cfs_credit_invoices import CfsCreditInvoices
from .custom_query import CustomQuery
from .db import db, ma # noqa: I001
from .disbursement_status_code import DisbursementStatusCode
Expand Down
75 changes: 75 additions & 0 deletions pay-api/src/pay_api/models/cfs_credit_invoices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright © 2024 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model that is populated from feedback files."""
from datetime import datetime, timezone
from sqlalchemy import ForeignKey, func

from .base_model import BaseModel
from .db import db


# NOTE THIS IS SPECIFIC ONLY FOR PAD / ONLINE BANKING CREDIT MEMOS.
# This can also be seen in the ar_applied_receivables table in the CAS datawarehouse.
class CfsCreditInvoices(BaseModel):
"""This class manages the mapping from cfs account credit memos to invoices."""

__tablename__ = 'cfs_credit_invoices'
# this mapper is used so that new and old versions of the service can be run simultaneously,
# making rolling upgrades easier
# This is used by SQLAlchemy to explicitly define which fields we're interested
# so it doesn't freak out and say it can't map the structure if other fields are present.
# This could occur from a failed deploy or during an upgrade.
# The other option is to tell SQLAlchemy to ignore differences, but that is ambiguous
# and can interfere with Alembic upgrades.
#
# NOTE: please keep mapper names in alpha-order, easier to track that way
# Exception, id is always first, _fields first
__mapper_args__ = {
'include_properties': [
'id',
'account_id',
'amount_applied',
'application_id',
'cfs_account',
'cfs_identifier',
'created_on',
'credit_id',
'invoice_amount',
'invoice_number'
]
}

id = db.Column(db.Integer, primary_key=True, autoincrement=True)

account_id = db.Column(db.Integer, ForeignKey('payment_accounts.id'), nullable=True, index=True)
amount_applied = db.Column(db.Numeric, nullable=False)
# External application_id that comes straight from the CSV, looks like an identifier in an external system.
application_id = db.Column(db.Integer, nullable=True, index=True, unique=True)
cfs_account = db.Column(db.String(50), nullable=False, index=True)
cfs_identifier = db.Column(db.String(50), nullable=False, index=True)
created_on = db.Column('created_on', db.DateTime, nullable=False, default=lambda: datetime.now(tz=timezone.utc))
credit_id = db.Column(db.Integer, ForeignKey('credits.id'), nullable=True, index=True)
invoice_amount = db.Column(db.Numeric, nullable=False)
invoice_number = db.Column(db.String(50), nullable=False)

@classmethod
def credit_for_invoice_number(cls, invoice_number: str):
"""Return the credit associated with the invoice number."""
return cls.query.with_entities(func.sum(CfsCreditInvoices.amount_applied).label('credit_invoice_total')) \
.filter_by(invoice_number=invoice_number).scalar()

@classmethod
def find_by_application_id(cls, application_id: int):
"""Return the credit associated with the application id."""
return cls.query.filter_by(application_id=application_id).first()
6 changes: 3 additions & 3 deletions pay-queue/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pay-queue/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ itsdangerous = "^2.1.2"
protobuf = "4.25.3"
launchdarkly-server-sdk = "^8.2.1"
cachecontrol = "^0.14.0"
pay-api = {git = "https://github.com/seeker25/sbc-pay.git", subdirectory = "pay-api", branch = "21519"}
pay-api = {git = "https://github.com/seeker25/sbc-pay.git", subdirectory = "pay-api", branch = "19163"}
pg8000 = "^1.30.5"


Expand Down
Loading
Loading