[IMP] better templates

bzr revid: fp@tinyerp.com-20140303155355-1nxn9yaudzeu5dei
This commit is contained in:
Fabien Pinckaers 2014-03-03 16:53:55 +01:00
commit 13a4923a10
23 changed files with 1756 additions and 2 deletions

View File

@ -42,7 +42,7 @@ import os
from distutils.version import LooseVersion
from pyPdf import PdfFileWriter, PdfFileReader
#from pyPdf import PdfFileWriter, PdfFileReader
from werkzeug import exceptions
from werkzeug.test import Client
from werkzeug.wrappers import BaseResponse

View File

@ -104,7 +104,7 @@
</field>
</record>
<menuitem id="menu_page" parent="menu_wiki" name="Blog Posts" action="action_blog_post" sequence="10"/>
<record model="ir.actions.act_window" id="action_blog_blog">
<field name="name">Blogs</field>
<field name="res_model">blog.blog</field>

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
import controllers
import models

View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
{
'name': 'Forum',
'category': 'Website',
'summary': 'Ask Questions and give Answers',
'version': '1.0',
'description': """
Ask questions, get answers, no distractions
""",
'author': 'OpenERP SA',
'depends': ['website', 'website_mail'],
'data': [
'data/forum_data.xml',
'views/website_forum.xml',
'security/ir.model.access.csv',
'security/website_forum.xml',
],
'qweb': [
'static/src/xml/*.xml'
],
'demo': [
'data/forum_demo.xml'
],
'css': ['static/src/css/website_forum.css'],
'installable': True,
'application': True,
}

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
import main

View File

@ -0,0 +1,221 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
import werkzeug.urls
from openerp import tools
from openerp import SUPERUSER_ID
from openerp.addons.web import http
from openerp.tools.translate import _
from datetime import datetime, timedelta
from openerp.addons.web.http import request
from dateutil.relativedelta import relativedelta
from openerp.addons.website.controllers.main import Website as controllers
controllers = controllers()
class website_forum(http.Controller):
@http.route(['/forum/', '/forum/page/<int:page>'], type='http', auth="public", website=True, multilang=True)
def questions(self, page=1, **searches):
cr, uid, context = request.cr, request.uid, request.context
forum_obj = request.registry['website.forum.post']
user_obj = request.registry['res.users']
domain = [('parent_id', '=', False)]
search = searches.get('search',False)
type = searches.get('type',False)
if not type:
searches['type'] = 'all'
if search:
domain += ['|',
('name', 'ilike', search),
('content', 'ilike', search)]
if type == 'unanswered':
domain += [ ('child_ids', '=', False) ]
#TODO: update domain to show followed questions of user
if type == 'followed':
user = user_obj.browse(cr, uid, uid, context=context)
domain += [ ('id', 'in', [que.id for que in user.question_ids]) ]
step = 10
question_count = forum_obj.search(cr, uid, domain, count=True, context=context)
pager = request.website.pager(url="/forum/", total=question_count, page=page, step=step, scope=10)
obj_ids = forum_obj.search(cr, uid, domain, limit=step, offset=pager['offset'], context=context)
question_ids = forum_obj.browse(cr, uid, obj_ids, context=context)
#If dose not get any related question then redirect to ask question form.
if search and not question_ids:
values = {
'question_name': search,
}
return request.website.render("website_forum.ask_question", values)
values = {
'total_questions': question_count,
'question_ids': question_ids,
'pager': pager,
'searches': searches,
}
return request.website.render("website_forum.index", values)
@http.route(['/forum/question/<model("website.forum.post"):question>/page/<page:page>'], type='http', auth="public", website=True, multilang=True)
def question(self, question, page, **post):
values = {
'question': question,
'main_object': question
}
return request.website.render(page, values)
@http.route(['/forum/question/<model("website.forum.post"):question>'], type='http', auth="public", website=True, multilang=True)
def open_question(self, question, **post):
answer_done = False
for answer in question.child_ids:
if answer.create_uid.id == request.uid:
answer_done = True
values = {
'question': question,
'main_object': question,
'searches': post,
'answer_done': answer_done
}
return request.website.render("website_forum.post_description_full", values)
@http.route(['/forum/user/<model("res.users"):user>'], type='http', auth="public", website=True, multilang=True)
def open_user(self, user, **post):
values = {
'user': user,
'main_object': user,
'searches': post
}
return request.website.render("website_forum.user_detail_full", values)
@http.route('/forum/question/ask/', type='http', auth="user", multilang=True, methods=['POST'], website=True)
def register_question(self, forum_id=1, **question):
cr, uid, context = request.cr, request.uid, request.context
create_context = dict(context)
new_question_id = request.registry['website.forum.post'].create(
request.cr, request.uid, {
#'forum_id': forum_id,
'name': question.get('question_name'),
'content': question.get('question_content'),
#'tags' : question.get('question_tags'),
'state': 'active',
'active': True,
}, context=create_context)
return werkzeug.utils.redirect("/forum/question/%s" % new_question_id)
@http.route('/forum/question/postanswer/', type='http', auth="user", multilang=True, methods=['POST'], website=True)
def post_answer(self, post_id, forum_id=1, **question):
cr, uid, context = request.cr, request.uid, request.context
create_context = dict(context)
new_question_id = request.registry['website.forum.post'].create(
request.cr, request.uid, {
#'forum_id': forum_id,
'parent_id': post_id,
'content': question.get('answer_content'),
'state': 'active',
'active': True,
}, context=create_context)
return werkzeug.utils.redirect("/forum/question/%s" % post_id)
@http.route(['/forum/question/editanswer'], type='http', auth="user", website=True, multilang=True)
def edit_answer(self, post_id, **kwargs):
cr, uid, context = request.cr, request.uid, request.context
post = request.registry['website.forum.post'].browse(cr, uid, int(post_id), context=context)
for answer in post.child_ids:
if answer.create_uid.id == request.uid:
post_answer = answer
values = {
'post': post,
'post_answer': post_answer,
'searches': kwargs
}
return request.website.render("website_forum.edit_answer", values)
@http.route('/forum/question/saveanswer/', type='http', auth="user", multilang=True, methods=['POST'], website=True)
def save_edited_answer(self, forum_id=1, **post):
cr, uid, context = request.cr, request.uid, request.context
answer_id = int(post.get('answer_id'))
new_question_id = request.registry['website.forum.post'].write( cr, uid, [answer_id], {
'content': post.get('answer_content'),
}, context=context)
return werkzeug.utils.redirect("/forum/question/%s" % post.get('post_id'))
@http.route(['/forum/tag/<model("website.forum.tag"):tag>'], type='http', auth="public", website=True, multilang=True)
def tag_questions(self, tag, page=1, **kwargs):
cr, uid, context = request.cr, request.uid, request.context
step = 10
pager = request.website.pager(url="/forum/", total=len(tag.post_ids), page=page, step=step, scope=10)
values = {
'question_ids': tag.post_ids,
'pager': pager,
'searches': kwargs
}
return request.website.render("website_forum.index", values)
@http.route(['/forum/tags', '/forum/tags/page/<int:page>'], type='http', auth="public", website=True, multilang=True)
def tags(self, page=1, **searches):
cr, uid, context = request.cr, request.uid, request.context
tag_obj = request.registry['website.forum.tag']
step = 30
tag_count = tag_obj.search(cr, uid, [], count=True, context=context)
pager = request.website.pager(url="/forum/tags/", total=tag_count, page=page, step=step, scope=30)
obj_ids = tag_obj.search(cr, uid, [], limit=step, offset=pager['offset'], context=context)
tags = tag_obj.browse(cr, uid, obj_ids, context=context)
searches['tags'] = 'True'
values = {
'tags': tags,
'pager': pager,
'searches': searches,
}
return request.website.render("website_forum.tag", values)
@http.route(['/forum/users', '/forum/users/page/<int:page>'], type='http', auth="public", website=True, multilang=True)
def users(self, page=1, **searches):
cr, uid, context = request.cr, request.uid, request.context
user_obj = request.registry['res.users']
step = 30
tag_count = user_obj.search(cr, uid, [], count=True, context=context)
pager = request.website.pager(url="/forum/users/", total=tag_count, page=page, step=step, scope=30)
obj_ids = user_obj.search(cr, uid, [], limit=step, offset=pager['offset'], context=context)
users = user_obj.browse(cr, uid, obj_ids, context=context)
searches['users'] = 'True'
values = {
'users': users,
'pager': pager,
'searches': searches,
}
return request.website.render("website_forum.users", values)

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="menu_questions" model="website.menu">
<field name="name">Support</field>
<field name="url">/forum</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">40</field>
</record>
<!--record id="action_open_website" model="ir.actions.act_url">
<field name="name">Website Home</field>
<field name="target">self</field>
<field name="url">/forum?tutorial.question=true</field>
</record>
<record id="base.open_menu" model="ir.actions.todo">
<field name="action_id" ref="action_open_website"/>
<field name="state">open</field>
</record-->
</data>
</openerp>

View File

@ -0,0 +1,290 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Tag -->
<record id="tags_0" model="website.forum.tag">
<field name="name">Contract</field>
</record>
<record id="tags_1" model="website.forum.tag">
<field name="name">e-mail</field>
</record>
<record id="tags_2" model="website.forum.tag">
<field name="name">Csv</field>
</record>
<record id="tags_3" model="website.forum.tag">
<field name="name">Action</field>
</record>
<record id="tags_4" model="website.forum.tag">
<field name="name">Alert</field>
</record>
<record id="tags_5" model="website.forum.tag">
<field name="name">POS</field>
</record>
<record id="tags_6" model="website.forum.tag">
<field name="name">Menu</field>
</record>
<record id="question_0" model="website.forum.post">
<field name="name">How to configure alerts for employee contract expiration.</field>
<field name="views">45</field>
<field name="tags" eval="[(4,ref('website_forum.tags_0')),(4,ref('website_forum.tags_3')),(4,ref('website_forum.tags_4'))]"/>
</record>
<record id="question_1" model="website.forum.post">
<field name="name">How to get translated state through browse ?</field>
<field name="content">Hello everybody,
I use a XML-RPC to access to invoices, I want to get the states of invoices, but always I get paid instead of Payé (French)</field>
<field name="views">45</field>
</record>
<record id="question_2" model="website.forum.post">
<field name="name">Restrain the user from confirming the Purchase requisition</field>
<field name="views">45</field>
<field name="content">Can anybody tell me how to restrict the user from confirming the purchase requisition? In my case when a user is creating a purchase requisition than the user after saving it is able to send it to the supplier rather I want the user to just generate the purchase requisition and let the manager do the remaining works like sending the purchase requisition to the supplier and than receiving the goods. Please help me out. Thanks in advance.</field>
<field name="tags" eval="[(4,ref('website_forum.tags_5'))]"/>
</record>
<record id="question_4" model="website.forum.post">
<field name="name">Offline installing for add-ons</field>
<field name="views">45</field>
<field name="content">How can I install web based addons without Internet connections (I'm using OpenERP over LAN)?
P.S.
AFAIK current version (7.x) supports web interface while the desktop clients became deprecated.
BTW, I left OpenERP since ver. 6.x to use PostBooks instead but I recently decided to use OpenERP once again after recent new features.</field>
</record>
<record id="question_5" model="website.forum.post">
<field name="name">CMS replacement for ERP and eCommerce</field>
<field name="views">45</field>
<field name="content">I use Wordpress as a CMS and eCommerce platform. The developing in Wordpress is too easy and solid but it missing ERP feature (there is single plugin to integrate with Frontaccounting) so I wonder:
Can I use OpenERP as a replacement CMS of Wordpress + eCommerce plugin?
In simple words does OpenERP became CMS+ERP platform?</field>
</record>
<record id="question_6" model="website.forum.post">
<field name="name">Register payment using XMLRPC</field>
<field name="views">45</field>
<field name="content">Hi there,
I have been trying to register an invoice payment through OpenERP. I have been able to manually create and approve the invoice, the voucher and its line
I'm currently creating the voucher using this information:</field>
</record>
<record id="question_7" model="website.forum.post">
<field name="name">Create one field on two modules</field>
<field name="views">45</field>
<field name="content">Hello,
I shall like creating a field "x" on an order form ( stock.picking.form ) and to reveal it also on the delivery slip ( stock.picking.form ).
Thank you in advance</field>
</record>
<record id="question_8" model="website.forum.post">
<field name="name">access rights to one2many field</field>
<field name="views">45</field>
<field name="content">Now i create new group , assign user and access right as READ &amp; CREATE to object stock.picking.ads but nothing is reflected , iam able to delete and write which should not happen. Very Strange!!!</field>
</record>
<record id="question_9" model="website.forum.post">
<field name="name">how to import csv into customer database</field>
<field name="views">45</field>
<field name="content">hi, how to import csv into customer database? Thanks</field>
<field name="tags" eval="[(4,ref('website_forum.tags_2'))]"/>
</record>
<record id="question_10" model="website.forum.post">
<field name="name">send mails not receiving properly</field>
<field name="views">45</field>
<field name="content">Hi, The options for sending mails have been enabled in openerp.
There are options to send the invoice,sales order,
quotations etc by the email.But the issue is even after the button 'Send By Email' is clicked,
the email is not received to the recipients .Those emails are stored in the Archives under the Messaging window.How to configure incoming and outgoing mails in openerp</field>
<field name="tags" eval="[(4,ref('website_forum.tags_1'))]"/>
</record>
<record id="question_11" model="website.forum.post">
<field name="name">How to refresh weight of stock move lines after product weight update?</field>
<field name="views">45</field>
</record>
<record id="question_12" model="website.forum.post">
<field name="name">Update new module v7.0 Ubuntu 12.04</field>
<field name="views">45</field>
</record>
<record id="question_13" model="website.forum.post">
<field name="name">Can view top menu In openerp 7.0. (black taskbar at top of window???)</field>
<field name="views">45</field>
<field name="tags" eval="[(4,ref('website_forum.tags_6'))]"/>
</record>
<!-- Answer -->
<record id="answer_0" model="website.forum.post">
<field name="content">Just for posterity so other can see. Here are the steps to set automatic alerts on any contract.. i.e. HR Employee, or Fleet for example. I will use fleet as an example.
Step 1. As a user who has access rights to Technical Features, go to Settings --> Automated Actions. Create A new Automated Action. For the Related Document Model choose.. Contract information on a vehicle (you can also type in the actual model name.. fleet.vehicle.log.contract ) . Set the trigger date to ... Contract Expiration Date.
The Next Field (Delay After Trigger Date) is a bit ridiculous. Who wants to be reminded of a contract expiration AFTER the fact? The field should say Days Before Date to Fire Action and the number should be converted to a negative. IMHO. Any way... to get a workable solution you must enter in the number in the negative. So for instance like me if you want to be warned 35 days BEFORE the expiration... put in Delay After Trigger Date.. the number -35 But the sake of testing, right now just put in -1 for 1 day before. Save the Action.
Step 2. Go to Server Actions and create new Action. Call it Fleet Contract Expiration Warning. The Object will be the same as above .. Contract information on a vehicle. The Action Type is Email. For email address I just put my email. Under subject put in... [[object.name]]. This will tell you the name of the car. Message you can put any text message you like. Now save the Server Action.
Step 3. Now go back to the Automated Action you created and go to the Action tab next to the conditions tab. Click Add and add the server action you created . In this case Fleet Contract Expiration Warning. Then Save.
Step 4. To test, set a contract to expire tomorrow under one of your fleets vehicles. Then Save it.
Step 5. Go to Scheduled Actions.. Set interval number to 1. Interval Unit to Minutes. Then Set the Next Execution date to 2 minutes from now. If your SMTP is configured correctly you will start to get a mail every minute with the reminder.
</field>
<field name="parent_id" ref="question_0" />
</record>
<record id="answer_1" model="website.forum.post">
<field name="content"> Hello everybody,
I use a XML-RPC to access to invoices, I want to get the states of invoices, but always I get paid instead of Payé (French)
I use administrator to connect to the databse, he has as lang = 'fr_FR'
def _get_invoice_states(self, cr, uid, ids, field_name, args, context=None):
if not context :
context = {}
user = self.pool.get('res.users').read(cr, uid, uid, ['lang','tz'])
context.update({'lang' : str(user.get('lang',u'fr_FR'))})
context.update({'tz' : str(user.get('tz',u'GMT'))})
context.update({'uid' : uid})
result = {}
for invoice in self.browse(cr, uid, ids, context=context):
res = _('Name : ') + (invoice.number or '')
res += _('Etat : ') + (invoice.state or '')
</field>
<field name="parent_id" ref="question_1" />
</record>
<record id="answer_4" model="website.forum.post">
<field name="content">Yes you could download the module from internet on another
computer and unzip the file on the ERP server.
Then you have to activate the module, see the tutorial on acespritechblog.wordpress.com (sorry I cannot post the full link)
</field>
<field name="parent_id" ref="question_4" />
</record>
<record id="answer_5" model="website.forum.post">
<field name="content">OpenERP v8 (next release) provides a web module and an e-commerce module: www.openerp.com/website_cms
The CMS editor in OpernERP web is nice but I prefer drupal for customization and there is a drupal module for OpenERP. I think WP is better than OpenERP web too.
</field>
<field name="parent_id" ref="question_5" />
</record>
<record id="answer_6_0" model="website.forum.post">
<field name="content">
no need to inherit account.voucher. after creating the account.voucher record, you just add this in your XMLRPC script.
self.sock.execute(self.dbname, self.uid, self.pwd, 'account.voucher',
'button_proforma_voucher', voucher_id, {})
voucher_id should be the ID of the created voucher.
</field>
<field name="parent_id" ref="question_6" />
</record>
<record id="answer_6_1" model="website.forum.post">
<field name="content">
I had the same issue and in my case I needed to remove the field "move_id" from account.voucher and adding the field "move_line_id" to account.voucher.line, have you tried that?
move_line_id should match the ID of the account.move.line whose "move_id" field matches the "move_id" field of the invoice you created
I also set 'type'='cr' for account.voucher.line
After that, executing workflow('account.voucher', 'proforma_voucher', voucher_id) worked ok,
Hope this helps!
</field>
<field name="parent_id" ref="question_6" />
</record>
<record id="answer_9" model="website.forum.post">
<field name="content">
Step 1: First make sure the CRM module is installed. If it isnt then you can click on the CRM module in the applications view.
Step 2: Go to Settings -> Configuration -> General Settings and check the "Allow users to import data from CSV files" checkbox
Step 3: Go to Sales -> Customers then switch to the List view by clicking the List view button in the upper right corner
Step 4: Click on the "Import" link next to the red Create button
Step 5: Click the "Choose File" button and find your csv file to import
Step 6: Match the fields from the csv file to the fields in the drop down menus.
Step 7: Click the "Validate" button to see if any errors occurred. Correct any errors on the csv file, save it, then refresh the file by clicking the refresh button next to the "Choose File" button
Step 8: Click "Validate" again. If there are still errors, then repeat step 7, otherwise click the "Import" button. Then youre done
</field>
<field name="parent_id" ref="question_9" />
</record>
<record id="answer_10" model="website.forum.post">
<field name="content">
Hello,
Email outgoing server can be configured in: Settings >> General Settings >> Email >> Outgoing mail server.
SMTP Server: Your SMTP server address
Connection Security: SSL or none
Username: Your E-Mail user name
Password: Your E-Mail password
</field>
<field name="parent_id" ref="question_10" />
</record>
<record id="answer_13_0" model="website.forum.post">
<field name="content">
also settings-> update moduel list? can find this anywhere??
</field>
<field name="parent_id" ref="question_13" />
</record>
<record id="answer_13_1" model="website.forum.post">
<field name="content">
Give your admin user the technical features right and you will be able to see more options in the settings menu. (use a refresh)
</field>
<field name="parent_id" ref="question_13" />
</record>
<record id="tags_0" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_0'))]"/>
</record>
<record id="tags_1" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_10'))]"/>
</record>
<record id="tags_2" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_9'))]"/>
</record>
<record id="tags_3" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_0'))]"/>
</record>
<record id="tags_4" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_0'))]"/>
</record>
<record id="tags_5" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_2'))]"/>
</record>
<record id="tags_6" model="website.forum.tag">
<field name="post_ids" eval="[(4,ref('website_forum.question_13'))]"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,9 @@
.. _changelog:
Changelog
=========
`trunk (saas-3)`
----------------
- created ``website_forum``

View File

@ -0,0 +1,10 @@
Website Forum Module documentation topics
'''''''''''''''''''''''''''''''''''''''''
Changelog
'''''''''
.. toctree::
:maxdepth: 1
changelog.rst

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
import website_forum

View File

@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
import re
from openerp import SUPERUSER_ID
from openerp.osv import osv, fields
from openerp.tools.translate import _
from openerp.addons.website.models.website import slug
#TODO: Do we need a forum object like blog object ? Need to check with BE team
class Forum(osv.Model):
_name = 'website.forum'
_description = 'Blogs'
_inherit = ['mail.thread', 'website.seo.metadata']
_order = 'name'
_columnss = {
'name': fields.char('Name', required=True),
'description': fields.text('Description'),
'forum_post_ids': fields.one2many(
'website.forum.post', 'forum_id',
'Posts',
),
}
class Post(osv.Model):
_name = 'website.forum.post'
_description = "Question"
_inherit = ['mail.thread', 'website.seo.metadata']
_columns = {
'forum_id': fields.many2one('website.forum', 'Forum'),
'name': fields.char('Topic', size=64),
'content': fields.text('Contents', help='contents'),
'create_date': fields.datetime('Asked on', select=True, readonly=True),
'create_uid': fields.many2one('res.users', 'Asked by', select=True, readonly=True ),
'write_date': fields.datetime('Update on', select=True, readonly=True ),
'write_uid': fields.many2one('res.users', 'Update by', select=True, readonly=True),
'tags': fields.many2many('website.forum.tag', 'forum_tag_rel', 'forum_id', 'forum_tag_id', 'Tag'),
'vote_ids':fields.one2many('website.forum.post.vote', 'post_id', 'Vote'),
'favourite_ids': fields.many2many('res.users', 'forum_favourite_rel', 'forum_id', 'user_id', 'Favourite'),
'state': fields.selection([('active', 'Active'),('close', 'Close'),('offensive', 'Offensive')], 'Status'),
'active': fields.boolean('Active'),
'views': fields.integer('Views'),
'parent_id': fields.many2one('website.forum.post', 'Parent'),
'child_ids': fields.one2many('website.forum.post', 'parent_id', 'Child'),
# 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='Post Messages',
help="Comments on forum post",
),
}
_defaults = {
'state': 'active',
'active': True
}
def create_history(self, cr, uid, ids, vals, context=None):
for post in ids:
history = self.pool.get('website.forum.post.history')
if vals.get('content'):
create_date = vals.get('create_date')
res = {
'name': 'Update %s - %s' % (create_date, vals.get('name')),
'content': vals.get('content', ''),
'post_id': post
}
if vals.get('version'):
res.update({'version':vals.get('version')})
if vals.get('tags'):
res.update({'tags':vals.get('tags')})
history.create(cr, uid, res)
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}
create_context = dict(context, mail_create_nolog=True)
post_id = super(Post, self).create(cr, uid, vals, context=create_context)
self.create_history(cr, uid, [post_id], vals, context)
return post_id
def write(self, cr, uid, ids, vals, context=None):
result = super(Post, self).write(cr, uid, ids, vals, context)
self.create_history(cr, uid, ids, vals, context)
return result
class Users(osv.Model):
_inherit = 'res.users'
_columns = {
'question_ids':fields.one2many('website.forum.post', 'create_uid', 'Questions', domain=[('parent_id', '=', False)]),
'answer_ids':fields.one2many('website.forum.post', 'create_uid', 'Answers', domain=[('parent_id', '!=', False)]),
'vote_ids': fields.one2many('website.forum.post.vote', 'user_id', 'Votes'),
'tags': fields.many2many('website.forum.tag', 'forum_tag_rel', 'forum_id', 'forum_tag_id', 'Tag'),
'create_date': fields.datetime('Create Date', select=True, readonly=True),
'karma': fields.integer('Karma')
# TODO: 'tag_ids':fields.function()
# Badges : we will use the groups to define badges, two purpose will get solved
# - Define Groups as Badges with Forum as an Application
# - Access control
}
class PostHistory(osv.Model):
_name = 'website.forum.post.history'
_description = 'Post History'
_inherit = ['website.seo.metadata']
_columns = {
'post_id': fields.many2one('website.forum.post', 'Post'),
'create_date': fields.datetime('Created on', select=True, readonly=True),
'create_uid': fields.many2one('res.users', 'Created by', select=True, readonly=True),
'version': fields.integer('Version'),
'name': fields.char('Update Notes', size=64, required=True),
'content': fields.html('Contents', help='Automatically sanitized HTML contents'),
'tags': fields.many2many('website.forum.tag', 'forum_tag_rel', 'forum_id', 'forum_tag_id', 'Tag'),
}
class Vote(osv.Model):
_name = 'website.forum.post.vote'
_description = 'Vote'
_columns = {
'post_id': fields.many2one('website.forum.post', 'Post'),
'user_id': fields.many2one('res.users', 'User'),
'vote': fields.integer('rate'),
}
class ForumActivity(osv.Model):
_name = "website.forum.activity"
_description = "Activity"
_columns = {
'name': fields.char('Order Reference', size=64, required=True),
'post_id': fields.many2one('website.forum.post', 'Post'),
'user_id': fields.many2one('res.users', 'User'),
'create_date': fields.datetime('Created on', select=True, readonly=True),
'create_uid': fields.many2one('res.users', 'Created by', select=True, readonly=True),
'badge_id': fields.many2one('res.groups', 'Badge'),
'karma_add': fields.integer('Added Karma'),
'karma_sub': fields.integer('Karma Removed')
}
class Tags(osv.Model):
_name = "website.forum.tag"
_description = "Tag"
_inherit = ['website.seo.metadata']
_columns = {
'name': fields.char('Name', size=64, required=True),
'post_ids': fields.many2many('website.forum.post', 'forum_tag_que_rel', 'tag_id', 'forum_id', 'Questions', readonly=True),
}

View File

@ -0,0 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_website_forum_post,website.forum.post,model_website_forum_post,base.group_public,1,0,0,0
access_website_forum_post_history,website.forum.post.history,model_website_forum_post_history,base.group_public,1,0,0,0
access_website_forum_post_vote,website.forum.post.vote,model_website_forum_post_vote,base.group_public,1,0,0,0
access_website_forum_activity,website.forum.activity,model_website_forum_activity,base.group_public,1,0,0,0
access_website_forum_tag,website.forum.tag,model_website_forum_tag,base.group_public,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_website_forum_post website.forum.post model_website_forum_post base.group_public 1 0 0 0
3 access_website_forum_post_history website.forum.post.history model_website_forum_post_history base.group_public 1 0 0 0
4 access_website_forum_post_vote website.forum.post.vote model_website_forum_post_vote base.group_public 1 0 0 0
5 access_website_forum_activity website.forum.activity model_website_forum_activity base.group_public 1 0 0 0
6 access_website_forum_tag website.forum.tag model_website_forum_tag base.group_public 1 0 0 0

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--TODO: At this time given read acces but need to improve-->
<record model="ir.rule" id="res_partner_public_rule">
<field name="name">res_partner: public</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain_force">[]</field>
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="perm_write" eval="False"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,2 @@
sass:
sass --compass --unix-newlines -t expanded website_forum.sass:website_forum.css

View File

@ -0,0 +1,20 @@
.box {
padding-left: 8px;
padding-right: 8px;
}
.box span {
font-size: 200%;
font-weight: bold;
}
.question .pull-left {
margin-right: 14px;
min-width: 80px;
}
.question .question-name {
font-size: 150%;
}
.oe_grey {
background-color: #eeeeee;
}

View File

@ -0,0 +1,21 @@
@charset "utf-8"
@import "compass/css3"
.box
padding-left: 8px
padding-right: 8px
span
font-size: 200%
font-weight: bold
.question
.pull-left
margin-right: 14px
min-width: 80px
.question-name
font-size: 150%
.oe_grey
background-color: #eeeeee

View File

@ -0,0 +1,31 @@
(function () {
'use strict';
var website = openerp.website;
var _t = openerp._t;
website.EditorBar.include({
start: function () {
this.registerTour(new website.QuestionTour(this));
return this._super();
},
});
website.QuestionTour = website.Tour.extend({
id: 'question',
name: "Create a question",
testPath: '/forum(/[0-9]+/register)?',
init: function (editor) {
var self = this;
self.steps = [
{
title: _t("Create a question"),
content: _t("Let's go through the first steps to create a new question."),
popover: { next: _("Start Tutorial"), end: _("Skip It") },
},
];
return this._super();
}
});
}());

View File

@ -0,0 +1,31 @@
(function() {
"use strict";
var website = openerp.website;
var _t = openerp._t;
website.add_template_file('/website_forum/static/src/xml/website_forum.xml');
website.is_editable = true;
website.EditorBar.include({
start: function() {
website.is_editable_button = website.is_editable_button || !!$("#wrap.js_event").size();
var res = this._super();
this.$(".dropdown:has(.oe_content_menu)").removeClass("hidden");
return res;
},
events: _.extend({}, website.EditorBar.prototype.events, {
'click a[data-action=new_question]': function (ev) {
ev.preventDefault();
website.prompt({
id: "editor_new_question",
window_title: _t("New Question"),
input: "Question Name",
}).then(function (question_name) {
website.form('/forum/add_question', 'POST', {
question_name: question_name
});
});
}
}),
});
})();

View File

@ -0,0 +1,7 @@
<templates id="template" xml:space="preserve">
<t t-extend="website.editorbar">
<t t-jquery="ul.oe_content_menu" t-operation="append">
<li><a href="#" data-action="new_question">New Question</a></li>
</t>
</t>
</templates>

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 20123TODAY OpenERP S.A. <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/>.
#
##############################################################################
#import test_ui
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2013-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/>.
#
##############################################################################
import openerp.tests
class TestUi(openerp.tests.HttpCase):
def test_admin(self):
self.phantom_js("/", "openerp.website.Tour.run_test('question')", "openerp.website.Tour")

View File

@ -0,0 +1,717 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="editor_head" inherit_id="website.editor_head"
name="Event Editor">
<xpath expr="//script[@id='website_tour_js']" position="after">
<script type="text/javascript"
src="/website_forum/static/src/js/website.tour.forum.js"></script>
<!--
FP Note: Why do we need this ? Can we remove this code?
The problem is that you add your script for every page, not only for the forum
-->
<script type="text/javascript"
src="/website_forum/static/src/js/website_forum.editor.js"></script>
<script type="text/javascript">
CKEDITOR.config.toolbar = [['Bold','Italic','Underline','Strike'],['NumberedList','BulletedList']
,['Outdent','Indent','Link','Unlink'],] ;
</script>
</xpath>
</template>
<!-- Layout add nav and footer -->
<template id="header_footer_custom" inherit_id="website.layout"
name="Footer Questions Link">
<xpath expr="//footer//ul[@name='products']" position="inside">
<li>
<a href="/forum">Q&amp;A</a>
</li>
</xpath>
</template>
<!-- List of Questions -->
<template id="post_list">
<div class="question clearfix">
<div class="pull-left text-center">
<div t-attf-class="box #{len(question.child_ids) and 'oe_green' or 'oe_grey'}">
<span t-esc="len(question.child_ids)"/>
<div t-if="len(question.child_ids)&gt;1">Answers</div>
<div t-if="len(question.child_ids)&lt;=1">Answer</div>
</div>
<div class="text-muted text-center">
<span t-field="question.views"/> Views
</div>
</div>
<div>
<div class="question-name">
<a t-attf-href="/forum/question/#{ slug(question) }" t-field="question.name"/>
</div>
<div class="text-muted">
by <a t-attf-href="/forum/user/#{ question.create_uid.id }" t-field="question.create_uid"/>,
on <span t-field="question.write_date"/>
<div t-if="len(question.vote_ids)">
<strong>with <span t-esc="len(question.vote_ids)"/> votes</strong>
</div>
</div>
<t t-foreach="question.tags" t-as="tag">
<a t-attf-href="/forum/tag/#{ tag.id }" class="badge" t-field="tag.name"/>
</t>
</div>
</div>
</template>
<!-- Page Index -->
<template id="header" name="Forum Index">
<t t-call="website.layout">
<t t-set="head">
<link rel='stylesheet' href='/website_forum/static/src/css/website_forum.css' />
</t>
<div class="container mt16">
<div class="navbar navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#oe-help-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Help</a>
</div>
<div class="collapse navbar-collapse" id="oe-help-navbar-collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<t t-if="searches.get('type') == 'all'">All Questions</t>
<t t-if="searches.get('type') == 'unanswered'">Unanswered Questions</t>
<t t-if="searches.get('type') == 'followed'">Followed Questions</t>
<b class="caret"/>
</a>
<ul class="dropdown-menu">
<li class="dropdown-header">Filter on</li>
<li t-att-class="searches.get('type') == 'all' and 'active' or '' ">
<a t-attf-href="/forum/?{{ keep_query( type='all') }}">All</a>
</li>
<li t-att-class="searches.get('type') == 'unanswered' and 'active' or '' ">
<a t-attf-href="/forum/?{{ keep_query( type='unanswered') }}">Unanswered</a>
</li>
<li t-att-class="searches.get('type') == 'followed' and 'active' or '' ">
<a t-attf-href="/forum/?{{ keep_query( type='followed') }}">Followed</a>
</li>
<li class="dropdown-header">Sort by</li>
<li>
<a href="#" class="active">Last activity date</a> <!-- default order to implement -->
</li>
<li>
<a href="#">Most answered</a>
</li>
<li>
<a href="#">Most voted</a>
</li>
</ul>
</li>
<li t-att-class="searches.get('users') and 'active' or '' ">
<a href="/forum/users">People</a>
</li>
<li t-att-class="searches.get('tags') and 'active' or '' ">
<a href="/forum/tags">Tags</a>
</li>
<li t-att-class="searches.get('badge') and 'active' or '' ">
<a href="/forum/badge">Badges</a>
</li>
</ul>
<form class="navbar-form navbar-right" role="search" action="/forum/" method="get">
<div class="form-group">
<input type="search" class="form-control"
name="search" placeholder="Search a question..."
t-att-value="searches.get('search') or ''" />
<button type="submit" class="btn btn-default">Search</button>
</div>
</form>
</div>
</div>
</div>
<div id="wrap" class="container">
<div class="row">
<div class="col-sm-9">
<t t-raw="0"/>
</div><div class="col-sm-3" id="right-column">
<a class="btn btn-primary btn-lg btn-block mb16" href="/forum/ask">Ask a Question</a>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">About This Forum</h3>
</div>
<div class="panel-body">
This community is for professional and enthusiast about our
products and services.<br/>
<a href="/forum/faq" class="fa fa-arrow-right"> Read Guidelines</a>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
<template id="index">
<t t-call="website_forum.header">
<div t-foreach="question_ids" t-as="question" class="mb16">
<t t-call="website_forum.post_list" />
</div>
<t t-call="website.pager" />
</t>
</template>
<template id="404">
<t t-call="website_forum.header">
<div class="oe_structure oe_empty"/>
<h1 class="mt32">Question not found!</h1>
<p>Sorry, this question is not available anymore.</p>
<p>
<a t-attf-href="/forum">Return to the question list.</a>
</p>
</t>
</template>
<template id="user_detail">
<div class="col-sm-3 col-sm-offset-9 col-md-offset-8 text-right">
<div class="panel panel-primary">
<p class="text-center-heading">
<small>
asked
<span t-esc="question.create_date"></span>
</small>
</p>
<div class="row">
<div class="col-xs-3">
<div class="row">
<div class="col-xs-12">
<span t-field="question.create_uid.image" t-field-options='{"widget": "image"}' />
</div>
</div>
</div>
<div class="col-xs-9">
<div class="row">
<div class="col-xs-12">
<div class="text-left">
<a t-attf-href="/forum/user/#{ question.create_uid.id }">
<t t-esc="question.create_uid.name" />
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div style="font-size:10px" class="text-left">
<b style="color : green">11</b>
<span class="glyphicon glyphicon-certificate badge-gold"></span>
1
<span class="glyphicon glyphicon-certificate badge-silver"></span>
10
<span class="glyphicon glyphicon-certificate badge-bronze"></span>
5
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<template id="post_vote">
</template>
<template id="post_links">
<div class="row">
<div class="col-xs-12 text-right">
<a class="action-links" href="">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<a class="action-links" href="">
<span class="glyphicon glyphicon-flag"></span>
</a>
<a class="action-links" href="">
<span class="glyphicon glyphicon-trash"></span>
</a>
<a class="action-links" href="">
<span class="glyphicon glyphicon-link"></span>
</a>
</div>
</div>
</template>
<template id="ask_question">
<t t-call="website.layout">
<div class="container">
<div class="col-md-9 col-xs-11">
<div class="row">
<div class="col-xs-12 page-header">
<h3>Please Ask your Question here</h3>
</div>
<div class="col-xs-12">
<ul>
<li>
please, try to make your question interesting to others
</li>
<li>
provide enough details and, if possible, give an example
</li>
<li>
be clear and concise, avoid unnecessary introductions (Hi,
...
Thanks...)
</li>
</ul>
</div>
</div>
<div class="row">
<form action="/forum/question/ask/" method="post" role="form">
<div class="col-xs-12">
<input type="text" name="question_name" required="True"
t-attf-value="#{question_name or ''}" id="textbox_user_question"
class="form-control" placeholder="Enter your Question" />
</div>
<div class="col-xs-12">
Please enter a descriptive question (should
finish by a '?')
</div>
<div class="col-xs-12">
<textarea name="question_content" required="True"
t-attf-value="#{question_content or ''}" class="form-control"
id="textarea_ckeditor" rows="10" style="width : 100%" />
</div>
<div class="col-xs-12">
Tags:
</div>
<div class="col-xs-12">
<input type="text" name="question_tag" t-attf-value="#{question_tag or ''}"
class="form-control" id="textarea_tags" style="width : 100%" />
</div>
<div class="col-xs-8">
<button class="btn btn-default" id="btn_ask_your_question"
style="background-color : #df3f3f; color: white !important;">Post Your Question</button>
</div>
</form>
</div>
<script type="text/javascript">
CKEDITOR.replace("textarea_ckeditor");
</script>
</div>
</div>
</t>
</template>
<template id="post_answer">
<div class="col-md-9 col-xs-11">
<div class="row">
<div class="col-xs-12">
<div class="page-header">
<h3>Your answer</h3>
</div>
</div>
<div class="col-xs-12">
<p>
<b>Please try to give a substantial answer</b>
.
If you wanted to comment on the question or answer, just
<b>use the commenting tool.</b>
Please remember that you can always
<b>revise your answers</b>
- no need to answer the same question twice. Also, please
<b>don't forget to vote</b>
- it really helps to select the best questions and answers!
</p>
</div>
</div>
<div class="row">
<form action="/forum/question/postanswer/" method="post" role="form">
<div class="col-xs-12">
<div class="row">
<div class="col-xs-12">
<textarea name="answer_content" required="True"
t-attf-value="#{answer_content or ''}" class="form-control"
id="textarea_ckeditor" rows="10" style="width : 100%" />
</div>
</div>
</div>
<input name="post_id" t-att-value="question.id" type="hidden" />
<div class="col-xs-8">
<button class="btn btn-default"
style="background-color : #df3f3f; color: white !important;" id="btn_ask_your_question">
Post Your Answer
</button>
</div>
</form>
</div>
<script type="text/javascript">
CKEDITOR.replace("textarea_ckeditor");
</script>
</div>
</template>
<template id="edit_answer">
<t t-call="website.layout">
<div class="container">
<div class="col-md-9 col-xs-11">
<div class="row">
<h3>Edit answer</h3>
</div>
<div class="row">
<form action="/forum/question/saveanswer/" method="post" role="form">
<div >
<div class="row">
<div class="col-xs-12">
<textarea name="answer_content" required="True" value="content" class="form-control"
id="textarea_ckeditor" rows="10" style="width : 100%" />
</div>
</div>
</div>
<input name="post_id" t-att-value="post.id" type="hidden"/>
<input name="answer_id" t-att-value="post_answer.id" type="hidden"/>
<div>
<button class="btn btn-default btn-lg">
Save edit
</button>
</div>
</form>
</div>
<script type="text/javascript">
CKEDITOR.replace("textarea_ckeditor");
</script>
</div>
</div>
</t>
</template>
<template id="answer">
<ul class="media-list">
<div>
<li t-foreach="question.child_ids" t-as="answer" class="media">
<div>
<t t-call="website_forum.post_vote"/>
<div class="row col-md-9" style="font-size:14px">
<t t-esc="answer.content" />
</div>
<div class="row">
<t t-call="website_forum.user_detail" />
</div>
<t t-call="website_forum.post_links" />
</div>
</li>
</div>
</ul>
</template>
<template id="post_description_full" name="Question Navigation">
<t t-call="website_forum.header">
<div class="question">
<div class="pull-left text-center">
<div t-attf-class="box oe_grey">
<div class="fa fa-thumbs-up text-success"/>
<div>
<span t-esc="len(question.vote_ids)"/>
</div>
<div class="fa fa-thumbs-down text-warning"/>
</div>
<div class="text-muted">
<span t-esc="len(question.child_ids)"/>
<span t-if="len(question.child_ids)&gt;1">Answers</span>
<span t-if="len(question.child_ids)&lt;=1">Answer</span>
</div>
</div>
<div>
<h1 t-field="question.name" class="mt0"/>
<t t-raw="question.content"/>
<div>
<t t-foreach="question.tags" t-as="tag">
<a t-attf-href="/forum/tag/#{ tag.id }" class="badge" t-field="tag.name"/>
</t>
</div>
<div class="row">
<t t-call="website_forum.user_detail" />
</div>
</div>
</div>
<hr/>
<div class="row">
<t t-call="website_forum.answer"/>
</div>
<div t-if="not answer_done">
<t t-call="website_forum.post_answer"/>
</div>
<div t-if="answer_done">
<form action="/forum/question/editanswer/" method="post" role="form">
<input name="post_id" t-att-value="question.id" type="hidden"/>
<button class="btn btn-default btn-lg">
Edit Your Answer
</button>
<span> (only one answer per question is allowed) </span>
</form>
</div>
</t>
</template>
<template id="tag">
<t t-call="website.layout">
<div>
<t t-call="website_forum.header"/>
</div>
<!--Todo: Improve kanban-->
<div class="container">
<t t-foreach="tags" t-as="tag">
<a t-attf-href="/forum/tag/#{ tag.id }" class="badge">
<t t-esc="tag.name" />
</a>
<span>
X <t t-esc="len(tag.post_ids)"/>
</span>
</t>
<div class="pull-left">
<t t-call="website.pager" />
</div>
</div>
</t>
</template>
<template id="users">
<t t-call="website.layout">
<div>
<t t-call="website_forum.header"/>
</div>
<div class="container">
<t t-foreach="users" t-as="user">
<div class="row">
<div class="col-xs-3 ">
<div class="row">
<div class="col-xs-12 col-md-3">
<span t-field="user.image" t-field-options='{"widget": "image"}' />
</div>
</div>
</div>
<div class="col-xs-9">
<div class="row">
<div class="col-xs-12">
<div class="text-left">
<a t-attf-href="/forum/user/#{ user.id }">
<t t-esc="user.name" />
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div style="font-size:10px" class="text-left">
<b style="color : green">11</b>
<span class="glyphicon glyphicon-certificate badge-gold"></span>
1
<span class="glyphicon glyphicon-certificate badge-silver"></span>
10
<span class="glyphicon glyphicon-certificate badge-bronze"></span>
5
</div>
</div>
</div>
</div>
</div>
</t>
<div class="pull-left">
<t t-call="website.pager" />
</div>
</div>
</t>
</template>
<template id="user_detail_full">
<t t-call="website.layout">
<div>
<t t-call="website_forum.header"/>
</div>
<div class="container">
<div class="row col-xs-12 page-header">
<h3>
<span>
<t t-esc="user.name" />
's profile - overview
</span>
</h3>
</div>
<div class="row">
<ul class="nav nav-tabs">
<li class="active">
<a href="#overview" data-toggle="tab">Overview</a>
</li>
<li>
<a href="#network" data-toggle="tab">Network</a>
</li>
<li>
<a href="#karma" data-toggle="tab">Karma</a>
</li>
<li>
<a href="#followed_question" data-toggle="tab">Followed Question</a>
</li>
<li>
<a href="#activity" data-toggle="tab">Activity</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="overview">
<div class="row">
<div class="col-xs-3">
<span t-field="user.image" class="user-big-profile-image"
t-field-options='{"widget": "image"}' alt="User Name" />
</div>
<div class="col-xs-9">
<div class="row col-xs-12">
<b>Registerd User</b>
</div>
<div class="row">
<div class="col-xs-6">
Real Name :
</div>
<div class="col-xs-6">
<b>
<t t-esc="user.name" />
</b>
</div>
</div>
<div class="row">
<div class="col-xs-6">
Member since :
</div>
<div class="col-xs-6">
<b>
<t t-esc="user.create_date" />
3
</b>
</div>
</div>
<div class="row">
<div class="col-xs-6">
Last Seen :
</div>
<div class="col-xs-6">
<b>Feb 15'14</b>
</div>
</div>
<div class="row">
<div class="col-xs-12">
Todays unused votes 30 votes left
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-3 text-center" style="overflow : hidden">
<b>
<t t-esc="user.karma" />
</b>
</div>
</div>
<div class="row">
<div class="col-xs-3 text-center">
Karma
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default">Follow TressCLoud</button>
</div>
</div>
<div class="row col-xs-12 page-header">
<h3>
<b>
<t t-esc="len(user.question_ids)" />
Questions
</b>
</h3>
</div>
<div class="row col-xs-12">
<ul class="media-list">
<li t-foreach="user.question_ids" t-as="question" class="media">
<t t-call="website_forum.post_list" />
</li>
</ul>
</div>
<div class="row col-xs-12 page-header">
<h3>
<b>
<t t-esc="len(user.answer_ids)" />
Answers
</b>
</h3>
</div>
<!--div class="row col-xs-12"> <ul class="media-list"> <li t-foreach="user.answer_ids"
t-as="question" class="media"> <t t-call="website_forum.post_list" /> </li>
</ul> </div -->
<div class="row col-xs-12 page-header">
<h3>
<b>
<t t-esc="len(user.vote_ids)" />
Votes
</b>
</h3>
</div>
<div class="row">
<div class="col-xs-2">
<h3>
<a href="">
<span class="glyphicon glyphicon-thumbs-up"></span>
</a>
<b> 15 </b>
</h3>
</div>
<div class="col-xs-2">
<h3>
<a href="">
<span class="glyphicon glyphicon-thumbs-down"></span>
</a>
<b> 0 </b>
</h3>
</div>
</div>
<div class="row col-xs-12 page-header">
<h3>
<b>
<t t-esc="len(user.tags)" />
Tags
</b>
</h3>
</div>
<!--div class="row col-xs-12 page-header"> <h3> <b> <t t-esc="len(user.badges)"/>
Badges </b> </h3> </div> <div class="row col-xs-12"> <ul class="media-list">
<li t-foreach="user.badges" t-as="badge" class="media"> <t t-call="website_forum.badge"
/> </li> </ul> </div -->
</div>
<div class="tab-pane" id="network">
<h1>Network</h1>
</div>
<div class="tab-pane" id="karma">
<h1>Karma</h1>
</div>
<div class="tab-pane" id="followed_question">
<h1>Followed Questions</h1>
</div>
<div class="tab-pane" id="activity">
<h1>Activity</h1>
</div>
</div>
</div>
</div>
</t>
</template>
</data>
</openerp>