diff --git a/pre_commissions/__init__.py b/pre_commissions/__init__.py
new file mode 100644
index 00000000000..0650744f6bc
--- /dev/null
+++ b/pre_commissions/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/pre_commissions/__manifest__.py b/pre_commissions/__manifest__.py
new file mode 100644
index 00000000000..3c7339935e0
--- /dev/null
+++ b/pre_commissions/__manifest__.py
@@ -0,0 +1,13 @@
+{
+ 'name': "Sale Commission",
+ 'author': "Kunj Koradiya",
+ 'description': "This is the description",
+ 'license': "LGPL-3",
+ 'depends': ['base', 'account', 'sale'],
+ 'data': [
+ 'security/ir.model.access.csv',
+ 'views/commision_rule.xml',
+ 'views/sale_commission.xml',
+ 'views/menus.xml'
+ ]
+}
diff --git a/pre_commissions/models/__init__.py b/pre_commissions/models/__init__.py
new file mode 100644
index 00000000000..eb2b588db60
--- /dev/null
+++ b/pre_commissions/models/__init__.py
@@ -0,0 +1,3 @@
+from . import commission_rule
+from . import sale_commission
+from . import account_move
diff --git a/pre_commissions/models/account_move.py b/pre_commissions/models/account_move.py
new file mode 100644
index 00000000000..86d1d49ba80
--- /dev/null
+++ b/pre_commissions/models/account_move.py
@@ -0,0 +1,21 @@
+from odoo import models
+
+
+class AccountMove(models.Model):
+ _inherit = 'account.move'
+
+ def action_post(self):
+ res = super().action_post()
+ # breakpoint()
+ for move in self:
+ if move.move_type != 'out_invoice':
+ continue
+
+ sale_orders = move.invoice_line_ids.sale_line_ids.order_id
+ sale_orders = sale_orders.exists()
+
+ if not sale_orders:
+ continue
+
+ self.env['sale.commission'].sudo().check_commission_rules(sale_orders, move)
+ return res
diff --git a/pre_commissions/models/commission_rule.py b/pre_commissions/models/commission_rule.py
new file mode 100644
index 00000000000..04c5ca67aac
--- /dev/null
+++ b/pre_commissions/models/commission_rule.py
@@ -0,0 +1,52 @@
+from odoo import fields, models, api
+
+
+class CommisionRule(models.Model):
+ _name = 'commission.rule'
+ _desc = "Commission Rule"
+ _order = 'sequence'
+
+ sequence = fields.Integer()
+ active = fields.Boolean(default=True)
+ commission_rate = fields.Float(required=True)
+ due_at = fields.Selection([
+ ('invoice', "Invoice Posted"),
+ ('payment', "Payment Received")
+ ],
+ default='invoice',
+ required=True
+ )
+ commission_for = fields.Selection([
+ ('salesperson', "Salesperson"),
+ ('team', "Sales Team")
+ ])
+ product_category_id = fields.Many2one('product.category')
+ product_id = fields.Many2one('product.product')
+ product_expired = fields.Selection([
+ ('no_impact', 'No Impact'),
+ ('yes', "Expired Only"),
+ ('no', 'Not Expired')
+ ], default='no_impact'
+ )
+ max_discount = fields.Float(string="Max Discount %")
+ fast_payment = fields.Boolean()
+ fast_payment_days = fields.Integer()
+ salesperson_id = fields.Many2one('res.users')
+ team_id = fields.Many2one('crm.team', string="Sales Team")
+ condition_display = fields.Char(store=True, compute='_compute_condition_display')
+
+ @api.depends('product_category_id', 'product_id', 'salesperson_id', 'team_id', 'max_discount')
+ def _compute_condition_display(self):
+ for rec in self:
+ parts = []
+ if rec.product_category_id:
+ parts.append(f"Category: {rec.product_category_id.name}")
+ if rec.product_id:
+ parts.append(f"Product: {rec.product_id.name}")
+ if rec.salesperson_id:
+ parts.append(f"Salesperson: {rec.salesperson_id.name}")
+ if rec.team_id:
+ parts.append(f"Team: {rec.team_id.name}")
+ if rec.max_discount:
+ parts.append(f"Max Discount: {rec.max_discount}%")
+ rec.condition_display = " AND ".join(parts) or "All"
diff --git a/pre_commissions/models/sale_commission.py b/pre_commissions/models/sale_commission.py
new file mode 100644
index 00000000000..e69a18f0d62
--- /dev/null
+++ b/pre_commissions/models/sale_commission.py
@@ -0,0 +1,56 @@
+from odoo import fields, models, api
+
+
+class SaleCommission(models.Model):
+ _name = 'sale.commission'
+ _description = "Sale Commission"
+
+ date = fields.Date(required=True)
+ user_id = fields.Many2one('res.users', string="Salesperson")
+ team_id = fields.Many2one('crm.team', string="Sales Team")
+ invoice_id = fields.Many2one('account.move')
+ partner_id = fields.Many2one(related='invoice_id.partner_id', store=True)
+
+ amount = fields.Monetary()
+ currency_id = fields.Many2one(
+ 'res.currency',
+ default=lambda self: self.env.company.currency_id.id
+ )
+
+ rule_id = fields.Many2one('commission.rule')
+ sale_order_id = fields.Many2one('sale.order')
+
+ def check_commission_rules(self, sale_orders, invoice):
+ # breakpoint()
+ if not sale_orders:
+ return
+ rules = self.env['commission.rule'].search([
+ ('active', '=', True)
+ ])
+ for order in sale_orders:
+ for rule in rules:
+ condition_ok = True
+ if rule.salesperson_id and order.user_id != rule.salesperson_id:
+ condition_ok = False
+ if rule.team_id and order.team_id != rule.team_id:
+ condition_ok = False
+
+ if not condition_ok:
+ continue
+ # existing = self.search([
+ # ('invoice_id', '=', invoice.id),
+ # ('rule_id', '=', rule.id),
+ # ('sale_order_id', '=', order.id)
+ # ], limit=1)
+ # if existing:
+ # continue
+ commission_amount = invoice.amount_total * rule.commission_rate
+ self.create({
+ 'date': invoice.invoice_date,
+ 'invoice_id': invoice.id,
+ 'user_id': order.user_id.id,
+ 'team_id': order.team_id.id,
+ 'amount': commission_amount,
+ 'rule_id': rule.id,
+ 'sale_order_id': order.id,
+ })
diff --git a/pre_commissions/security/ir.model.access.csv b/pre_commissions/security/ir.model.access.csv
new file mode 100644
index 00000000000..835acb20bf8
--- /dev/null
+++ b/pre_commissions/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+access_commission_rules,access_commission_rules,model_commission_rule,base.group_user,1,1,1,1
+access_sale_commissions,access_sale_commissions,model_sale_commission,base.group_user,1,1,1,1
diff --git a/pre_commissions/views/commision_rule.xml b/pre_commissions/views/commision_rule.xml
new file mode 100644
index 00000000000..a514f77d8b9
--- /dev/null
+++ b/pre_commissions/views/commision_rule.xml
@@ -0,0 +1,65 @@
+
+
+
+
+ Commission Rules
+ commission.rule
+ list,form
+
+
+
+
+ commission.rule.view.form
+ commission.rule
+
+
+
+
+
+
+
+ commission.rule.view.list
+ commission.rule
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pre_commissions/views/menus.xml b/pre_commissions/views/menus.xml
new file mode 100644
index 00000000000..10b9e753f28
--- /dev/null
+++ b/pre_commissions/views/menus.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pre_commissions/views/sale_commission.xml b/pre_commissions/views/sale_commission.xml
new file mode 100644
index 00000000000..3211adcbc51
--- /dev/null
+++ b/pre_commissions/views/sale_commission.xml
@@ -0,0 +1,53 @@
+
+
+
+
+ Sale Commission
+ sale.commission
+ list,form,pivot,graph
+
+
+
+
+
+ sale.commission.view.list
+ sale.commission
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sale.commission.view.pivot
+ sale.commission
+
+
+
+
+
+
+
+
+
+
+
+
+ sale.commission.view.graph
+ sale.commission
+
+
+
+
+
+
+
+
+