Skip to content

Commit

Permalink
DO NOT MERGE: sale_commission_partial_settlement: major refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
aleuffre committed Dec 20, 2024
1 parent 62bea39 commit 1cbea36
Show file tree
Hide file tree
Showing 14 changed files with 453 additions and 100 deletions.
3 changes: 3 additions & 0 deletions sale_commission_partial_settlement/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
"website": "https://github.com/OCA/commission",
"data": [
"security/ir.model.access.csv",
"views/account_invoice_line_agent_views.xml",
"views/account_invoice_line_agent_partial_views.xml",
"views/res_config_settings_view.xml",
"views/sale_commission_settlement_line_partial_views.xml",
"views/sale_commission_settlement_view.xml",
"views/sale_commission_view.xml",
],
Expand Down
1 change: 1 addition & 0 deletions sale_commission_partial_settlement/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from . import sale_commission
from . import sale_commission_settlement
from . import sale_commission_settlement_line
from . import sale_commission_settlement_line_partial
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
# Copyright 2023 Nextev
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, 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"

payment_amount_type = fields.Selection(related="commission_id.payment_amount_type")
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"
"account.invoice.line.agent.partial",
"invoice_line_agent_id",
compute="_compute_invoice_line_agent_partial_ids",
store=True,
)
commission_settlement_line_partial_ids = fields.One2many(
"sale.commission.settlement.line.partial",
compute="_compute_commission_settlement_line_partial_ids",
)

@api.depends(
"invoice_line_agent_partial_ids.amount",
"invoice_line_agent_partial_ids.agent_line.settlement_id.state",
"invoice_line_agent_partial_ids.settled_amount",
)
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 any(
settlement.state != "cancel"
for settlement in ailap.mapped("agent_line.settlement_id")
)
ailap.settled_amount for ailap in rec.invoice_line_agent_partial_ids
)

@api.depends(
Expand All @@ -50,6 +52,51 @@ def _compute_is_fully_settled(self):
== 0
)

@api.depends(
"commission_id.payment_amount_type",
"object_id.move_id.move_type",
"object_id.move_id.line_ids.amount_residual",
)
def _compute_invoice_line_agent_partial_ids(self):
"""
Create an account.invoice.line.agent.partial for each
payment term move line
"""
for rec in self:
ailap_model = rec.invoice_line_agent_partial_ids.browse()
if rec.commission_id.payment_amount_type != "paid":
rec.invoice_line_agent_partial_ids = False
continue
pay_term_lines = rec.object_id.move_id.line_ids.filtered(
lambda line: line.account_internal_type in ("receivable", "payable")
)
forecast_lines = rec.invoice_line_agent_partial_ids.mapped("move_line_id")
for move_line in pay_term_lines:
if move_line not in forecast_lines:
ailap_model.create(
{"move_line_id": move_line.id, "invoice_line_agent_id": rec.id}
)

def _compute_commission_settlement_line_partial_ids(self):
for rec in self:
rec.commission_settlement_line_partial_ids = (
rec.invoice_line_agent_partial_ids.settlement_line_partial_ids
)

def action_see_partial_commissions(self):
view = self.env.ref(
"sale_commission_partial_settlement.account_invoice_line_agent_form_partial_only"
)
return {
"name": _("Partial Commissions"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": self._name,
"views": [(view.id, "form")],
"target": "new",
"res_id": self.id,
}

def _partial_commissions(self, date_payment_to):
"""
This method iterates through agent invoice lines and calculates
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,115 @@
# 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


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

move_line_id = fields.Many2one(
"account.move.line",
required=True, # TODO: migration? Probably cannot enforce
ondelete="cascade",
)
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,
settlement_line_partial_ids = fields.One2many(
"sale.commission.settlement.line.partial",
"invoice_agent_partial_id",
compute="_compute_settlement_line_partial_ids",
store=True,
)
account_partial_reconcile_id = fields.Many2one("account.partial.reconcile")
account_partial_reconcile_id = fields.Many2one(
"account.partial.reconcile"
) # TODO: Remove
amount = fields.Monetary(
compute="_compute_amount",
store=True,
string="Commission Amount",
)
currency_id = fields.Many2one(
related="invoice_line_agent_id.currency_id",
)
settled_amount = fields.Monetary(
compute="_compute_settled_amount",
store=True,
)
is_settled = fields.Boolean(
compute="_compute_settled_amount", store=True, string="Fully settled"
)

move_id = fields.Many2one(related="move_line_id.move_id", string="Invoice")
date_maturity = fields.Date(
related="move_line_id.date_maturity",
store=True,
)
invoice_line_id = fields.Many2one(
related="invoice_line_agent_id.object_id", string="Invoice Line"
)
agent_id = fields.Many2one(
related="invoice_line_agent_id.agent_id",
store=True,
)
invoice_date = fields.Date(
related="invoice_line_agent_id.invoice_date",
store=True,
)

@api.depends(
"settlement_line_partial_ids.amount",
"settlement_line_partial_ids.is_settled",
)
def _compute_settled_amount(self):
for rec in self:
# TODO: handle different currencies
rec.settled_amount = sum(
x.amount for x in rec.settlement_line_partial_ids if x.is_settled
)
rec.is_settled = rec.currency_id.is_zero(rec.settled_amount - rec.amount)

@api.depends(
"move_line_id.balance",
"move_line_id.move_id.amount_total",
"invoice_line_agent_id.amount",
)
def _compute_amount(self):
for rec in self:
rec.amount = (
rec.move_line_id.balance
* rec.invoice_line_agent_id.amount
/ rec.move_line_id.move_id.amount_total
)

@api.depends(
"move_line_id.matched_debit_ids",
"move_line_id.matched_credit_ids",
)
def _compute_settlement_line_partial_ids(self):
"""
Cf. method _get_reconciled_invoices_partials
in odoo.addons.account.models.account_move.AccountMove.
"""
for rec in self:
pay_term_line = rec.move_line_id
matched_partials = (
pay_term_line.matched_debit_ids + pay_term_line.matched_credit_ids
)
if not matched_partials:
continue
existing_partial_settlements = rec.settlement_line_partial_ids
existing_partials = existing_partial_settlements.mapped(
"partial_reconcile_id"
)

for partial in matched_partials:
if partial not in existing_partials:
existing_partial_settlements.create(
{
"partial_reconcile_id": partial.id,
"invoice_agent_partial_id": rec.id,
}
)
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
from odoo import api, fields, models
from odoo import fields, models


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

# 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
)
) # TODO: Remove?
# 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 = any(
settlement.state != "cancel"
for settlement in rec.mapped(
"account_invoice_line_agent_partial_ids.agent_line.settlement_id"
)
)
# APR can't tell if every agent was settled!
# @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 = any(
# settlement.state != "cancel"
# for settlement in rec.mapped(
# "account_invoice_line_agent_partial_ids.agent_line.settlement_id"
# )
# )
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ class SaleCommissionSettlement(models.Model):
help="The payment date used to create the settlement",
)

def unlink(self):
self.mapped("line_ids.agent_line_partial_ids").unlink()
return super().unlink()
# 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 @@ -4,12 +4,16 @@
class SettlementLine(models.Model):
_inherit = "sale.commission.settlement.line"

agent_line_partial_ids = fields.Many2many(
agent_line_partial_ids = fields.Many2many( # TODO: Remove?
comodel_name="account.invoice.line.agent.partial",
relation="settlement_agent_line_partial_rel",
column1="settlement_id",
column2="agent_line_partial_id",
)
settlement_line_partial_ids = fields.Many2many(
comodel_name="sale.commission.settlement.line.partial",
relation="settlement_line_line_partial_rel",
)
settled_amount = fields.Monetary(
compute="_compute_settled_amount",
related=False,
Expand All @@ -21,10 +25,19 @@ class SettlementLine(models.Model):
def _compute_settled_amount(self):
for rec in self:
if rec.commission_id.payment_amount_type == "paid":
rec.settled_amount = rec.agent_line_partial_ids[:1].amount
if rec.settlement_line_partial_ids:
rec.settled_amount = sum(
x.amount for x in rec.settlement_line_partial_ids
)
else: # TODO: Remove?
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()
# def unlink(self):
# """
# deprecated
# TODO: migrate?
# """
# self.mapped("agent_line_partial_ids").unlink()
# return super().unlink()
Loading

0 comments on commit 1cbea36

Please sign in to comment.