Rémy Taymans
7 years ago
7 changed files with 436 additions and 0 deletions
-
2easy_my_coop_website_document/__init__.py
-
32easy_my_coop_website_document/__openerp__.py
-
2easy_my_coop_website_document/controllers/__init__.py
-
210easy_my_coop_website_document/controllers/main.py
-
11easy_my_coop_website_document/security/easy_my_coop_website_document_security.xml
-
1easy_my_coop_website_document/security/ir.model.access.csv
-
178easy_my_coop_website_document/views/easy_my_coop_website_document_templates.xml
@ -0,0 +1,2 @@ |
|||||
|
# -*- coding: utf8 -*- |
||||
|
import controllers |
@ -0,0 +1,32 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
# Copyright 2018 Rémy Taymans <remytaymans@gmail.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
{ |
||||
|
'name': 'Easy My Coop Website Document', |
||||
|
|
||||
|
'summary': """ |
||||
|
Show documents in the website. |
||||
|
""", |
||||
|
'description': """ |
||||
|
""", |
||||
|
|
||||
|
'author': 'Rémy Taymans', |
||||
|
'license': 'AGPL-3', |
||||
|
'version': '9.0.1.0', |
||||
|
'website': "https://github.com/houssine78/vertical-cooperative", |
||||
|
|
||||
|
'category': 'Website, Cooperative Management', |
||||
|
|
||||
|
'depends': [ |
||||
|
'website', |
||||
|
'easy_my_coop_document', |
||||
|
], |
||||
|
|
||||
|
'data': [ |
||||
|
'views/easy_my_coop_website_document_templates.xml', |
||||
|
'security/easy_my_coop_website_document_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
] |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
from . import main |
@ -0,0 +1,210 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
# Copyright 2018 Rémy Taymans <remytaymans@gmail.com> |
||||
|
# Copyright 2015-2016 Odoo S.A. |
||||
|
# Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
|
||||
|
import base64 |
||||
|
|
||||
|
from openerp import http |
||||
|
from openerp.http import request, Response |
||||
|
from openerp.fields import Date |
||||
|
|
||||
|
|
||||
|
class DocumentWebsite(http.Controller): |
||||
|
|
||||
|
@http.route('/documents/<int:oid>', auth='public', website=True) |
||||
|
def get_document(self, oid=-1): |
||||
|
"""Render a http response for a document""" |
||||
|
document_mgr = request.env['easy_my_coop.document'].sudo() |
||||
|
doc = document_mgr.browse(oid) |
||||
|
ir_http_mgr = request.env['ir.http'].sudo() |
||||
|
status, headers, content = ir_http_mgr.binary_content( |
||||
|
model=doc._name, |
||||
|
id=oid, |
||||
|
field='document', |
||||
|
filename_field='filename', |
||||
|
download=True |
||||
|
) |
||||
|
if status == 304: |
||||
|
return Response(status, headers) |
||||
|
elif status == 301: |
||||
|
# TODO: test this case not sure if this render the same |
||||
|
# return werkzeug.utils.redirect(content, code=301) |
||||
|
return request.redirec(content, code=301) |
||||
|
elif status != 200: |
||||
|
return request.not_found() |
||||
|
content_base64 = base64.b64decode(content) |
||||
|
headers.append(('Content-Length', len(content_base64))) |
||||
|
return request.make_response(content_base64, headers) |
||||
|
|
||||
|
@http.route('/documents', auth='public', website=True) |
||||
|
def template_website_document(self, date_begin=None, date_end=None, **kw): |
||||
|
""" |
||||
|
""" |
||||
|
values = {} |
||||
|
values.update(self.website_document_side_bar( |
||||
|
date_begin=date_begin, |
||||
|
date_end=date_end, |
||||
|
user=request.env.user, |
||||
|
)) |
||||
|
values.update(self.display_categories_and_documents( |
||||
|
date_begin=date_begin, |
||||
|
date_end=date_end, |
||||
|
user=request.env.user, |
||||
|
)) |
||||
|
values['size_to_str'] = self.size_to_str |
||||
|
return request.render( |
||||
|
'easy_my_coop_website_document.template_website_document', |
||||
|
values, |
||||
|
) |
||||
|
|
||||
|
def website_document_side_bar(self, date_begin=None, date_end=None, |
||||
|
user=None): |
||||
|
domains = [] |
||||
|
# Show only doc that are published |
||||
|
domains.append(('published', '=', True)) |
||||
|
# Show only authorized documents |
||||
|
if not self._is_authorized_user(user): |
||||
|
domains.append(('public', '=', True)) |
||||
|
# Show only doc in the time frame |
||||
|
if date_begin and date_end: |
||||
|
domains.append(('document_date', '>=', date_begin)) |
||||
|
domains.append(('document_date', '<', date_end)) |
||||
|
return { |
||||
|
'archive_groups': self._get_archive_groups( |
||||
|
'easy_my_coop.document', |
||||
|
domains, |
||||
|
fields=['name', 'document_date'], |
||||
|
groupby='document_date', |
||||
|
order='document_date desc'), |
||||
|
} |
||||
|
|
||||
|
def display_categories_and_documents(self, date_begin=None, date_end=None, |
||||
|
user=None): |
||||
|
"""Prepare value for display_categories_and_documents template""" |
||||
|
data = self._data_tree() |
||||
|
# Show only doc that are published |
||||
|
data = self._data_filter_document( |
||||
|
data, |
||||
|
lambda r: r.published |
||||
|
) |
||||
|
# Show only authorized documents |
||||
|
if not self._is_authorized_user(user): |
||||
|
data = self._data_filter_document( |
||||
|
data, |
||||
|
lambda r: r.public |
||||
|
) |
||||
|
# Show only doc in the time frame |
||||
|
if date_begin and date_end: |
||||
|
data = self._data_filter_document( |
||||
|
data, |
||||
|
lambda r: (r.document_date >= date_begin |
||||
|
and r.document_date < date_end) |
||||
|
) |
||||
|
# After all the filter, remove the empty categories |
||||
|
data = self._data_remove_empty_category(data) |
||||
|
return { |
||||
|
'category_tree': data, |
||||
|
} |
||||
|
|
||||
|
def size_to_str(self, size): |
||||
|
units = ['o', 'ko', 'Mo', 'Go', 'To'] |
||||
|
size_float = float(size) |
||||
|
for unit in units: |
||||
|
if size_float < 1000: |
||||
|
return '%.01f %s' % (size_float, unit) |
||||
|
size_float /= 1000 |
||||
|
|
||||
|
def _data_tree(self, category=None): |
||||
|
"""Return a tree with categories and documents in it""" |
||||
|
category_mgr = request.env['easy_my_coop.document.category'].sudo() |
||||
|
document_mgr = request.env['easy_my_coop.document'].sudo() |
||||
|
if category: |
||||
|
categories = category.child_ids.sorted( |
||||
|
key=lambda r: r.name |
||||
|
) |
||||
|
documents = category.document_ids |
||||
|
else: |
||||
|
categories = category_mgr.search( |
||||
|
[('parent_id', '=', False)], |
||||
|
order="name" |
||||
|
) |
||||
|
documents = document_mgr.search( |
||||
|
[('category', '=', False)] |
||||
|
) |
||||
|
if categories.ids: |
||||
|
tree = [] |
||||
|
for cat in categories: |
||||
|
tree.append(self._data_tree(cat)) |
||||
|
return (category, tree, documents) |
||||
|
else: |
||||
|
return (category, [], documents) |
||||
|
|
||||
|
def _data_filter_document(self, data, filter_fun): |
||||
|
category, child_data, documents = data |
||||
|
tree = [] |
||||
|
for entry in child_data: |
||||
|
tree.append( |
||||
|
self._data_filter_document(entry, filter_fun) |
||||
|
) |
||||
|
return (category, tree, documents.filtered(filter_fun)) |
||||
|
|
||||
|
def _data_remove_empty_category(self, data): |
||||
|
category, child_data, documents = data |
||||
|
child_data = [ |
||||
|
self._data_remove_empty_category(c) for c in child_data |
||||
|
if not self._data_is_empty(c) |
||||
|
] |
||||
|
return (category, child_data, documents) |
||||
|
|
||||
|
def _data_is_empty(self, data): |
||||
|
"""Return True if data is empty""" |
||||
|
_, child_data, documents = data |
||||
|
# If there is documents, it's not empty. |
||||
|
if documents.ids: |
||||
|
return False |
||||
|
# We are sure there is no documents. |
||||
|
# If there is no child, it's empty. |
||||
|
if not child_data: |
||||
|
return True |
||||
|
# We are sure there is childs |
||||
|
for entry in child_data: |
||||
|
# If a child is not empty, it's not empty |
||||
|
if not self._data_is_empty(entry): |
||||
|
return False |
||||
|
# Else it's empty |
||||
|
return True |
||||
|
|
||||
|
def _is_authorized_user(self, user=None): |
||||
|
return user is not None and (user.has_group('base.group_portal') |
||||
|
or user.has_group('base.group_user')) |
||||
|
|
||||
|
def _get_archive_groups(self, model, domain=None, fields=None, |
||||
|
groupby="create_date", order="create_date desc"): |
||||
|
if not model: |
||||
|
return [] |
||||
|
if domain is None: |
||||
|
domain = [] |
||||
|
if fields is None: |
||||
|
fields = ['name', 'create_date'] |
||||
|
groups = [] |
||||
|
for group in request.env[model].sudo().read_group( |
||||
|
domain, fields=fields, groupby=groupby, orderby=order): |
||||
|
label = group[groupby] |
||||
|
date_begin = date_end = None |
||||
|
for leaf in group["__domain"]: |
||||
|
if leaf[0] == groupby: |
||||
|
if leaf[1] == ">=": |
||||
|
date_begin = leaf[2] |
||||
|
elif leaf[1] == "<": |
||||
|
date_end = leaf[2] |
||||
|
groups.append({ |
||||
|
'date_begin': Date.to_string(Date.from_string(date_begin)), |
||||
|
'date_end': Date.to_string(Date.from_string(date_end)), |
||||
|
'name': label, |
||||
|
'item_count': group[groupby + '_count'] |
||||
|
}) |
||||
|
return groups |
@ -0,0 +1,11 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Copyright 2015-2016 Odoo S.A. |
||||
|
Copyright 2018 Rémy Taymans <remytaymans@gmail.com> |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
<openerp> |
||||
|
<data noupdate="0"> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
@ -0,0 +1,178 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
Copyright 2018 Rémy Taymans <remytaymans@gmail.com> |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
<openerp> |
||||
|
|
||||
|
<!-- Add menu entries --> |
||||
|
<data noupdate="0"> |
||||
|
<record id="menu_website_document" model="website.menu"> |
||||
|
<field name="name">Documents</field> |
||||
|
<field name="url">/documents</field> |
||||
|
<field name="parent_id" ref="website.main_menu"/> |
||||
|
<field name="sequence" type="int">40</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
|
||||
|
|
||||
|
<!-- Reusable template --> |
||||
|
<!-- Side bar --> |
||||
|
<template |
||||
|
id="website_document_side_bar" |
||||
|
name="Easy My Coop Website Document: Side bar"> |
||||
|
|
||||
|
<div class="oe_structure"/> |
||||
|
|
||||
|
<h3 class="page-header">Archives</h3> |
||||
|
<ul class="nav nav-pills nav-stacked"> |
||||
|
<t t-foreach="archive_groups" t-as="group"> |
||||
|
<t t-if="group['date_begin'] == date"> |
||||
|
<li class="active"> |
||||
|
<a t-att-href="default_url" t-ignore="True"> |
||||
|
<t t-esc="group['name']"/> |
||||
|
<span class="pull-right badge" t-esc="group['item_count']"/> |
||||
|
</a> |
||||
|
</li> |
||||
|
</t> |
||||
|
<t t-if="group['date_begin'] != date"> |
||||
|
<li> |
||||
|
<a t-ignore="True" |
||||
|
t-attf-href="#{default_url}?date_begin=#{group['date_begin']}&date_end=#{group['date_end']}"> |
||||
|
<t t-esc="group['name']"/> |
||||
|
<span class="pull-right badge" t-esc="group['item_count']"/> |
||||
|
</a> |
||||
|
</li> |
||||
|
</t> |
||||
|
</t> |
||||
|
</ul> |
||||
|
|
||||
|
<div class="oe_structure"/> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<!-- Display document list --> |
||||
|
<template |
||||
|
id="website_document_display_document_list" |
||||
|
name="Easy My Coop Website Document: Display document list"> |
||||
|
|
||||
|
<div class="list-group" t-foreach="documents" t-as="doc"> |
||||
|
<a t-attf-href="/documents/{{doc.id}}" |
||||
|
class="list-group-item clearfix"> |
||||
|
<span class="fa fa-file"></span> |
||||
|
<t t-esc="doc.name"/> - <small t-field="doc.document_date"/> |
||||
|
<span class="pull-right"> |
||||
|
<span class="fa fa-download"></span> |
||||
|
<t t-esc="size_to_str(doc.file_size)"/> |
||||
|
</span> |
||||
|
<t t-if="doc.description"> |
||||
|
<p t-field="doc.description" class="mb0 small"/> |
||||
|
</t> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<!-- Display of a category and its documents --> |
||||
|
<template |
||||
|
id="display_categories_and_documents" |
||||
|
name="Easy My Coop Website Document: Display Category and documents"> |
||||
|
|
||||
|
<t t-set="cat" t-value="category_tree[0]"/> |
||||
|
<t t-set="child_category_tree" t-value="category_tree[1]"/> |
||||
|
<t t-set="documents" t-value="category_tree[2]"/> |
||||
|
|
||||
|
<div class="panel panel-default" t-if="cat"> |
||||
|
<div class="panel-heading" role="tab" t-attf-id="heading-{{ cat.id }}"> |
||||
|
<a role="button" |
||||
|
class="h4" |
||||
|
t-attf-href="#collapse-{{ cat.id }}" |
||||
|
data-toggle="collapse" |
||||
|
aria-expanded="false" |
||||
|
t-attf-aria-controls="collapse-{{ cat.id }}"> |
||||
|
<h4 class="panel-title"> |
||||
|
<t t-esc="cat.name"/> |
||||
|
<t t-if="cat.description"> |
||||
|
<small> |
||||
|
- <t t-esc="cat.description"/> |
||||
|
</small> |
||||
|
</t> |
||||
|
</h4> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div t-attf-id="collapse-{{ cat.id }}" |
||||
|
class="panel-collapse collapse" |
||||
|
role="tabpanel" t-attf-aria-labelledby="heading-{{ cat.id }}"> |
||||
|
<div class="panel-body"> |
||||
|
|
||||
|
<t t-foreach="child_category_tree" t-as="child_cat_tree"> |
||||
|
<t t-call="easy_my_coop_website_document.display_categories_and_documents"> |
||||
|
<t t-set="category_tree" t-value="child_cat_tree"/> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-call="easy_my_coop_website_document.website_document_display_document_list"/> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<t t-if="not cat"> |
||||
|
<t t-foreach="child_category_tree" t-as="child_cat_tree"> |
||||
|
<t t-call="easy_my_coop_website_document.display_categories_and_documents"> |
||||
|
<t t-set="category_tree" t-value="child_cat_tree"/> |
||||
|
</t> |
||||
|
</t> |
||||
|
<t t-call="easy_my_coop_website_document.website_document_display_document_list"/> |
||||
|
</t> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
|
||||
|
<!-- Document main page --> |
||||
|
<template |
||||
|
id="template_website_document" |
||||
|
name="Easy My Coop Website Document: Main page" |
||||
|
page="True"> |
||||
|
<t t-call="website.layout"> |
||||
|
|
||||
|
<div class="oe_structure"/> |
||||
|
|
||||
|
<section class="wrap"> |
||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col-md-12"> |
||||
|
<h1 class="text-center"> |
||||
|
Documents |
||||
|
</h1> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<div class="oe_structure"/> |
||||
|
|
||||
|
<section class="wrap"> |
||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<!-- Main panel --> |
||||
|
<div class="col-xs-12 col-md-8"> |
||||
|
|
||||
|
<t t-call="easy_my_coop_website_document.display_categories_and_documents"/> |
||||
|
|
||||
|
</div> <!-- col-md-8 --> |
||||
|
|
||||
|
<!-- Side panel --> |
||||
|
<div class="col-xs-12 col-md-4"> |
||||
|
<t t-call="easy_my_coop_website_document.website_document_side_bar"/> |
||||
|
</div> <!-- col-md-4 --> |
||||
|
|
||||
|
</div> <!-- row --> |
||||
|
</div> <!-- container --> |
||||
|
</section> |
||||
|
|
||||
|
</t> |
||||
|
</template> |
||||
|
|
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue