From 0b2d085c1b24f68b1f5d8ce25f2671019560f18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 6 Jan 2014 14:57:27 +0100 Subject: [PATCH] [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 --- addons/mail/__init__.py | 1 + addons/mail/ir_attachment.py | 197 +++++++++++++++++++++ addons/mail/mail_message.py | 9 +- addons/mail/static/src/js/mail.js | 52 ------ addons/mail/static/src/xml/mail.xml | 6 +- addons/product/product.py | 2 +- addons/product/product_view.xml | 8 + addons/website_sale/controllers/main.py | 13 ++ addons/website_sale/models/product.py | 9 + addons/website_sale/views/website_sale.xml | 55 +++++- 10 files changed, 293 insertions(+), 59 deletions(-) create mode 100644 addons/mail/ir_attachment.py diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py index 26578e19af1..08a7a926cee 100644 --- a/addons/mail/__init__.py +++ b/addons/mail/__init__.py @@ -19,6 +19,7 @@ # ############################################################################## +import ir_attachment import mail_message_subtype import mail_alias import mail_followers diff --git a/addons/mail/ir_attachment.py b/addons/mail/ir_attachment.py new file mode 100644 index 00000000000..99c5a9e054e --- /dev/null +++ b/addons/mail/ir_attachment.py @@ -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 . +# +############################################################################## + +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'), + } diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 4d8d00ec7b9..40a51df91d2 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -351,8 +351,13 @@ class mail_message(osv.Model): 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 - attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname', 'name'], context=context) - attachments_tree = dict((attachment['id'], {'id': attachment['id'], 'filename': attachment['datas_fname'], 'name': attachment['name']}) for attachment in attachments) + 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'], + 'file_type': attachment['file_type'], + }) for attachment in attachments) # 3. Update message dictionaries for message_dict in messages: diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 4378d2f75b5..d9fd2526b8e 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -114,57 +114,6 @@ openerp.mail = function (session) { } 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]; if (!attach.formating) { 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.formating = true; } diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index 31539e24ab3..3a7a5469ee1 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -88,10 +88,10 @@ --> - +
- +
[
@@ -100,7 +100,7 @@
- +
diff --git a/addons/product/product.py b/addons/product/product.py index e73486c2e13..f82b13fb134 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -361,6 +361,7 @@ class product_public_category(osv.osv): #---------------------------------------------------------- class product_template(osv.osv): _name = "product.template" + _inherit = ['mail.thread'] _description = "Product Template" def _get_image(self, cr, uid, ids, name, args, context=None): @@ -650,7 +651,6 @@ class product_product(osv.osv): _table = "product_product" _inherits = {'product.template': 'product_tmpl_id'} _inherit = ['mail.thread'] - _inherit = ['mail.thread'] _order = 'default_code,name_template' _columns = { 'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'), diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index 6e4d31b3b93..1a75a6e023b 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -840,6 +840,10 @@ +
+ + +
@@ -852,5 +856,9 @@ + + diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 2e19fe24a96..23872a1e855 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -2,6 +2,7 @@ import random import simplejson import urllib +import werkzeug from openerp import SUPERUSER_ID from openerp.addons.web import http @@ -285,6 +286,18 @@ class Ecommerce(http.Controller): } return request.website.render("website_sale.product", values) + @website.route(['/shop/product//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//add_product/'], type='http', auth="user", multilang=True, methods=['POST']) def add_product(self, name="New Product", cat_id=0, **post): Product = request.registry.get('product.product') diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index 7070f923e2b..03798fb105f 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -44,6 +44,15 @@ class product_template(osv.Model): _columns = { 'website_published': fields.boolean('Available in 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_ids': fields.one2many('product.template', 'suggested_product_id', 'Suggested Products'), 'website_size_x': fields.integer('Size X'), diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index 629c615e5b3..3f040dae0fd 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -336,11 +336,12 @@
-
+
+ + + + +