Files
odoo_source/addons/website_sale_digital/controllers/main.py
T
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

104 lines
4.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import io
import os
import mimetypes
from odoo import http
from odoo.http import request
from odoo.addons.sale.controllers.portal import CustomerPortal
class WebsiteSaleDigital(CustomerPortal):
orders_page = '/my/orders'
@http.route([
'/my/orders/<int:order_id>',
], type='http', auth='public', website=True)
def portal_order_page(self, order_id=None, **post):
response = super(WebsiteSaleDigital, self).portal_order_page(order_id=order_id, **post)
if not 'sale_order' in response.qcontext:
return response
order = response.qcontext['sale_order']
invoiced_lines = request.env['account.move.line'].sudo().search([('move_id', 'in', order.invoice_ids.ids), ('move_id.payment_state', 'in', ['paid', 'in_payment'])])
products = invoiced_lines.mapped('product_id') | order.order_line.filtered(lambda r: not r.price_subtotal).mapped('product_id')
if not order.amount_total:
# in that case, we should add all download links to the products
# since there is nothing to pay, so we shouldn't wait for an invoice
products = order.order_line.mapped('product_id')
Attachment = request.env['ir.attachment'].sudo()
purchased_products_attachments = {}
for product in products.filtered(lambda p: p.attachment_count):
# Search for product attachments
product_id = product.id
template = product.product_tmpl_id
att = Attachment.sudo().search_read(
domain=['|', '&', ('res_model', '=', product._name), ('res_id', '=', product_id), '&', ('res_model', '=', template._name), ('res_id', '=', template.id), ('product_downloadable', '=', True)],
fields=['name', 'write_date'],
order='write_date desc',
)
# Ignore products with no attachments
if not att:
continue
purchased_products_attachments[product_id] = att
response.qcontext.update({
'digital_attachments': purchased_products_attachments,
})
return response
@http.route([
'/my/download',
], type='http', auth='public')
def download_attachment(self, attachment_id):
# Check if this is a valid attachment id
attachment = request.env['ir.attachment'].sudo().search_read(
[('id', '=', int(attachment_id))],
["name", "datas", "mimetype", "res_model", "res_id", "type", "url"]
)
if attachment:
attachment = attachment[0]
else:
return request.redirect(self.orders_page)
# Check if the user has bought the associated product
res_model = attachment['res_model']
res_id = attachment['res_id']
purchased_products = request.env['account.move.line'].get_digital_purchases()
if res_model == 'product.product':
if res_id not in purchased_products:
return request.redirect(self.orders_page)
# Also check for attachments in the product templates
elif res_model == 'product.template':
template_ids = request.env['product.product'].sudo().browse(purchased_products).mapped('product_tmpl_id').ids
if res_id not in template_ids:
return request.redirect(self.orders_page)
else:
return request.redirect(self.orders_page)
# The client has bought the product, otherwise it would have been blocked by now
if attachment["type"] == "url":
if attachment["url"]:
return request.redirect(attachment["url"])
else:
return request.not_found()
elif attachment["datas"]:
data = io.BytesIO(base64.standard_b64decode(attachment["datas"]))
# we follow what is done in ir_http's binary_content for the extension management
extension = os.path.splitext(attachment["name"] or '')[1]
extension = extension if extension else mimetypes.guess_extension(attachment["mimetype"] or '')
filename = attachment['name']
filename = filename if os.path.splitext(filename)[1] else filename + extension
return http.send_file(data, filename=filename, as_attachment=True)
else:
return request.not_found()