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 12, 2024
1 parent 99972ba commit 251d270
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 55 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,47 @@
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):
env["account.invoice.line.agent"].search(
[("settled", "=", False), ("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,24 +1,50 @@
# 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,
)
invoice_line_agent_partial_ids = fields.One2many(
"account.invoice.line.agent.partial", "invoice_line_agent_id"
)

@api.depends("commission_id.payment_amount_type", "amount", "partial_settled")
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

line.settled = line.amount > 0 and (
float_compare(
line.partial_settled,
line.amount,
precision_rounding=line.currency_id.rounding,
)
>= 0 # partial_settled >= line.amount
)
super(AccountInvoiceLineAgent, filtered_lines)._compute_settled()

@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"
)

def _partial_commissions(self, date_payment_to):
"""
This method iterates through agent invoice lines and calculates
Expand All @@ -30,7 +56,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 +80,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 +97,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,20 @@
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")
def _compute_partial_commission_settled(self):
for rec in self:
rec.partial_commission_settled = bool(
rec.account_invoice_line_agent_partial_ids
)
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()
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()
19 changes: 11 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,17 @@ 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,
# agent_lines_to_update,
# ) = main_agent_line._partial_commissions(self.date_payment_to)
partial_agent_lines = 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]
# )
for company in partial_agent_lines.mapped(
"invoice_line_agent_id.company_id"
):
Expand Down

0 comments on commit 251d270

Please sign in to comment.