From 187bb3e40f3f17031c0ec2091f048a3479bb69cd Mon Sep 17 00:00:00 2001 From: mileomai2008 Date: Tue, 4 Oct 2022 14:33:58 +0100 Subject: [PATCH] OD-2177 download report from Adyen --- .../controllers/main.py | 37 ++++++++----- .../models/payment_acquirer.py | 55 ++++++++++++++++++- .../views/payment_views.xml | 10 ++++ 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/addons/payment_adyen_paybylink/controllers/main.py b/addons/payment_adyen_paybylink/controllers/main.py index 63ea206d506ee..fbb99101a20c1 100644 --- a/addons/payment_adyen_paybylink/controllers/main.py +++ b/addons/payment_adyen_paybylink/controllers/main.py @@ -37,24 +37,30 @@ def adyen_notification(self, **post): ) try: # Check the integrity of the notification - tx_sudo = request.env['payment.transaction'].sudo().\ - _adyen_form_get_tx_from_data(post) - self._verify_notification_signature(post, tx_sudo) - - # Check whether the event of the notification succeeded and - # reshape the notification data for parsing event_code = post['eventCode'] - if event_code in ('AUTHORISATION', 'REFUND') and post['success'] == 'true': - post['authResult'] = 'AUTHORISED' + if event_code == 'REPORT_AVAILABLE' and post['success'] == 'true': + # 'merchantReference': '' + # 'psp_reference': 'settlement_detail_report_batch_554.xlsx' + acquirer = request.env['payment.acquirer'].sudo()._adyen_get_acquirer_from_data(post) + acquirer.download_report(post) + else: + tx_sudo = request.env['payment.transaction'].sudo(). \ + _adyen_form_get_tx_from_data(post) + self._verify_notification_signature(post, tx_sudo) - # Handle the notification data - request.env['payment.transaction'].sudo().form_feedback( - post, 'adyen') + # Check whether the event of the notification succeeded and + # reshape the notification data for parsing + if event_code in ('AUTHORISATION', 'REFUND') and post['success'] == 'true': + post['authResult'] = 'AUTHORISED' - # Handle fraud cases - elif (event_code == 'NOTIFICATION_OF_CHARGEBACK' and - post['success'] == 'true'): - tx_sudo.process_fraud_case(post) + # Handle the notification data + request.env['payment.transaction'].sudo().form_feedback( + post, 'adyen') + + # Handle fraud cases + elif (event_code == 'NOTIFICATION_OF_CHARGEBACK' and + post['success'] == 'true'): + tx_sudo.process_fraud_case(post) # Acknowledge the notification to avoid getting spammed except ValidationError: @@ -107,6 +113,7 @@ def _compute_signature(payload, hmac_key): :return: The computed signature :rtype: str """ + def _flatten_dict(_value, _path_base='', _separator='.'): """ Recursively generate a flat representation of a dict. diff --git a/addons/payment_adyen_paybylink/models/payment_acquirer.py b/addons/payment_adyen_paybylink/models/payment_acquirer.py index c2e7df960429a..7fdfac60e4588 100644 --- a/addons/payment_adyen_paybylink/models/payment_acquirer.py +++ b/addons/payment_adyen_paybylink/models/payment_acquirer.py @@ -3,18 +3,32 @@ import logging import re import requests +import subprocess from werkzeug import urls from odoo import _, api, fields, models -from odoo.exceptions import ValidationError +from odoo.exceptions import ValidationError, UserError from odoo.addons.payment_adyen_paybylink.const import API_ENDPOINT_VERSIONS - _logger = logging.getLogger(__name__) +def runcmd(cmd, verbose=False, *args, **kwargs): + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + shell=True + ) + std_out, std_err = process.communicate() + if verbose: + _logger.info(std_out.strip(), std_err) + pass + + class PaymentAcquirer(models.Model): _inherit = 'payment.acquirer' @@ -40,6 +54,8 @@ class PaymentAcquirer(models.Model): # the 'NOT NULL' constraint on those fields. adyen_skin_code = fields.Char(default="Do not use this field") adyen_skin_hmac_key = fields.Char(default="Do not use this field") + adyen_report_user = fields.Char(string="Report User") + adyen_report_password = fields.Char(string="Reporting Password") @api.model_create_multi def create(self, values_list): @@ -102,6 +118,40 @@ def adyen_get_form_action_url(self): form_action_url_values['adyen_paybylink_data']) return False + @api.model + def _adyen_get_acquirer_from_data(self, data): + merchant_account = data.get('merchantAccountCode') + if not merchant_account: + error_msg = _('Adyen: received data with missing merchant account code') + _logger.info(error_msg) + raise ValidationError(error_msg) + acquirer = self.search([("adyen_merchant_account", "=", merchant_account)]) + if not acquirer: + error_msg = _(f'No Valid Merchant Account Was Found.\n ' + f'Merchant Account Code:({merchant_account})') + _logger.info(error_msg) + raise ValidationError(error_msg) + return acquirer + + def download_report(self, post): + """ Download bank statement report from Adyen to the server + """ + path = '/tmp/adyen/bank_statement/' + cmd = "mkdir -p {path} && wget -P {path} --http-user='{user}@Company.VANMOOF' " \ + "--http-password='{pwd}' --no-check-certificate {url}".format( + path=path, user=self.adyen_report_user, + pwd=self.adyen_report_password, url=post["reason"]) + try: + _logger.debug('Downloading {url} to {path}{file}'.format( + file=post['pspReference'], url=post["reason"], path=path)) + runcmd(cmd, verbose=True) + return path + post['pspReference'] + except Exception as e: + message = f" Download Failed for Ayden Report notification {post} \n " \ + f"with the exception: {e.args[0]}." + _logger.error(message) + raise UserError(message) + def _adyen_get_paybylink(self, data): paybylink_response = self._adyen_make_request( url_field_name='adyen_checkout_api_url', @@ -173,3 +223,4 @@ def _build_url(_base_url, _version, _endpoint): raise ValidationError( "Adyen: " + _("The communication with the API failed.")) return response.json() + diff --git a/addons/payment_adyen_paybylink/views/payment_views.xml b/addons/payment_adyen_paybylink/views/payment_views.xml index c88f4b4afe717..a1572ef693f96 100644 --- a/addons/payment_adyen_paybylink/views/payment_views.xml +++ b/addons/payment_adyen_paybylink/views/payment_views.xml @@ -19,6 +19,16 @@ + + + + + + + + +