Skip to content

Comments

[REF] sale_exception_credit_limit: evaluate debt at company hierarchy level#1566

Open
matiasperalta1 wants to merge 1 commit intoingadhoc:19.0from
adhoc-dev:19.0-t-62207-mnp
Open

[REF] sale_exception_credit_limit: evaluate debt at company hierarchy level#1566
matiasperalta1 wants to merge 1 commit intoingadhoc:19.0from
adhoc-dev:19.0-t-62207-mnp

Conversation

@matiasperalta1
Copy link
Contributor

No description provided.

Copilot AI review requested due to automatic review settings February 5, 2026 14:46
@roboadhoc
Copy link
Contributor

Pull request status dashboard

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Este PR refactoriza el módulo sale_exception_credit_limit para evaluar la deuda del cliente a nivel de jerarquía de compañías en lugar de considerar todas las compañías del sistema. El objetivo es calcular el límite de crédito considerando solo las compañías relacionadas jerárquicamente (compañía raíz y sus hijas).

Changes:

  • Se agrega un nuevo modelo res_company.py con campo compute para propagar account_use_credit_limit desde la compañía padre
  • Se implementa método _get_company_hierarchy en res_partner.py para obtener todas las compañías en la jerarquía
  • Se modifica _compute_credit_with_confirmed_orders para filtrar órdenes de venta y facturas por jerarquía de compañías y eliminar conversión de moneda
  • Se añade restricción en vista para que account_use_credit_limit solo sea editable en compañía raíz

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 11 comments.

File Description
sale_exception_credit_limit/models/init.py Importa el nuevo modelo res_company
sale_exception_credit_limit/models/res_company.py Define campo compute account_use_credit_limit que hereda valor desde compañía padre
sale_exception_credit_limit/models/res_partner.py Implementa _get_company_hierarchy y refactoriza cálculo de crédito para filtrar por jerarquía
sale_exception_credit_limit/views/res_config_settings_views.xml Restringe edición de account_use_credit_limit a compañía raíz usando is_root_company

Comment on lines +11 to +15
account_use_credit_limit = fields.Boolean(
compute="_compute_account_use_credit_limit",
store=True,
readonly=False,
)
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El campo account_use_credit_limit se define como compute con store=True y readonly=False, lo que permite editarlo manualmente. Sin embargo, no se define un método inverse para manejar la escritura manual del campo. Cuando un usuario intente editar este campo en una compañía raíz (desde la vista que está siendo modificada en este PR), el valor podría ser sobrescrito por el compute en el próximo recompute, perdiendo el cambio manual. Se debe agregar un método inverse o reconsiderar el diseño: si debe ser editable solo en compañías raíz, podría no ser un campo compute sino un campo normal con herencia a hijas mediante otro mecanismo.

Copilot uses AI. Check for mistakes.
</xpath>
<!-- Hacer que el campo account_use_credit_limit solo sea editable en la compañía padre -->
<xpath expr="//field[@name='account_use_credit_limit']" position="attributes">
<attribute name="readonly">not is_root_company</attribute>
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El campo is_root_company no existe en el modelo res.config.settings ni en el modelo res.company del core de Odoo ni en ningún módulo del repositorio. Esta expresión causará un error en tiempo de ejecución cuando se intente renderizar la vista. Debe definirse este campo en el modelo correspondiente o usar un campo existente como company_id.parent_id para verificar si es compañía raíz.

Suggested change
<attribute name="readonly">not is_root_company</attribute>
<attribute name="readonly">company_id.parent_id</attribute>

Copilot uses AI. Check for mistakes.
return super().write(vals)

def _get_company_hierarchy(self, company):
"""Get all companies in the hierarchy (parent and all childs)"""
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

Error ortográfico en el comentario: "childs" debe ser "children" en inglés. El plural correcto de "child" es "children".

Copilot uses AI. Check for mistakes.
root = root.parent_id
company = root

# Get all childs recursively
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

Error ortográfico en el comentario: "childs" debe ser "children" en inglés. El plural correcto de "child" es "children".

Copilot uses AI. Check for mistakes.
Comment on lines 56 to 137
@@ -43,13 +61,17 @@ def _compute_credit_with_confirmed_orders(self):
rec.credit_with_confirmed_orders = 0
else:
company_id = self.env.company
# Get all companies in the hierarchy
hierarchy_companies = rec._get_company_hierarchy(company_id)

domain = [
("order_id.partner_id.commercial_partner_id", "=", rec.commercial_partner_id.id),
# We look for order lines that are to be invoiced or not yet invoiced, since we are interested
# in the total amount, not just the invoiced part. This search helps avoid including fully invoiced orders.
("invoice_status", "in", ["to invoice", "no"]),
("order_id.state", "in", ["sale", "done"]),
# Filter by company hierarchy
("order_id.company_id", "in", hierarchy_companies.ids),
]
order_lines = rec.env["sale.order.line"].sudo().search(domain)

@@ -81,6 +103,8 @@ def _compute_credit_with_confirmed_orders(self):
("move_id.partner_id.commercial_partner_id", "=", rec.commercial_partner_id.id),
("move_id.move_type", "in", ["out_invoice", "out_refund"]),
("move_id.state", "=", "draft"),
# Filter by company hierarchy
("move_id.company_id", "in", hierarchy_companies.ids),
# Include lines without sale_line_ids or those whose related sale order is fully invoiced
"|",
("sale_line_ids", "=", False),
@@ -104,12 +128,10 @@ def _compute_credit_with_confirmed_orders(self):
)
draft_invoice_lines_amount += total

# Sum the credit for all companies, converting to the current company currency
# Sum the credit for all companies in the hierarchy
# No currency conversion needed as all companies in a hierarchy share the same currency
total_credit = 0.0
for company in rec.env["res.company"].search([]):
credit = rec.sudo().with_company(company).credit
total_credit += company.currency_id._convert(
credit, company_id.currency_id, company_id, fields.Date.today()
)
for company in hierarchy_companies:
total_credit += rec.sudo().with_company(company).credit

rec.credit_with_confirmed_orders = to_invoice_amount + draft_invoice_lines_amount + total_credit
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El cambio de evaluar crédito por todas las compañías a solo las compañías en la jerarquía puede tener implicaciones operacionales significativas. Este cambio modifica el comportamiento existente y podría afectar a usuarios con configuraciones multi-compañía complejas. No se observa ningún script de migración que: 1) notifique a los usuarios sobre este cambio de comportamiento, 2) valide que la configuración de jerarquías es correcta, o 3) proporcione datos sobre el impacto del cambio (diferencias en los cálculos antes/después). Se recomienda considerar agregar documentación o advertencias sobre este cambio de comportamiento.

Copilot uses AI. Check for mistakes.
def _compute_account_use_credit_limit(self):
for rec in self:
if rec.parent_id:
rec.account_use_credit_limit = rec.parent_id.account_use_credit_limit
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El compute method solo maneja el caso cuando existe parent_id, pero no define qué valor debe tener account_use_credit_limit cuando NO existe parent_id (compañía raíz). Esto puede dejar el campo con un valor indefinido o None. Se debe agregar un else: rec.account_use_credit_limit = rec.account_use_credit_limit para mantener el valor actual, o definir explícitamente qué comportamiento se espera para compañías raíz.

Suggested change
rec.account_use_credit_limit = rec.parent_id.account_use_credit_limit
rec.account_use_credit_limit = rec.parent_id.account_use_credit_limit
else:
rec.account_use_credit_limit = rec.account_use_credit_limit

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +135
# Sum the credit for all companies in the hierarchy
# No currency conversion needed as all companies in a hierarchy share the same currency
total_credit = 0.0
for company in rec.env["res.company"].search([]):
credit = rec.sudo().with_company(company).credit
total_credit += company.currency_id._convert(
credit, company_id.currency_id, company_id, fields.Date.today()
)
for company in hierarchy_companies:
total_credit += rec.sudo().with_company(company).credit
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El comentario indica "No currency conversion needed as all companies in a hierarchy share the same currency", pero esta suposición no está validada en el código. No hay ninguna constraint o validación que garantice que todas las compañías en una jerarquía compartan la misma moneda. Si en la práctica existen compañías con monedas diferentes en una jerarquía, esto generará cálculos incorrectos del crédito total. Se debe agregar una validación o constraint que asegure que las compañías hijas heredan la moneda de la compañía padre, o mantener la conversión de moneda original.

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +54
def _get_company_hierarchy(self, company):
"""Get all companies in the hierarchy (parent and all childs)"""
if company.parent_id:
# Get the root parent
root = company
while root.parent_id:
root = root.parent_id
company = root

# Get all childs recursively
companies = company
childs = self.env["res.company"].search([("parent_id", "=", company.id)])
while childs:
companies |= childs
childs = self.env["res.company"].search([("parent_id", "in", childs.ids)])

return companies
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El nuevo método _get_company_hierarchy implementa lógica compleja de navegación jerárquica pero no cuenta con cobertura de tests. Dado que el repositorio tiene tests para otros módulos (por ejemplo, sale_stock_ux, sale_ux) y esta lógica es crítica para el cálculo correcto del límite de crédito, se recomienda agregar tests que validen: 1) obtención correcta de la compañía raíz, 2) obtención de todas las compañías hijas en jerarquías de múltiples niveles, y 3) comportamiento con compañías sin parent_id.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +21
account_use_credit_limit = fields.Boolean(
compute="_compute_account_use_credit_limit",
store=True,
readonly=False,
)

@api.depends("parent_id.account_use_credit_limit")
def _compute_account_use_credit_limit(self):
for rec in self:
if rec.parent_id:
rec.account_use_credit_limit = rec.parent_id.account_use_credit_limit
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El campo compute account_use_credit_limit con store=True y readonly=False introduce una nueva funcionalidad de propagación desde la compañía padre, pero no tiene cobertura de tests. Se recomienda agregar tests que validen: 1) que el campo se computa correctamente desde parent_id, 2) que se propaga a compañías hijas cuando cambia en la compañía padre, y 3) que se puede modificar manualmente en compañías raíz.

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +52
childs = self.env["res.company"].search([("parent_id", "=", company.id)])
while childs:
companies |= childs
childs = self.env["res.company"].search([("parent_id", "in", childs.ids)])
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

El nombre de variable childs es incorrecto en inglés (debería ser "children"). Esto puede causar confusión y dificulta la mantenibilidad del código. Se recomienda renombrar a children para seguir las convenciones de nomenclatura correctas del idioma.

Copilot uses AI. Check for mistakes.
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.

2 participants