Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][MIG] sale_coupon_multi_gift>sale_loyalty_multi_gift: Migration to version 16.0 #196

Merged
merged 10 commits into from
Jul 12, 2024
Merged
106 changes: 106 additions & 0 deletions sale_loyalty_multi_gift/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
=======================
Sale Loyalty Multi Gift
=======================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:214d59fbe6811aa1a74e43630c640fc5230b22769cefa87b7a3bba3eee355706
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--promotion-lightgray.png?logo=github
:target: https://github.com/OCA/sale-promotion/tree/16.0/sale_loyalty_multi_gift
:alt: OCA/sale-promotion
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/sale-promotion-16-0/sale-promotion-16-0-sale_loyalty_multi_gift
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/sale-promotion&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows to define multiple reward products on promotions on sale orders.

**Table of contents**

.. contents::
:local:

Configuration
=============

Configure the promotion as told in ``coupon_multi_gift`` readme.

Usage
=====

Once configured, apply the programs as usual to get the expected rewards.

Known issues / Roadmap
======================

* Gifts are applied just once independently from the min quantity set.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-promotion/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/sale-promotion/issues/new?body=module:%20sale_loyalty_multi_gift%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Tecnativa

Contributors
~~~~~~~~~~~~

* `Tecnativa <https://www.tecnativa.com>`_:

* David Vidal
* Pilar Vargas

* `Domatix <https://www.domatix.com>`_:

* Carolina Ferrer

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-chienandalu| image:: https://github.com/chienandalu.png?size=40px
:target: https://github.com/chienandalu
:alt: chienandalu

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-chienandalu|

This module is part of the `OCA/sale-promotion <https://github.com/OCA/sale-promotion/tree/16.0/sale_loyalty_multi_gift>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions sale_loyalty_multi_gift/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
18 changes: 18 additions & 0 deletions sale_loyalty_multi_gift/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Sale Loyalty Multi Gift",
"summary": "Allows to configure multiple gift rewards per promotion in sales",
"version": "16.0.1.0.0",
"development_status": "Beta",
"category": "Sale",
"website": "https://github.com/OCA/sale-promotion",
"author": "Tecnativa, Odoo Community Association (OCA)",
"maintainers": ["chienandalu"],
"license": "AGPL-3",
"depends": ["sale_loyalty_order_line_link", "loyalty_multi_gift"],
"data": [
"security/ir.model.access.csv",
"wizard/sale_loyalty_reward_wizard_views.xml",
],
}
49 changes: 49 additions & 0 deletions sale_loyalty_multi_gift/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_coupon_multi_gift
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-17 10:02+0000\n"
"PO-Revision-Date: 2023-11-08 13:38+0000\n"
"Last-Translator: Ivorra78 <[email protected]>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"

#. module: sale_coupon_multi_gift
#: model:ir.model,name:sale_coupon_multi_gift.model_coupon_program
msgid "Coupon display on a website"
msgstr "Visualización de cupones en un sitio web"

#. module: sale_coupon_multi_gift
#: code:addons/sale_coupon_multi_gift/models/sale_order.py:0
#, python-format
msgid "Free Product"
msgstr "Producto gratis"

#. module: sale_coupon_multi_gift
#: model:ir.model.fields,field_description:sale_coupon_multi_gift.field_sale_order_line__multi_gift_reward_line_id
msgid "Multi Gift Reward Line"
msgstr "Línea de recompensa multi regalo"

#. module: sale_coupon_multi_gift
#: model:ir.model.fields,field_description:sale_coupon_multi_gift.field_sale_order_line__multi_gift_reward_line_id_option_product_id
msgid "Multi Gift Reward Line Id Option Product"
msgstr "Producto opcional de la línea de recompensa multi regalo"

#. module: sale_coupon_multi_gift
#: model:ir.model,name:sale_coupon_multi_gift.model_sale_order
msgid "Sales Order"
msgstr "Pedido de venta"

#. module: sale_coupon_multi_gift
#: model:ir.model,name:sale_coupon_multi_gift.model_sale_order_line
msgid "Sales Order Line"
msgstr "Línea de pedido de venta"
45 changes: 45 additions & 0 deletions sale_loyalty_multi_gift/i18n/sale_coupon_multi_gift.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_coupon_multi_gift
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: sale_coupon_multi_gift
#: model:ir.model,name:sale_coupon_multi_gift.model_coupon_program
msgid "Coupon display on a website"
msgstr ""

#. module: sale_coupon_multi_gift
#: code:addons/sale_coupon_multi_gift/models/sale_order.py:0
#, python-format
msgid "Free Product"
msgstr ""

#. module: sale_coupon_multi_gift
#: model:ir.model.fields,field_description:sale_coupon_multi_gift.field_sale_order_line__multi_gift_reward_line_id
msgid "Multi Gift Reward Line"
msgstr ""

#. module: sale_coupon_multi_gift
#: model:ir.model.fields,field_description:sale_coupon_multi_gift.field_sale_order_line__multi_gift_reward_line_id_option_product_id
msgid "Multi Gift Reward Line Id Option Product"
msgstr ""

#. module: sale_coupon_multi_gift
#: model:ir.model,name:sale_coupon_multi_gift.model_sale_order
msgid "Sales Order"
msgstr ""

#. module: sale_coupon_multi_gift
#: model:ir.model,name:sale_coupon_multi_gift.model_sale_order_line
msgid "Sales Order Line"
msgstr ""
2 changes: 2 additions & 0 deletions sale_loyalty_multi_gift/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# from . import coupon_program
from . import sale_order
163 changes: 163 additions & 0 deletions sale_loyalty_multi_gift/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import random

from odoo import _, fields, models
from odoo.exceptions import UserError
from odoo.fields import Command, first
from odoo.tools.float_utils import float_round


class SaleOrder(models.Model):
_inherit = "sale.order"

def action_open_reward_wizard(self):
self.ensure_one()
self._update_programs_and_rewards()
claimable_rewards = self._get_claimable_rewards()

Check warning on line 17 in sale_loyalty_multi_gift/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

sale_loyalty_multi_gift/models/sale_order.py#L15-L17

Added lines #L15 - L17 were not covered by tests
if (
len(claimable_rewards) == 1
and claimable_rewards.get(next(iter(claimable_rewards))).reward_type
== "multi_gift"
and any(
len(record.reward_product_ids) > 1
for record in claimable_rewards.get(
next(iter(claimable_rewards))
).loyalty_multi_gift_ids
)
):
ctx = {

Check warning on line 29 in sale_loyalty_multi_gift/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

sale_loyalty_multi_gift/models/sale_order.py#L29

Added line #L29 was not covered by tests
"default_selected_reward_id": claimable_rewards.get(
next(iter(claimable_rewards))
).id,
}
return {

Check warning on line 34 in sale_loyalty_multi_gift/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

sale_loyalty_multi_gift/models/sale_order.py#L34

Added line #L34 was not covered by tests
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "sale.loyalty.reward.wizard",
"target": "new",
"context": ctx,
}
else:
return super().action_open_reward_wizard()

Check warning on line 42 in sale_loyalty_multi_gift/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

sale_loyalty_multi_gift/models/sale_order.py#L42

Added line #L42 was not covered by tests

def _get_reward_values_multi_gift_line(
self, reward, coupon, cost, reward_line=False, product=False
):
"""Multi Gift reward rules. For every gift reward rule, we'll create a new
sale order line flagged as reward line with a 100% discount"""
self.ensure_one()
assert reward.reward_type == "multi_gift"
selected_product = (
self.env["product.product"].browse(
self.env.context.get("reward_line_options", {}).get(reward_line.id)
)
& reward_line.reward_product_ids
)
reward_product_id = (
selected_product or product or first(reward_line.reward_product_ids)
)
if (
not reward_product_id
or reward_product_id not in reward.loyalty_multi_gift_ids.reward_product_ids
):
raise UserError(_("Invalid product to claim."))

Check warning on line 64 in sale_loyalty_multi_gift/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

sale_loyalty_multi_gift/models/sale_order.py#L64

Added line #L64 was not covered by tests
taxes = self.fiscal_position_id.map_tax(
reward_product_id.taxes_id.filtered(
lambda t: t.company_id == self.company_id
)
)
vals = {
"order_id": self.id,
"is_reward_line": True,
"name": _(
"Free Product - %(product)s",
product=reward_product_id.with_context(
display_default_code=False
).display_name,
),
"product_id": reward_product_id.id,
"price_unit": reward_product_id.list_price,
"discount": 100,
"product_uom_qty": reward_line.reward_product_quantity,
"reward_id": reward.id,
"coupon_id": coupon.id,
"points_cost": cost,
"reward_identifier_code": str(random.getrandbits(32)),
"product_uom": reward_product_id.uom_id.id,
"sequence": max(
self.order_line.filtered(lambda x: not x.is_reward_line).mapped(
"sequence"
),
default=10,
)
+ 1,
"tax_id": [(Command.CLEAR, 0, 0)]
+ [(Command.LINK, tax.id, False) for tax in taxes],
"loyalty_program_id": reward.program_id.id,
"multi_gift_reward_line_id": reward_line.id,
"multi_gift_reward_line_id_option_product_id": reward_product_id.id,
}
return vals

def _get_reward_values_multi_gift(self, reward, coupon, **kwargs):
"""Wrapper to create the reward lines for a multi gift promotion"""
points = self._get_real_points_for_coupon(coupon)
claimable_count = (
float_round(
points / reward.required_points,
precision_rounding=1,
rounding_method="DOWN",
)
if not reward.clear_wallet
else 1
)
total_cost = (
points if reward.clear_wallet else claimable_count * reward.required_points
)
cost = total_cost / len(reward.loyalty_multi_gift_ids)
order_lines = self.order_line.filtered(
lambda x: x.is_reward_line
and x.reward_id.reward_type == "multi_gift"
and x.coupon_id == coupon
)
if order_lines:
return [
self._get_reward_values_multi_gift_line(
reward,
coupon,
cost,
reward_line=reward_line.multi_gift_reward_line_id,
product=reward_line.multi_gift_reward_line_id_option_product_id,
)
for reward_line in order_lines
]
else:
return [
self._get_reward_values_multi_gift_line(
reward, coupon, cost, reward_line=reward_line
)
for reward_line in reward.loyalty_multi_gift_ids
]

def _get_reward_line_values(self, reward, coupon, **kwargs):
"""Hook into the core method considering multi gift rewards"""
self.ensure_one()
self = self.with_context(lang=self.partner_id.lang)
reward = reward.with_context(lang=self.partner_id.lang)
if reward.reward_type == "multi_gift":
return self._get_reward_values_multi_gift(reward, coupon, **kwargs)
return super()._get_reward_line_values(reward, coupon, **kwargs)


class SaleOrderLine(models.Model):
_inherit = "sale.order.line"

multi_gift_reward_line_id = fields.Many2one(
comodel_name="loyalty.reward.product_line",
readonly=True,
)
multi_gift_reward_line_id_option_product_id = fields.Many2one(
comodel_name="product.product",
readonly=True,
)
1 change: 1 addition & 0 deletions sale_loyalty_multi_gift/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Configure the promotion as told in ``coupon_multi_gift`` readme.
Loading
Loading