diff --git a/jobs/payment-jobs/tasks/common/dataclasses.py b/jobs/payment-jobs/tasks/common/dataclasses.py index c6da9ec17..e8b747bc0 100644 --- a/jobs/payment-jobs/tasks/common/dataclasses.py +++ b/jobs/payment-jobs/tasks/common/dataclasses.py @@ -22,13 +22,20 @@ @dataclass -class RevenueLine(JSONWizard): - """Revenue line from order status query.""" +class RefundData(JSONWizard): + """Refund data from order status query.""" refundglstatus: Optional[PaymentDetailsGlStatus] refundglerrormessage: str +@dataclass +class RevenueLine(JSONWizard): + """Revenue line from order status query.""" + + refund_data: List[RefundData] + + @dataclass class OrderStatus(JSONWizard): # pylint:disable=too-many-instance-attributes """Return from order status query.""" diff --git a/jobs/payment-jobs/tasks/direct_pay_automated_refund_task.py b/jobs/payment-jobs/tasks/direct_pay_automated_refund_task.py index 9feef1995..e3976530e 100644 --- a/jobs/payment-jobs/tasks/direct_pay_automated_refund_task.py +++ b/jobs/payment-jobs/tasks/direct_pay_automated_refund_task.py @@ -108,7 +108,8 @@ def _query_order_status(cls, invoice: Invoice): def _refund_error(cls, status: OrderStatus, invoice: Invoice): """Log error for rejected GL status.""" current_app.logger.error(f'Refund error - Invoice: {invoice.id} - detected RJCT on refund, contact PAYBC.') - errors = ' '.join([revenue_line.refundglerrormessage.strip() for revenue_line in status.revenue])[:250] + errors = ' '.join([refund_data.refundglerrormessage.strip() for revenue_line in status.revenue + for refund_data in revenue_line.refund_data])[:250] current_app.logger.error(f'Refund error - Invoice: {invoice.id} - glerrormessage: {errors}') refund = RefundModel.find_by_invoice_id(invoice.id) refund.gl_error = errors @@ -135,21 +136,30 @@ def _refund_complete(cls, invoice: Invoice): @staticmethod def _is_glstatus_rejected(status: OrderStatus) -> bool: """Check for bad refundglstatus.""" - return any(line.refundglstatus == PaymentDetailsGlStatus.RJCT - for line in status.revenue) + return any(refund_data.refundglstatus == PaymentDetailsGlStatus.RJCT + for line in status.revenue for refund_data in line.refund_data) @staticmethod def _is_status_paid_and_invoice_refund_requested(status: OrderStatus, invoice: Invoice) -> bool: """Check for successful refund and invoice status = REFUND_REQUESTED.""" - return all(line.refundglstatus == PaymentDetailsGlStatus.PAID - for line in status.revenue) \ - and invoice.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value + for line in status.revenue: + if len(line.refund_data) == 0: + return False + for refund_data in line.refund_data: + if refund_data.refundglstatus != PaymentDetailsGlStatus.PAID: + return False + return invoice.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value @staticmethod def _is_status_complete(status: OrderStatus) -> bool: """Check for successful refund.""" - return all(line.refundglstatus == PaymentDetailsGlStatus.CMPLT - for line in status.revenue) + for line in status.revenue: + if len(line.refund_data) == 0: + return False + for refund_data in line.refund_data: + if refund_data.refundglstatus != PaymentDetailsGlStatus.CMPLT: + return False + return True @staticmethod def _set_invoice_and_payment_to_refunded(invoice: Invoice): diff --git a/jobs/payment-jobs/tests/jobs/test_direct_pay_automated_refund_task.py b/jobs/payment-jobs/tests/jobs/test_direct_pay_automated_refund_task.py index 545d19ee0..f7dc306d5 100644 --- a/jobs/payment-jobs/tests/jobs/test_direct_pay_automated_refund_task.py +++ b/jobs/payment-jobs/tests/jobs/test_direct_pay_automated_refund_task.py @@ -43,8 +43,12 @@ def payment_status(cls): # pylint: disable=unused-argument; mocks of library me return { 'revenue': [ { - 'refundglstatus': 'PAID', - 'refundglerrormessage': '' + 'refund_data': [ + { + 'refundglstatus': 'PAID', + 'refundglerrormessage': '' + } + ] } ] } @@ -69,8 +73,12 @@ def payment_status(cls): # pylint: disable=unused-argument; mocks of library me return { 'revenue': [ { - 'refundglstatus': 'CMPLT', - 'refundglerrormessage': '' + 'refund_data': [ + { + 'refundglstatus': 'CMPLT', + 'refundglerrormessage': '' + } + ] } ] } @@ -101,8 +109,12 @@ def payment_status(cls): # pylint: disable=unused-argument; mocks of library me 'revenueamount': '130', 'glstatus': 'PAID', 'glerrormessage': None, - 'refundglstatus': 'RJCT', - 'refundglerrormessage': 'BAD' + 'refund_data': [ + { + 'refundglstatus': 'RJCT', + 'refundglerrormessage': 'BAD' + } + ] }, { 'linenumber': '2', @@ -110,8 +122,12 @@ def payment_status(cls): # pylint: disable=unused-argument; mocks of library me 'revenueamount': '1.5', 'glstatus': 'PAID', 'glerrormessage': None, - 'refundglstatus': 'RJCT', - 'refundglerrormessage': 'BAD' + 'refund_data': [ + { + 'refundglstatus': 'RJCT', + 'refundglerrormessage': 'BAD' + } + ] } ] }