Skip to content

Commit

Permalink
ADD module contract_fixed_discount
Browse files Browse the repository at this point in the history
  • Loading branch information
damdam-s committed Oct 23, 2023
1 parent 16e2fd1 commit d68f30a
Show file tree
Hide file tree
Showing 17 changed files with 303 additions and 3 deletions.
12 changes: 9 additions & 3 deletions contract/models/abstract_contract_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,18 @@ def _inverse_price_unit(self):
for line in self.filtered(lambda x: not x.automatic_price):
line.specific_price = line.price_unit

def _compute_price_subtotal_helper(self):
self.ensure_one()
subtotal = self.quantity * self.price_unit
discount = self.discount / 100
subtotal *= 1 - discount
return subtotal

@api.depends("quantity", "price_unit", "discount")
def _compute_price_subtotal(self):
for line in self:
subtotal = line.quantity * line.price_unit
discount = line.discount / 100
subtotal *= 1 - discount
subtotal = line._compute_price_subtotal_helper()

if line.contract_id.pricelist_id:
cur = line.contract_id.pricelist_id.currency_id
line.price_subtotal = cur.round(subtotal)
Expand Down
Empty file.
1 change: 1 addition & 0 deletions contract_fixed_discount/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
21 changes: 21 additions & 0 deletions contract_fixed_discount/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

{
"name": "Contract Fixed Discount",
"version": "14.0.1.0.0",
"category": "Contract Management",
"author": "Foodles, Odoo Community Association (OCA)",
"maintainers": [],
"website": "https://github.com/OCA/contract",
"depends": [
"account_invoice_fixed_discount",
"contract",
],
"data": [
"views/abstract_contract_line.xml",
"views/contract_line.xml",
"views/contract.xml",
],
"license": "AGPL-3",
"installable": True,
}
1 change: 1 addition & 0 deletions contract_fixed_discount/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import abstract_contract_line, contract_line
47 changes: 47 additions & 0 deletions contract_fixed_discount/models/abstract_contract_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


class ContractAbstractContractLine(models.AbstractModel):
_inherit = "contract.abstract.contract.line"

discount_fixed = fields.Float(
string="Discount (Fixed)",
digits="Product Price",
default=0.00,
help="Fixed amount discount.",
)

@api.onchange("discount")
def _onchange_discount(self):
if self.discount:
self.discount_fixed = 0.0

@api.onchange("discount_fixed")
def _onchange_discount_fixed(self):
if self.discount_fixed:
self.discount = 0.0

@api.constrains("discount", "discount_fixed")
def _check_only_one_discount(self):
for rec in self:
for line in rec:
if line.discount and line.discount_fixed:
raise ValidationError(
_("You can only set one type of discount per line.")
)

def _compute_price_subtotal_helper(self):
self.ensure_one()
subtotal = self.quantity * self.price_unit
if self.discount:
subtotal = super()._compute_price_subtotal_helper()
elif self.discount_fixed:
subtotal -= self.discount_fixed
return subtotal

@api.depends("quantity", "price_unit", "discount", "discount_fixed")
def _compute_price_subtotal(self):
super()._compute_price_subtotal()
12 changes: 12 additions & 0 deletions contract_fixed_discount/models/contract_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class ContractLine(models.Model):
_inherit = "contract.line"

def _prepare_invoice_line(self, move_form):
vals = super()._prepare_invoice_line(move_form=move_form)
vals["discount_fixed"] = self.discount_fixed
return vals
4 changes: 4 additions & 0 deletions contract_fixed_discount/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* `Foodles <https://www.foodles.co>`_:

* Damien Crier <[email protected]>
* Pierre Verkest <[email protected]>
1 change: 1 addition & 0 deletions contract_fixed_discount/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module extends the functionality of contracts to allow you to apply fixed amount discounts at contract line level.
1 change: 1 addition & 0 deletions contract_fixed_discount/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_contract_discount_fixed, test_contract_invoice_discount_fixed
64 changes: 64 additions & 0 deletions contract_fixed_discount/tests/test_contract_discount_fixed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2023 Foodles (http://www.foodles.co/)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.exceptions import ValidationError
from odoo.tests import Form

from odoo.addons.contract.tests.test_contract import TestContractBase


class TestContractDiscounts(TestContractBase):
@classmethod
def setUpClass(cls):
super().setUpClass()

cls.contract4 = cls.env["contract.contract"].create(
{
"name": "Test Contract4",
"partner_id": cls.partner.id,
"pricelist_id": cls.partner.property_product_pricelist.id,
"line_recurrence": True,
"contract_line_ids": [
(
0,
0,
{
"product_id": cls.product_1.id,
"name": "Services from #START# to #END#",
"quantity": 1,
"uom_id": cls.product_1.uom_id.id,
"price_unit": 100,
"discount_fixed": 48,
"recurring_rule_type": "monthly",
"recurring_interval": 1,
"date_start": "2018-02-15",
"recurring_next_date": "2018-02-22",
},
)
],
}
)

def test_onchange_discount(self):
contract = Form(self.contract)
line = contract.contract_line_ids.edit(0)
line.discount_fixed = 42
self.assertFalse(line.discount)

def test_onchange_discount_fixed(self):
contract = Form(self.contract)
line = contract.contract_line_ids.edit(0)
line.discount = 42
self.assertFalse(line.discount_fixed)

def test_constraint_discount_discount_fixed(self):
with self.assertRaisesRegex(
ValidationError, "You can only set one type of discount per line."
):
self.contract4.contract_line_ids.discount = 42

def test_price_subtotal_discount_percent(self):
self.assertEqual(self.contract.contract_line_ids.price_subtotal, 50.0)

def test_price_subtotal_discount_fixed(self):
self.assertEqual(self.contract4.contract_line_ids.price_subtotal, 52.0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2023 Foodles (http://www.foodles.co/)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.addons.contract.tests.test_contract import TestContractBase


class TestContractDiscounts(TestContractBase):
@classmethod
def setUpClass(cls):
super().setUpClass()

cls.contract4 = cls.env["contract.contract"].create(
{
"name": "Test Contract4",
"partner_id": cls.partner.id,
"pricelist_id": cls.partner.property_product_pricelist.id,
"line_recurrence": True,
"contract_line_ids": [
(
0,
0,
{
"product_id": cls.product_1.id,
"name": "Services from #START# to #END#",
"quantity": 1,
"uom_id": cls.product_1.uom_id.id,
"price_unit": 100,
"discount_fixed": 48,
"recurring_rule_type": "monthly",
"recurring_interval": 1,
"date_start": "2018-02-15",
"recurring_next_date": "2018-02-22",
},
)
],
}
)

def test_invoice_lines_discount_fixed(self):
invoice = self.contract4.recurring_create_invoice()
self.assertEquals(invoice.invoice_line_ids.discount_fixed, 48)
self.assertEquals(invoice.invoice_line_ids.discount, 0)
27 changes: 27 additions & 0 deletions contract_fixed_discount/views/abstract_contract_line.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>

<record
id="contract_abstract_contract_line_add_discount_fixed_form_view"
model="ir.ui.view"
>
<field
name="name"
>contract.abstract.contract.line form view (in contract)</field>
<field name="model">contract.abstract.contract.line</field>
<field
name="inherit_id"
ref="contract.contract_abstract_contract_line_form_view"
/>

<field name="arch" type="xml">
<field name="discount" position="after">
<field
name="discount_fixed"
groups="product.group_discount_per_so_line"
/>
</field>
</field>
</record>

</odoo>
30 changes: 30 additions & 0 deletions contract_fixed_discount/views/contract.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="contract_contract_form_view" model="ir.ui.view">
<field name="name">contract.contract form view (in contract)</field>
<field name="model">contract.contract</field>
<field name="inherit_id" ref="contract.contract_contract_form_view" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='contract_line_fixed_ids']//tree//field[@name='discount']"
position="after"
>
<field
name="discount_fixed"
groups="product.group_discount_per_so_line"
optional="show"
/>
</xpath>
<xpath
expr="//field[@name='contract_line_ids']//tree//field[@name='discount']"
position="after"
>
<field
name="discount_fixed"
groups="product.group_discount_per_so_line"
optional="show"
/>
</xpath>
</field>
</record>
</odoo>
36 changes: 36 additions & 0 deletions contract_fixed_discount/views/contract_line.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>

<record id="contract_line_tree_view" model="ir.ui.view">
<field name="name">contract.contract_line_tree_view</field>
<field name="model">contract.line</field>
<field name="inherit_id" ref="contract.contract_line_tree_view" />

<field name="arch" type="xml">
<field name="discount" position="after">
<field
name="discount_fixed"
groups="product.group_discount_per_so_line"
optional="show"
/>
</field>
</field>
</record>

<record id="contract_line_report_tree_view" model="ir.ui.view">
<field name="name">contract.contract_line_report_tree_view</field>
<field name="model">contract.line</field>
<field name="inherit_id" ref="contract.contract_line_report_tree_view" />

<field name="arch" type="xml">
<field name="discount" position="after">
<field
name="discount_fixed"
groups="product.group_discount_per_so_line"
optional="show"
/>
</field>
</field>
</record>

</odoo>
6 changes: 6 additions & 0 deletions setup/contract_fixed_discount/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

0 comments on commit d68f30a

Please sign in to comment.