diff --git a/commission_simple_agent_purchase/__init__.py b/commission_simple_agent_purchase/__init__.py new file mode 100644 index 0000000..aee8895 --- /dev/null +++ b/commission_simple_agent_purchase/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/commission_simple_agent_purchase/__manifest__.py b/commission_simple_agent_purchase/__manifest__.py new file mode 100644 index 0000000..a4261ba --- /dev/null +++ b/commission_simple_agent_purchase/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2019-2024 Akretion France (http://www.akretion.com) +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Commission Simple Agent Purchase', + 'version': '14.0.1.0.0', + 'category': 'Sales', + 'license': 'AGPL-3', + 'summary': 'Glue module between commission_simple_agent and purchase', + 'author': 'Akretion', + 'website': 'https://github.com/akretion/odoo-usability', + 'depends': [ + 'commission_simple_agent', + 'purchase', + ], + 'data': [ + 'views/commission_result.xml', + 'wizards/res_config_settings.xml', + ], + 'installable': True, +} diff --git a/commission_simple_agent_purchase/i18n/fr.po b/commission_simple_agent_purchase/i18n/fr.po new file mode 100644 index 0000000..8bb85f5 --- /dev/null +++ b/commission_simple_agent_purchase/i18n/fr.po @@ -0,0 +1,79 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * commission_simple_agent_purchase +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-11-29 23:33+0000\n" +"PO-Revision-Date: 2024-11-29 23:34+0000\n" +"Last-Translator: Alexis de Lattre \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: commission_simple_agent_purchase +#. odoo-python +#: code:addons/commission_simple_agent_purchase/models/commission_result.py:0 +#, python-format +msgid "" +"Cannot delete commission %(commission)s because it is linked to purchase " +"order %(po)s. You must delete the purchase order first." +msgstr "" +"Impossible de supprimer la commission %(commission)s car elle est liée à la " +"commande fournisseur %(po)s. Vous devez d'abord supprimer la commande " +"fournisseur." + +#. module: commission_simple_agent_purchase +#. odoo-python +#: code:addons/commission_simple_agent_purchase/models/commission_result.py:0 +#, python-format +msgid "Commission %s" +msgstr "Commission %s" + +#. module: commission_simple_agent_purchase +#: model:ir.model.fields,field_description:commission_simple_agent_purchase.field_res_company__commission_product_id +#: model:ir.model.fields,field_description:commission_simple_agent_purchase.field_res_config_settings__commission_product_id +msgid "Commission Product" +msgstr "Produit de commission" + +#. module: commission_simple_agent_purchase +#: model:ir.model,name:commission_simple_agent_purchase.model_commission_result +msgid "Commission Result" +msgstr "État des commissions" + +#. module: commission_simple_agent_purchase +#. odoo-python +#: code:addons/commission_simple_agent_purchase/models/commission_result.py:0 +#, python-format +msgid "Commission product is not set on company %s." +msgstr "Le produit de commission n'est pas défini sur la société %s." + +#. module: commission_simple_agent_purchase +#: model:ir.model,name:commission_simple_agent_purchase.model_res_company +msgid "Companies" +msgstr "Sociétés" + +#. module: commission_simple_agent_purchase +#: model:ir.model,name:commission_simple_agent_purchase.model_res_config_settings +msgid "Config Settings" +msgstr "Configuration" + +#. module: commission_simple_agent_purchase +#: model:ir.model.fields,field_description:commission_simple_agent_purchase.field_commission_result__purchase_id +msgid "Purchase Order" +msgstr "Commande fournisseur" + +#. module: commission_simple_agent_purchase +#. odoo-python +#: code:addons/commission_simple_agent_purchase/models/commission_result.py:0 +#, python-format +msgid "" +"Purchase Order %s has already been confirmed. You should cancel it first." +msgstr "" +"La commande fournisseur %s a déjà été confirmée. Vous devez d'abord " +"l'annuler." diff --git a/commission_simple_agent_purchase/models/__init__.py b/commission_simple_agent_purchase/models/__init__.py new file mode 100644 index 0000000..8b8e848 --- /dev/null +++ b/commission_simple_agent_purchase/models/__init__.py @@ -0,0 +1,2 @@ +from . import commission_result +from . import res_company diff --git a/commission_simple_agent_purchase/models/commission_result.py b/commission_simple_agent_purchase/models/commission_result.py new file mode 100644 index 0000000..9c3778c --- /dev/null +++ b/commission_simple_agent_purchase/models/commission_result.py @@ -0,0 +1,78 @@ +# Copyright Akretion France (https://www.akretion.com/) +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models, _ +from odoo.exceptions import UserError +from odoo.tools.misc import format_amount, formatLang + + +class CommissionResult(models.Model): + _inherit = 'commission.result' + + purchase_id = fields.Many2one('purchase.order', string="Purchase Order", tracking=True, readonly=True) + + def draft2done(self): + for result in self: + if result.assign_type == 'agent': + if not result.purchase_id: + vals = result._prepare_purchase_order() + po = self.env['purchase.order'].create(vals) + result.write({'purchase_id': po.id}) + else: + po = self.purchase_id + if po.state in ('draft', 'sent', 'cancel'): + po.order_line.unlink() + 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)) + po_lines = self.env['purchase.order.line'].create(line_vals) + po_lines._compute_tax_id() + return super().draft2done() + + def _prepare_purchase_order(self): + self.ensure_one() + fp = self.env['account.fiscal.position']._get_fiscal_position(self.partner_id) + vals = { + 'partner_id': self.partner_id.id, + 'origin': _('Commission %s') % self.date_range_id.display_name, + 'company_id': self.company_id.id, + 'currency_id': self.company_id.currency_id.id, + 'fiscal_position_id': fp and fp.id or False, + 'payment_term_id': self.partner_id.property_supplier_payment_term_id.id, + } + return vals + + def _prepare_purchase_order_line(self, move_line, order): + self.ensure_one() + move = move_line.move_id + 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 + vals = { + 'order_id': order.id, + 'product_id': product.id, + 'name': f"""{move.name} {move.commercial_partner_id.name}: {move_line.product_id.display_name} x {formatLang(env, move_line.quantity, dp='Product Unit of Measure')} {move_line.product_uom_id.display_name}\n{_('Base:')} {format_amount(env, move_line.commission_base, company_currency)} - {_('Rate:')} {formatLang(env, move_line.commission_rate, dp='Commission Rate')} %""", + 'product_qty': 1, + 'product_uom': product.uom_id.id, + 'price_unit': move_line.commission_amount, + } + return vals + + def unlink(self): + for result in self: + if result.purchase_id: + raise UserError(_( + "Cannot delete commission %(commission)s because it is linked to " + "purchase order %(po)s. You must delete the purchase order first.", + commission=result.display_name, po=result.purchase_id.display_name)) + return super().unlink() diff --git a/commission_simple_agent_purchase/models/res_company.py b/commission_simple_agent_purchase/models/res_company.py new file mode 100644 index 0000000..253223a --- /dev/null +++ b/commission_simple_agent_purchase/models/res_company.py @@ -0,0 +1,14 @@ +# Copyright 2024 Akretion France (https://www.akretion.com/) +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = 'res.company' + + commission_product_id = fields.Many2one( + 'product.product', string='Commission Product', ondelete='restrict', check_company=True, + domain=[('type', '=', 'service')]) diff --git a/commission_simple_agent_purchase/views/commission_result.xml b/commission_simple_agent_purchase/views/commission_result.xml new file mode 100644 index 0000000..320a428 --- /dev/null +++ b/commission_simple_agent_purchase/views/commission_result.xml @@ -0,0 +1,21 @@ + + + + + + + commission.result + + + + + + + + + + diff --git a/commission_simple_agent_purchase/wizards/__init__.py b/commission_simple_agent_purchase/wizards/__init__.py new file mode 100644 index 0000000..0deb68c --- /dev/null +++ b/commission_simple_agent_purchase/wizards/__init__.py @@ -0,0 +1 @@ +from . import res_config_settings diff --git a/commission_simple_agent_purchase/wizards/res_config_settings.py b/commission_simple_agent_purchase/wizards/res_config_settings.py new file mode 100644 index 0000000..0a99838 --- /dev/null +++ b/commission_simple_agent_purchase/wizards/res_config_settings.py @@ -0,0 +1,12 @@ +# Copyright 2019-2024 Akretion France (https://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + commission_product_id = fields.Many2one( + related='company_id.commission_product_id', readonly=False) diff --git a/commission_simple_agent_purchase/wizards/res_config_settings.xml b/commission_simple_agent_purchase/wizards/res_config_settings.xml new file mode 100644 index 0000000..8f3ffe7 --- /dev/null +++ b/commission_simple_agent_purchase/wizards/res_config_settings.xml @@ -0,0 +1,26 @@ + + + + + + + + commission.res.config.settings.form + res.config.settings + + + +
+
+
+
+
+ + +