From c89b0ce520adfaf0634cf3c985d12c33313e922f Mon Sep 17 00:00:00 2001 From: "Luis J. Salvatierra" Date: Thu, 8 Aug 2024 09:19:55 +0200 Subject: [PATCH] [UPD] account_statement_import_online_gocardless: refactor requests methods --- .../models/online_bank_statement_provider.py | 113 ++++++++---------- 1 file changed, 49 insertions(+), 64 deletions(-) diff --git a/account_statement_import_online_gocardless/models/online_bank_statement_provider.py b/account_statement_import_online_gocardless/models/online_bank_statement_provider.py index a3fc2559d..c02c91ab6 100644 --- a/account_statement_import_online_gocardless/models/online_bank_statement_provider.py +++ b/account_statement_import_online_gocardless/models/online_bank_statement_provider.py @@ -13,7 +13,7 @@ from odoo.exceptions import UserError from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF -GOCARDLESS_ENDPOINT = "https://bankaccountdata.gocardless.com/api/v2" +GOCARDLESS_API = "https://bankaccountdata.gocardless.com/api/v2" REQUESTS_TIMEOUT = 60 @@ -46,6 +46,31 @@ def _get_available_services(self): ("gocardless", "GoCardless"), ] + def _gocardless_get_headers(self, basic=False): + """Generic method for providing the needed request headers.""" + self.ensure_one() + headers = { + "accept": "application/json", + "Content-Type": "application/json", + } + if not basic: + headers["Authorization"] = f"Bearer {self._gocardless_get_token()}" + return headers + + def _gocardless_request(self, endpoint, request_type="get", params=None, data=None): + content = {} + url = url_join(GOCARDLESS_API, endpoint) + response = getattr(requests, request_type)( + url, + data=data, + params=params, + headers=self._gocardless_get_headers(), + timeout=REQUESTS_TIMEOUT, + ) + if response.status_code in [200, 201]: + content = json.loads(response.text) + return response, content + def _gocardless_get_token(self): """Resolve and return the corresponding GoCardless token for doing the requests. If there's still no token, it's requested. If it exists, but it's expired and @@ -59,20 +84,16 @@ def _gocardless_get_token(self): self.gocardless_refresh_token and now > self.gocardless_refresh_expiration ): - url = f"{GOCARDLESS_ENDPOINT}/token/refresh/" + endpoint = "token/refresh" else: - url = f"{GOCARDLESS_ENDPOINT}/token/new/" - response = requests.post( - url, + endpoint = "token/new" + _response, data = self._gocardless_request( + endpoint, + request_type="post", data=json.dumps( {"secret_id": self.username, "secret_key": self.password} ), - headers=self._gocardless_get_headers(basic=True), - timeout=REQUESTS_TIMEOUT, ) - data = {} - if response.status_code == 200: - data = json.loads(response.text) expiration_date = now + relativedelta(seconds=data.get("access_expires", 0)) vals = { "gocardless_token": data.get("access", False), @@ -86,17 +107,6 @@ def _gocardless_get_token(self): self.sudo().write(vals) return self.gocardless_token - def _gocardless_get_headers(self, basic=False): - """Generic method for providing the needed request headers.""" - self.ensure_one() - headers = { - "accept": "application/json", - "Content-Type": "application/json", - } - if not basic: - headers["Authorization"] = f"Bearer {self._gocardless_get_token()}" - return headers - def action_select_gocardless_bank(self): if not self.journal_id.bank_account_id: raise UserError( @@ -137,15 +147,12 @@ def _gocardless_select_bank_instituion(self): country = ( self.journal_id.bank_account_id.company_id or self.journal_id.company_id ).country_id - response = requests.get( - f"{GOCARDLESS_ENDPOINT}/institutions/", - params={"country": country.code}, - headers=self._gocardless_get_headers(), - timeout=REQUESTS_TIMEOUT, + response, data = self._gocardless_request( + "institutions", params={"country": country.code} ) if response.status_code == 400: raise UserError(_("Incorrect country code or country not supported.")) - institutions = json.loads(response.text) + institutions = data # Prepare data for being showed in the JS widget ctx = self.env.context.copy() ctx.update( @@ -172,8 +179,9 @@ def action_check_gocardless_agreement(self): self.gocardless_requisition_ref = str(uuid4()) base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url") redirect_url = url_join(base_url, "gocardless/response") - response = requests.post( - f"{GOCARDLESS_ENDPOINT}/requisitions/", + _response, data = self._gocardless_request( + "requisitions", + request_type="post", data=json.dumps( { "redirect": redirect_url, @@ -181,44 +189,26 @@ def action_check_gocardless_agreement(self): "reference": self.gocardless_requisition_ref, } ), - headers=self._gocardless_get_headers(), - timeout=REQUESTS_TIMEOUT, ) - if response.status_code == 201: - requisition_data = json.loads(response.text) + if data: + requisition_data = data self.gocardless_requisition_id = requisition_data["id"] # JS code expects here to return a plain link or nothing return requisition_data["link"] def _gocardless_request_requisition(self): - response = requests.get( - f"{GOCARDLESS_ENDPOINT}/requisitions/{self.gocardless_requisition_id}/", - headers=self._gocardless_get_headers(), - timeout=REQUESTS_TIMEOUT, + _response, data = self._gocardless_request( + f"requisitions/{self.gocardless_requisition_id}" ) - if response.status_code == 200: - return json.loads(response.text) - return {} + return data def _gocardless_request_account(self, account_id): - response = requests.get( - f"{GOCARDLESS_ENDPOINT}/accounts/{account_id}/", - headers=self._gocardless_get_headers(), - timeout=REQUESTS_TIMEOUT, - ) - if response.status_code == 200: - return json.loads(response.text) - return {} + _response, data = self._gocardless_request(f"accounts/{account_id}") + return data def _gocardless_request_agreement(self, agreement_id): - response = requests.get( - f"{GOCARDLESS_ENDPOINT}/agreements/enduser/" f"{agreement_id}/", - headers=self._gocardless_get_headers(), - timeout=REQUESTS_TIMEOUT, - ) - if response.status_code == 200: - return json.loads(response.text) - return {} + _response, data = self._gocardless_request(f"agreements/enduser/{agreement_id}") + return data def _gocardless_finish_requisition(self, dry=False): """Once the requisiton to the bank institution has been made, and this is called @@ -295,19 +285,14 @@ def _gocardless_request_transactions(self, date_since, date_until): now = fields.Datetime.now() if now > date_since and now < date_until: date_until = now - transaction_response = requests.get( - f"{GOCARDLESS_ENDPOINT}/accounts/" - f"{self.gocardless_account_id}/transactions/", + _response, data = self._gocardless_request( + f"accounts/{self.gocardless_account_id}/transactions", params={ "date_from": date_since.strftime(DF), "date_to": date_until.strftime(DF), }, - headers=self._gocardless_get_headers(), - timeout=REQUESTS_TIMEOUT, ) - if transaction_response.status_code == 200: - return json.loads(transaction_response.text) - return {} + return data def _gocardless_obtain_statement_data(self, date_since, date_until): """Called from the cron or the manual pull wizard to obtain transactions for