Skip to content

since migrating to 14 rejected payment order are not treated#272

Closed
davidwul wants to merge 3 commits intoCompassionCH:14.0from
davidwul:14.0-gift_wizard
Closed

since migrating to 14 rejected payment order are not treated#272
davidwul wants to merge 3 commits intoCompassionCH:14.0from
davidwul:14.0-gift_wizard

Conversation

@davidwul
Copy link
Contributor

No description provided.

@gemini-code-assist
Copy link

Summary of Changes

Hello @davidwul, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily addresses a critical issue where rejected payment orders were not being properly processed after a migration to Odoo 14. It enhances the payment return mechanism to correctly identify and handle rejected transactions, ensuring that associated payment lines are freed and states are updated appropriately. Additionally, the PR includes a minor correction in the recurring contract module and a substantial cleanup of the project's Odoo addon packaging setup, streamlining the build process.

Highlights

  • Payment Order State Expansion: Rejected payment orders are now processed not only when in the "generated" state but also when in the "uploaded" state, ensuring comprehensive handling of rejections.
  • Payment Line Identification Refinement: The logic for identifying specific payment lines associated with rejected transactions in PAIN002 messages has been updated to correctly link to payment_ids and payment_line_ids in the Odoo 14 context.
  • Robust Payment Line Freeing: The process of freeing individual payment lines upon rejection has been made more robust with iterative processing, improved logging, and error handling.
  • Build System Simplification: A significant number of setup.py files and related Odoo addon packaging configurations have been removed, indicating a cleanup and streamlining of the project's build system.
  • Contract Reference Correction: A minor fix was applied in the recurring_contract module to correctly reference current_contract_id instead of contract_id when building invoice line data from a gift wizard.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@davidwul davidwul closed this Jan 12, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to fix an issue where rejected payment orders are not processed correctly, which seems to be a problem since migrating to Odoo 14. The main changes are in account_ebics_payment_return to handle the 'uploaded' state for payment orders and to correctly identify payment lines for rejected transactions. While the intent is clear, I've found a few issues. There's a critical bug in the logic for finding payment lines that could lead to application crashes. I've also suggested improvements for error handling and code style to enhance robustness and maintainability. The change in recurring_contract and the removal of setup files appear to be correct.

Comment on lines +124 to +128
endtoend_id=t.find("./ns:OrgnlEndToEndId", namespaces={"ns": ns}).text
payment_id = payment_order.payment_ids.filtered(
lambda l: l.move_id.id == int(endtoend_id))
payment_line_ids = payment_order.payment_line_ids.filtered(lambda l: l.payment_ids.id ==payment_id.id)
_logger.info(f"PAIN002 payment_line_ids: {payment_id.name} with endtoend_id: {endtoend_id}", )

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The logic for finding payment_line_ids has several critical issues that could lead to runtime errors and incorrect behavior:

  1. int(endtoend_id) will raise a ValueError if endtoend_id from the XML is not a string representing an integer. This will crash the import process and should be handled gracefully.
  2. The result of filtered, payment_id, is a recordset. If no payment is found, it will be empty. If multiple are found, it will contain multiple records. Accessing attributes like .id or .name will fail if payment_id is not a singleton recordset. This needs to be handled, for example by using ensure_one().
  3. The expression l.payment_ids.id == payment_id.id is incorrect. l.payment_ids is a Many2many field, so it's a recordset and doesn't have an .id attribute. You should check for membership, e.g., payment in l.payment_ids.
  4. The log message is confusing as it says payment_line_ids but logs payment_id.name.
                        endtoend_id = t.find("./ns:OrgnlEndToEndId", namespaces={"ns": ns}).text
                        try:
                            move_id = int(endtoend_id)
                        except (ValueError, TypeError):
                            _logger.warning(f"PAIN002: Invalid OrgnlEndToEndId '{endtoend_id}'.")
                            continue
                        payment = payment_order.payment_ids.filtered(
                            lambda p: p.move_id.id == move_id
                        )
                        if not payment:
                            _logger.warning(f"PAIN002: No payment found for move_id {move_id}.")
                            continue
                        payment.ensure_one()
                        payment_line_ids = payment_order.payment_line_ids.filtered(
                            lambda l: payment in l.payment_ids
                        )
                        _logger.info(
                            f"PAIN002 found payment lines {payment_line_ids.ids} for payment {payment.name} with endtoend_id: {endtoend_id}"
                        )

)
_logger.info("PAIN002 payment_order: %s", payment_order)
if payment_order.state == "generated":
if payment_order.state in ("generated","uploaded"):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better readability and adherence to PEP 8 style guidelines, it's recommended to add a space after the comma within the tuple.

Suggested change
if payment_order.state in ("generated","uploaded"):
if payment_order.state in ("generated", "uploaded"):
References
  1. PEP 8 suggests adding a space after commas in tuples, dicts, and lists to improve readability. (link)

Comment on lines +139 to +144
for b in payment_line_ids:
try:
b.free_line(rsn_txt)
_logger.info(f"PAIN002 line free: {rsn_txt}" ,)
except Exception as e:
_logger.info(f"error line free: {e}" ,)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The try...except block is a good addition for robustness. However, it can be improved:

  1. Catching the generic Exception is too broad. The free_line method raises odoo.exceptions.UserError. It's better to catch this specific exception to avoid hiding other unexpected errors.
  2. When an error occurs, logging it with _logger.info is not ideal for an error condition. _logger.warning or _logger.error would be more appropriate to highlight the problem. The log message should also include more context, like which payment line failed.
  3. The trailing comma in the logger calls is unnecessary and can be removed for cleaner code.
                        for b in payment_line_ids:
                            try:
                                b.free_line(rsn_txt)
                                _logger.info(f"PAIN002 line free: {rsn_txt}")
                            except UserError as e:
                                _logger.error(f"Error freeing line {b.id}: {e}")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant