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][ADD] website_sale_restrict_sepa_dd #337

Draft
wants to merge 2 commits into
base: 16.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions setup/website_sale_restrict_sepa_dd/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,
)
70 changes: 70 additions & 0 deletions website_sale_restrict_sepa_dd/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
==================================
Restrict SEPA Direct Debit Payment
==================================

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

.. |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-coopiteasy%2Faddons-lightgray.png?logo=github
:target: https://github.com/coopiteasy/addons/tree/16.0/website_sale_restrict_sepa_dd
:alt: coopiteasy/addons

|badge1| |badge2| |badge3|

Form to order subscription product

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `GitHub Issues <https://github.com/coopiteasy/addons/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/coopiteasy/addons/issues/new?body=module:%20website_sale_restrict_sepa_dd%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
~~~~~~~

* Coop IT Easy SC

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

* `Coop IT Easy SC <https://coopiteasy.be>`_:

* Rémy Taymans

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

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

Current maintainer:

|maintainer-remytms|

This module is part of the `coopiteasy/addons <https://github.com/coopiteasy/addons/tree/16.0/website_sale_restrict_sepa_dd>`_ project on GitHub.

You are welcome to contribute.
5 changes: 5 additions & 0 deletions website_sale_restrict_sepa_dd/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from . import models
from . import controllers
26 changes: 26 additions & 0 deletions website_sale_restrict_sepa_dd/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

{
"name": "Restrict SEPA Direct Debit Payment",
"summary": """
Restrict payment by SEPA Direct Debit for some products.""",
"version": "16.0.1.0.0",
"category": "Website",
"website": "https://github.com/coopiteasy/addons",
"author": "Coop IT Easy SC",
"maintainers": ["remytms"],
"license": "AGPL-3",
"application": False,
"depends": [
"website_sale_sepa_dd_payment",
],
"excludes": [],
"data": [
"views/product_views.xml",
"views/templates.xml",
],
"demo": [],
"qweb": [],
}
4 changes: 4 additions & 0 deletions website_sale_restrict_sepa_dd/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from . import main
63 changes: 63 additions & 0 deletions website_sale_restrict_sepa_dd/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from odoo import http
from odoo.http import request

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


class WebsiteSaleRestrictSEPADD(WebsiteSale):
@http.route(
["/shop/cart/update"],
type="http",
auth="public",
methods=["POST"],
website=True,
)
def cart_update(
self,
product_id,
add_qty=1,
set_qty=0,
product_custom_attribute_values=None,
no_variant_attribute_values=None,
express=False,
**kwargs
):
sale_order = request.website.sale_get_order(force_create=True)
if sale_order.state != "draft":
request.session["sale_order_id"] = None
sale_order = request.website.sale_get_order(force_create=True)

warning = sale_order.check_product_compatibility(int(product_id))

request.session["website_sale_cart_warning"] = warning

if warning:
return request.redirect("/shop/cart")

return super().cart_update(
product_id=product_id,
add_qty=add_qty,
set_qty=set_qty,
product_custom_attribute_values=product_custom_attribute_values,
no_variant_attribute_values=no_variant_attribute_values,
express=express,
**kwargs
)

@http.route(["/shop/cart"], type="http", auth="public", website=True, sitemap=False)
def cart(self, access_token=None, revive="", **post):
warning = ""
if "website_sale_cart_warning" in request.session:
warning = request.session["website_sale_cart_warning"]
del request.session["website_sale_cart_warning"]
response = super().cart(access_token=access_token, revive=revive, **post)
response.qcontext.update(
{
"website_sale_cart_warning": warning,
}
)
return response
6 changes: 6 additions & 0 deletions website_sale_restrict_sepa_dd/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from . import product_template
from . import payment_provider
from . import sale_order
52 changes: 52 additions & 0 deletions website_sale_restrict_sepa_dd/models/payment_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from odoo import api, models


class PaymentProvider(models.Model):
_inherit = "payment.provider"

@api.model
def _get_compatible_providers(
self, *args, sale_order_id=None, website_id=None, **kwargs
):
"""Override of payment to exclude SEPA Direct Debit if product
does not allow it.

:param int sale_order_id: The sale order to be paid, if any, as
a `sale.order` id
:param int website_id: The provided website, as a `website` id
:return: The compatible providers
:rtype: recordset of `payment.provider`
"""
compatible_providers = super()._get_compatible_providers(
*args, sale_order_id=sale_order_id, website_id=website_id, **kwargs
)
order = self.env["sale.order"].browse(sale_order_id).exists()
# Allow SEPA Direct Debit only if all products allow SEPA DD payment
allow_sepa_dd_payment = all(
order.order_line.mapped("product_id").mapped("allow_sepa_dd_payment")
)
# Allow only SEPA Direct Debit if at least one product must be payed
# by SEPA Direct Debit
only_sepa_dd_payment = any(
order.order_line.mapped("product_id").mapped("only_sepa_dd_payment")
)
if not allow_sepa_dd_payment and not only_sepa_dd_payment:
# Exclude sepa_dd
compatible_providers = compatible_providers.filtered(
lambda p: p.code != "custom" or p.custom_mode != "sepa_dd"
)
elif allow_sepa_dd_payment and only_sepa_dd_payment:
# Get only sepa_dd
compatible_providers = compatible_providers.filtered(
lambda p: p.code == "custom" and p.custom_mode == "sepa_dd"
)
elif not allow_sepa_dd_payment and only_sepa_dd_payment:
# Product are not compatible between each other. No payement
# provider can be used.
compatible_providers = self.env["payment.provider"]

return compatible_providers
37 changes: 37 additions & 0 deletions website_sale_restrict_sepa_dd/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

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


class SaleOrder(models.Model):
_inherit = "product.template"

allow_sepa_dd_payment = fields.Boolean(string="Allow SEPA Direct Debit Payment")
only_sepa_dd_payment = fields.Boolean(string="Only SEPA Direct Debit Payment")

@api.constrains("allow_sepa_dd_payment", "only_sepa_dd_payment")
def _check_allow_sepa_dd_payment(self):
"""Ensure that allow_sepa_dd_payment is set if
only_sepa_dd_payment is set.
"""
for product in self:
if product.only_sepa_dd_payment and not product.allow_sepa_dd_payment:
raise ValidationError(
_(
"Allow SEPA Direct Debit payment for the product "
"in ordre to set Only SEPA Direct Debit payment."
)
)

@api.onchange("only_sepa_dd_payment")
def _onchange_only_sepa_dd_payment(self):
if self.only_sepa_dd_payment:
self.allow_sepa_dd_payment = True

@api.onchange("allow_sepa_dd_payment")
def _onchange_allow_sepa_dd_payment(self):
if not self.allow_sepa_dd_payment:
self.only_sepa_dd_payment = False
97 changes: 97 additions & 0 deletions website_sale_restrict_sepa_dd/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later


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


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

allow_sepa_dd_payment = fields.Boolean(compute="_compute_allow_sepa_dd_payment")
only_sepa_dd_payment = fields.Boolean(compute="_compute_only_sepa_dd_payment")

@api.constrains("order_line")
def _check_compatible_product(self):
"""Prevent incompatible product to be added to the same sale order"""
for order in self:
only_sepa_dd_payment = any(
order.order_line.mapped("product_id").mapped("only_sepa_dd_payment")
)
allow_sepa_dd_payment = all(
order.order_line.mapped("product_id").mapped("allow_sepa_dd_payment")
)
if only_sepa_dd_payment and not allow_sepa_dd_payment:
raise ValidationError(
_(
"Cannot add product that does not allow SEPA "
"Direct Debit with products that allow only SEPA "
"Direct Debit payment."
)
)

@api.depends("order_line")
def _compute_allow_sepa_dd_payment(self):
for order in self:
allow_sepa_dd_payment = all(
order.order_line.mapped("product_id").mapped("allow_sepa_dd_payment")
)
order.allow_sepa_dd_payment = allow_sepa_dd_payment

@api.depends("order_line")
def _compute_only_sepa_dd_payment(self):
for order in self:
order.only_sepa_dd_payment = any(
order.order_line.mapped("product_id").mapped("only_sepa_dd_payment")
)

def check_product_compatibility(self, product_id):
self.ensure_one()
product = self.env["product.product"].browse(product_id).exists()
warning = ""
only_sepa_dd_product = self.order_line.mapped("product_id").filtered(
lambda p: p.only_sepa_dd_payment
)
allow_sepa_dd_payment = all(
self.order_line.mapped("product_id").mapped("allow_sepa_dd_payment")
)
if product:
if only_sepa_dd_product and not product.allow_sepa_dd_payment:
# This product cannot be added
warning = _(
f"Product {product.name} cannot be added to cart "
"because product(s) : "
f"{', '.join(p.name for p in only_sepa_dd_product)} "
"must be payed by SEPA Direct Debit and product "
f"{product.name} cannot be payed by such method."
"Please process this order first, or clear "
f"the order."
)
elif not allow_sepa_dd_payment and product.only_sepa_dd_payment:
warning = _(
f"Product {product.name} cannot be added to cart "
"because other products in the cart does not allow "
"SEPA Direct Debit as payment method and "
f"{product.name} must be payed with such a method."
"Please process this order first, or clear it."
)
return warning

def _cart_update(self, product_id, line_id=None, add_qty=0, set_qty=0, **kwargs):
"""Prevent incompatible product to be added to the cart."""
self.ensure_one()
warning = self.check_product_compatibility(product_id)
if warning:
add_qty = None
set_qty = 0
values = super()._cart_update(
product_id=product_id,
line_id=line_id,
add_qty=add_qty,
set_qty=set_qty,
**kwargs,
)
values["warning"] = warning
return values
3 changes: 3 additions & 0 deletions website_sale_restrict_sepa_dd/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Coop IT Easy SC <https://coopiteasy.be>`_:

* Rémy Taymans
1 change: 1 addition & 0 deletions website_sale_restrict_sepa_dd/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Form to order subscription product
Loading
Loading