[IMP] shop: added openchatter on product shop
- product.template now inherits from mail.thread - added opencahtter on product.template form view - added discussion thread + attachments in product website view - added file_type field on ir_attachment, that replaces the javascript thing from mail.js - added a controller to comment a product.template bzr revid: tde@openerp.com-20140106135727-uf0zaxav28pdx4sv
This commit is contained in:
parent
49c0b7a820
commit
0b2d085c1b
|
@ -19,6 +19,7 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
import ir_attachment
|
||||||
import mail_message_subtype
|
import mail_message_subtype
|
||||||
import mail_alias
|
import mail_alias
|
||||||
import mail_followers
|
import mail_followers
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2014-TODAY OpenERP SA (http://www.openerp.com)
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
|
class IrAttachment(osv.Model):
|
||||||
|
""" Update partner to add a field about notification preferences """
|
||||||
|
_name = "ir.attachment"
|
||||||
|
_inherit = 'ir.attachment'
|
||||||
|
|
||||||
|
_fileext_to_type = {
|
||||||
|
'7z': 'archive',
|
||||||
|
'aac': 'audio',
|
||||||
|
'ace': 'archive',
|
||||||
|
'ai': 'vector',
|
||||||
|
'aiff': 'audio',
|
||||||
|
'apk': 'archive',
|
||||||
|
'app': 'binary',
|
||||||
|
'as': 'script',
|
||||||
|
'asf': 'video',
|
||||||
|
'ass': 'text',
|
||||||
|
'avi': 'video',
|
||||||
|
'bat': 'script',
|
||||||
|
'bin': 'binary',
|
||||||
|
'bmp': 'image',
|
||||||
|
'bzip2': 'archive',
|
||||||
|
'c': 'script',
|
||||||
|
'cab': 'archive',
|
||||||
|
'cc': 'script',
|
||||||
|
'ccd': 'disk',
|
||||||
|
'cdi': 'disk',
|
||||||
|
'cdr': 'vector',
|
||||||
|
'cer': 'certificate',
|
||||||
|
'cgm': 'vector',
|
||||||
|
'cmd': 'script',
|
||||||
|
'coffee': 'script',
|
||||||
|
'com': 'binary',
|
||||||
|
'cpp': 'script',
|
||||||
|
'crl': 'certificate',
|
||||||
|
'crt': 'certificate',
|
||||||
|
'cs': 'script',
|
||||||
|
'csr': 'certificate',
|
||||||
|
'css': 'html',
|
||||||
|
'csv': 'spreadsheet',
|
||||||
|
'cue': 'disk',
|
||||||
|
'd': 'script',
|
||||||
|
'dds': 'image',
|
||||||
|
'deb': 'archive',
|
||||||
|
'der': 'certificate',
|
||||||
|
'djvu': 'image',
|
||||||
|
'dmg': 'archive',
|
||||||
|
'dng': 'image',
|
||||||
|
'doc': 'document',
|
||||||
|
'docx': 'document',
|
||||||
|
'dvi': 'print',
|
||||||
|
'eot': 'font',
|
||||||
|
'eps': 'vector',
|
||||||
|
'exe': 'binary',
|
||||||
|
'exr': 'image',
|
||||||
|
'flac': 'audio',
|
||||||
|
'flv': 'video',
|
||||||
|
'gif': 'webimage',
|
||||||
|
'gz': 'archive',
|
||||||
|
'gzip': 'archive',
|
||||||
|
'h': 'script',
|
||||||
|
'htm': 'html',
|
||||||
|
'html': 'html',
|
||||||
|
'ico': 'image',
|
||||||
|
'icon': 'image',
|
||||||
|
'img': 'disk',
|
||||||
|
'iso': 'disk',
|
||||||
|
'jar': 'archive',
|
||||||
|
'java': 'script',
|
||||||
|
'jp2': 'image',
|
||||||
|
'jpe': 'webimage',
|
||||||
|
'jpeg': 'webimage',
|
||||||
|
'jpg': 'webimage',
|
||||||
|
'jpx': 'image',
|
||||||
|
'js': 'script',
|
||||||
|
'key': 'presentation',
|
||||||
|
'keynote': 'presentation',
|
||||||
|
'lisp': 'script',
|
||||||
|
'lz': 'archive',
|
||||||
|
'lzip': 'archive',
|
||||||
|
'm': 'script',
|
||||||
|
'm4a': 'audio',
|
||||||
|
'm4v': 'video',
|
||||||
|
'mds': 'disk',
|
||||||
|
'mdx': 'disk',
|
||||||
|
'mid': 'audio',
|
||||||
|
'midi': 'audio',
|
||||||
|
'mkv': 'video',
|
||||||
|
'mng': 'image',
|
||||||
|
'mp2': 'audio',
|
||||||
|
'mp3': 'audio',
|
||||||
|
'mp4': 'video',
|
||||||
|
'mpe': 'video',
|
||||||
|
'mpeg': 'video',
|
||||||
|
'mpg': 'video',
|
||||||
|
'nrg': 'disk',
|
||||||
|
'numbers': 'spreadsheet',
|
||||||
|
'odg': 'vector',
|
||||||
|
'odm': 'document',
|
||||||
|
'odp': 'presentation',
|
||||||
|
'ods': 'spreadsheet',
|
||||||
|
'odt': 'document',
|
||||||
|
'ogg': 'audio',
|
||||||
|
'ogm': 'video',
|
||||||
|
'otf': 'font',
|
||||||
|
'p12': 'certificate',
|
||||||
|
'pak': 'archive',
|
||||||
|
'pbm': 'image',
|
||||||
|
'pdf': 'print',
|
||||||
|
'pem': 'certificate',
|
||||||
|
'pfx': 'certificate',
|
||||||
|
'pgf': 'image',
|
||||||
|
'pgm': 'image',
|
||||||
|
'pk3': 'archive',
|
||||||
|
'pk4': 'archive',
|
||||||
|
'pl': 'script',
|
||||||
|
'png': 'webimage',
|
||||||
|
'pnm': 'image',
|
||||||
|
'ppm': 'image',
|
||||||
|
'pps': 'presentation',
|
||||||
|
'ppt': 'presentation',
|
||||||
|
'ps': 'print',
|
||||||
|
'psd': 'image',
|
||||||
|
'psp': 'image',
|
||||||
|
'py': 'script',
|
||||||
|
'r': 'script',
|
||||||
|
'ra': 'audio',
|
||||||
|
'rar': 'archive',
|
||||||
|
'rb': 'script',
|
||||||
|
'rpm': 'archive',
|
||||||
|
'rtf': 'text',
|
||||||
|
'sh': 'script',
|
||||||
|
'sub': 'disk',
|
||||||
|
'svg': 'vector',
|
||||||
|
'sxc': 'spreadsheet',
|
||||||
|
'sxd': 'vector',
|
||||||
|
'tar': 'archive',
|
||||||
|
'tga': 'image',
|
||||||
|
'tif': 'image',
|
||||||
|
'tiff': 'image',
|
||||||
|
'ttf': 'font',
|
||||||
|
'txt': 'text',
|
||||||
|
'vbs': 'script',
|
||||||
|
'vc': 'spreadsheet',
|
||||||
|
'vml': 'vector',
|
||||||
|
'wav': 'audio',
|
||||||
|
'webp': 'image',
|
||||||
|
'wma': 'audio',
|
||||||
|
'wmv': 'video',
|
||||||
|
'woff': 'font',
|
||||||
|
'xar': 'vector',
|
||||||
|
'xbm': 'image',
|
||||||
|
'xcf': 'image',
|
||||||
|
'xhtml': 'html',
|
||||||
|
'xls': 'spreadsheet',
|
||||||
|
'xlsx': 'spreadsheet',
|
||||||
|
'xml': 'html',
|
||||||
|
'zip': 'archive'
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_attachment_type(self, cr, uid, ids, name, args, context=None):
|
||||||
|
result = {}
|
||||||
|
for attachment in self.browse(cr, uid, ids, context=context):
|
||||||
|
fileext = os.path.splitext(attachment.datas_fname)[1].lower()
|
||||||
|
if not fileext or not fileext[1:] in self._fileext_to_type:
|
||||||
|
return 'unknown'
|
||||||
|
result[attachment.id] = self._fileext_to_type[fileext[1:]]
|
||||||
|
return result
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'file_type': fields.function(get_attachment_type, type='char', string='File Type'),
|
||||||
|
}
|
|
@ -351,8 +351,13 @@ class mail_message(osv.Model):
|
||||||
partner_tree = dict((partner[0], partner) for partner in partners)
|
partner_tree = dict((partner[0], partner) for partner in partners)
|
||||||
|
|
||||||
# 2. Attachments as SUPERUSER, because could receive msg and attachments for doc uid cannot see
|
# 2. Attachments as SUPERUSER, because could receive msg and attachments for doc uid cannot see
|
||||||
attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname', 'name'], context=context)
|
attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname', 'name', 'file_type'], context=context)
|
||||||
attachments_tree = dict((attachment['id'], {'id': attachment['id'], 'filename': attachment['datas_fname'], 'name': attachment['name']}) for attachment in attachments)
|
attachments_tree = dict((attachment['id'], {
|
||||||
|
'id': attachment['id'],
|
||||||
|
'filename': attachment['datas_fname'],
|
||||||
|
'name': attachment['name'],
|
||||||
|
'file_type': attachment['file_type'],
|
||||||
|
}) for attachment in attachments)
|
||||||
|
|
||||||
# 3. Update message dictionaries
|
# 3. Update message dictionaries
|
||||||
for message_dict in messages:
|
for message_dict in messages:
|
||||||
|
|
|
@ -114,57 +114,6 @@ openerp.mail = function (session) {
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
},
|
},
|
||||||
|
|
||||||
// returns the file type of a file based on its extension
|
|
||||||
// As it only looks at the extension it is quite approximative.
|
|
||||||
filetype: function(url){
|
|
||||||
var url = url && url.filename || url;
|
|
||||||
var tokens = typeof url == 'string' ? url.split('.') : [];
|
|
||||||
if(tokens.length <= 1){
|
|
||||||
return 'unknown';
|
|
||||||
}
|
|
||||||
var extension = tokens[tokens.length -1];
|
|
||||||
if(extension.length === 0){
|
|
||||||
return 'unknown';
|
|
||||||
}else{
|
|
||||||
extension = extension.toLowerCase();
|
|
||||||
}
|
|
||||||
var filetypes = {
|
|
||||||
'webimage': ['png','jpg','jpeg','jpe','gif'], // those have browser preview
|
|
||||||
'image': ['tif','tiff','tga',
|
|
||||||
'bmp','xcf','psd','ppm','pbm','pgm','pnm','mng',
|
|
||||||
'xbm','ico','icon','exr','webp','psp','pgf','xcf',
|
|
||||||
'jp2','jpx','dng','djvu','dds'],
|
|
||||||
'vector': ['ai','svg','eps','vml','cdr','xar','cgm','odg','sxd'],
|
|
||||||
'print': ['dvi','pdf','ps'],
|
|
||||||
'document': ['doc','docx','odm','odt'],
|
|
||||||
'presentation': ['key','keynote','odp','pps','ppt'],
|
|
||||||
'font': ['otf','ttf','woff','eot'],
|
|
||||||
'archive': ['zip','7z','ace','apk','bzip2','cab','deb','dmg','gzip','jar',
|
|
||||||
'rar','tar','gz','pak','pk3','pk4','lzip','lz','rpm'],
|
|
||||||
'certificate': ['cer','key','pfx','p12','pem','crl','der','crt','csr'],
|
|
||||||
'audio': ['aiff','wav','mp3','ogg','flac','wma','mp2','aac',
|
|
||||||
'm4a','ra','mid','midi'],
|
|
||||||
'video': ['asf','avi','flv','mkv','m4v','mpeg','mpg','mpe','wmv','mp4','ogm'],
|
|
||||||
'text': ['txt','rtf','ass'],
|
|
||||||
'html': ['html','xhtml','xml','htm','css'],
|
|
||||||
'disk': ['iso','nrg','img','ccd','sub','cdi','cue','mds','mdx'],
|
|
||||||
'script': ['py','js','c','cc','cpp','cs','h','java','bat','sh',
|
|
||||||
'd','rb','pl','as','cmd','coffee','m','r','vbs','lisp'],
|
|
||||||
'spreadsheet': ['123','csv','ods','numbers','sxc','xls','vc','xlsx'],
|
|
||||||
'binary': ['exe','com','bin','app'],
|
|
||||||
};
|
|
||||||
for(filetype in filetypes){
|
|
||||||
var ext_list = filetypes[filetype];
|
|
||||||
for(var i = 0, len = ext_list.length; i < len; i++){
|
|
||||||
if(extension === ext_list[i]){
|
|
||||||
return filetype;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 'unknown';
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,7 +253,6 @@ openerp.mail = function (session) {
|
||||||
var attach = this.attachment_ids[l];
|
var attach = this.attachment_ids[l];
|
||||||
if (!attach.formating) {
|
if (!attach.formating) {
|
||||||
attach.url = mail.ChatterUtils.get_attachment_url(this.session, this.id, attach.id);
|
attach.url = mail.ChatterUtils.get_attachment_url(this.session, this.id, attach.id);
|
||||||
attach.filetype = mail.ChatterUtils.filetype(attach.filename || attach.name);
|
|
||||||
attach.name = mail.ChatterUtils.breakword(attach.name || attach.filename);
|
attach.name = mail.ChatterUtils.breakword(attach.name || attach.filename);
|
||||||
attach.formating = true;
|
attach.formating = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,10 +88,10 @@
|
||||||
-->
|
-->
|
||||||
<t t-name="mail.thread.message.attachments">
|
<t t-name="mail.thread.message.attachments">
|
||||||
<t t-foreach='widget.attachment_ids' t-as='attachment'>
|
<t t-foreach='widget.attachment_ids' t-as='attachment'>
|
||||||
<t t-if="attachment.filetype !== 'webimage'">
|
<t t-if="attachment.file_type !== 'webimage'">
|
||||||
<div t-attf-class="oe_attachment #{attachment.upload ? 'oe_uploading' : ''}">
|
<div t-attf-class="oe_attachment #{attachment.upload ? 'oe_uploading' : ''}">
|
||||||
<a t-att-href='attachment.url' target="_blank">
|
<a t-att-href='attachment.url' target="_blank">
|
||||||
<img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.filetype + '.png'"></img>
|
<img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.file_type + '.png'"></img>
|
||||||
<div class='oe_name'><t t-raw='attachment.name' /></div>
|
<div class='oe_name'><t t-raw='attachment.name' /></div>
|
||||||
</a>
|
</a>
|
||||||
<div class='oe_delete oe_e' title="Delete this attachment" t-att-data-id="attachment.id">[</div>
|
<div class='oe_delete oe_e' title="Delete this attachment" t-att-data-id="attachment.id">[</div>
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-if="attachment.filetype === 'webimage'">
|
<t t-if="attachment.file_type === 'webimage'">
|
||||||
<div t-attf-class="oe_attachment oe_preview #{attachment.upload ? 'oe_uploading' : ''}">
|
<div t-attf-class="oe_attachment oe_preview #{attachment.upload ? 'oe_uploading' : ''}">
|
||||||
<a t-att-href='attachment.url' target="_blank">
|
<a t-att-href='attachment.url' target="_blank">
|
||||||
<img t-att-src="widget.attachments_resize_image(attachment.id, [100,80])"></img>
|
<img t-att-src="widget.attachments_resize_image(attachment.id, [100,80])"></img>
|
||||||
|
|
|
@ -361,6 +361,7 @@ class product_public_category(osv.osv):
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
class product_template(osv.osv):
|
class product_template(osv.osv):
|
||||||
_name = "product.template"
|
_name = "product.template"
|
||||||
|
_inherit = ['mail.thread']
|
||||||
_description = "Product Template"
|
_description = "Product Template"
|
||||||
|
|
||||||
def _get_image(self, cr, uid, ids, name, args, context=None):
|
def _get_image(self, cr, uid, ids, name, args, context=None):
|
||||||
|
@ -650,7 +651,6 @@ class product_product(osv.osv):
|
||||||
_table = "product_product"
|
_table = "product_product"
|
||||||
_inherits = {'product.template': 'product_tmpl_id'}
|
_inherits = {'product.template': 'product_tmpl_id'}
|
||||||
_inherit = ['mail.thread']
|
_inherit = ['mail.thread']
|
||||||
_inherit = ['mail.thread']
|
|
||||||
_order = 'default_code,name_template'
|
_order = 'default_code,name_template'
|
||||||
_columns = {
|
_columns = {
|
||||||
'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
|
'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
|
||||||
|
|
|
@ -840,6 +840,10 @@
|
||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
</sheet>
|
</sheet>
|
||||||
|
<div class="oe_chatter">
|
||||||
|
<field name="message_follower_ids" widget="mail_followers"/>
|
||||||
|
<field name="message_ids" widget="mail_thread"/>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -852,5 +856,9 @@
|
||||||
<field name="view_id" ref="product_template_tree_view"/>
|
<field name="view_id" ref="product_template_tree_view"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="product_template_menu"
|
||||||
|
parent="base.menu_product" sequence="25"
|
||||||
|
action="product_template_action_tree"/>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import random
|
import random
|
||||||
import simplejson
|
import simplejson
|
||||||
import urllib
|
import urllib
|
||||||
|
import werkzeug
|
||||||
|
|
||||||
from openerp import SUPERUSER_ID
|
from openerp import SUPERUSER_ID
|
||||||
from openerp.addons.web import http
|
from openerp.addons.web import http
|
||||||
|
@ -285,6 +286,18 @@ class Ecommerce(http.Controller):
|
||||||
}
|
}
|
||||||
return request.website.render("website_sale.product", values)
|
return request.website.render("website_sale.product", values)
|
||||||
|
|
||||||
|
@website.route(['/shop/product/<int:product_template_id>/comment'], type='http', auth="public")
|
||||||
|
def product_comment(self, product_template_id, **post):
|
||||||
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
|
if post.get('comment'):
|
||||||
|
request.registry['product.template'].message_post(
|
||||||
|
cr, uid, product_template_id,
|
||||||
|
body=post.get('comment'),
|
||||||
|
type='comment',
|
||||||
|
subtype='mt_comment',
|
||||||
|
context=dict(context, mail_create_nosubcribe=True))
|
||||||
|
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
|
||||||
|
|
||||||
@website.route(['/shop/add_product/', '/shop/category/<int:cat_id>/add_product/'], type='http', auth="user", multilang=True, methods=['POST'])
|
@website.route(['/shop/add_product/', '/shop/category/<int:cat_id>/add_product/'], type='http', auth="user", multilang=True, methods=['POST'])
|
||||||
def add_product(self, name="New Product", cat_id=0, **post):
|
def add_product(self, name="New Product", cat_id=0, **post):
|
||||||
Product = request.registry.get('product.product')
|
Product = request.registry.get('product.product')
|
||||||
|
|
|
@ -44,6 +44,15 @@ class product_template(osv.Model):
|
||||||
_columns = {
|
_columns = {
|
||||||
'website_published': fields.boolean('Available in the website'),
|
'website_published': fields.boolean('Available in the website'),
|
||||||
'website_description': fields.html('Description for the website'),
|
'website_description': fields.html('Description for the website'),
|
||||||
|
# TDE TODO FIXME: when website_mail/mail_thread.py inheritance work -> this field won't be necessary
|
||||||
|
'website_message_ids': fields.one2many(
|
||||||
|
'mail.message', 'res_id',
|
||||||
|
domain=lambda self: [
|
||||||
|
'&', ('model', '=', self._name), ('type', '=', 'comment')
|
||||||
|
],
|
||||||
|
string='Website Messages',
|
||||||
|
help="Website communication history",
|
||||||
|
),
|
||||||
'suggested_product_id': fields.many2one('product.template', 'Suggested For Product'),
|
'suggested_product_id': fields.many2one('product.template', 'Suggested For Product'),
|
||||||
'suggested_product_ids': fields.one2many('product.template', 'suggested_product_id', 'Suggested Products'),
|
'suggested_product_ids': fields.one2many('product.template', 'suggested_product_id', 'Suggested Products'),
|
||||||
'website_size_x': fields.integer('Size X'),
|
'website_size_x': fields.integer('Size X'),
|
||||||
|
|
|
@ -336,11 +336,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<div t-field="product.website_description" class="oe_structure" id="product_full_description"/>
|
<div t-field="product.website_description" class="oe_structure mt16" id="product_full_description"/>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Product option: related / recommended products -->
|
||||||
<template id="recommended_products" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Recommended Products">
|
<template id="recommended_products" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Recommended Products">
|
||||||
<xpath expr="//div[@id='product_full_description']" position="after">
|
<xpath expr="//div[@id='product_full_description']" position="after">
|
||||||
<div class="container mt32" t-if="product.recommended_products()">
|
<div class="container mt32" t-if="product.recommended_products()">
|
||||||
|
@ -365,6 +366,7 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Product option: attributes -->
|
||||||
<template id="product_attributes" inherit_option_id="website_sale.product" name="Product Attributes">
|
<template id="product_attributes" inherit_option_id="website_sale.product" name="Product Attributes">
|
||||||
<xpath expr="//p[@t-field='product.description_sale']" position="after">
|
<xpath expr="//p[@t-field='product.description_sale']" position="after">
|
||||||
<hr t-if="product.website_attribute_ids"/>
|
<hr t-if="product.website_attribute_ids"/>
|
||||||
|
@ -375,6 +377,57 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Product options: OpenChatter -->
|
||||||
|
<template id="product_option_openchatter" inherit_option_id="website_sale.product" name="Discussion">
|
||||||
|
<xpath expr="//div[@t-field='product.website_description']" position="after">
|
||||||
|
<hr class="mb32"/>
|
||||||
|
<section class="container">
|
||||||
|
<div class="row col-md-10 col-md-offset-1">
|
||||||
|
<a id="comments"/>
|
||||||
|
<ul class="media-list" id="comments-list">
|
||||||
|
<li t-foreach="product.website_message_ids" t-as="message" class="media">
|
||||||
|
<div class="media-body">
|
||||||
|
<img class="media-object pull-left" t-att-src="'/website/image?model=res.partner&field=image_small&id='+str(message.author_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||||
|
<div class="media-body">
|
||||||
|
<t t-call="website.publish_short">
|
||||||
|
<t t-set="object" t-value="message"/>
|
||||||
|
</t>
|
||||||
|
<h5 class="media-heading">
|
||||||
|
<span t-field="message.author_id"/> <small>on <span t-field="message.date"/></small>
|
||||||
|
</h5>
|
||||||
|
<div t-field="message.body"/>
|
||||||
|
<div>
|
||||||
|
<div class="col-md-2" t-foreach='message.attachment_ids' t-as='attachment'>
|
||||||
|
<a t-att-href="'/mail/download_attachment?model=mail.message&id='+str(message.id)+'&method=download_attachment&attachment_id='+str(attachment.id)" target="_blank">
|
||||||
|
<t t-if="attachment.file_type == 'webimage'">
|
||||||
|
<img t-att-src="'/web/binary/image?model=ir.attachment&field=datas&id=' + str(attachment.id) + '&resize=100,80'"></img>
|
||||||
|
</t>
|
||||||
|
<t t-if="attachment.file_type != 'webimage'">
|
||||||
|
<img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.file_type + '.png'"></img>
|
||||||
|
</t>
|
||||||
|
<div class='oe_name'><t t-raw='attachment.name' /></div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="css_editable_mode_hidden">
|
||||||
|
<form id="comment" t-attf-action="/shop/product/#{product.id}/comment"
|
||||||
|
method="POST">
|
||||||
|
<img class="img pull-left img-rounded" t-att-src="'/website/image?model=res.partner&field=image_small&id='+str(user_id.partner_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||||
|
<div class="pull-left mb32" style="width: 75%%">
|
||||||
|
<textarea rows="3" name="comment" class="form-control" placeholder="Write a comment..."></textarea>
|
||||||
|
<button type="submit" class="btn btn-primary mt8">Post</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Page Shop my cart -->
|
<!-- Page Shop my cart -->
|
||||||
|
|
||||||
<template id="mycart" name="Your Cart">
|
<template id="mycart" name="Your Cart">
|
||||||
|
|
Loading…
Reference in New Issue