ponto: date field to use is now configurable

Add debug messages
Set raw_data in bank statement lines
This commit is contained in:
Alexis de Lattre
2023-01-19 12:43:35 +01:00
committed by Ronald Portier (Therp BV)
parent c32a65fe3c
commit d34fac97eb
3 changed files with 35 additions and 10 deletions

View File

@@ -8,7 +8,7 @@ from datetime import datetime
import pytz import pytz
from odoo import _, api, models from odoo import _, api, fields, models
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -16,6 +16,19 @@ _logger = logging.getLogger(__name__)
class OnlineBankStatementProviderPonto(models.Model): class OnlineBankStatementProviderPonto(models.Model):
_inherit = "online.bank.statement.provider" _inherit = "online.bank.statement.provider"
ponto_date_field = fields.Selection(
[
("execution_date", "Execution Date"),
("value_date", "Value Date"),
],
string="Ponto Date Field",
default="execution_date",
help="Select the Ponto date field that will be used for "
"the Odoo bank statement line date. If you change this parameter "
"on a provider that already has transactions, you will have to "
"purge the Ponto buffers.",
)
@api.model @api.model
def _get_available_services(self): def _get_available_services(self):
"""Each provider model must register its service.""" """Each provider model must register its service."""
@@ -46,7 +59,7 @@ class OnlineBankStatementProviderPonto(models.Model):
new_transactions = [] new_transactions = []
sequence = 0 sequence = 0
for transaction in lines: for transaction in lines:
date = self._ponto_get_execution_datetime(transaction) date = self._ponto_get_transaction_datetime(transaction)
if date < date_since or date > date_until: if date < date_since or date > date_until:
continue continue
sequence += 1 sequence += 1
@@ -69,7 +82,7 @@ class OnlineBankStatementProviderPonto(models.Model):
while transactions: while transactions:
lines.extend(transactions) lines.extend(transactions)
latest_identifier = transactions[-1].get("id") latest_identifier = transactions[-1].get("id")
earliest_datetime = self._ponto_get_execution_datetime(transactions[-1]) earliest_datetime = self._ponto_get_transaction_datetime(transactions[-1])
if earliest_datetime < date_since: if earliest_datetime < date_since:
break break
transactions = interface_model._get_transactions( transactions = interface_model._get_transactions(
@@ -90,7 +103,7 @@ class OnlineBankStatementProviderPonto(models.Model):
if attributes.get(x) if attributes.get(x)
] ]
ref = " ".join(ref_list) ref = " ".join(ref_list)
date = self._ponto_get_execution_datetime(transaction) date = self._ponto_get_transaction_datetime(transaction)
vals_line = { vals_line = {
"sequence": sequence, "sequence": sequence,
"date": date, "date": date,
@@ -106,7 +119,7 @@ class OnlineBankStatementProviderPonto(models.Model):
vals_line["partner_name"] = attributes["counterpartName"] vals_line["partner_name"] = attributes["counterpartName"]
return vals_line return vals_line
def _ponto_get_execution_datetime(self, transaction): def _ponto_get_transaction_datetime(self, transaction):
"""Get execution datetime for a transaction. """Get execution datetime for a transaction.
Odoo often names variables containing date and time just xxx_date or Odoo often names variables containing date and time just xxx_date or
@@ -114,12 +127,16 @@ class OnlineBankStatementProviderPonto(models.Model):
much for variables and fields of type datetime. much for variables and fields of type datetime.
""" """
attributes = transaction.get("attributes", {}) attributes = transaction.get("attributes", {})
return self._ponto_datetime_from_string(attributes.get("executionDate")) if self.ponto_date_field == "value_date":
datetime_str = attributes.get("valueDate")
else:
datetime_str = attributes.get("executionDate")
return self._ponto_datetime_from_string(datetime_str)
def _ponto_datetime_from_string(self, date_str): def _ponto_datetime_from_string(self, datetime_str):
"""Dates in Ponto are expressed in UTC, so we need to convert them """Dates in Ponto are expressed in UTC, so we need to convert them
to supplied tz for proper classification. to supplied tz for proper classification.
""" """
dt = datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%fZ") dt = datetime.strptime(datetime_str, "%Y-%m-%dT%H:%M:%S.%fZ")
dt = dt.replace(tzinfo=pytz.utc).astimezone(pytz.timezone(self.tz or "utc")) dt = dt.replace(tzinfo=pytz.utc).astimezone(pytz.timezone(self.tz or "utc"))
return dt.replace(tzinfo=None) return dt.replace(tzinfo=None)

View File

@@ -35,6 +35,7 @@ class PontoInterface(models.AbstractModel):
"Accept": "application/json", "Accept": "application/json",
"Authorization": "Basic %s" % login, "Authorization": "Basic %s" % login,
} }
_logger.debug(_("POST request on %s"), url)
response = requests.post( response = requests.post(
url, url,
params={"grant_type": "client_credentials"}, params={"grant_type": "client_credentials"},
@@ -67,6 +68,7 @@ class PontoInterface(models.AbstractModel):
def _set_access_account(self, access_data, account_number): def _set_access_account(self, access_data, account_number):
"""Set ponto account for bank account in access_data.""" """Set ponto account for bank account in access_data."""
url = PONTO_ENDPOINT + "/accounts" url = PONTO_ENDPOINT + "/accounts"
_logger.debug(_("GET request on %s"), url)
response = requests.get( response = requests.get(
url, params={"limit": 100}, headers=self._get_request_headers(access_data) url, params={"limit": 100}, headers=self._get_request_headers(access_data)
) )
@@ -124,13 +126,14 @@ class PontoInterface(models.AbstractModel):
"""Interact with Ponto to get next page of data.""" """Interact with Ponto to get next page of data."""
headers = self._get_request_headers(access_data) headers = self._get_request_headers(access_data)
_logger.debug( _logger.debug(
_("Get request to %s, with headers %s and params %s"), url, params, headers _("GET request to %s with headers %s and params %s"), url, params, headers
) )
response = requests.get(url, params=params, headers=headers) response = requests.get(url, params=params, headers=headers)
return self._get_response_data(response) return self._get_response_data(response)
def _get_response_data(self, response): def _get_response_data(self, response):
"""Get response data for GET or POST request.""" """Get response data for GET or POST request."""
_logger.debug(_("HTTP answer code %s from Ponto"), response.status_code)
if response.status_code not in (200, 201): if response.status_code not in (200, 201):
raise UserError( raise UserError(
_("Server returned status code %s: %s") _("Server returned status code %s: %s")

View File

@@ -9,9 +9,14 @@
/> />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//group[@name='main']" position="inside"> <xpath expr="//group[@name='main']" position="inside">
<group name="ponto" attrs="{'invisible':[('service','!=','ponto')]}"> <group
name="ponto"
string="Ponto Config"
attrs="{'invisible':[('service','!=','ponto')]}"
>
<field name="username" string="Login" /> <field name="username" string="Login" />
<field name="password" string="Secret Key" /> <field name="password" string="Secret Key" />
<field name="ponto_date_field" />
</group> </group>
</xpath> </xpath>
</field> </field>