[ADD] website_sale_digital
This commit is contained in:
parent
70dc7c819b
commit
f3333f9c57
|
@ -0,0 +1 @@
|
||||||
|
import controllers # NOQA
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
'name': 'Website Sale Digital - Sell digital products',
|
||||||
|
'version': '0.0.1',
|
||||||
|
'description': """
|
||||||
|
Sell data product through attachments
|
||||||
|
""",
|
||||||
|
'author': 'OpenERP S.A.',
|
||||||
|
'depends': [
|
||||||
|
'website_sale',
|
||||||
|
],
|
||||||
|
'website': 'http://apps.openerp.com',
|
||||||
|
'active': False,
|
||||||
|
'installable': True,
|
||||||
|
'data': [
|
||||||
|
'views/website_sale_digital.xml',
|
||||||
|
],
|
||||||
|
'demo': [
|
||||||
|
],
|
||||||
|
'qweb': [
|
||||||
|
],
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
import main
|
|
@ -0,0 +1,94 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import base64
|
||||||
|
from openerp import SUPERUSER_ID as SU
|
||||||
|
from openerp.addons.web import http
|
||||||
|
from openerp.addons.web.http import request
|
||||||
|
from openerp.addons.website_sale.controllers.main import website_sale
|
||||||
|
from itertools import groupby
|
||||||
|
from werkzeug.exceptions import NotFound
|
||||||
|
|
||||||
|
|
||||||
|
class website_sale_digital(website_sale):
|
||||||
|
|
||||||
|
@http.route([
|
||||||
|
'/shop/confirmation',
|
||||||
|
], type='http', auth="public", website=True)
|
||||||
|
def display_attachments(self, **post):
|
||||||
|
r = super(website_sale_digital, self).payment_confirmation(**post)
|
||||||
|
return r
|
||||||
|
|
||||||
|
@http.route([
|
||||||
|
'/shop/attachment',
|
||||||
|
], auth='public')
|
||||||
|
def download_attachment(self, attachment_id):
|
||||||
|
res = request.env(user=SU)['ir.attachment'].search_read([('id', '=', int(attachment_id))], ["name", "datas", "file_type"])
|
||||||
|
if res:
|
||||||
|
res = res[0]
|
||||||
|
else:
|
||||||
|
raise NotFound()
|
||||||
|
data = base64.standard_b64decode(res["datas"])
|
||||||
|
headers = [
|
||||||
|
('Content-Type', res['file_type']),
|
||||||
|
('Content-Length', len(data)),
|
||||||
|
('Content-Disposition', 'attachment; filename="' + res['name'] + '"')
|
||||||
|
]
|
||||||
|
return request.make_response(data, headers)
|
||||||
|
|
||||||
|
@http.route([
|
||||||
|
'/website_sale_digital/downloads',
|
||||||
|
], type='http', auth='public', website=True)
|
||||||
|
def get_downloads(self):
|
||||||
|
user = request.env['res.users'].browse(request.uid)
|
||||||
|
partner = user.partner_id
|
||||||
|
|
||||||
|
# purchased_products = request.env['sale.order.line'].read_group(
|
||||||
|
# domain = ['&', ('order_id.partner_id', '=', partner.id), ('state', '=', 'confirmed')],#, ('product_id.data','=' true)])
|
||||||
|
# fields = ['order_id', product_id'],
|
||||||
|
# groupby = 'product_id',
|
||||||
|
# #orderby = 'order_id',
|
||||||
|
# )
|
||||||
|
|
||||||
|
purchased_products = request.env['sale.order.line'].search_read(
|
||||||
|
domain = ['&', ('order_id.partner_id', '=', partner.id), ('state', '=', 'confirmed')],#, ('product_id.data','=' true)])
|
||||||
|
fields = ['product_id'],
|
||||||
|
)
|
||||||
|
|
||||||
|
products_ids = []
|
||||||
|
names = {}
|
||||||
|
attachments = {}
|
||||||
|
A = request.env['ir.attachment']
|
||||||
|
P = request.env['product.product']
|
||||||
|
for product in purchased_products:
|
||||||
|
# Ignore duplicate products
|
||||||
|
p_id = product['product_id'][0]
|
||||||
|
if p_id in products_ids:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Search for product attachments
|
||||||
|
p_name = product['product_id'][1]
|
||||||
|
p_obj = P.browse(p_id)
|
||||||
|
template = p_obj.product_tmpl_id
|
||||||
|
att = A.search_read(
|
||||||
|
domain = ['|', '&', ('res_model', '=', 'product.product'), ('res_id', '=', p_id), '&', ('res_model', '=', 'product.template'), ('res_id', '=', template.id)],
|
||||||
|
fields = ['name'],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ignore products with no attachments
|
||||||
|
if not att:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Store values for QWeb
|
||||||
|
products_ids.append(p_id)
|
||||||
|
attributes = p_obj.attribute_value_ids
|
||||||
|
if attributes:
|
||||||
|
names[p_id] = template.name + ' (' + ', '.join([a.name for a in attributes]) + ')'
|
||||||
|
else:
|
||||||
|
names[p_id] = template.name
|
||||||
|
attachments[p_id] = att
|
||||||
|
|
||||||
|
return request.website.render('website_sale_digital.downloads', {
|
||||||
|
'products': products_ids,
|
||||||
|
'names': names,
|
||||||
|
'attachments': attachments
|
||||||
|
})
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<template id="product_attachments" name="Product Attachments" inherit_id="website_sale.confirmation">
|
||||||
|
<xpath expr="//div[@class='oe_website_sale_tx_status']" position="after">
|
||||||
|
<!-- TODO: if not confirmed: "available soon" -->
|
||||||
|
<div> Your product will soon be available for download.</div>
|
||||||
|
<div style="margin-left: 50px;">
|
||||||
|
<a href="/website_sale_digital/downloads">
|
||||||
|
<button class="btn btn-primary btn-sm">
|
||||||
|
<i class="fa fa-arrow-right"></i> Go to the Downloads page
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="downloads" name="Downloads">
|
||||||
|
<title>Odoo - Downloads</title>
|
||||||
|
<t t-call="website.layout">
|
||||||
|
<div id="wrap">
|
||||||
|
<div class="oe_structure">
|
||||||
|
<h1 class="text-center">
|
||||||
|
Odoo Downloads
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-center text-muted">
|
||||||
|
Download your purchased products
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="container mt32 mb32">
|
||||||
|
<t t-if="products">
|
||||||
|
<t t-call="website_sale_digital.products_attachments"/>
|
||||||
|
</t>
|
||||||
|
<t t-if="not products">
|
||||||
|
<h4 class="text-muted text-center mt64 mb64">
|
||||||
|
You have no digital purchase to download, <br/>or your payment has yet to be confirmed.
|
||||||
|
</h4>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="products_attachments" name="Display Products Attachments">
|
||||||
|
<t t-foreach="products" t-as="p">
|
||||||
|
<div class="media row">
|
||||||
|
<div class="col-md-1 mt8" style="text-align:center">
|
||||||
|
<a href="#"> <!-- TODO: Link to product -->
|
||||||
|
<img t-att-src="'/website/image?model=product.product&field=image&id='+str(p)" style="max-width: 64px; max-height: 64px;"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="media-body col-md-10">
|
||||||
|
<!-- <h4 class="media-heading">Media heading</h4> -->
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><t t-esc="names[p]"/></h3> <!-- TODO: Link to product -->
|
||||||
|
</div>
|
||||||
|
<t t-foreach="attachments[p]" t-as="a">
|
||||||
|
<div class="panel-body">
|
||||||
|
<t t-esc="a['name']"/>
|
||||||
|
<span class="pull-right">
|
||||||
|
<!-- <small><t class="text-muted" t-esc="a['create_date'].split(' ')[0]"/></small> -->
|
||||||
|
<a t-att-href="'/shop/attachment?attachment_id=%i' % a['id']">
|
||||||
|
<button class="btn btn-primary btn-xs" type="button" >
|
||||||
|
Download
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
|
@ -233,6 +233,10 @@ class Cursor(object):
|
||||||
params = params or None
|
params = params or None
|
||||||
res = self._obj.execute(query, params)
|
res = self._obj.execute(query, params)
|
||||||
except psycopg2.ProgrammingError, pe:
|
except psycopg2.ProgrammingError, pe:
|
||||||
|
print self
|
||||||
|
print self._obj
|
||||||
|
print query
|
||||||
|
print params
|
||||||
if self._default_log_exceptions if log_exceptions is None else log_exceptions:
|
if self._default_log_exceptions if log_exceptions is None else log_exceptions:
|
||||||
_logger.error("Programming error: %s, in query %s", pe, query)
|
_logger.error("Programming error: %s, in query %s", pe, query)
|
||||||
raise
|
raise
|
||||||
|
|
Loading…
Reference in New Issue