You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
7.6 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2018 Rémy Taymans <remytaymans@gmail.com>
  3. # Copyright 2015-2016 Odoo S.A.
  4. # Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
  5. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  6. import base64
  7. from openerp import http
  8. from openerp.http import request, Response
  9. from openerp.fields import Date
  10. class DocumentWebsite(http.Controller):
  11. @http.route('/documents/<int:oid>', auth='public', website=True)
  12. def get_document(self, oid=-1):
  13. """Render a http response for a document"""
  14. document_mgr = request.env['easy_my_coop.document']
  15. doc = document_mgr.sudo().browse(oid)
  16. ir_http_mgr = request.env['ir.http']
  17. status, headers, content = ir_http_mgr.sudo().binary_content(
  18. model=doc._name,
  19. id=oid,
  20. field='document',
  21. filename_field='filename',
  22. download=True
  23. )
  24. if status == 304:
  25. return Response(status, headers)
  26. elif status == 301:
  27. # TODO: test this case not sure if this render the same
  28. # return werkzeug.utils.redirect(content, code=301)
  29. return request.redirect(content, code=301)
  30. elif status != 200:
  31. return request.not_found()
  32. content_base64 = base64.b64decode(content)
  33. headers.append(('Content-Length', len(content_base64)))
  34. return request.make_response(content_base64, headers)
  35. @http.route('/documents', auth='public', website=True)
  36. def template_website_document(self, date_begin=None, date_end=None, **kw):
  37. """
  38. """
  39. values = {}
  40. values.update(self.website_document_side_bar(
  41. date_begin=date_begin,
  42. date_end=date_end,
  43. user=request.env.user,
  44. ))
  45. values.update(self.display_categories_and_documents(
  46. date_begin=date_begin,
  47. date_end=date_end,
  48. user=request.env.user,
  49. ))
  50. values['size_to_str'] = self.size_to_str
  51. return request.render(
  52. 'easy_my_coop_website_document.template_website_document',
  53. values,
  54. )
  55. def website_document_side_bar(self, date_begin=None, date_end=None,
  56. user=None):
  57. domains = []
  58. # Show only doc that are published
  59. domains.append(('published', '=', True))
  60. # Show only authorized documents
  61. if not self._is_authorized_user(user):
  62. domains.append(('public', '=', True))
  63. # Show only doc in the time frame
  64. if date_begin and date_end:
  65. domains.append(('document_date', '>=', date_begin))
  66. domains.append(('document_date', '<', date_end))
  67. return {
  68. 'archive_groups': self._get_archive_groups(
  69. 'easy_my_coop.document',
  70. domains,
  71. fields=['name', 'document_date'],
  72. groupby='document_date',
  73. order='document_date desc'),
  74. }
  75. def display_categories_and_documents(self, date_begin=None, date_end=None,
  76. user=None):
  77. """Prepare value for display_categories_and_documents template"""
  78. data = self._data_tree()
  79. # Show only doc that are published
  80. data = self._data_filter_document(
  81. data,
  82. lambda r: r.published
  83. )
  84. # Show only authorized documents
  85. if not self._is_authorized_user(user):
  86. data = self._data_filter_document(
  87. data,
  88. lambda r: r.public
  89. )
  90. # Show only doc in the time frame
  91. if date_begin and date_end:
  92. data = self._data_filter_document(
  93. data,
  94. lambda r: (r.document_date >= date_begin
  95. and r.document_date < date_end)
  96. )
  97. # After all the filter, remove the empty categories
  98. data = self._data_remove_empty_category(data)
  99. return {
  100. 'category_tree': data,
  101. }
  102. def size_to_str(self, size):
  103. units = ['o', 'ko', 'Mo', 'Go', 'To']
  104. size_float = float(size)
  105. for unit in units:
  106. if size_float < 1000:
  107. return '%.01f %s' % (size_float, unit)
  108. size_float /= 1000
  109. def _data_tree(self, category=None):
  110. """Return a tree with categories and documents in it"""
  111. category_mgr = request.env['easy_my_coop.document.category']
  112. document_mgr = request.env['easy_my_coop.document']
  113. if category:
  114. categories = category.child_ids.sorted(
  115. key=lambda r: r.name
  116. )
  117. documents = category.document_ids
  118. else:
  119. categories = category_mgr.sudo().search(
  120. [('parent_id', '=', False)],
  121. order="name"
  122. )
  123. documents = document_mgr.sudo().search(
  124. [('category', '=', False)]
  125. )
  126. if categories.ids:
  127. tree = []
  128. for cat in categories:
  129. tree.append(self._data_tree(cat))
  130. return (category, tree, documents)
  131. else:
  132. return (category, [], documents)
  133. def _data_filter_document(self, data, filter_fun):
  134. category, child_data, documents = data
  135. tree = []
  136. for entry in child_data:
  137. tree.append(
  138. self._data_filter_document(entry, filter_fun)
  139. )
  140. return (category, tree, documents.filtered(filter_fun))
  141. def _data_remove_empty_category(self, data):
  142. category, child_data, documents = data
  143. child_data = [
  144. self._data_remove_empty_category(c) for c in child_data
  145. if not self._data_is_empty(c)
  146. ]
  147. return (category, child_data, documents)
  148. def _data_is_empty(self, data):
  149. """Return True if data is empty"""
  150. _, child_data, documents = data
  151. # If there is documents, it's not empty.
  152. if documents.ids:
  153. return False
  154. # We are sure there is no documents.
  155. # If there is no child, it's empty.
  156. if not child_data:
  157. return True
  158. # We are sure there is childs
  159. for entry in child_data:
  160. # If a child is not empty, it's not empty
  161. if not self._data_is_empty(entry):
  162. return False
  163. # Else it's empty
  164. return True
  165. def _is_authorized_user(self, user=None):
  166. return user is not None and (user.has_group('base.group_portal')
  167. or user.has_group('base.group_user'))
  168. def _get_archive_groups(self, model, domain=None, fields=None,
  169. groupby="create_date", order="create_date desc"):
  170. if not model:
  171. return []
  172. if domain is None:
  173. domain = []
  174. if fields is None:
  175. fields = ['name', 'create_date']
  176. groups = []
  177. for group in request.env[model].sudo().read_group(
  178. domain, fields=fields, groupby=groupby, orderby=order):
  179. label = group[groupby]
  180. date_begin = date_end = None
  181. for leaf in group["__domain"]:
  182. if leaf[0] == groupby:
  183. if leaf[1] == ">=":
  184. date_begin = leaf[2]
  185. elif leaf[1] == "<":
  186. date_end = leaf[2]
  187. groups.append({
  188. 'date_begin': Date.to_string(Date.from_string(date_begin)),
  189. 'date_end': Date.to_string(Date.from_string(date_end)),
  190. 'name': label,
  191. 'item_count': group[groupby + '_count']
  192. })
  193. return groups