Skip to content

Commit

Permalink
[FIX] sale_commission_partial_settlement: handle settlement deletion
Browse files Browse the repository at this point in the history
This commit fixes an issue where, if a settlement was deleted, any
partial commission would not be recreated because it was still
considered paid.

Includes a small refactor of the files and deletion of
some unused fields.
  • Loading branch information
aleuffre committed Nov 13, 2024
1 parent 99972ba commit 9b2ece1
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 60 deletions.
2 changes: 1 addition & 1 deletion sale_commission_partial_settlement/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright 2023 Nextev
{
"name": "Sales commissions based on paid amount",
"version": "14.0.1.0.1",
"version": "14.0.1.1.0",
"author": "Nextev Srl," "Ooops," "Odoo Community Association (OCA)",
"maintainers": ["aleuffre", "renda-dev", "PicchiSeba"],
"category": "Sales Management",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from openupgradelib import openupgrade


def unlink_orphan_agent_partials(env):
"""
Delete agent partials that are not linked
to a settlement line
e.g. because the settlement was deleted
but the ailap was left behind
"""
openupgrade.logged_query(
env.cr,
"""
SELECT id
FROM account_invoice_line_agent_partial
WHERE id not in
(SELECT agent_line_partial_id
FROM settlement_agent_line_partial_rel)
""",
)
ids = [row[0] for row in env.cr.fetchall()]
env["account.invoice.line.agent.partial"].browse(ids).unlink()


def recompute_partial_settled(env):
"""
"partial_settled" was not recomputed properly if a
settlement was canceled or deleted
"""
env["account.invoice.line.agent"].search(
[
("commission_id.payment_amount_type", "=", "paid"),
("partial_settled", "!=", 0),
]
)._compute_partial_settled()


def recompute_settled(env):
"""
Sometimes AILA were not marked as "settled" properly
for commissions of type "paid"
"""
env["account.invoice.line.agent"].search(
[
("commission_id.payment_amount_type", "=", "paid"),
]
)._compute_settled()


@openupgrade.migrate()
def migrate(env, version):
unlink_orphan_agent_partials(env)
recompute_partial_settled(env)
recompute_settled(env)
8 changes: 5 additions & 3 deletions sale_commission_partial_settlement/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import sale_commission
from . import account_move
from . import account_invoice_line_agent
from . import account_invoice_line_agent_partial
from . import account_partial_reconcile
from . import settlement
from . import sale_commission
from . import sale_commission_settlement
from . import sale_commission_settlement_line
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
# Copyright 2023 Nextev
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models
from odoo import api, fields, models
from odoo.tools.float_utils import float_compare


class AccountInvoiceLineAgent(models.Model):
_inherit = "account.invoice.line.agent"

partial_settled = fields.Monetary(string="Partial Commission Amount Settled")
partial_settled = fields.Monetary(
string="Partial Commission Amount Settled",
compute="_compute_partial_settled",
store=True,
)
is_fully_settled = fields.Boolean(compute="_compute_is_fully_settled", store=True)
invoice_line_agent_partial_ids = fields.One2many(
"account.invoice.line.agent.partial", "invoice_line_agent_id"
)

def _compute_settled(self):
filtered_lines = self.filtered(
lambda x: x.commission_id.payment_amount_type != "paid"
)
for line in self - filtered_lines:
if not line.mapped("agent_line.settlement_id"):
line.settled = False
@api.depends(
"invoice_line_agent_partial_ids.amount",
"invoice_line_agent_partial_ids.agent_line.settlement_id.state",
)
def _compute_partial_settled(self):
for rec in self:
rec.partial_settled = sum(
ailap.amount
for ailap in rec.invoice_line_agent_partial_ids
if ailap.mapped("agent_line.settlement_id")[:1].state != "cancel"
)

super(AccountInvoiceLineAgent, filtered_lines)._compute_settled()
@api.depends(
"commission_id.payment_amount_type", "amount", "settled", "partial_settled"
)
def _compute_is_fully_settled(self):
for rec in self:
if rec.commission_id.payment_amount_type != "paid":
rec.is_fully_settled = rec.settled
else:
rec.is_fully_settled = rec.settled and (
float_compare(
rec.partial_settled,
rec.amount,
precision_rounding=rec.currency_id.rounding,
)
== 0
)

def _partial_commissions(self, date_payment_to):
"""
Expand All @@ -30,7 +58,6 @@ def _partial_commissions(self, date_payment_to):
"""
partial_lines_to_settle = []
partial_payment_remaining = {}
lines_to_update = {}
for line in self:
line_total_amount = line.amount
for (
Expand All @@ -55,12 +82,9 @@ def _partial_commissions(self, date_payment_to):
"invoice_line_agent_id": line.id,
"currency_id": line.currency_id.id,
"amount": line_total_amount,
"account_partial_reconcile_id": partial.id,
}
)
lines_to_update[line.id] = {
"partial_settled": line_total_amount,
"settled": True,
}
partial_payment_remaining[partial.id] = {
"remaining_amount": amount - line.object_id.price_total
}
Expand All @@ -75,39 +99,10 @@ def _partial_commissions(self, date_payment_to):
"invoice_line_agent_id": line.id,
"currency_id": line.currency_id.id,
"amount": partial_commission,
"account_partial_reconcile_id": partial.id,
}
)
if line.id in lines_to_update:
lines_to_update[line.id]["partial_settled"] += partial_commission
else:
lines_to_update[line.id] = {"partial_settled": partial_commission}

if lines_to_update[line.id]["partial_settled"] >= line_total_amount:
lines_to_update[line.id].update({"settled": True})
break
partial.partial_commission_settled = True
partial_agent_lines = self.env["account.invoice.line.agent.partial"].create(
partial_lines_to_settle
)
return partial_agent_lines, lines_to_update


class AccountInvoiceLineAgentPartial(models.Model):
_name = "account.invoice.line.agent.partial"
_description = "Partial agent commissions"

invoice_line_agent_id = fields.Many2one("account.invoice.line.agent", required=True)
agent_line = fields.Many2many(
comodel_name="sale.commission.settlement.line",
relation="settlement_agent_line_partial_rel",
column1="agent_line_partial_id",
column2="settlement_id",
copy=False,
)
amount = fields.Monetary(
string="Commission Amount",
)
currency_id = fields.Many2one(
related="invoice_line_agent_id.currency_id",
)
settled = fields.Boolean()
return partial_agent_lines
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2023 Nextev
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class AccountInvoiceLineAgentPartial(models.Model):
_name = "account.invoice.line.agent.partial"
_description = "Partial agent commissions"

invoice_line_agent_id = fields.Many2one(
"account.invoice.line.agent", required=True, ondelete="cascade"
)
# logically a One2one
agent_line = fields.Many2many(
comodel_name="sale.commission.settlement.line",
relation="settlement_agent_line_partial_rel",
column1="agent_line_partial_id",
column2="settlement_id",
copy=False,
)
account_partial_reconcile_id = fields.Many2one("account.partial.reconcile")
amount = fields.Monetary(
string="Commission Amount",
)
currency_id = fields.Many2one(
related="invoice_line_agent_id.currency_id",
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
from odoo import fields, models
from odoo import api, fields, models


class AccountPartialReconcile(models.Model):
_inherit = "account.partial.reconcile"

partial_commission_settled = fields.Boolean()
# Logically a One2one
account_invoice_line_agent_partial_ids = fields.One2many(
"account.invoice.line.agent.partial", "account_partial_reconcile_id"
)
partial_commission_settled = fields.Boolean(
compute="_compute_partial_commission_settled", store=True
)

@api.depends(
"account_invoice_line_agent_partial_ids",
"account_invoice_line_agent_partial_ids.agent_line.settlement_id.state",
)
def _compute_partial_commission_settled(self):
for rec in self:
rec.partial_commission_settled = bool(
rec.account_invoice_line_agent_partial_ids.filtered(
lambda x: x.mapped("agent_line.settlement_id")[:1].state != "cancel"
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from odoo import models


class Settlement(models.Model):
_inherit = "sale.commission.settlement"

def unlink(self):
self.mapped("line_ids.agent_line_partial_ids").unlink()
return super().unlink()

Check warning on line 9 in sale_commission_partial_settlement/models/sale_commission_settlement.py

View check run for this annotation

Codecov / codecov/patch

sale_commission_partial_settlement/models/sale_commission_settlement.py#L8-L9

Added lines #L8 - L9 were not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ def _compute_settled_amount(self):
rec.settled_amount = rec.agent_line_partial_ids[:1].amount
else:
rec.settled_amount = rec.agent_line[:1].amount

def unlink(self):
self.mapped("agent_line_partial_ids").unlink()
return super().unlink()

Check warning on line 30 in sale_commission_partial_settlement/models/sale_commission_settlement_line.py

View check run for this annotation

Codecov / codecov/patch

sale_commission_partial_settlement/models/sale_commission_settlement_line.py#L29-L30

Added lines #L29 - L30 were not covered by tests
11 changes: 3 additions & 8 deletions sale_commission_partial_settlement/wizard/wizard_settle.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,9 @@ def action_settle_partial(self):
for agent in agents:
date_to_agent = self._get_period_start(agent, date_to)
main_agent_line = self.get_partial_agent_lines(agent, date_to_agent)
(
partial_agent_lines,
agent_lines_to_update,
) = main_agent_line._partial_commissions(self.date_payment_to)
for line_id in agent_lines_to_update:
self.env["account.invoice.line.agent"].browse(line_id).update(
agent_lines_to_update[line_id]
)
partial_agent_lines = main_agent_line._partial_commissions(
self.date_payment_to
)
for company in partial_agent_lines.mapped(
"invoice_line_agent_id.company_id"
):
Expand Down

0 comments on commit 9b2ece1

Please sign in to comment.