[IMP] commission_simple*: add XLSX report + improve PO generation

Add message un chatter of PO
This commit is contained in:
Alexis de Lattre
2025-09-01 21:43:54 +00:00
committed by Florian da Costa
parent 827119df6e
commit 232cb24fd9
15 changed files with 244 additions and 5 deletions

View File

@@ -16,6 +16,7 @@
],
'data': [
'views/commission_result.xml',
'views/commission_profile.xml',
'wizards/res_config_settings.xml',
],
'installable': False,

View File

@@ -1,2 +1,3 @@
from . import commission_result
from . import commission_profile
from . import res_company

View File

@@ -0,0 +1,20 @@
# Copyright Akretion France (http://www.akretion.com/)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models, api, _
from odoo.exceptions import ValidationError
class CommissionProfile(models.Model):
_inherit = 'commission.profile'
commission_product_id = fields.Many2one(
'product.product', string='Specific Commission Product', ondelete='restrict',
check_company=True,
domain=[('type', '=', 'service')],
help="If not set, Odoo will use the commission product configured on the accounting "
"configuration page."
)

View File

@@ -5,6 +5,7 @@
from odoo import fields, models, _
from odoo.exceptions import UserError
from odoo.tools.misc import format_amount, formatLang
from markupsafe import Markup
class CommissionResult(models.Model):
@@ -18,22 +19,30 @@ class CommissionResult(models.Model):
if not result.purchase_id:
vals = result._prepare_purchase_order()
po = self.env['purchase.order'].create(vals)
po.message_post(body=Markup(_("Generated from commission <a href=# data-oe-model=commission.result data-oe-id=%d>%s</a>.") % (result.id, result.display_name)))
result.write({'purchase_id': po.id})
else:
po = self.purchase_id
if po.state in ('draft', 'sent', 'cancel'):
po.order_line.unlink()
po.message_post(body=Markup(_("Purchase order lines re-generated from commission <a href=# data-oe-model=commission.result data-oe-id=%d>%s</a>.") % (result.id, result.display_name)))
else:
raise UserError(_("Purchase Order %s has already been confirmed. You should cancel it first.") % po.display_name)
if po.state == 'cancel':
po.button_draft()
assert not po.order_line
# create lines
if not result.company_id.commission_product_id:
raise UserError(_("Commission product is not set on company %s.") % result.company_id.display_name)
line_vals = []
for move_line in result.line_ids:
line_vals.append(result._prepare_purchase_order_line(move_line, po))
if not result.company_id.commission_po_config:
raise UserError(_(
"Purchase order configuration for commission is not set on "
"the accounting configuration page of company '%s'.")
% result.company_id.display_name)
if result.company_id.commission_po_config == 'single_line':
line_vals.append(result._prepare_purchase_order_line_single_line(po))
else:
for move_line in result.line_ids:
line_vals.append(result._prepare_purchase_order_line(move_line, po))
po_lines = self.env['purchase.order.line'].create(line_vals)
po_lines._compute_tax_id()
return super().draft2done()
@@ -57,7 +66,13 @@ class CommissionResult(models.Model):
company_currency = move_line.company_id.currency_id
lang = self.partner_id.lang or self.env.lang
env = self.with_context(lang=lang).env
product = self.company_id.commission_product_id
product = self.profile_id.commission_product_id or self.company_id.commission_product_id
if not product:
raise UserError(_(
"Commission product is not set on profile '%(profile)s' "
"nor on company '%(company)s'.",
profile=self.profile_id.display_name,
company=self.company_id.display_name))
vals = {
'order_id': order.id,
'product_id': product.id,
@@ -68,6 +83,24 @@ class CommissionResult(models.Model):
}
return vals
def _prepare_purchase_order_line_single_line(self, order):
product = self.profile_id.commission_product_id or self.company_id.commission_product_id
if not product:
raise UserError(_(
"Commission product is not set on profile '%(profile)s' "
"nor on company '%(company)s'.",
profile=self.profile_id.display_name,
company=self.company_id.display_name))
vals = {
'order_id': order.id,
'product_id': product.id,
'name': _("Commissions for period %(period)s", period=self.date_range_id.name),
'product_qty': 1,
'product_uom': product.uom_id.id,
'price_unit': self.amount_total,
}
return vals
def unlink(self):
for result in self:
if result.purchase_id:

View File

@@ -12,3 +12,7 @@ class ResCompany(models.Model):
commission_product_id = fields.Many2one(
'product.product', string='Commission Product', ondelete='restrict', check_company=True,
domain=[('type', '=', 'service')])
commission_po_config = fields.Selection([
('single_line', 'Single Line'),
('details', 'One line per commission line'),
], default='details', string="Purchase Order Configuration")

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 Akretion France (https://www.akretion.com)
@author Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
-->
<odoo>
<record id="commission_profile_form" model="ir.ui.view">
<field name="model">commission.profile</field>
<field name="inherit_id" ref="commission_simple_agent.commission_profile_form"/>
<field name="arch" type="xml">
<group name="main-right" position="inside">
<field name="commission_product_id"/>
</group>
</field>
</record>
</odoo>

View File

@@ -10,3 +10,4 @@ class ResConfigSettings(models.TransientModel):
commission_product_id = fields.Many2one(
related='company_id.commission_product_id', readonly=False)
commission_po_config = fields.Selection(related="company_id.commission_po_config", readonly=False)

View File

@@ -18,6 +18,10 @@
<label for="commission_product_id" class="col-md-5" />
<field name="commission_product_id" context="{'default_detailed_type': 'service', 'default_purchase_ok': True, 'default_sale_ok': False, 'default_available_in_pos': False, 'default_purchase_method': 'purchase'}"/>
</div>
<div class="row" id="commission_po_config">
<label for="commission_po_config" class="col-md-5" string="Purchase Order"/>
<field name="commission_po_config" />
</div>
</xpath>
</field>
</record>