Skip to content

Commit

Permalink
[Fix #25] Fixing validation date offset
Browse files Browse the repository at this point in the history
Currently, validation dates on transactions are stored in the French
timezone, but in Odoo the timezone is expected to be in UTC.
A minor fix is needed in the _payfip_evaluate_data method to
convert the timezone into a UTC one.

Migrate all previous dates validations to fix the timezone issue.
All transactions are processed in chunk of one hundred.

Signed-off-by: Logan Gonet <[email protected]>
  • Loading branch information
Warlocklogan committed Dec 31, 2024
1 parent f69ca67 commit 368d37e
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 43 deletions.
10 changes: 3 additions & 7 deletions payment_payfip/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
'name': "Intermédiaire de paiement PayFIP",
'version': '13.0.1.0.0',
'version': '13.0.24.12.31',
'summary': """Intermédiaire de paiement : Implémentation de PayFIP""",
'author': "Horanet",
'website': "https://www.horanet.com/",
Expand All @@ -11,23 +11,19 @@
'openupgradelib',
]
},
'depends': [
'payment'
],
'depends': ['payment'],
'qweb': [],
'init_xml': [],
'update_xml': [],
'data': [
# Views must be before data to avoid loading issues
'views/payment_payfip_templates.xml',
'views/payment_views.xml',

'data/payment_acquirer.xml',
'data/draft_payments_recovered_mail.xml',
'data/cron_check_drafts.xml',
],
'demo': [
],
'demo': [],
'application': False,
'auto_install': False,
'installable': True,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import logging
import pytz

from openupgradelib import openupgrade

from odoo import fields

_logger = logging.getLogger(__name__)


@openupgrade.migrate(use_env=True)
def migrate(env, version):
"""Migrate Payfip transaction confirmation date to UTC date instead of french timezone."""
# Payfip timezone
payfip_tz = pytz.timezone('Europe/Paris')
# Retreive all payfip transaction with a confirmation date
payfip_transactions = env['payment.transaction'].search(
[
('acquirer_id.provider', '=', 'payfip'),
('date_validate', '!=', False),
]
)

_logger.info(f"Number of Payfip transaction to migrate : {len(payfip_transactions)}")
chunk_size = 100
# Chunk transactions for processing
payfip_transactions_chunked = [
payfip_transactions[i : i + chunk_size] for i in range(0, len(payfip_transactions), chunk_size)
]

for idx, payfip_transaction_chunk in enumerate(payfip_transactions_chunked, start=1):
_logger.info(f"Payfip transaction processing chunk : {idx}/{len(payfip_transactions_chunked)}")
for payfip_transaction in payfip_transaction_chunk:
# Validate date to datetime object
date_validate = fields.Datetime.from_string(payfip_transaction.date_validate)
# Localize datetime and transform into an UTC one
utc_date_validate = payfip_tz.localize(date_validate).astimezone(pytz.UTC).replace(tzinfo=None)
# Set UTC value into datetime
payfip_transaction.date_validate = utc_date_validate
_logger.info(f"Payfip transaction all chunks have been processed.")
85 changes: 49 additions & 36 deletions payment_payfip/models/inherited_payment_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def create(self, vals):
def action_payfip_check_transaction(self):
self.ensure_one()
self._payfip_check_transactions()

# endregion

# region Model methods
Expand Down Expand Up @@ -149,45 +150,52 @@ def _payfip_evaluate_data(self, data=False):
hour = int(payfip_datetime[:2])
minute = int(payfip_datetime[2:4])
td_minute = timedelta(minutes=1)
payfip_tz = pytz.timezone('Europe/Paris')
date_validate = datetime(year, month, day, hour=hour, minute=minute) + td_minute

self.write({
'state': 'done',
'payfip_state': result,
'date': date_validate,
'payfip_amount': payfip_amount,
})
date_validate = payfip_tz.localize(date_validate).astimezone(pytz.UTC).replace(tzinfo=None)

self.write(
{
'state': 'done',
'payfip_state': result,
'date': date_validate,
'payfip_amount': payfip_amount,
}
)
return True
elif result in ['A']:
message = 'Received notification for PayFIP payment %s: set as canceled' % self.reference
_logger.info(message)
self.write({
'state': 'cancel',
'payfip_state': result,
'payfip_amount': payfip_amount,
})
self.write(
{
'state': 'cancel',
'payfip_state': result,
'payfip_amount': payfip_amount,
}
)
return True
elif result in ['R', 'Z']:
message = 'Received notification for PayFIP payment %s: set as error' % self.reference
_logger.info(message)
self.write({
'state': 'error',
'payfip_state': result,
'state_message': message,
'payfip_amount': payfip_amount,
})
self.write(
{
'state': 'error',
'payfip_state': result,
'state_message': message,
'payfip_amount': payfip_amount,
}
)
return True
else:
message = 'Received unrecognized status for PayFIP payment %s: %s, set as error' % (
self.reference,
result
)
message = 'Received unrecognized status for PayFIP payment %s: %s, set as error' % (self.reference, result)
_logger.error(message)
self.write({
'state': 'error',
'payfip_state': 'U',
'state_message': message,
})
self.write(
{
'state': 'error',
'payfip_state': 'U',
'state_message': message,
}
)
return False

@api.model
Expand All @@ -212,20 +220,25 @@ def payfip_cron_check_draft_payment_transactions(self, options=None):
transaction_model = self.env['payment.transaction']
acquirer_model = self.env['payment.acquirer']

payfip_acquirers = acquirer_model.search([
('provider', '=', 'payfip'),
])
transactions = transaction_model.search([
('acquirer_id', 'in', payfip_acquirers.ids),
('state', 'in', ['draft', 'pending']),
('payfip_operation_identifier', 'not in', [False, '']),
('create_date', '>=', date_from),
])
payfip_acquirers = acquirer_model.search(
[
('provider', '=', 'payfip'),
]
)
transactions = transaction_model.search(
[
('acquirer_id', 'in', payfip_acquirers.ids),
('state', 'in', ['draft', 'pending']),
('payfip_operation_identifier', 'not in', [False, '']),
('create_date', '>=', date_from),
]
)

for tx in transactions:
self.env['payment.transaction'].form_feedback(tx.payfip_operation_identifier, 'payfip')

if send_summary:
mail_template = self.env.ref('payment_payfip.mail_template_draft_payments_recovered')
mail_template.with_context(transactions=transactions).send_mail(self.env.user.id)

# endregion

0 comments on commit 368d37e

Please sign in to comment.