mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
381 lines
16 KiB
Python
381 lines
16 KiB
Python
# Copyright 2020 Tecnativa - Carlos Dauden
|
|
# Copyright 2020 Tecnativa - Sergio Teruel
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
|
|
from freezegun import freeze_time
|
|
|
|
from odoo import fields
|
|
from odoo.tests.common import Form, TransactionCase, tagged
|
|
|
|
|
|
@freeze_time("2022-02-01 09:30:00")
|
|
@tagged("-at_install", "post_install")
|
|
class TestAgreementRebate(TransactionCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.Partner = self.env["res.partner"]
|
|
self.ProductTemplate = self.env["product.template"]
|
|
self.Product = self.env["product.product"]
|
|
self.ProductCategory = self.env["product.category"]
|
|
self.AccountInvoice = self.env["account.move"]
|
|
self.AccountInvoiceLine = self.env["account.move.line"]
|
|
self.AccountJournal = self.env["account.journal"]
|
|
self.Agreement = self.env["agreement"]
|
|
self.AgreementType = self.env["agreement.type"]
|
|
self.ProductAttribute = self.env["product.attribute"]
|
|
self.ProductAttributeValue = self.env["product.attribute.value"]
|
|
self.ProductTmplAttributeValue = self.env["product.template.attribute.value"]
|
|
self.AgreementSettlement = self.env["agreement.rebate.settlement"]
|
|
self.AgreementSettlementCreateWiz = self.env["agreement.settlement.create.wiz"]
|
|
self.rebate_type = [
|
|
"global",
|
|
"line",
|
|
"section_total",
|
|
"section_prorated",
|
|
]
|
|
self.category_all = self.env.ref("product.product_category_all")
|
|
self.categ_1 = self.ProductCategory.create(
|
|
{"parent_id": self.category_all.id, "name": "Category 1"}
|
|
)
|
|
self.categ_2 = self.ProductCategory.create(
|
|
{"parent_id": self.category_all.id, "name": "Category 2"}
|
|
)
|
|
self.product_1 = self.Product.create(
|
|
{
|
|
"name": "Product test 1",
|
|
"categ_id": self.categ_1.id,
|
|
"list_price": 1000.00,
|
|
}
|
|
)
|
|
self.product_2 = self.Product.create(
|
|
{
|
|
"name": "Product test 2",
|
|
"categ_id": self.categ_2.id,
|
|
"list_price": 2000.00,
|
|
}
|
|
)
|
|
# Create a product with variants
|
|
self.product_attribute = self.ProductAttribute.create(
|
|
{"name": "Test", "create_variant": "always"}
|
|
)
|
|
self.product_attribute_value_test_1 = self.ProductAttributeValue.create(
|
|
{"name": "Test v1", "attribute_id": self.product_attribute.id}
|
|
)
|
|
self.product_attribute_value_test_2 = self.ProductAttributeValue.create(
|
|
{"name": "Test v2", "attribute_id": self.product_attribute.id}
|
|
)
|
|
self.product_template = self.ProductTemplate.create(
|
|
{
|
|
"name": "Product template with variant test",
|
|
"type": "consu",
|
|
"list_price": 100.0,
|
|
"attribute_line_ids": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"attribute_id": self.product_attribute.id,
|
|
"value_ids": [
|
|
(4, self.product_attribute_value_test_1.id),
|
|
(4, self.product_attribute_value_test_2.id),
|
|
],
|
|
},
|
|
),
|
|
],
|
|
}
|
|
)
|
|
self.partner_1 = self.Partner.create(
|
|
{"name": "partner test rebate 1", "ref": "TST-001"}
|
|
)
|
|
self.partner_2 = self.Partner.create(
|
|
{"name": "partner test rebate 2", "ref": "TST-002"}
|
|
)
|
|
self.invoice_partner_1 = self.create_invoice(self.partner_1)
|
|
self.invoice_partner_2 = self.create_invoice(self.partner_2)
|
|
self.agreement_type = self.AgreementType.create(
|
|
{"name": "Rebate", "domain": "sale", "is_rebate": True}
|
|
)
|
|
# Product to use when we create invoices from settlements
|
|
self.product_rappel = self.Product.create(
|
|
{"name": "Rappel sales", "categ_id": self.categ_1.id, "list_price": 1.00}
|
|
)
|
|
|
|
# Create some invoices for partner
|
|
def create_invoice(self, partner):
|
|
move_form = Form(
|
|
self.env["account.move"].with_context(default_type="out_invoice")
|
|
)
|
|
move_form.invoice_date = fields.Date.from_string(
|
|
"{}-01-01".format(fields.Date.today().year)
|
|
)
|
|
move_form.ref = "Test Customer Invoice"
|
|
move_form.partner_id = partner
|
|
products = (
|
|
self.product_template.product_variant_ids + self.product_1 + self.product_2
|
|
)
|
|
self.create_invoice_line(move_form, products)
|
|
invoice = move_form.save()
|
|
invoice.action_post()
|
|
return invoice
|
|
|
|
def create_invoice_line(self, invoice_form, products):
|
|
for product in products:
|
|
with invoice_form.invoice_line_ids.new() as line_form:
|
|
line_form.product_id = product
|
|
# Assign distinct prices for product with variants
|
|
if product == self.product_template.product_variant_ids[0]:
|
|
line_form.price_unit = 300.00
|
|
if product == self.product_template.product_variant_ids[1]:
|
|
line_form.price_unit = 500.00
|
|
|
|
# Create Agreements rebates for customers for all available types
|
|
def create_agreements_rebate(self, rebate_type, partner):
|
|
agreement = self.Agreement.create(
|
|
{
|
|
"domain": "sale",
|
|
"start_date": "{}-01-01".format(fields.Date.today().year),
|
|
"rebate_type": rebate_type,
|
|
"name": "A discount {} for all lines for {}".format(
|
|
rebate_type, partner.name
|
|
),
|
|
"code": "R-{}-{}".format(rebate_type, partner.ref),
|
|
"partner_id": partner.id,
|
|
"agreement_type_id": self.agreement_type.id,
|
|
"rebate_discount": 10,
|
|
"rebate_line_ids": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"rebate_target": "product",
|
|
"rebate_product_ids": [(6, 0, self.product_1.ids)],
|
|
"rebate_discount": 20,
|
|
},
|
|
),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"rebate_target": "product",
|
|
"rebate_product_ids": [
|
|
(6, 0, self.product_template.product_variant_ids[0].ids)
|
|
],
|
|
"rebate_discount": 30,
|
|
},
|
|
),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"rebate_target": "product_tmpl",
|
|
"rebate_product_tmpl_ids": [
|
|
(6, 0, self.product_2.product_tmpl_id.ids)
|
|
],
|
|
"rebate_discount": 40,
|
|
},
|
|
),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"rebate_target": "category",
|
|
"rebate_category_ids": [(6, 0, self.category_all.ids)],
|
|
"rebate_discount": 40,
|
|
},
|
|
),
|
|
],
|
|
"rebate_section_ids": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"amount_from": 0.00,
|
|
"amount_to": 100.00,
|
|
"rebate_discount": 10,
|
|
},
|
|
),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"amount_from": 100.01,
|
|
"amount_to": 300.00,
|
|
"rebate_discount": 20,
|
|
},
|
|
),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"amount_from": 300.01,
|
|
"amount_to": 6000.00,
|
|
"rebate_discount": 30,
|
|
},
|
|
),
|
|
],
|
|
}
|
|
)
|
|
return agreement
|
|
|
|
def get_settlements_from_action(self, action):
|
|
if action.get("res_id", False):
|
|
return self.AgreementSettlement.browse(action["res_id"])
|
|
else:
|
|
return self.AgreementSettlement.search(action["domain"])
|
|
|
|
def create_settlement_wizard(self, agreements=False):
|
|
vals = {
|
|
"date_to": "{}-12-31".format(fields.Date.today().year),
|
|
}
|
|
if agreements:
|
|
vals["agreement_ids"] = [(6, 0, agreements.ids)]
|
|
settlement_wiz = self.AgreementSettlementCreateWiz.create(vals)
|
|
return settlement_wiz
|
|
|
|
def test_create_settlement_wo_filters_global(self):
|
|
# Invoice Lines:
|
|
# Product template variants: 300, 500
|
|
# Product 1: 1000
|
|
# Product 2: 2000
|
|
# Total by invoice: 3800 amount invoiced
|
|
|
|
# Global rebate without filters
|
|
agreement_global = self.create_agreements_rebate("global", self.partner_1)
|
|
agreement_global.rebate_line_ids = False
|
|
settlement_wiz = self.create_settlement_wizard(agreement_global)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 3800)
|
|
self.assertEqual(settlements.amount_rebate, 380)
|
|
|
|
def test_create_settlement_wo_filters_line(self):
|
|
# Line rebate without filters
|
|
agreement = self.create_agreements_rebate("line", self.partner_1)
|
|
agreement.rebate_line_ids = False
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 0)
|
|
|
|
def test_create_settlement_wo_filters_section_total(self):
|
|
# section_total rebate without filters
|
|
agreement = self.create_agreements_rebate("section_total", self.partner_1)
|
|
agreement.rebate_line_ids = False
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 3800)
|
|
self.assertEqual(settlements.amount_rebate, 1140)
|
|
|
|
def test_create_settlement_wo_filters_section_prorated(self):
|
|
# section_prorated rebate without filters
|
|
agreement = self.create_agreements_rebate("section_prorated", self.partner_1)
|
|
agreement.rebate_line_ids = False
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 3800)
|
|
self.assertAlmostEqual(settlements.amount_rebate, 1120.00, 2)
|
|
|
|
def _create_agreement_product_filter(self, agreement_type):
|
|
agreement = self.create_agreements_rebate(agreement_type, self.partner_1)
|
|
agreement.rebate_line_ids = [
|
|
(5, 0),
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"rebate_target": "product",
|
|
"rebate_product_ids": [(6, 0, self.product_1.ids)],
|
|
"rebate_discount": 20,
|
|
},
|
|
),
|
|
]
|
|
return agreement
|
|
|
|
def test_create_settlement_products_filters_global(self):
|
|
# Invoice Lines:
|
|
# Product template variants: 300, 500
|
|
# Product 1: 1000
|
|
# Product 2: 2000
|
|
# Total by invoice: 3800 amount invoiced
|
|
agreement = self._create_agreement_product_filter("global")
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 1000)
|
|
self.assertEqual(settlements.amount_rebate, 100)
|
|
|
|
def test_create_settlement_products_filters_line(self):
|
|
agreement = self._create_agreement_product_filter("line")
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 1000)
|
|
self.assertEqual(settlements.amount_rebate, 200)
|
|
|
|
def test_create_settlement_products_filters_section_total(self):
|
|
agreement = self._create_agreement_product_filter("section_total")
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 1000)
|
|
self.assertEqual(settlements.amount_rebate, 300)
|
|
|
|
def test_create_settlement_products_filters_section_prorated(self):
|
|
agreement = self._create_agreement_product_filter("section_prorated")
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
self.assertEqual(len(settlements), 1)
|
|
self.assertEqual(settlements.amount_invoiced, 1000)
|
|
self.assertAlmostEqual(settlements.amount_rebate, 280, 2)
|
|
|
|
def _create_invoice_wizard(self):
|
|
sale_journal = self.env["account.journal"].search(
|
|
[("type", "=", "sale")], limit=1
|
|
)
|
|
wiz_create_invoice_form = Form(self.env["agreement.invoice.create.wiz"])
|
|
wiz_create_invoice_form.date_from = "2022-01-01"
|
|
wiz_create_invoice_form.date_to = "2022-12-31"
|
|
wiz_create_invoice_form.invoice_type = "out_invoice"
|
|
wiz_create_invoice_form.journal_id = sale_journal
|
|
wiz_create_invoice_form.product_id = self.product_rappel
|
|
wiz_create_invoice_form.agreement_type_ids.add(self.agreement_type)
|
|
return wiz_create_invoice_form.save()
|
|
|
|
def test_invoice_agreements(self):
|
|
# Create some rebate settlements
|
|
agreement = self._create_agreement_product_filter("section_total")
|
|
settlement_wiz = self.create_settlement_wizard(agreement)
|
|
settlements = self.get_settlements_from_action(
|
|
settlement_wiz.action_create_settlement()
|
|
)
|
|
wiz_create_invoice = self._create_invoice_wizard()
|
|
wiz_create_invoice.agreement_ids = [(6, 0, agreement.ids)]
|
|
wiz_create_invoice.settlements_ids = [(6, 0, settlements.ids)]
|
|
action = wiz_create_invoice.action_create_invoice()
|
|
invoices = self.env["account.move"].search(action["domain"])
|
|
self.assertTrue(invoices)
|
|
|
|
# Force invoice to partner
|
|
invoices.unlink()
|
|
wiz_create_invoice.invoice_partner_id = self.partner_2
|
|
action = wiz_create_invoice.action_create_invoice()
|
|
invoices = self.env["account.move"].search(action["domain"])
|
|
self.assertEqual(invoices.partner_id, self.partner_2)
|