Commit Graph
43 Commits
Author SHA1 Message Date
Jeremy Kersten 478068c829 [IMP] *: always use Odoo Response
This branch adds request.redirect on all requests.
In case of a front end request, we do an url_for to the location.

We removed redirect_with_hash that was only for retro compatibility

local_redirect has been renamed to redirect_query, and param keep_hash has been
removed and moved.

Default code for redirect is 303 now instead of 302.

Now redirect and redirect_query make local redirect by default, you need to
pass local=False to make external redirect.

All werkeug.utils.redirect has been replaced by request.redirect.

Http.redirect now use an http.Response type, and it become easy to add an
override like 'set_cookies' e.g.

Dispatch of a website.page return an http.response too, so we first need to
check if it is a cached version before to check if it is an Odoo Response.

Migrate your code:

http.redirect -> request.redirect(location, code, local)
http.local_redirect -> request.redirect_query(location, query, code, local)
http.redirect_with_hash -> request.redirect

Courtesy of odony for help and review ;)

closes odoo/odoo#72599

Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
2021-07-08 07:00:06 +00:00
Romain Derie 6ca30e23ee [REM] website_sale_digital: remove dead code
Product field type value `digital` doesn't exist anymore, see 1a1efe3fce
Moreover, `digital` as qcontext seems like it was not used anyway, see
8a1b8e880c.

closes odoo/odoo#71629

Related: odoo/enterprise#18697
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
2021-06-03 12:03:13 +00:00
Antoine Vandevenne (anv)andVictor Feyens 573ed74c12 [REF] payment, *: refactor online payments API
This commit replaces the old online payments API of the `payment`
module with the new one and adapts to it all the implementing modules.

See the merge commit for more details.

task-2085989
task-2119838
task-2165982
task-2289255

Co-authored-by: Victor Feyens <vfe@odoo.com>
2021-03-30 09:25:51 +02:00
IEL 1bb2ed9623 [FIX] website_sale_digital: allow download without reconciliation
TLDR: after installation accounting app, invoices paid online get status "In Payment" until
reconciliation; this commit allows to download digital content without waiting
reconciliation which may take days or week

Steps:

* Install Accounting app
* Install website_sale_digital
* Create Digital product (Product Type: Service + use Digital Files smart button
to upload a file)
* Setup payment acquirer (e.g. Paypal)
* Buy digital product online and pay
* Open the Sale Order in Portal

Before:

* No "Downloads" button near to product name

After

* User can download files after purchasing

Notes

* In Odoo 13.0 it worked via "post_at" option, which is removed in Odoo 14. See
https://github.com/odoo/odoo/commit/caeb782841fc5a7ad71a196e2c9ee67644ef9074:

  > - Remove the post_at bank reconciliation feature. The "paid" state will be set on the invoices only if reconciled with a journal entry involving the journal's liquidity account.
  >     With invoicing, the payment will do that so the "in_payment" state should never be shown up.
  >     With accounting, only the statement lines have the power to move an invoice to the "paid" state.

---

opw-2353064

closes odoo/odoo#59959

X-original-commit: 103abd3284cea1723adc0e4b90e57961a4fac2a0
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2020-10-14 09:48:04 +00:00
oco-odoo 8e4158af81 [IMP] account: add 'partial' and 'reversed' payment states to invoices
- 'partial' payment state corresponds to invoices whose payable/receivable move line has been partially reconciled with some other line.

- 'reversed' payment state corresponds to entries that have been cancelled by the creation of a single reverse entry (using the dedicated button on the form view). This state can be set on invoice as well as on regular entries.

=> To stay consistent with the naming conventions, this commit also renames invoice_payment_state field to payment_state, since it's no longer only applicable on invoices.

closes odoo/odoo#41723

Related: odoo/enterprise#7202
Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
2020-01-16 18:04:26 +00:00
Jorge Pinna Puissant 6977f85d2f [FIX] website_sale_digital: limit attachment search
Before this commit, in a sales order preview, a search is performed to
search all the attachments in invoiced products or free products.

Now, the search is only performed if the product is a digital product.

opw-2172563

closes odoo/odoo#43434

X-original-commit: 2c9e7832a02d2e4e2f219e979dd8ae3cbaa77bd9
Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
2020-01-16 16:15:08 +00:00
alt-odoo 0bea630c98 [FIX] website_sale_digital: access rights error in preview order page
In preview order page, we are looking for product attachments, but if we are
using public user, we get an access rights error leading to a 403 page.

opw-2172563

X-original-commit: d07800eadf49e75c249f9a28aca2412b6b106793
2020-01-16 16:15:07 +00:00
ryv-odoo f01ce96204 [FIX] website_sale_digital : fix AccessError attachment
A user get a AccessError during a valid flow on the website shop
due to a attachment search (with website_sale_digital installed) :
- As a portal user buy a product and pay with wire tranfer (or other)
- Check the your quotation with this user and we get a AccessError
for the read ir.attachment model.

The bug comes from the website_sale_digital module which add a search
on ir.attachment for each product (allows digital product sell,
eg. ebook) on the controller rendering orders. To fix this issue, add
a sudo call before the search. It is legit because only the name and
date is retrieved and the download (of the digital product) checks
the access of this product attachment (if user already paid for it).

TASK_ID : 2004031

closes odoo/odoo#39043

X-original-commit: c757e14cb791262485a949eacdcfb2029d03fa5f
Signed-off-by: ryv-odoo <ryv-odoo@users.noreply.github.com>
2019-10-18 13:52:17 +00:00
Christophe Simonis 51354fadb0 [MERGE] forward port branch saas-12.3 up to 50e571acf7
closes odoo/odoo#36491

Signed-off-by: Christophe Simonis <chs@odoo.com>
2019-09-11 09:39:33 +00:00
Fanny He df85ddc28f [FIX] website_sale_digital: download file.extension when name has no extension
When selling a digital file on the web shop, if the file 'name'
has no extension (e.g. the pdf "Free Booklet"), the buyer
will download "Free Booklet" even when the mimetype is application/pdf).
This causes issues on Mac, as pdf files without extension are renamed
with .dms extensions.

We follow what is done in ir_http's binary_content for the extension management,
using the new one if provided in the name, then the original filename extension
if it exists, and we fallback on guessing it from the mimetype.

OPW 2057302

closes odoo/odoo#36294

Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
2019-08-30 14:29:09 +00:00
Toufik Ben Jaa 0f6740c80c [FIX] website_sale_digital: invoice_id doesn't exists anymore
- Since commit https://github.com/odoo/odoo/commit/beaa30a3d1843de43a45f419bfbc1bfa7613a920
the object `account.invoice` has been removed.

We now refer to `account.move` when talking about invoices.
In website_sale_digital, a piece of code was still refering to the
field `invoice_id` in `account.move.line` instead of using `move_id`.
- Fixing some missing adaptation after the account refactoring

closes odoo/odoo#35630

Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
2019-08-13 11:43:50 +00:00
Laurent Smet beaa30a3d1 [IMP/REF] accounting-pocalypse yeaaahh
This commit merges the following models
 * account.invoice and account.move
 * account.invoice.line and account.move.line
 * account.voucher and account.move
 * account.voucher.line and account.move.line

It was the opportunity for a big cleanup of the code, so it also restructures the whole account module, its different models/fields, the tests etc. for a better world and a better code readability.

==== Rationale ====
The rationale of this huge change is that we want journal entries / invoices to be easily edited, and changes reflected in the other model. It's a HUGE feature and very strategic for the fiduciary companies. For example, changing the account of a journal entry needs to be automatically reflected on the related invoice.

The same reasoning applies to sale/purchase vouchers.

==== Changes made in features =====
When creating an invoice, you are now creating a journal entry directly.
--> The object account.invoice no longer exists.
In the same fashion when creating an invoice line, you're now adding journal items directly in the journal entry representing the invoice. If this invoice line has some tax, it may create additional journal items as well.
--> The models account.invoice.line & account.invoice.tax no longer exist

Identically, when creating a sale/purchase receipt with its lines, you are now creating a journal entry directly and there's no more usability difference between encoding a receipt or an invoice.
--> The object account.voucher no longer exists.
--> The object account.voucher.line no longer exists.
--> The whole account_voucher module no longer exists.

Positive side-effects coming from these changes are
* draft invoices/bills/sale or purchase receipts now create a draft accounting entry. Validate these objects now simply post its journal entry. That means that draft invoices/bills/sale or purchase receipt can straightforwardly be included in reporting or budgets.
* opening a journal entry in form view will now always open the correct view: if it's a sale/purchase journal entry we will have a customer invoice/vendor bill view or a sale/purchase receipt view, whatever the menu we're coming from.
* code & business logic simplification. It is also condensed in a single place instead of being partially duplicated on invoices, vouchers and journal entries.

There should be no feature loss, except the one allowing to group multiple journal items together based on the same product during the invoice validation.

==== Changes made in models =====
* account.invoice: model removed. Instead, now use account.move with following mapping

field (account.invoice) 		field (account.move)
-----------------------			--------------------
name 					invoice_payment_ref
number 					name
reference 				ref
comment 				narration
user_id 				invoice_user_id
amount_					total_company_signed amount_total_signed
residual 				amount_residual
state 					state + invoice_payment_state 		/!\ selection changed
date_invoice 				invoice_date
date_due 				invoice_date_due
sent 					invoice_sent
origin 					invoice_origin
payment_term_id 			invoice_payment_term_id
partner_bank_id 			invoice_partner_bank_id
incoterm_id 				invoice_incoterm_id
vendor_bill_id 				invoice_vendor_bill_id
source_email 				invoice_source_email
vendor_display_name 			invoice_vendor_display_name
invoice_icon 				invoice_vendor_icon
cash_rounding_id 			invoice_cash_rounding_id
sequence_number_next 			invoice_sequence_number_next
sequence_number_next_prefix 		invoice_sequence_number_next_prefix

'invoices' subset of account.move can be accessed by using the selection field 'type' or one of the many helpers like is_invoice()

* account.move: now has a valid state 'cancel' that has to be excluded from all business logic
* account.move: field 'amount' renamed into 'amount_total'
* account.move: field 'reverse_entry_id' renamed into 'reversed_entry_id'
* account.move.line: now has a field 'display_type' that has to be excluded from all business logic, in order to support invoice layouting
* account.invoice.line: model removed. Instead, now use account.move.line with following mapping

field (account.invoice.line) 		field (account.move.line)
----------------------------		-------------------------
invoice_id 				move_id
uom_id 					product_uom_id
invoice_line_tax_ids 			tax_ids
account_analytic_id 			analytic_account_id

'invoice lines' subset of all account.move.line from a journal entry can be accessed by using the boolean field 'exclude_from_invoice_tab'

* account.invoice.tax: model removed. Instead, now use account.move.line with following mapping

field (account.invoice.tax) 		field (account.move.line)
---------------------------		-------------------------
invoice_id 				move_id
account_analytic_id 			analytic_account_id
amount 					price_unit
base 					tax_base_amount

'tax lines' subset of all account.move.line from a journal entry can be accessed by using the relational field 'tax_line_id'

* account.invoice.confirm: model removed. Instead, now use the 'post()' function of account.move
* account.invoice.refund: model removed. Instead, now use account.move.reversal to reverse the entries with the same options as we had for invoices
* account.voucher: model removed. Instead, now use account.move of type in ['out_receipt', 'in_receipt]
* account.voucher.line: model removed. Instead, now use account.move.line

==== Changes made in functions ====
* on account.move, method _run_post_draft_to_post() renamed into _autopost_draft_entries()
* on account.move, method action_account_invoice_payment() renamed into action_invoice_register_payment()
* on account.move, method action_invoice_reconcile_to_check() renamed into action_open_matching_suspense_moves()
* on account.move, method _get_domain_edition_mode_available() renamed into _get_domain_matching_supsense_moves()
* on account.move, method _get_intrastat_country_id() renamed into _get_invoice_intrastat_country_id()
* on account.move.line, method _get_domain_for_edition_mode() renamed into _get_suspense_moves_domain()
* in account.bank.statement, contextual key 'edition_mode' renamed into 'suspense_moves_mode'

Was task 1917430
2019-06-28 11:52:55 +00:00
Christophe Simonis b4e1be8ab0 [MERGE] forward port branch saas-11.3 up to b09f624f20 2018-11-22 20:06:48 +01:00
len-odoo 0081321136 [FIX] website_sale_digital: display download links on free digital orders
Create a coupon/promotion that gives a 100% discount on some digital product.
If the total of the order is 0, then the client won't have the possibility
to download the product(s), since the download links appear on invoiced lines;
and no invoice has been created.

We display the download link on the products if the order total is 0,
as the other cases are already covered by the existing code.

opw 1905682

closes odoo/odoo#28799
2018-11-19 13:46:02 +00:00
Nicolas Martinelli 384b56cb55 [FIX] website_sale_digital: no link to download
In the portal, there is no link to the downloadable content.

This is because the content of the `super` call has been changed in
4c31a758cf. The key is now `sale_order`.

opw-1895878

closes odoo/odoo#28132
2018-10-25 07:40:33 +00:00
Christophe Simonis 7499b47ffa [MERGE] forward port branch saas-11.4 up to edd586002e 2018-08-10 13:37:21 +02:00
Mitali Patel 84f528bcff [IMP] Portal - Share link : Easily share the url of a document
Purpose
=======
- Quickly share the url to someone else (a client, a colleague,...)
- Ensure that the recipient can access at least
  the portal view of the shared record.
- Typically used when a client cannot retrieve the mail to access his order.
  The share link can be used in this case.

Specifications
==============
For any object inheriting form portal.mixin:
    - Add a button SHARE (not visible in edit mode)
    - When clicking on this button, a popup opens with :
        - A warning message for tasks and projects only (see below)
        - the link (like in gmail) that can be copied
        - Recipients
        - mail composer (with preselected template) ==> see below
        - button [Send Link] [Copy Link] Discard
        - After sharing document, put internal note like
          "Document shared to xyz,...." with template message
    - Anyone with the link, even anonymous user (not logged in) can have access
      to the document with the access token provided in the url.

Impacted models:
    - account.invoice (Community)
    - project.project (Community)
    - project.task (Community)
    - purchase.order (Community)
    - sale.order (Community)
    - helpdesk.ticket (Enterprise)

Warning messages and access rules:
    Allowed :
        - SO canceled or draft will be accessible with the link
          with access_token
        - If the customer account is B2B (signup not enabled), the recipient
          will anyway see the document as the user specifically wants the
          recipient to see the document.
    Restrictions :
        - For Project and Task, if the privacy is not public, then, there is a
          contradiction between the access_token mechanism
          and the privacy of the document.
        - A warning message will be displayed in the share wizard to inform the
          user if the document cannot be visible by the recipients and to
          ask him to set the privacy to 'Visible by following customer'.
          The send button will, in that case, be hidden.
        - To avoid to block the share for a new project, default privacy value
          is now set to 'Visible by followong customer'

Technical implementation
========================
- Move the access_token mechanism (field + methods + mail controller)
  to the portal.mixin to be able to use it in a generic way for each object
  inheriting the portal.mixin
- Generalise a part of the _*model*_get_page_view_values method
  into a single one in portal
- Generalize the _*model*_check_access into the portal controller of the
  portal module
- Remove the init_column + default value for the access_token
  > old records have an access_token,
  > new one won't but it will be generated on demand via the get_access_token
  Done for performance reasons
- Add share button into action menu separately. + kanban view context menu
  (except for task and project where button not in action menu but 'simple'
  button for task and project because other modules already provide action
  to send documents by email, which is not the case for project and task.)
- Add a sign_token used to authentify the recipient in the portal view chatter,
  if any. The message will be posted as if the user was logged in.
- Set the _get_share_url as private for security reason
- Add a redirect parameter to _get_share_url to get
    If false : The direct portal view url
    If True : The redirect url (mail/view/?)
- Cleaning up unnecessary code

- Bug fix :
    - Before, if user was not logged and record had partner_id,
      if partner id was null, post message was done as admin.
      Now, the post message is done as public user.
    - If the user had an uid but had no access_token, he could be able
      to gain the access token of the record.
      check_access_rights was missing in the get_access_action.

Task ID : 30985
Closes #25629
2018-08-03 15:20:42 +02:00
Luis González b623695ee7 [FIX] website_sale_digital: portal files as digital products
Currently, when a digital product is purchased, the list of attachments
is incorrectly computed. Product template's portal files are retrieved
correctly, but all product variant's attachments are taken into account,
not only its portal files.

This commit causes the portal attachments to be computed correctly,
taking into account only portal files from both the product template and
product variant.

Closes #25609
2018-08-03 10:41:02 +02:00
Joren Van Onder 2362ea09f8 [FIX] website_sale_digital: make /my/orders accessible with just token
This route should be public because the public user should have access
if the correct access token is passed. super() will ensure that.
2018-06-28 18:47:51 +02:00
Lucas Perais (lpe) ea2650aa79 [FIX] website_sale_digital: fix download attachement Py3
Before this commit, an Error 500 was thrown to the user upon downloading an attachement
It was due to two things:
- wrong return on a function
- the filename that http.send_file takes shouldn't be a string, but bytes in Py3
2017-09-29 10:47:37 +02:00
Thibault Delavallée 2ec4dbeb49 [MOV] sale: put all assets in same file and rename portal templates 2017-09-04 11:15:38 +02:00
Christophe Simonis 017ee5eab3 [MERGE] forward port branch saas-17 up to 877e709871 2017-08-24 13:17:53 +02:00
Christophe Simonis 30bd5ac0e9 [MERGE] forward port branch saas-16 up to aec6248bb3 2017-08-23 16:44:58 +02:00
Christophe Simonis 59f8b849fb [MERGE] forward port branch saas-15 up to d5f2a38b50 2017-08-23 11:23:08 +02:00
Xavier Morel 3824b5dcc1 [FIX] P3: fix base64 and StringIO uses
* StringIO removed from stdlib, replace with io
* try to correctly handle BytesIO/StringIO (one is for bytes the other
  is for text)
* fix base64: Python 3 removed bytes-encoding and bytes-bytes
  codecs (via #encode) so replace all calls to str.encode('base64'),
  also b64encode is a bytes->bytes conversion so attempt to properly
  handle that

issue #8530
2017-08-20 23:25:54 +02:00
Nicolas Martinelli 110bf158f6 [FIX] website_sale_digital: special character in filename
- Create a product with attachment, and name the attachment 'テスト'
- Purchase the product, make a payment, validate and pay the invoice
- Go to My Orders under My Account, open the order, and try to download
  the file 'テスト'.

An error 500 is raised due to a UnicodeEncodeError.

```
  File "/home/nim/src/odoo/addons/website_sale_digital/controllers/main.py", line 104, in download_attachment
    return http.send_file(data, filename=attachment['name'], as_attachment=True)
  File "/home/nim/src/odoo/odoo/http.py", line 1595, in send_file
    headers.add('Content-Disposition', 'attachment', filename=filename)
  File "/usr/lib/python2.7/dist-packages/werkzeug/datastructures.py", line 1093, in add
    _value = _options_header_vkw(_value, kw)
  File "/usr/lib/python2.7/dist-packages/werkzeug/datastructures.py", line 830, in _options_header_vkw
    for k, v in kw.items()))
  File "/usr/lib/python2.7/dist-packages/werkzeug/http.py", line 212, in dump_options_header
    segments.append('%s=%s' % (key, quote_header_value(value)))
  File "/usr/lib/python2.7/dist-packages/werkzeug/http.py", line 165, in quote_header_value
    value = str(value)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

```

opw-766568
2017-08-18 11:26:08 +02:00
Thibault Delavallée 9381334f6e [MOV] sale_*: move sale customer portal to sale
Customer portal is now a feature coming directly with sale module. As
it uses a simple website renderer customization and advanced website
features are not available and depends on having website module
installed.
2017-08-08 15:36:25 +02:00
Christophe Simonis bf51fe55a1 [MERGE] forward port branch saas-16 up to 0f2b2c4e2b 2017-07-07 14:30:30 +02:00
Christophe Simonis 780ae8a808 [MERGE] forward port branch saas-15 up to 10cb34bcac 2017-07-04 18:14:13 +02:00
Nicolas Lempereur 2bda46ce78 [FIX] website_sale_digital: check product tmpl sudo
For example the portal user has restricted access to product template,
this can lead to an issue that should not be in this instance that is
checking if the product template correspond to a product sold.

opw-748480
closes #17871
2017-06-28 09:36:09 +02:00
Xavier Morel 4957296f1d [FIX] P3: incorrect dependencies
website_sale_digital overrides a method defined on
website_portal_sale, but only depends on website_portal and extends
the base controller from website_portal. Depending on the (relative)
order in which the system decides to load website_sale_digital and
website_portal_sale we can end up with the former's template but the
latter's methods (without the proper context data). Which ends up
commonly crashing in P35.

Fix dependencies and controller inheritance.
2017-06-12 11:04:23 +02:00
xmo-odoo fffaf735f5 [FIX] P3: list -> iterable builtins (#16811)
In Python 3:

* various builtins and dict methods were changed to return
  view/iterable objects rather than lists
* and the separate Python 2 view/iterable builtins and methods were
  removed altogether

This is problematic when using these items as list (which the happens
repeatedly in Odoo), but more viciously when iterating *multiple times*
over them (which also happens, which I've messed up multiple times while
writing this, and which is a pain to debug even when you've just created
the issue).

Convert all code using these to semantics-matching cross-version
helper functions to get the LCD behaviour between P2 and P3, and
forbid the builtins via lint.

issue #8530
2017-05-10 09:39:55 +02:00
xmo-odoo b4429c2a91 [FIX] Various P3-related import changes
* LDAP import: python-ldap is not python3-compatible, pyldap is

  Warning: only supported from debian Stretch (current testing)?
  https://packages.debian.org/search?searchon=names&keywords=pyldap

* implicitly relative imports
* imports of moved or removed stdlib modules

issue #8530
2017-04-28 09:06:53 +02:00
Nicolas Martinelli 483324393e [FIX] website_sale_digital: free product
- Buy only a free product with digital download content
- It is not possible to access the download link

Since the product is free, there is no invoice created. Therefore, the
product is never considered as paid.

opw-705258
2017-02-06 11:01:16 +01:00
Nicolas Martinelli a01188e1a5 [FIX] website_sale_digital: no more 'digital' product
Following commit 1a1efe3fce, the module has some troubles to work
correctly. For example, it's impossible to get the download link in the
frontend of an attachment when the product was bought and paid.

Not really a big deal, but just in case the client wants to download
what he bought, we add back the link in the eCommerce.

A more complete fix will land later in master branch.

opw-705725
2017-02-02 14:57:39 +01:00
Jérome Maes 09b783794e [MIG] website_sale_*: migration to new api
Those module were almost already migrated, this commit simply modified the import and the xml tags.
2016-07-12 14:29:31 +02:00
Ravi Gadhia 4c2cda3fd8 [IMP] website_sale_digital: almost a new api migration
Ok it was already written in new api, so what is the purpose of this commit?
Just a nice spring code cleaning.

Closes #10941
2016-04-06 16:37:54 +02:00
Christophe Simonis 79976bd779 [MERGE] forward port of branch saas-10 up to 6e95659 2016-04-01 19:10:34 +02:00
Nicolas Martinelli fd8570770d [FIX] website_portal_sale, website_sale_(*): access to orders
When a user tries to access one of his orders, the order is shown empty.
This is due to the domain which is applied as an "access check" attempt
and might filter out the order.

The fix directly checks the access rights of the user regarding the
sales order, and return a '403' code if necessary.

opw-671107
2016-03-30 13:33:33 +02:00
Ravi Gadhia 788c1334e2 [IMP] website_sale: migration to new api 2016-03-17 17:26:52 +01:00
Thibault Delavallée 59f448a3ca [IMP] product and misc: type field cleaning
Now using a method for the selection. This method is overriden in
various addons to add specific selection entries instead of
completely hardcoding the values. Indeed this breaks inheritance.

Some views have been updated to try to make the various attributes
more inheritable-friendly.
2015-08-25 11:06:23 +02:00
Damien Bouvy c3c0408471 [ADD] website_portal
- manage your sale documents from the frontend in the 'My Account' page
- move 'My Orders' page from website_sale to website_portal to manage your orders and quotations
- update website_sale_digital and website_sale_stock controllers and view
2015-06-15 14:57:15 +02:00
David Monjoie 8a1b8e880c [ADD] website_sale_digital: allows the user to set a product as digital product and use the attachments to sell files. The download link is added on the My Orders page when the payment is confirmed 2015-01-16 15:47:18 +01:00