Skip to content

Commit

Permalink
[13.0][Fix #25] Fixing validation date offset (#34)
Browse files Browse the repository at this point in the history
[Fix #25] Fixing validation date offset

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 authored Jan 6, 2025
1 parent f69ca67 commit 9b07304
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 9b07304

Please sign in to comment.