From e01699d15ce63a486bfbd45752fd9eb40746acb0 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 5 Apr 2024 18:06:28 +0200 Subject: [PATCH] [IMP] joint_buying_account : Allow to create commission invoices also on transport requests --- joint_buying_account/__manifest__.py | 1 + joint_buying_account/i18n/fr.po | 46 ++++++--- joint_buying_account/models/__init__.py | 1 + .../models/joint_buying_transport_request.py | 21 +++++ joint_buying_account/tests/test_commission.py | 18 +++- .../view_joint_buying_transport_request.xml | 19 ++++ .../joint_buying_invoice_commission_wizard.py | 4 +- ...t_buying_invoice_commission_wizard_line.py | 94 +++++++++++++++++-- ...joint_buying_invoice_commission_wizard.xml | 3 +- joint_buying_base/demo/res_partner.xml | 8 ++ joint_buying_base/i18n/fr.po | 9 +- joint_buying_sale/tests/__init__.py | 1 + joint_buying_sale/tests/test_commission.py | 70 ++++++++++++++ 13 files changed, 267 insertions(+), 28 deletions(-) create mode 100644 joint_buying_account/models/joint_buying_transport_request.py create mode 100644 joint_buying_account/views/view_joint_buying_transport_request.xml create mode 100644 joint_buying_sale/tests/test_commission.py diff --git a/joint_buying_account/__manifest__.py b/joint_buying_account/__manifest__.py index 8cf3f889..3affbe2b 100644 --- a/joint_buying_account/__manifest__.py +++ b/joint_buying_account/__manifest__.py @@ -25,6 +25,7 @@ "wizards/view_joint_buying_invoice_commission_wizard.xml", "views/view_res_config_settings.xml", "views/view_joint_buying_purchase_order_grouped.xml", + "views/view_joint_buying_transport_request.xml", ], "installable": True, "auto_install": True, diff --git a/joint_buying_account/i18n/fr.po b/joint_buying_account/i18n/fr.po index 0af35237..60862e6e 100644 --- a/joint_buying_account/i18n/fr.po +++ b/joint_buying_account/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-15 14:08+0000\n" -"PO-Revision-Date: 2024-03-15 14:08+0000\n" +"POT-Creation-Date: 2024-04-05 16:01+0000\n" +"PO-Revision-Date: 2024-04-05 16:01+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,7 +16,7 @@ msgstr "" "Plural-Forms: \n" #. module: joint_buying_account -#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:179 +#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:246 #, python-format msgid "\n" "- Non-commissioned sale: %s ; %.2f €" @@ -30,11 +30,13 @@ msgstr "Annuler" #. module: joint_buying_account #: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_purchase_order_grouped__invoice_id +#: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_transport_request__invoice_id msgid "Commission Invoice" msgstr "Facture de commission" #. module: joint_buying_account #: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_purchase_order_grouped__invoice_line_id +#: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_transport_request__invoice_line_id msgid "Commission Invoice Line" msgstr "Ligne de facture de commission" @@ -50,7 +52,7 @@ msgid "Commission VAT 20% Excl" msgstr "Commission 20% HT" #. module: joint_buying_account -#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:165 +#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:232 #, python-format msgid "Commission on %s deposited on %s\n" "- Ordered Amount : %.2f €\n" @@ -61,6 +63,16 @@ msgstr "Commission sur %s déposé le %s\n" "- %d Clients: %s\n" "- Taux : %.2f %%" +#. module: joint_buying_account +#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:258 +#, python-format +msgid "Commission on transport Request from %s to %s available on %s\n" +"- Amount : %.2f €\n" +"- Rate : %.2f %%" +msgstr "Commission sur demande de transport de %s à %s disponible le %s\n" +"- Montant : %.2f €\n" +"- Taux : %.2f %%" + #. module: joint_buying_account #: model:ir.model,name:joint_buying_account.model_res_company msgid "Companies" @@ -105,6 +117,11 @@ msgstr "Nom affiché" msgid "Ecureuil Garni 150gr LAIT (VAT INCL)" msgstr "" +#. module: joint_buying_account +#: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_invoice_commission_wizard_line__grouped_order_qty +msgid "Grouped Order Quantity" +msgstr "Quantité de commandes groupées" + #. module: joint_buying_account #: model:product.product,name:joint_buying_account.product_ELD_hibou #: model:product.template,name:joint_buying_account.product_ELD_hibou_product_template @@ -118,13 +135,13 @@ msgid "ID" msgstr "" #. module: joint_buying_account -#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:124 +#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:190 #, python-format msgid "Incorrect fiscal settings block the possibility to generate commission invoices : Incorrect tax type on the tax %s" msgstr "Le paramétrage fiscal incorrect empêche de générer des factures de commission : type de taxe incorrect sur la taxe %s" #. module: joint_buying_account -#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:114 +#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:180 #, python-format msgid "Incorrect fiscal settings block the possibility to generate commission invoices : Too many taxes %s" msgstr "Le paramétrage fiscal incorrect empêche de générer des factures de commissions : Trop de taxes %s" @@ -150,6 +167,11 @@ msgstr "Commande groupée" msgid "Joint Buying Invoice Commission Wizard" msgstr "Assistant de commission de commande groupé" +#. module: joint_buying_account +#: model:ir.model,name:joint_buying_account.model_joint_buying_transport_request +msgid "Joint Buying Transport Request" +msgstr "Demande de transport" + #. module: joint_buying_account #: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_invoice_commission_wizard____last_update #: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_invoice_commission_wizard_line____last_update @@ -199,11 +221,6 @@ msgstr "Aucune commande groupée à facturer pour les fournisseurs sélectionné msgid "Product" msgstr "Article" -#. module: joint_buying_account -#: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_invoice_commission_wizard_line__grouped_order_qty -msgid "Quantity" -msgstr "Quantité" - #. module: joint_buying_account #: model_terms:ir.ui.view,arch_db:joint_buying_account.view_res_config_settings_form msgid "Set the product used to make commission invoices." @@ -229,6 +246,11 @@ msgstr "Fournisseurs" msgid "The commission will be computed for the grouped order deposited by the suppliers until this date included." msgstr "La commission sera calculée pour les commandes groupées déposés par les fournisseurs jusqu'à cette date inclue." +#. module: joint_buying_account +#: model:ir.model.fields,field_description:joint_buying_account.field_joint_buying_invoice_commission_wizard_line__transport_request_qty +msgid "Transport Request Quantity" +msgstr "Quantité de demandes de transport" + #. module: joint_buying_account #: model:product.product,uom_name:joint_buying_account.product_ELD_ecureuil #: model:product.product,uom_name:joint_buying_account.product_ELD_hibou @@ -245,7 +267,7 @@ msgid "Wizard" msgstr "Assistant" #. module: joint_buying_account -#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:196 +#: code:addons/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py:290 #, python-format msgid "You should define a local partner for the supplier %s." msgstr "Vous devez définir un partenaire local pour le fournisseur %s." diff --git a/joint_buying_account/models/__init__.py b/joint_buying_account/models/__init__.py index dd777c8a..8c30ddaf 100644 --- a/joint_buying_account/models/__init__.py +++ b/joint_buying_account/models/__init__.py @@ -2,3 +2,4 @@ from . import res_config_settings from . import product_product from . import joint_buying_purchase_order_grouped +from . import joint_buying_transport_request diff --git a/joint_buying_account/models/joint_buying_transport_request.py b/joint_buying_account/models/joint_buying_transport_request.py new file mode 100644 index 00000000..b94b49f2 --- /dev/null +++ b/joint_buying_account/models/joint_buying_transport_request.py @@ -0,0 +1,21 @@ +# Copyright (C) 2024-Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class JointBuyingTransportRequest(models.Model): + _inherit = "joint.buying.transport.request" + + invoice_line_id = fields.Many2one( + string="Commission Invoice Line", + comodel_name="account.invoice.line", + readonly=True, + ) + + invoice_id = fields.Many2one( + string="Commission Invoice", + comodel_name="account.invoice", + related="invoice_line_id.invoice_id", + ) diff --git a/joint_buying_account/tests/test_commission.py b/joint_buying_account/tests/test_commission.py index 2ac22c58..58ad54e2 100644 --- a/joint_buying_account/tests/test_commission.py +++ b/joint_buying_account/tests/test_commission.py @@ -13,29 +13,35 @@ def setUp(self): super().setUp() self.company_LOG = self.env.ref("joint_buying_base.company_LOG") self.benoit_ronzon = self.env.ref("joint_buying_base.supplier_benoit_ronzon") - self.CommissionWizard = self.env[ + self.CommissionWizardRonzon = self.env[ "joint.buying.invoice.commission.wizard" ].with_context(active_ids=self.benoit_ronzon.ids) self.AccountInvoice = self.env["account.invoice"] self.grouped_orders = self.benoit_ronzon.joint_buying_grouped_order_ids self.env.user.company_id = self.company_LOG - def test_01_create_commission(self): + def test_01_create_commission_from_grouped_orders(self): # Wizard in a date BEFORE the delivery of grouped orders, should fail day_before_deposit = min( self.grouped_orders.mapped("deposit_date") ) + timedelta(days=-1) - wizard = self.CommissionWizard.create({"max_deposit_date": day_before_deposit}) + wizard = self.CommissionWizardRonzon.create( + {"max_deposit_date": day_before_deposit} + ) self.assertEqual(len(wizard.line_ids), 1) self.assertEqual(wizard.line_ids[0].grouped_order_qty, 0) + self.assertEqual(wizard.line_ids[0].transport_request_qty, 0) with self.assertRaises(UserError): wizard.invoice_commission() # Wizard in a date AFTER the delivery of grouped orders, should success day_after_deposit = max(self.grouped_orders.mapped("deposit_date")) - wizard = self.CommissionWizard.create({"max_deposit_date": day_after_deposit}) + wizard = self.CommissionWizardRonzon.create( + {"max_deposit_date": day_after_deposit} + ) self.assertEqual(len(wizard.line_ids), 1) self.assertEqual(wizard.line_ids[0].grouped_order_qty, len(self.grouped_orders)) + self.assertEqual(wizard.line_ids[0].transport_request_qty, 0) result = wizard.invoice_commission() # Check invoice content @@ -47,6 +53,8 @@ def test_01_create_commission(self): ) # Try to re create invoices, should fail - wizard = self.CommissionWizard.create({"max_deposit_date": day_after_deposit}) + wizard = self.CommissionWizardRonzon.create( + {"max_deposit_date": day_after_deposit} + ) with self.assertRaises(UserError): wizard.invoice_commission() diff --git a/joint_buying_account/views/view_joint_buying_transport_request.xml b/joint_buying_account/views/view_joint_buying_transport_request.xml new file mode 100644 index 00000000..7da60518 --- /dev/null +++ b/joint_buying_account/views/view_joint_buying_transport_request.xml @@ -0,0 +1,19 @@ + + + + + + joint.buying.transport.request + + + + + + + + + diff --git a/joint_buying_account/wizards/joint_buying_invoice_commission_wizard.py b/joint_buying_account/wizards/joint_buying_invoice_commission_wizard.py index 70d10dfb..e3656b99 100644 --- a/joint_buying_account/wizards/joint_buying_invoice_commission_wizard.py +++ b/joint_buying_account/wizards/joint_buying_invoice_commission_wizard.py @@ -53,7 +53,9 @@ def invoice_commission(self): self._check_values() invoices = self.env["account.invoice"] - for wizard_line in self.line_ids.filtered(lambda x: x.grouped_order_qty): + for wizard_line in self.line_ids.filtered( + lambda x: x.grouped_order_qty or x.transport_request_qty + ): invoice = wizard_line._create_invoice() invoices |= invoice diff --git a/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py b/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py index 7429fb63..ae726551 100644 --- a/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py +++ b/joint_buying_account/wizards/joint_buying_invoice_commission_wizard_line.py @@ -43,16 +43,19 @@ class JointbuyingInvoiceCommissionWizardLine(models.TransientModel): ) grouped_order_qty = fields.Integer( - string="Quantity", compute="_compute_grouped_order_info" + string="Grouped Order Quantity", compute="_compute_info" ) - grouped_order_detail = fields.Text( - string="Detail", compute="_compute_grouped_order_info" + transport_request_qty = fields.Integer( + string="Transport Request Quantity", compute="_compute_info" ) + grouped_order_detail = fields.Text(string="Detail", compute="_compute_info") + @api.depends("wizard_id.max_deposit_date", "partner_id") - def _compute_grouped_order_info(self): + def _compute_info(self): for line in self: + # Grouped Orders grouped_orders = self._compute_grouped_order_ids_model( line.wizard_id.max_deposit_date, line.partner_id ) @@ -69,6 +72,36 @@ def _compute_grouped_order_info(self): ] ) + # Transport Requests (Except from Grouped Orders) + transport_requests = self._compute_transport_request_ids_model( + line.wizard_id.max_deposit_date, line.partner_id + ) + line.transport_request_qty = len(transport_requests) + all_data = transport_requests.search_read( + [("id", "in", transport_requests.ids)], + ["name", "availability_date", "amount_untaxed"], + ) + line.grouped_order_detail += "\n".join( + [f"- {x['name']} - {x['amount_untaxed']:.2f} €" for x in all_data] + ) + + @api.model + def _compute_transport_request_ids_model(self, max_deposit_date, partner): + max_deposit_date = datetime( + max_deposit_date.year, max_deposit_date.month, max_deposit_date.day + ) + timedelta(days=1) + return self.env["joint.buying.transport.request"].search( + [ + ("supplier_id", "=", partner.id), + ("invoice_line_id", "=", False), + ("availability_date", "<", max_deposit_date), + ("amount_untaxed", ">", 0.0), + ("state", "=", "computed"), + ("request_type", "!=", "joint_buying"), + ], + order="availability_date", + ) + @api.model def _compute_grouped_order_ids_model(self, max_deposit_date, partner): max_deposit_date = datetime( @@ -97,16 +130,34 @@ def _create_invoice(self): invoice_vals = self._prepare_invoice() invoice = AccountInvoice.create(invoice_vals) + # Grouped Orders for grouped_order in self._compute_grouped_order_ids_model( self.wizard_id.max_deposit_date, self.partner_id ): - invoice_line_vals = self._prepare_invoice_line(invoice, grouped_order) + invoice_line_vals = self._prepare_invoice_line_from_grouped_order( + invoice, grouped_order + ) if not invoice_line_vals: continue - line = AccountInvoiceLine.create(invoice_line_vals) + grouped_order.invoice_line_id = AccountInvoiceLine.create( + invoice_line_vals + ).id - grouped_order.invoice_line_id = line.id + # Transport Requests (Except from Grouped Orders) + for transport_request in self._compute_transport_request_ids_model( + self.wizard_id.max_deposit_date, self.partner_id + ): + invoice_line_vals = self._prepare_invoice_line_from_transport_request( + invoice, transport_request + ) + if not invoice_line_vals: + continue + transport_request.invoice_line_id = AccountInvoiceLine.create( + invoice_line_vals + ).id + # Compute extra line values (taxes, name, etc...) + for line in invoice.invoice_line_ids: # We try to compute correctly taxes, check vat included, etc... price_unit = line.price_unit line_name = line.name @@ -154,7 +205,7 @@ def _prepare_invoice(self): } @api.multi - def _prepare_invoice_line(self, invoice, grouped_order): + def _prepare_invoice_line_from_grouped_order(self, invoice, grouped_order): self.ensure_one() valid_orders = grouped_order.order_ids.filtered( @@ -184,6 +235,33 @@ def _prepare_invoice_line(self, invoice, grouped_order): deposit_order.customer_id.joint_buying_code, deposit_order.amount_untaxed, ) + return self._prepare_invoice_line(invoice, base, description) + + @api.multi + def _prepare_invoice_line_from_transport_request(self, invoice, transport_request): + self.ensure_one() + + base = transport_request.amount_untaxed + + description = _( + "Commission on transport Request from %s to %s available on %s\n" + "- Amount : %.2f €\n" + "- Rate : %.2f %%" + ) % ( + transport_request.start_partner_id.joint_buying_code, + transport_request.arrival_partner_id.joint_buying_code, + self.datetime_to_string( + transport_request.availability_date, self.local_partner_id + ), + base, + self.partner_id.joint_buying_commission_rate, + ) + + return self._prepare_invoice_line(invoice, base, description) + + @api.multi + def _prepare_invoice_line(self, invoice, base, description): + self.ensure_one() product = self.local_partner_id.company_id.joint_buying_commission_product_id return { "invoice_id": invoice.id, diff --git a/joint_buying_account/wizards/view_joint_buying_invoice_commission_wizard.xml b/joint_buying_account/wizards/view_joint_buying_invoice_commission_wizard.xml index db6333e2..bf7698ca 100644 --- a/joint_buying_account/wizards/view_joint_buying_invoice_commission_wizard.xml +++ b/joint_buying_account/wizards/view_joint_buying_invoice_commission_wizard.xml @@ -16,12 +16,13 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - + diff --git a/joint_buying_base/demo/res_partner.xml b/joint_buying_base/demo/res_partner.xml index c9c6a023..01a8bebc 100644 --- a/joint_buying_base/demo/res_partner.xml +++ b/joint_buying_base/demo/res_partner.xml @@ -129,6 +129,14 @@ + + Elodia D @ Logistics + + + + + + Three Peas @ Elodia D diff --git a/joint_buying_base/i18n/fr.po b/joint_buying_base/i18n/fr.po index 75b1e6ba..7bc0f68e 100644 --- a/joint_buying_base/i18n/fr.po +++ b/joint_buying_base/i18n/fr.po @@ -953,7 +953,7 @@ msgid "Manager" msgstr "Gestionnaire" #. module: joint_buying_base -#: code:addons/joint_buying_base/models/joint_buying_transport_request.py:198 +#: code:addons/joint_buying_base/models/joint_buying_transport_request.py:212 #: selection:joint.buying.transport.request,request_type:0 #, python-format msgid "Manual" @@ -964,6 +964,11 @@ msgstr "Manuel" msgid "Manual Description" msgstr "Description (Manuelle)" +#. module: joint_buying_base +#: model:ir.model.fields,field_description:joint_buying_base.field_joint_buying_transport_request__manual_supplier_id +msgid "Manual Supplier" +msgstr "Fournisseur (Manuel)" + #. module: joint_buying_base #: model:ir.model.fields,field_description:joint_buying_base.field_joint_buying_carrier__message_has_error #: model:ir.model.fields,field_description:joint_buying_base.field_joint_buying_tour__message_has_error @@ -1140,6 +1145,7 @@ msgstr "Demande" #. module: joint_buying_base #: model:ir.model.fields,field_description:joint_buying_base.field_joint_buying_transport_request__request_type +#: model_terms:ir.ui.view,arch_db:joint_buying_base.view_joint_buying_transport_request_search msgid "Request Type" msgstr "Type de demande" @@ -1301,6 +1307,7 @@ msgid "Summary" msgstr "Résumé" #. module: joint_buying_base +#: model:ir.model.fields,field_description:joint_buying_base.field_joint_buying_transport_request__supplier_id #: model_terms:ir.ui.view,arch_db:joint_buying_base.view_res_partner_form msgid "Supplier" msgstr "Fournisseur" diff --git a/joint_buying_sale/tests/__init__.py b/joint_buying_sale/tests/__init__.py index 182ffc1f..84eba614 100644 --- a/joint_buying_sale/tests/__init__.py +++ b/joint_buying_sale/tests/__init__.py @@ -1,3 +1,4 @@ +from . import test_commission from . import test_wizard_create_sale_order from . import test_wizard_create_transport_request from . import test_joint_buying_transport_request_compute diff --git a/joint_buying_sale/tests/test_commission.py b/joint_buying_sale/tests/test_commission.py new file mode 100644 index 00000000..b00b2861 --- /dev/null +++ b/joint_buying_sale/tests/test_commission.py @@ -0,0 +1,70 @@ +# Copyright (C) 2022 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from datetime import timedelta + +from odoo.exceptions import Warning as UserError +from odoo.tests.common import TransactionCase + + +class TestCommission(TransactionCase): + def setUp(self): + super().setUp() + self.company_LOG = self.env.ref("joint_buying_base.company_LOG") + self.elodie_d = self.env.ref( + "joint_buying_base.company_ELD" + ).joint_buying_partner_id + self.CommissionWizardElodieD = self.env[ + "joint.buying.invoice.commission.wizard" + ].with_context(active_ids=self.elodie_d.ids) + self.AccountInvoice = self.env["account.invoice"] + self.TransportRequest = self.env["joint.buying.transport.request"] + self.transport_requests = self.TransportRequest.search( + [("supplier_id", "=", self.elodie_d.id)] + ) + self.env.user.company_id = self.company_LOG + + def test_01_create_commission_from_transport_requests_sale(self): + # Wizard in a date BEFORE the availability date of transport Requests, should fail + day_before_availability = min( + self.transport_requests.mapped("availability_date") + ) + timedelta(days=-1) + wizard = self.CommissionWizardElodieD.create( + {"max_deposit_date": day_before_availability} + ) + self.assertEqual(len(wizard.line_ids), 1) + self.assertEqual(wizard.line_ids[0].grouped_order_qty, 0) + self.assertEqual(wizard.line_ids[0].transport_request_qty, 0) + with self.assertRaises(UserError): + wizard.invoice_commission() + + # Wizard in a date AFTER the delivery of grouped orders, should success + day_after_availability = max( + self.transport_requests.mapped("availability_date") + ) + wizard = self.CommissionWizardElodieD.create( + {"max_deposit_date": day_after_availability} + ) + self.assertEqual(len(wizard.line_ids), 1) + self.assertEqual(wizard.line_ids[0].grouped_order_qty, 0) + self.assertEqual( + wizard.line_ids[0].transport_request_qty, len(self.transport_requests) + ) + + result = wizard.invoice_commission() + + # Check invoice content + invoice = self.AccountInvoice.browse(result.get("res_id", False)) + self.assertEqual(len(invoice), 1) + self.assertEqual( + set(self.transport_requests.mapped("invoice_line_id").ids), + set(invoice.mapped("invoice_line_ids").ids), + ) + + # Try to re create invoices, should fail + wizard = self.CommissionWizardElodieD.create( + {"max_deposit_date": day_after_availability} + ) + with self.assertRaises(UserError): + wizard.invoice_commission()