96 lines
4.3 KiB
Python
96 lines
4.3 KiB
Python
# Copyright 2019-2024 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 api, fields, models, _
|
|
from datetime import datetime, timedelta
|
|
from odoo.exceptions import UserError
|
|
from odoo.tools.misc import format_date
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class CommissionCompute(models.TransientModel):
|
|
_name = 'commission.compute'
|
|
_description = 'Compute Commissions'
|
|
|
|
company_id = fields.Many2one('res.company', required=True)
|
|
date_start = fields.Date(string="Period Start Date", required=True)
|
|
|
|
@api.model
|
|
def default_get(self, fields_list):
|
|
res = super().default_get(fields_list)
|
|
company = self.env.company
|
|
last_commission_result = self.env['commission.result'].search([
|
|
('company_id', '=', company.id),
|
|
], order='date_start desc', limit=1)
|
|
if last_commission_result:
|
|
last_start_date = last_commission_result.date_start
|
|
commissions_last_start_date = self.env['commission.result'].search([
|
|
('date_start', '=', last_start_date),
|
|
('company_id', '=', company.id),
|
|
], order="date_end asc", limit=1)
|
|
min_end_date = commissions_last_start_date.date_end
|
|
date_start = min_end_date + timedelta(1)
|
|
else:
|
|
today = fields.Date.context_today(self)
|
|
date_start = datetime(today.year, today.month, 1)
|
|
res.update({
|
|
'company_id': company.id,
|
|
'date_start': date_start,
|
|
})
|
|
return res
|
|
|
|
def run(self):
|
|
self.ensure_one()
|
|
if not self.date_start:
|
|
raise UserError(_("Missing Period Start Date."))
|
|
creso = self.env['commission.result']
|
|
existing_commissions = creso.search_read([
|
|
('date_start', '=', self.date_start),
|
|
('company_id', '=', self.company_id.id),
|
|
], ['assignment_id'])
|
|
exclude_assignment_ids = [x['assignment_id'][0] for x in existing_commissions if x['assignment_id']]
|
|
com_result_ids = self._core_compute(exclude_assignment_ids)
|
|
if not com_result_ids:
|
|
raise UserError(_('No commissions generated.'))
|
|
action = self.env['ir.actions.actions']._for_xml_id(
|
|
'commission_simple.commission_result_action')
|
|
action.update({
|
|
'views': False,
|
|
'domain': f"[('id', 'in', {com_result_ids})]",
|
|
})
|
|
return action
|
|
|
|
def _core_compute(self, exclude_assignment_ids):
|
|
rules = self.env['commission.rule'].load_all_rules()
|
|
com_result_ids = []
|
|
assignments = self.env['commission.profile.assignment'].search(
|
|
[('company_id', '=', self.company_id.id), ('id', 'not in', exclude_assignment_ids)])
|
|
date_range_type2date_range = {}
|
|
for assignment in assignments:
|
|
profile = assignment.profile_id
|
|
date_range_type = profile.date_range_type_id
|
|
if not date_range_type:
|
|
raise UserError(_("Missing commission periodicity on commission profile '%s'.") % profile.display_name)
|
|
if date_range_type not in date_range_type2date_range:
|
|
domain = [
|
|
('date_start', '=', self.date_start),
|
|
('type_id', '=', date_range_type.id),
|
|
]
|
|
date_range = self.env['date.range'].search(
|
|
domain + [('company_id', '=', self.company_id.id)], limit=1)
|
|
if not date_range:
|
|
date_range = self.env['date.range'].search(
|
|
domain + [('company_id', '=', False)], limit=1)
|
|
if not date_range:
|
|
logger.info('There is no date range with type %s starting on %s. Skipping commission generation for assignment ID %s', date_range_type.name, self.date_start, assignment.id)
|
|
continue
|
|
date_range_type2date_range[date_range_type] = date_range
|
|
com_result = assignment._generate_commission_result(date_range_type2date_range[date_range_type], rules)
|
|
if com_result:
|
|
com_result_ids.append(com_result.id)
|
|
else:
|
|
logger.info("No commission for %s", assignment._get_partner().display_name)
|
|
return com_result_ids
|