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

Refund fixes #1700

Merged
merged 9 commits into from
Aug 21, 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
6 changes: 3 additions & 3 deletions jobs/payment-jobs/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 jobs/payment-jobs/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"
pay-api = {git = "https://github.com/seeker25/sbc-pay.git", branch = "21597_", subdirectory = "pay-api"}
pay-api = {git = "https://github.com/seeker25/sbc-pay.git", branch = "refund_fixes", subdirectory = "pay-api"}
gunicorn = "^21.2.0"
flask = "^3.0.2"
flask-sqlalchemy = "^3.1.1"
Expand Down
16 changes: 15 additions & 1 deletion jobs/payment-jobs/tasks/eft_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from pay_api.services.cfs_service import CFSService
from pay_api.services.eft_service import EftService
from pay_api.services.invoice import Invoice as InvoiceService
from pay_api.utils.constants import CFS_ADJ_ACTIVITY_NAME
from pay_api.utils.enums import (
CfsAccountStatus, DisbursementStatus, EFTCreditInvoiceStatus, InvoiceReferenceStatus, InvoiceStatus, PaymentMethod,
PaymentStatus, PaymentSystem, ReverseOperation)
Expand Down Expand Up @@ -319,10 +320,23 @@ def _handle_invoice_refund(cls,
invoice_reference: InvoiceReferenceModel):
"""Handle invoice refunds adjustment on a non-rolled up invoice."""
if invoice_reference:
CFSService.adjust_invoice(cfs_account, invoice_reference.invoice_number, -invoice.total)
adjustment_lines = cls._build_reversal_adjustment_lines(invoice)
CFSService.adjust_invoice(cfs_account, invoice_reference.invoice_number, adjustment_lines=adjustment_lines)
invoice_reference.status_code = InvoiceReferenceStatus.CANCELLED.value
invoice_reference.flush()
invoice.invoice_status_code = InvoiceStatus.REFUNDED.value
invoice.refund_date = datetime.now(tz=timezone.utc)
invoice.refund = invoice.total
invoice.flush()

@classmethod
def _build_reversal_adjustment_lines(cls, invoice: InvoiceModel) -> list:
"""Build the adjustment lines for the invoice."""
return [
{
'line_number': line['line_number'],
'adjustment_amount': line['unit_price'],
'activity_name': CFS_ADJ_ACTIVITY_NAME
}
for line in CFSService.build_lines(invoice.payment_line_items, negate=True)
]
8 changes: 4 additions & 4 deletions jobs/payment-jobs/tests/jobs/test_eft_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ def test_reverse_electronic_funds_transfers(session):
session.commit()

with patch('pay_api.services.CFSService.reverse_rs_receipt_in_cfs') as mock_reverse:
with patch('pay_api.services.CFSService.adjust_invoice') as mock_adjust_invoice:
with patch('pay_api.services.CFSService.adjust_invoice') as mock_invoice:
EFTTask.reverse_electronic_funds_transfers_cfs()
mock_adjust_invoice.assert_called()
mock_invoice.assert_called()
mock_reverse.assert_called()

assert invoice_reference.status_code == InvoiceReferenceStatus.ACTIVE.value
Expand Down Expand Up @@ -328,9 +328,9 @@ def test_handle_unlinked_refund_requested_invoices(session):
invoice_ref_2 = factory_invoice_reference(invoice_id=invoice_2.id).save()
invoice_3 = factory_invoice(payment_account=payment_account, status_code=InvoiceStatus.REFUND_REQUESTED.value,
payment_method_code=PaymentMethod.EFT.value, total=10).save()
with patch('pay_api.services.CFSService.adjust_invoice') as mock_adjust_invoice:
with patch('pay_api.services.CFSService.adjust_invoice') as mock_invoice:
EFTTask.handle_unlinked_refund_requested_invoices()
mock_adjust_invoice.assert_called()
mock_invoice.assert_called()
# Has CIL so it's excluded
assert invoice_1.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value
# Has no CIL and invoice reference
Expand Down
2 changes: 1 addition & 1 deletion pay-api/poetry.lock

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

10 changes: 5 additions & 5 deletions pay-api/src/pay_api/services/cfs_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def create_account_invoice(cls, transaction_number: str, line_items: List[Paymen
'gl_date': curr_time,
'term_name': CFS_TERM_NAME,
'comments': '',
'lines': cls._build_lines(line_items)
'lines': cls.build_lines(line_items)
}

access_token = CFSService.get_token().json().get('access_token')
Expand All @@ -372,7 +372,7 @@ def _build_reversal_comment(cls, operation: ReverseOperation):
}.get(operation)

@classmethod
def _build_lines(cls, payment_line_items: List[PaymentLineItemModel], negate: bool = False):
def build_lines(cls, payment_line_items: List[PaymentLineItemModel], negate: bool = False):
"""Build lines for the invoice."""
# Fetch all distribution codes to reduce DB hits. Introduce caching if needed later
distribution_codes: List[DistributionCodeModel] = DistributionCodeModel.find_all()
Expand Down Expand Up @@ -491,7 +491,7 @@ def add_nsf_adjustment(cls, cfs_account: CfsAccountModel, inv_number: str, amoun
return adjustment_response.json()

@classmethod
def adjust_invoice(cls, cfs_account: CfsAccountModel, inv_number: str, amount=0.0):
def adjust_invoice(cls, cfs_account: CfsAccountModel, inv_number: str, amount=0.0, adjustment_lines=None):
"""Add adjustment to the invoice."""
current_app.logger.debug('>Creating Adjustment for Invoice: %s', inv_number)
access_token: str = CFSService.get_token().json().get('access_token')
Expand All @@ -502,7 +502,7 @@ def adjust_invoice(cls, cfs_account: CfsAccountModel, inv_number: str, amount=0.

adjustment = {
'comment': 'Invoice cancellation',
'lines': [
'lines': adjustment_lines or [
{
'line_number': '1',
'adjustment_amount': str(amount),
Expand Down Expand Up @@ -597,7 +597,7 @@ def create_cms(cls, line_items: List[PaymentLineItemModel], cfs_account: CfsAcco
'transaction_date': curr_time,
'gl_date': curr_time,
'comments': '',
'lines': cls._build_lines(line_items, negate=True)
'lines': cls.build_lines(line_items, negate=True)
}

cms_response = CFSService.post(cms_url, access_token, AuthHeaderType.BEARER, ContentType.JSON, cms_payload)
Expand Down
2 changes: 1 addition & 1 deletion pay-api/tests/unit/services/test_cfs_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,6 @@ def test_ensure_totals_quantized(session):
fee_distribution_id=1,
)
]
lines = cfs_service._build_lines(payment_line_items) # pylint: disable=protected-access
lines = cfs_service.build_lines(payment_line_items) # pylint: disable=protected-access
# Same distribution code for filing fees and service fees.
assert float(lines[0]['unit_price']) == 2.8
Loading