Skip to content
Open
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_digital_improved/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_digital_improved/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

===========================
Digital Products - enhanced
===========================

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

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/license-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%2Fe--commerce-lightgray.png?logo=github
:target: https://github.com/OCA/e-commerce/tree/16.0/website_sale_digital_improved
:alt: OCA/e-commerce
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/e-commerce-16-0/e-commerce-16-0-website_sale_digital_improved
: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/e-commerce&target_branch=16.0
:alt: Try me on Runboat

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

This module extends the functionality of website_sale_digital:

- allow downloading digital products without portal account
- allow attaching digital products to the invoice mail

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Usage
=====

Access to digital products for customers without a portal account works
out of the box. Note that the links to digital products are designed to
be valid for an hour, so in case you receive complaints from your
customers that they don't work, ask them to refresh the page showing the
sale order.

To have Odoo mail digital products along with the invoice, enable
``Attach to invoice mail`` on a digital attachment of a product. This
only works as expected if you're using an instant payment method, and
have enabled ``Automatic Invoice`` in the website settings.

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/e-commerce/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/e-commerce/issues/new?body=module:%20website_sale_digital_improved%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
-------

* Hunki Enterprises BV

Contributors
------------

- Holger Brunn <mail@hunki-enterprises.com>
(https://hunki-enterprises.com)

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-hbrunn| image:: https://github.com/hbrunn.png?size=40px
:target: https://github.com/hbrunn
:alt: hbrunn

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

|maintainer-hbrunn|

This module is part of the `OCA/e-commerce <https://github.com/OCA/e-commerce/tree/16.0/website_sale_digital_improved>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions website_sale_digital_improved/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import controllers
from . import models
from . import wizards
24 changes: 24 additions & 0 deletions website_sale_digital_improved/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2026 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

{
"name": "Digital Products - enhanced",
"summary": "Makes digital products more accessible",
"version": "16.0.1.0.0",
"development_status": "Alpha",
"category": "Website/Website",
"website": "https://github.com/OCA/e-commerce",
"author": "Hunki Enterprises BV, Odoo Community Association (OCA)",
"maintainers": ["hbrunn"],
"license": "AGPL-3",
"depends": [
"website_sale_digital",
],
"data": [
"templates/website_sale_digital.xml",
"views/ir_attachment.xml",
],
"demo": [
"demo/ir_attachment.xml",
],
}
1 change: 1 addition & 0 deletions website_sale_digital_improved/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
47 changes: 47 additions & 0 deletions website_sale_digital_improved/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2026 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

import time

from odoo import http

from odoo.addons.sale.controllers import portal


class CustomerPortal(portal.CustomerPortal):
@http.route()
def portal_order_page(self, *args, **post):
# add timestamp+checksum to links to accessible digital products if not authenticated
result = super().portal_order_page(*args, **post)
if (
result.qcontext.get("digital_attachments")
and http.request.env["website"].is_public_user()
):
Attachment = http.request.env["ir.attachment"].sudo()
timestamp = int(time.time()) + int(
http.request.env["ir.config_parameter"]
.sudo()
.get_param("website_sale_digital_improved.url_timeout")
or 3600
)
for attachments in result.qcontext["digital_attachments"].values():
for attachment_vals in attachments:
checksum = Attachment.browse(
attachment_vals["id"]
)._generate_download_checksum(timestamp)
attachment_vals["website_sale_digital_improved_url"] = (
f"/my/download?attachment_id={attachment_vals['id']}"
f"&timestamp={timestamp}&checksum={checksum}"
)
return result

@http.route()
def download_attachment(self, attachment_id, timestamp=None, checksum=None):
# sudo super if attachment is authenticated by checksum
if timestamp and checksum and int(timestamp) > time.time():
attachment = (
http.request.env["ir.attachment"].sudo().browse(int(attachment_id))
)
if attachment._generate_download_checksum(timestamp) == checksum:
http.request.update_env(su=True)
return super().download_attachment(attachment_id)
5 changes: 5 additions & 0 deletions website_sale_digital_improved/demo/ir_attachment.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<odoo>
<record id="website_sale_digital.attach1" model="ir.attachment">
<field name="product_mailable" eval="True" />
</record>
</odoo>
2 changes: 2 additions & 0 deletions website_sale_digital_improved/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import account_move
from . import ir_attachment
37 changes: 37 additions & 0 deletions website_sale_digital_improved/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2026 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

from odoo import fields, models


class AccountMove(models.Model):
_inherit = "account.move"

def _website_sale_digital_get_attachments(self):
"""
Return attachment records for products that are considered digital products
"""
return self.env["ir.attachment"].search(
[
"|",
"&",
("res_model", "=", "product.template"),
("res_id", "in", self.invoice_line_ids.product_id.product_tmpl_id.ids),
"&",
("res_model", "=", "product.product"),
("res_id", "in", self.invoice_line_ids.product_id.ids),
("product_downloadable", "=", True),
("product_mailable", "=", True),
]
)

def _message_set_main_attachment_id(self, attachment_ids):
# never use a digital product as main attachment
Attachment = self.env["ir.attachment"]
attachment_ids = [
attachment_tuple
for attachment_tuple in attachment_ids
if attachment_tuple[0] != fields.Command.LINK
or not Attachment.browse(attachment_tuple[1]).product_downloadable
]
return super()._message_set_main_attachment_id(attachment_ids)
18 changes: 18 additions & 0 deletions website_sale_digital_improved/models/ir_attachment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2026 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

from odoo import fields, models, tools


class IrAttachment(models.Model):
_inherit = "ir.attachment"

product_mailable = fields.Boolean(
"Attach to invoice mail",
help="Attach this digital product to the invoice. "
"Enable only if you use instant payment methods exclusively.",
)

def _generate_download_checksum(self, timestamp):
self.ensure_one()
return tools.hmac(self.env, f"website_sale_digital-{self.id}", str(timestamp))
1 change: 1 addition & 0 deletions website_sale_digital_improved/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Holger Brunn \<mail@hunki-enterprises.com> (https://hunki-enterprises.com)
4 changes: 4 additions & 0 deletions website_sale_digital_improved/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This module extends the functionality of website\_sale\_digital:

- allow downloading digital products without portal account
- allow attaching digital products to the invoice mail
3 changes: 3 additions & 0 deletions website_sale_digital_improved/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Access to digital products for customers without a portal account works out of the box. Note that the links to digital products are designed to be valid for an hour, so in case you receive complaints from your customers that they don't work, ask them to refresh the page showing the sale order.

To have Odoo mail digital products along with the invoice, enable `Attach to invoice mail` on a digital attachment of a product. This only works as expected if you're using an instant payment method, and have enabled `Automatic Invoice` in the website settings.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading