Files
enterprise-addons/partner_commission/models/commission_plan.py
T

87 lines
3.7 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class CommissionPlan(models.Model):
_name = 'commission.plan'
_description = 'Commission plan'
name = fields.Char('Name', required=True)
active = fields.Boolean(default=True)
product_id = fields.Many2one(
'product.product',
'Purchase Default Product',
domain=[('purchase_ok', '=', True)],
default=lambda self: self.env.ref('partner_commission.product_commission'),
required=True)
commission_rule_ids = fields.One2many('commission.rule', 'plan_id', 'Rules', copy=True)
company_id = fields.Many2one('res.company')
def _match_rules(self, product, template, pricelist):
self.ensure_one()
parent_path = product.categ_id.parent_path
ancestor_ids = parent_path and parent_path.split('/') or []
ancestor_ids = [int(cat_id) for cat_id in ancestor_ids if cat_id]
rules = self.env['commission.rule'].search([
('plan_id', '=', self.id),
('category_id', 'in', ancestor_ids),
'|',
('product_id', '=', product.id),
('product_id', '=', False),
'|',
('template_id', '=', template),
('template_id', '=', False),
'|',
('pricelist_id', '=', pricelist),
('pricelist_id', '=', False),
], order='sequence')
for cat_id in reversed(ancestor_ids):
rule = rules.filtered(lambda r: r.category_id.id == cat_id)
if rule:
return rule[0]
return self.env['commission.rule']
class CommissionRule(models.Model):
_name = 'commission.rule'
_description = 'Commission rules management.'
plan_id = fields.Many2one('commission.plan', 'Commission Plan', required=True, index=True, ondelete='cascade')
category_id = fields.Many2one('product.category', 'Product Category', required=True, ondelete='cascade')
product_id = fields.Many2one(
'product.product',
'Product',
ondelete='cascade',
help="If set, the rule does not apply to the whole category but only on the given product.\n"
"The product must belong to the selected category.\n"
"Use several rules if you need to match multiple products within a category.")
template_id = fields.Many2one('sale.order.template', 'Sale Order Template', ondelete="cascade")
pricelist_id = fields.Many2one('product.pricelist', string='Pricelist', ondelete="cascade")
rate = fields.Float('Rate', required=True, default=0)
is_capped = fields.Boolean('Capped', required=True, default=False, help='Whether the commission is capped.')
max_commission = fields.Float('Max Commission', help="Maximum amount, specified in the currency of the pricelist, if given.")
sequence = fields.Integer(string='Sequence')
_check_rate = models.Constraint(
'CHECK(rate >= 0 AND rate <= 100)',
'Rate should be between 0 and 100.',
)
_check_combination_unique_index = models.UniqueIndex(
"(plan_id, category_id, COALESCE(product_id, -1), COALESCE(template_id, -1), COALESCE(pricelist_id, -1))"
)
@api.constrains('product_id', 'category_id')
def _check_product_category(self):
for rule in self:
if rule.product_id and rule.product_id.categ_id != rule.category_id:
raise ValidationError(_('Product %(product)s does not belong to category %(category)s', product=rule.product_id.code, category=rule.category_id.name))
@api.onchange('is_capped')
def _onchange_is_capped(self):
if not self.is_capped:
self.max_commission = 0