Skip to content

Commit

Permalink
Merge PR #203 into 16.0
Browse files Browse the repository at this point in the history
Signed-off-by pedrobaeza
  • Loading branch information
OCA-git-bot committed Dec 11, 2024
2 parents 8a620b0 + 9f50369 commit bacc701
Show file tree
Hide file tree
Showing 21 changed files with 1,640 additions and 0 deletions.
6 changes: 6 additions & 0 deletions setup/website_sale_loyalty_suggestion_wizard/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,
)
111 changes: 111 additions & 0 deletions website_sale_loyalty_suggestion_wizard/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
======================================
Website Sale Loyalty Suggestion Wizard
======================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8c11a0d3f2c9fac24b5e452a5da349a41d86d34df86fa10b103b47acd0babf25
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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/website_sale_loyalty_suggestion_wizard
: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-website_sale_loyalty_suggestion_wizard
: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 makes suggestions for promotions whose rules include a product added to the
cart. It also allows you to configure and apply these promotions with an elegant eCommerce
wizard.

**Table of contents**

.. contents::
:local:

Usage
=====

To apply promotions:

Option 1:

#. Go to /promotions and choose the one apply.
#. You'll be prompted to check the promotion configuration.
#. Apply after that.

Option 2:

#. Add a product in the promotion rules.
#. A cart suggestion will appear.
#. Add the promotion and configure the options.

Option 3:

#. Select a suggested promotion in the shopping cart from a list of "Suggested promotions".
#. Add the promotion and configure the options.

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:%20website_sale_loyalty_suggestion_wizard%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

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/website_sale_loyalty_suggestion_wizard>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions website_sale_loyalty_suggestion_wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
27 changes: 27 additions & 0 deletions website_sale_loyalty_suggestion_wizard/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Website Sale Loyalty Suggestion Wizard",
"summary": "Suggests promotions and allows you to configure and apply these "
"promotions directly from the website",
"version": "16.0.1.0.0",
"development_status": "Beta",
"category": "eCommerce",
"website": "https://github.com/OCA/sale-promotion",
"author": "Tecnativa, Odoo Community Association (OCA)",
"maintainers": ["chienandalu"],
"license": "AGPL-3",
"depends": [
"sale_loyalty",
"sale_loyalty_order_suggestion",
"website_sale_loyalty_page",
],
"data": ["templates/promotion_templates.xml", "templates/wizard_templates.xml"],
"assets": {
"web.assets_frontend": [
"/website_sale_loyalty_suggestion_wizard/static/src/scss/"
"website_sale_loyalty_suggestion_wizard.scss",
"/website_sale_loyalty_suggestion_wizard/static/src/js/*",
]
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import promotion_page
from . import main
from . import promotion_wizard
66 changes: 66 additions & 0 deletions website_sale_loyalty_suggestion_wizard/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright 2021 Tecnativa - David Vidal
# Copyright 2024 Tecnativa - Pilar Vargas
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.http import request, route

from odoo.addons.website_sale.controllers.main import WebsiteSale


class WebsiteSaleLoyaltySuggestionWizard(WebsiteSale):
def _get_sale_loyalty_reward_wizard(self, order, program):
wizard = (
request.env["sale.loyalty.reward.wizard"]
.with_context(active_id=order.id)
.sudo()
.create({"selected_reward_id": program.reward_ids[:1].id})
)
return wizard

@route(
["/promotions/<int:program_id>/apply"], type="http", auth="public", website=True
)
def promotion_program_apply(self, program_id, **kwargs):
program = request.env["loyalty.program"].sudo().browse(program_id).exists()
request.session.pop("wizard_id", None)
if not program or not program.active or not program.is_published:
return request.redirect("/shop/cart")
# Prevent to apply a promotion to a processed order
order = request.website.sale_get_order()
if order and order.state != "draft":
request.session["sale_order_id"] = None
order = request.website.sale_get_order()
# We won't apply it twice
if program in order._get_reward_programs():
return request.redirect("/shop/cart")
# Let's inject some context into the view
request.session["promotion_id"] = program.id
request.session["order_id"] = order.id
return request.redirect("/shop/cart")

@route()
def cart(self, **post):
error = request.session.get("error_promo_code")
response = super().cart(**post)
promotion = request.session.get("promotion_id")
order = request.session.get("sale_order_id")
if promotion:
program_id = request.env["loyalty.program"].sudo().browse(promotion)
order_id = request.env["sale.order"].browse(order)
wizard_id = self._get_sale_loyalty_reward_wizard(order_id, program_id)
mandatory_program_options = (
response.qcontext.get("mandatory_program_options")
or wizard_id.loyalty_rule_line_ids
)
response.qcontext["promotion_id"] = program_id
response.qcontext["order_id"] = order_id
response.qcontext["mandatory_program_options"] = mandatory_program_options
if error:
request.session["error_promo_code"] = error
return response

@route(["/promotions/dismiss"], type="http", auth="public", website=True)
def promotion_in_cart_dismiss(self, **kw):
request.session.pop("promotion_id", None)
request.session.pop("error_promo_code", None)
request.session.pop("wizard_id", None)
return request.redirect("/shop/cart")
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.http import request, route

from odoo.addons.website_sale_loyalty_page.controllers.main import WebsiteSale


class LoyaltyPage(WebsiteSale):
@route()
def promotion(self, **post):
"""Rules to render the 'Apply promotion' button"""
response = super().promotion(**post)
order = request.website.sale_get_order(force_create=True)
if not order:
return response
promo_values = response.qcontext.get("promos", [])
for promo_dict in promo_values:
promo_dict["applicable"] = False
promo = request.env["loyalty.program"].sudo().browse(promo_dict["id"])
if promo not in order.sudo()._filter_programs_by_rules_with_products():
continue
promo_dict["applicable"] = True
return response
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Copyright 2021 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.exceptions import ValidationError
from odoo.http import request, route

from odoo.addons.website_sale_loyalty.controllers.main import WebsiteSale


class WebsiteSaleLoyaltySuggestionWizardController(WebsiteSale):
def _process_promotion_lines(self, wizard_id, promotion_lines):
for product, qty in promotion_lines.items():
line = wizard_id.loyalty_rule_line_ids.filtered(
lambda x: x.product_id.id == int(product)
)
if len(promotion_lines) == 1:
qty = line.units_required - line.units_included
if not qty:
continue
line.units_to_include = qty

def _process_reward_line_options(self, wizard_id, reward_line_options):
reward_id = wizard_id.selected_reward_id
if reward_id.reward_type == "product":
reward_products = reward_id.reward_product_ids
if len(reward_products) == 1:
wizard_id.selected_product_id = reward_products.id
else:
wizard_id.selected_product_id = (
int(reward_line_options.get("selected_product_ids", False)[0])
or wizard_id.selected_product_id.id
)

@route(
"/website_sale_loyalty_suggestion_wizard/get_defaults",
type="json",
auth="public",
methods=["POST"],
)
def get_default_products(self):
program_id = (
request.env["loyalty.program"]
.sudo()
.browse(request.session.get("promotion_id"))
)
order_id = request.env["sale.order"].browse(
request.session.get("sale_order_id")
)
wiz = self._get_sale_loyalty_reward_wizard(order_id, program_id)
return wiz.selected_product_id.ids

@route(
"/website_sale_loyalty_suggestion_wizard/apply",
type="json",
auth="public",
methods=["POST"],
)
def apply_promotion_public(
self, program_id, promotion_lines, reward_line_options, **kw
):
"""Frontend controller that wraps common methods and handles errors properly"""
order_id = request.env["sale.order"].browse(
request.session.get("sale_order_id")
)
program_id = request.env["loyalty.program"].sudo().browse(program_id)
wiz = self._get_sale_loyalty_reward_wizard(order_id, program_id)
reward_id = reward_line_options.get("reward_id", False)
wiz.selected_reward_id = int(reward_id) or (
program_id.reward_ids.id if len(program_id.reward_ids) == 1 else False
)
if wiz.selected_reward_id:
self._process_promotion_lines(wiz, promotion_lines)
self._process_reward_line_options(wiz, reward_line_options)
try:
wiz.action_apply()
except ValidationError as e:
request.session["error_promo_code"] = str(e)
return
request.session.pop("promotion_id", None)
request.session.pop("error_promo_code", None)
68 changes: 68 additions & 0 deletions website_sale_loyalty_suggestion_wizard/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * website_sale_loyalty_suggestion_wizard
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-18 16:05+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: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.configure_promotion
msgid "<i class=\"fa fa-gift\"/> Configure"
msgstr "<i class=\"fa fa-gift\"/> Configurar"

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.configure_promotion
msgid "<span>×</span>"
msgstr "<span>×</span>"

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.website_sale_loyalty_suggestion
msgid "<strong>Add</strong>"
msgstr "<strong>Añadir</strong>"

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.configure_promotion
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.promotion_item
msgid "Apply"
msgstr "Aplicar"

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.configure_promotion
msgid "Close"
msgstr "Cerrar"

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.website_sale_loyalty_suggestion
msgid "Configurable promotions suggested"
msgstr "Promociones configurables sugeridas"

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.configure_promotion
msgid "In order to apply this promotion you need to configure some options."
msgstr "Para aplicar esta promoción necesita configurar algunas opciones."

#. module: website_sale_loyalty_suggestion_wizard
#: model_terms:ir.ui.view,arch_db:website_sale_loyalty_suggestion_wizard.website_sale_loyalty_suggestion
msgid "Suggested Promotions:"
msgstr "Promociones Sugeridas:"

#. module: website_sale_loyalty_suggestion_wizard
#: code:addons/website_sale_loyalty_suggestion_wizard/controllers/promotion_wizard.py:0
#, python-format
msgid "This promotion can't be applied to this order"
msgstr "Esta promoción no puede ser aplicada en este pedido"

#~ msgid "Sales Order"
#~ msgstr "Pedido de Venta"
Loading

0 comments on commit bacc701

Please sign in to comment.