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