From 4c1be875ccb0f29d4b0ebb9a6d726d84334cbdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20Alan=20Ramos=20Rodri=CC=81guez?= Date: Thu, 30 Nov 2023 12:00:22 -0600 Subject: [PATCH 1/2] [WIP] samsara commissions --- account_commission/models/account_move.py | 2 +- .../models/commission_settlement.py | 28 +++++++++++++++-- commission/models/commission_mixin.py | 30 +++++++++++++++---- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/account_commission/models/account_move.py b/account_commission/models/account_move.py index 3a6acca71..39e0d8d8c 100644 --- a/account_commission/models/account_move.py +++ b/account_commission/models/account_move.py @@ -221,7 +221,7 @@ class AccountInvoiceLineAgent(models.Model): def _compute_amount(self): for line in self: inv_line = line.object_id - line.amount = line._get_commission_amount( + line.amount = line.with_context(inv_line=inv_line)._get_commission_amount( line.commission_id, inv_line.price_subtotal, inv_line.product_id, diff --git a/account_commission/models/commission_settlement.py b/account_commission/models/commission_settlement.py index 9aff08d02..5784355b8 100644 --- a/account_commission/models/commission_settlement.py +++ b/account_commission/models/commission_settlement.py @@ -6,7 +6,7 @@ from odoo import _, api, fields, models from odoo.exceptions import UserError from odoo.tests import Form -from odoo.tools import groupby +from odoo.tools import groupby, float_compare class CommissionSettlement(models.Model): @@ -35,6 +35,12 @@ class CommissionSettlement(models.Model): comodel_name="account.move", compute="_compute_invoice_id", ) + total_sales = fields.Monetary( + string="Total Sales", + compute="_compute_total_sales", + store=True, + help="Total sales amount for this settlement.", + ) def _compute_can_edit(self): """Make settlements coming from invoice lines to not be editable.""" @@ -49,6 +55,11 @@ def _compute_invoice_id(self): lambda x: x.parent_state != "cancel" )[:1].move_id + @api.depends("line_ids.invoice_line_id") + def _compute_total_sales(self): + for record in self: + record.total_sales = sum(record.line_ids.mapped("invoice_line_id.amount_total")) + def action_cancel(self): """Check if any settlement has been invoiced.""" if any(x.state != "settled" for x in self): @@ -177,5 +188,18 @@ def _compute_commission_id(self): @api.depends("invoice_agent_line_id") def _compute_settled_amount(self): + total_sales = self.settelment_id.total_sales + agent_goal = self.settelment_id.agent_id.sales_goal + company_goal = self.env.company.sales_goal + if float_compare(total_sales, company_goal, precision_digits=2) >= 0 or if float_compare(total_sales, agent_goal, precision_digits=2) >= 0:: + percentage = 1 + else: + percentage_archived = (total_sales * 100) / agent_goal + if float_compare(percentage_archived, 80, precision_digits=2) >= 0: + percentage = 0.8 + elif float_compare(percentage_archived, 40, precision_digits=2) >= 0: + percentage = percentage_archived / 100 + elif float_compare(percentage_archived, 40, precision_digits=2) == -1: + percentage = 0 for record in self.filtered("invoice_agent_line_id"): - record.settled_amount = record.invoice_agent_line_id.amount + record.settled_amount = record.invoice_agent_line_id.amount * percentage diff --git a/commission/models/commission_mixin.py b/commission/models/commission_mixin.py index 31268ab68..2c9e5bbc3 100644 --- a/commission/models/commission_mixin.py +++ b/commission/models/commission_mixin.py @@ -143,13 +143,31 @@ def _get_commission_amount(self, commission, subtotal, product, quantity): self.ensure_one() if product.commission_free or not commission: return 0.0 - if commission.amount_base_type == "net_amount": - # If subtotal (sale_price * quantity) is less than - # standard_price * quantity, it means that we are selling at - # lower price than we bought, so set amount_base to 0 - subtotal = max([0, subtotal - product.standard_price * quantity]) + if commission.amount_base_type == "net_amount" and self.env.context.get("inv_line"): + qty_to_take = quantity + cost = 0 + inv_line = self.env.context["inv_line"] + for so_line in inv_line.sale_line_ids.filtered(lambda s: s.supplierinfo_ids): + cost += so_line.purchase_price * min(so_line.product_uom_qty, qty_to_take) + qty_to_take -= so_line.product_uom_qty + if qty_to_take <= 0: + break + subtotal = subtotal - cost if commission.commission_type == "fixed": - return subtotal * (commission.fix_qty / 100.0) + percent = commission.fix_qty + cust_line = inv_line.move_id.line_ids.filtered(lambda s: s.account_id.user_type_id.type == "receivable") + days_to_payment = (max(cust_line.matched_debit_ids.mapped("max_date")) - inv_line.date_due).days + if inv_line and days_to_payment > 90: + percent = commission.fix_qty - 2 + elif inv_line and days_to_payment > 120: + percent = commission.fix_qty - 4 + elif inv_line and days_to_payment > 150: + percent = commission.fix_qty - 6 + elif inv_line and days_to_payment > 180: + percent = commission.fix_qty - 8 + elif inv_line and days_to_payment > 181: + percent = 0 + return subtotal * (percent / 100.0) elif commission.commission_type == "section": return commission.calculate_section(subtotal) From 56dec09d3202714c35667ae60ed519661280b273 Mon Sep 17 00:00:00 2001 From: Desarrollador Samsara Date: Mon, 4 Dec 2023 11:17:27 -0600 Subject: [PATCH 2/2] [WIP] samsara commission --- account_commission/models/account_move.py | 2 +- .../models/commission_settlement.py | 28 ++-------------- .../wizards/commission_make_settle.py | 32 ++++++++++++++++++- commission/models/__init__.py | 1 + commission/models/commission_mixin.py | 15 +-------- commission/models/res_company.py | 13 ++++++++ commission/models/res_partner.py | 6 ++++ 7 files changed, 55 insertions(+), 42 deletions(-) create mode 100644 commission/models/res_company.py diff --git a/account_commission/models/account_move.py b/account_commission/models/account_move.py index 39e0d8d8c..3a6acca71 100644 --- a/account_commission/models/account_move.py +++ b/account_commission/models/account_move.py @@ -221,7 +221,7 @@ class AccountInvoiceLineAgent(models.Model): def _compute_amount(self): for line in self: inv_line = line.object_id - line.amount = line.with_context(inv_line=inv_line)._get_commission_amount( + line.amount = line._get_commission_amount( line.commission_id, inv_line.price_subtotal, inv_line.product_id, diff --git a/account_commission/models/commission_settlement.py b/account_commission/models/commission_settlement.py index 5784355b8..9aff08d02 100644 --- a/account_commission/models/commission_settlement.py +++ b/account_commission/models/commission_settlement.py @@ -6,7 +6,7 @@ from odoo import _, api, fields, models from odoo.exceptions import UserError from odoo.tests import Form -from odoo.tools import groupby, float_compare +from odoo.tools import groupby class CommissionSettlement(models.Model): @@ -35,12 +35,6 @@ class CommissionSettlement(models.Model): comodel_name="account.move", compute="_compute_invoice_id", ) - total_sales = fields.Monetary( - string="Total Sales", - compute="_compute_total_sales", - store=True, - help="Total sales amount for this settlement.", - ) def _compute_can_edit(self): """Make settlements coming from invoice lines to not be editable.""" @@ -55,11 +49,6 @@ def _compute_invoice_id(self): lambda x: x.parent_state != "cancel" )[:1].move_id - @api.depends("line_ids.invoice_line_id") - def _compute_total_sales(self): - for record in self: - record.total_sales = sum(record.line_ids.mapped("invoice_line_id.amount_total")) - def action_cancel(self): """Check if any settlement has been invoiced.""" if any(x.state != "settled" for x in self): @@ -188,18 +177,5 @@ def _compute_commission_id(self): @api.depends("invoice_agent_line_id") def _compute_settled_amount(self): - total_sales = self.settelment_id.total_sales - agent_goal = self.settelment_id.agent_id.sales_goal - company_goal = self.env.company.sales_goal - if float_compare(total_sales, company_goal, precision_digits=2) >= 0 or if float_compare(total_sales, agent_goal, precision_digits=2) >= 0:: - percentage = 1 - else: - percentage_archived = (total_sales * 100) / agent_goal - if float_compare(percentage_archived, 80, precision_digits=2) >= 0: - percentage = 0.8 - elif float_compare(percentage_archived, 40, precision_digits=2) >= 0: - percentage = percentage_archived / 100 - elif float_compare(percentage_archived, 40, precision_digits=2) == -1: - percentage = 0 for record in self.filtered("invoice_agent_line_id"): - record.settled_amount = record.invoice_agent_line_id.amount * percentage + record.settled_amount = record.invoice_agent_line_id.amount diff --git a/account_commission/wizards/commission_make_settle.py b/account_commission/wizards/commission_make_settle.py index d2e5c32c5..89fcd0b62 100644 --- a/account_commission/wizards/commission_make_settle.py +++ b/account_commission/wizards/commission_make_settle.py @@ -4,6 +4,7 @@ from odoo import fields, models +from odoo.tools import float_compare class CommissionMakeSettle(models.TransientModel): @@ -33,12 +34,41 @@ def _prepare_settlement_line_vals(self, settlement, line): """ res = super()._prepare_settlement_line_vals(settlement, line) if self.settlement_type == "sale_invoice": + lines = self._get_agent_lines(settlement.agent_id, settlement.date_to) + total_sales = sum(lines.mapped("invoice_id.amount_untaxed")) + agent_goal = settlement.agent_id.sales_goal + company_goal = self.env.company.sales_goal + if float_compare(total_sales, company_goal, precision_digits=2) >= 0 or float_compare(total_sales, agent_goal, precision_digits=2) >= 0: + percentage = 1 + else: + percentage_archived = (total_sales * 100) / agent_goal + if float_compare(percentage_archived, 80, precision_digits=2) >= 0: + percentage = 0.8 + elif float_compare(percentage_archived, 40, precision_digits=2) >= 0: + percentage = percentage_archived / 100 + elif float_compare(percentage_archived, 40, precision_digits=2) == -1: + percentage = 0 + date_percentage = 1 + inv_line = line.object_id + cust_line = inv_line.move_id.line_ids.filtered(lambda s: s.account_id.user_type_id.type == "receivable") + days_to_payment = (max(cust_line.matched_credit_ids.mapped("max_date")) - inv_line.move_id.invoice_date_due).days + if inv_line and days_to_payment > 90: + date_percentage = 0.8 + elif inv_line and days_to_payment > 120: + date_percentage = 0.6 + elif inv_line and days_to_payment > 150: + date_percentage = 0.4 + elif inv_line and days_to_payment > 180: + date_percentage = 0.2 + elif inv_line and days_to_payment > 181: + date_percentage = 0 + settled_amount = line.amount * percentage * date_percentage res.update( { "invoice_agent_line_id": line.id, "date": line.invoice_date, "commission_id": line.commission_id.id, - "settled_amount": line.amount, + "settled_amount": settled_amount, } ) return res diff --git a/commission/models/__init__.py b/commission/models/__init__.py index 890d9a2c6..46d1b809a 100644 --- a/commission/models/__init__.py +++ b/commission/models/__init__.py @@ -3,3 +3,4 @@ from . import commission_settlement from . import product_template from . import res_partner +from . import res_company diff --git a/commission/models/commission_mixin.py b/commission/models/commission_mixin.py index 2c9e5bbc3..ba50931fa 100644 --- a/commission/models/commission_mixin.py +++ b/commission/models/commission_mixin.py @@ -154,20 +154,7 @@ def _get_commission_amount(self, commission, subtotal, product, quantity): break subtotal = subtotal - cost if commission.commission_type == "fixed": - percent = commission.fix_qty - cust_line = inv_line.move_id.line_ids.filtered(lambda s: s.account_id.user_type_id.type == "receivable") - days_to_payment = (max(cust_line.matched_debit_ids.mapped("max_date")) - inv_line.date_due).days - if inv_line and days_to_payment > 90: - percent = commission.fix_qty - 2 - elif inv_line and days_to_payment > 120: - percent = commission.fix_qty - 4 - elif inv_line and days_to_payment > 150: - percent = commission.fix_qty - 6 - elif inv_line and days_to_payment > 180: - percent = commission.fix_qty - 8 - elif inv_line and days_to_payment > 181: - percent = 0 - return subtotal * (percent / 100.0) + return subtotal * (commission.fix_qty / 100.0) elif commission.commission_type == "section": return commission.calculate_section(subtotal) diff --git a/commission/models/res_company.py b/commission/models/res_company.py new file mode 100644 index 000000000..a1279db7a --- /dev/null +++ b/commission/models/res_company.py @@ -0,0 +1,13 @@ + +from odoo import api, fields, models + +class ResCompany(models.Model): + + _inherit = "res.company" + + sales_goal = fields.Float( + string='Sales Goal', + store=True, + help='Transactional sales goal', + tracking=True, + ) diff --git a/commission/models/res_partner.py b/commission/models/res_partner.py index 605ba0151..778fc0679 100644 --- a/commission/models/res_partner.py +++ b/commission/models/res_partner.py @@ -52,6 +52,12 @@ class ResPartner(models.Model): inverse_name="agent_id", readonly=True, ) + sales_goal = fields.Float( + string='Sales Goal', + store=True, + help='Transactional sales goal', + tracking=True, + ) @api.model def _commercial_fields(self):