Initial commit: OCA Technical packages (595 packages)
47
odoo-bringout-oca-dms-dms/README.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Document Management System
|
||||
|
||||
Odoo addon: dms
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-dms-dms
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- mail
|
||||
- http_routing
|
||||
- portal
|
||||
- base
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Document Management System
|
||||
- **Version**: 16.0.1.8.6
|
||||
- **Category**: Document Management
|
||||
- **License**: LGPL-3
|
||||
- **Installable**: False
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/dms](https://github.com/OCA/dms) branch 16.0, addon `dms`.
|
||||
|
||||
## License
|
||||
|
||||
This package maintains the original LGPL-3 license from the upstream Odoo project.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Overview: doc/OVERVIEW.md
|
||||
- Architecture: doc/ARCHITECTURE.md
|
||||
- Models: doc/MODELS.md
|
||||
- Controllers: doc/CONTROLLERS.md
|
||||
- Wizards: doc/WIZARDS.md
|
||||
- Install: doc/INSTALL.md
|
||||
- Usage: doc/USAGE.md
|
||||
- Configuration: doc/CONFIGURATION.md
|
||||
- Dependencies: doc/DEPENDENCIES.md
|
||||
- Troubleshooting: doc/TROUBLESHOOTING.md
|
||||
- FAQ: doc/FAQ.md
|
||||
189
odoo-bringout-oca-dms-dms/dms/README.rst
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
==========================
|
||||
Document Management System
|
||||
==========================
|
||||
|
||||
..
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:4ca37da84fb902307a08168a40a5048ba34c2af01b05c97a139cca5eb19b8301
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Beta
|
||||
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
|
||||
:alt: License: LGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fdms-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/dms/tree/16.0/dms
|
||||
:alt: OCA/dms
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/dms-16-0/dms-16-0-dms
|
||||
:alt: Translate me on Weblate
|
||||
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
||||
:target: https://runboat.odoo-community.org/builds?repo=OCA/dms&target_branch=16.0
|
||||
:alt: Try me on Runboat
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
|
||||
DMS is a module for creating, managing and viewing document files directly
|
||||
within Odoo.
|
||||
This module is only the basis for an entire ecosystem of apps that extend and
|
||||
seamlessly integrate with the document management system.
|
||||
|
||||
This module adds portal functionality for directories and files for allowed users, both portal or internal users. You can get as well a tokenized link from a directory or a file for sharing it with any anonymous user.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Preview
|
||||
~~~~~~~
|
||||
|
||||
``mail_preview_base`` is required for DMS but it is recommended to install all
|
||||
the other `mail_preview` modules from `social` OCA repository
|
||||
in order to improve the preview of files.
|
||||
|
||||
``python-magic`` library is recommended to be installed for having whole support
|
||||
to get proper file types and file preview.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
To configure this module, you need to:
|
||||
|
||||
#. Go to *Documents -> Configuration -> Storages*.
|
||||
#. Create a new document storage. You can choose between two options on `Save Type`:
|
||||
* `Database`: Store the files on the database as a field
|
||||
* `Attachment`: Store the files as attachments
|
||||
#. Next create an administrative access group. Go to *Configuration -> Access Groups*.
|
||||
* Create a new group, name it appropriately, and turn on all three permissions (Create, Write and Unlink - Read is implied and always enabled).
|
||||
* Add any other top-level administrative users to the group if needed (your user should already be there).
|
||||
* You can create other groups in here later for fine grained access control.
|
||||
#. Afterwards go to *Documents -> Directories*.
|
||||
#. Create a new directory, mark it as root and select the previously created setting.
|
||||
* Select the *Groups* tab and add your administrative group created above.
|
||||
#. On the Directory you can also add other access groups (created above) that will be able to:
|
||||
* read
|
||||
* create
|
||||
* write
|
||||
* delete
|
||||
|
||||
|
||||
Migration
|
||||
~~~~~~~~~
|
||||
|
||||
If you need to modify the storage Save Type you might want to migrate the file data.
|
||||
In order to achieve it you need to:
|
||||
|
||||
#. Go to *Documents -> Configuration -> Storage* and select the storage you want to modify
|
||||
#. Modify the save type
|
||||
#. Press the button `Migrate files` if you want to migrate all the files at once
|
||||
#. Press the button `Manual File Migration` in order to specify files one by one
|
||||
|
||||
You can check all the files that still needs to be migrated from all storages
|
||||
and migrate them manually on *Documents -> Configuration -> Migration*
|
||||
|
||||
|
||||
File Wizard Selection
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There is an action called `action_dms_file_wizard_selector` to open a wizard to list files in kanban view.
|
||||
This can be used (example `dms_attachment_link` module) to add a button in kanban view with the action we need.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
The best way to manage the documents is to switch to the Documents view.
|
||||
Existing documents can be managed there and new documents can be created.
|
||||
|
||||
Portal functionality
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can add any portal user to DMS access groups, and then allow that group in directories, so they will see in the portal such directories and their files.
|
||||
Another possibility is to click on "Share" button inside a directory or a file for obtaining a tokenized link for single access to that resource, no matter if logged or not.
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
- Files preview in portal
|
||||
- Allow to download folder in portal and create zip file with all content
|
||||
- Save in cache own_root directories and update in every create/write/unlink function
|
||||
- Add a migration procedure for converting an storage to attachment one for populating existing records with attachments as folders
|
||||
- Add a link from attachment view in chatter to linked documents
|
||||
- If Inherit permissions from related record (the inherit_access_from_parent_record field from storage) is changed when directories already exist, inconsistencies may occur because groups defined in the directories and subdirectories will still exist, all groups in these directories should be removed before changing.
|
||||
- Since portal users can read ``dms.storage`` records, if your module extends this model to another storage backend that needs using secrets, remember to forbid access to the secrets fields by other means. It would be nice to be able to remove that rule at some point.
|
||||
- Searchpanel in files: Highlight items (shading) without records when filtering something (by name for example).
|
||||
- Accessing the clipboard (for example copy share link of file/directory) is limited to secure connections. It also happens in any part of Odoo.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/dms/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||
`feedback <https://github.com/OCA/dms/issues/new?body=module:%20dms%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Do not contact contributors directly about support or help with technical issues.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
* MuK IT
|
||||
* Tecnativa
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Mathias Markl <mathias.markl@mukit.at>
|
||||
* Enric Tobella <etobella@creublanca.es>
|
||||
* Antoni Romera
|
||||
* Gelu Boros <gelu.boros@rgbconsulting.com>
|
||||
|
||||
* `Tecnativa <https://www.tecnativa.com>`_:
|
||||
|
||||
* Víctor Martínez
|
||||
* Pedro M. Baeza
|
||||
* Jairo Llopis
|
||||
|
||||
* `Elego <https://www.elegosoft.com>`_:
|
||||
|
||||
* Yu Weng <yweng@elegosoft.com>
|
||||
* Philip Witte <phillip.witte@elegosoft.com>
|
||||
* Khanh Bui <khanh.bui@mail.elegosoft.com>
|
||||
|
||||
Other credits
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The migration of this module from 15.0 to 16.0 was financially supported by `AgentERP <https://www.agenterp.com>`_
|
||||
|
||||
Some pictures are based on or inspired by:
|
||||
|
||||
* `Roundicons <https://www.flaticon.com/authors/roundicons>`_
|
||||
* `Smashicons <https://www.flaticon.com/authors/smashicons>`_
|
||||
|
||||
Maintainers
|
||||
~~~~~~~~~~~
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
This module is part of the `OCA/dms <https://github.com/OCA/dms/tree/16.0/dms>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
3
odoo-bringout-oca-dms-dms/dms/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from . import controllers
|
||||
from . import models
|
||||
from . import wizards
|
||||
60
odoo-bringout-oca-dms-dms/dms/__manifest__.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
{
|
||||
"name": "Document Management System",
|
||||
"summary": """Document Management System for Odoo""",
|
||||
"version": "16.0.1.8.6",
|
||||
"category": "Document Management",
|
||||
"license": "LGPL-3",
|
||||
"website": "https://github.com/OCA/dms",
|
||||
"author": "MuK IT, Tecnativa, Odoo Community Association (OCA)",
|
||||
"depends": [
|
||||
"mail",
|
||||
"http_routing",
|
||||
"portal",
|
||||
"base",
|
||||
],
|
||||
"data": [
|
||||
"security/security.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"actions/file.xml",
|
||||
"template/onboarding.xml",
|
||||
"views/menu.xml",
|
||||
"views/tag.xml",
|
||||
"views/category.xml",
|
||||
"views/dms_file.xml",
|
||||
"views/directory.xml",
|
||||
"views/storage.xml",
|
||||
"views/dms_access_groups_views.xml",
|
||||
"views/res_config_settings.xml",
|
||||
"views/dms_portal_templates.xml",
|
||||
"wizards/wizard_dms_file_move_views.xml",
|
||||
"wizards/wizard_dms_share_views.xml",
|
||||
],
|
||||
"assets": {
|
||||
"mail.assets_messaging": [
|
||||
("include", "mail.assets_core_messaging"),
|
||||
"dms/static/src/models/*.js",
|
||||
],
|
||||
"web.assets_backend": [
|
||||
"dms/static/src/scss/*",
|
||||
"dms/static/src/js/fields/*",
|
||||
"dms/static/src/js/views/*.esm.js",
|
||||
"dms/static/src/js/views/*.xml",
|
||||
"dms/static/src/js/views/fields/binary/*",
|
||||
],
|
||||
"web.assets_frontend": ["dms/static/src/js/dms_portal_tour.js"],
|
||||
},
|
||||
"demo": [
|
||||
"demo/res_users.xml",
|
||||
"demo/access_group.xml",
|
||||
"demo/category.xml",
|
||||
"demo/tag.xml",
|
||||
"demo/storage.xml",
|
||||
"demo/directory.xml",
|
||||
"demo/file.xml",
|
||||
],
|
||||
"images": ["static/description/banner.png"],
|
||||
"application": True,
|
||||
}
|
||||
16
odoo-bringout-oca-dms-dms/dms/actions/file.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo>
|
||||
<record id="action_dms_attachment_migrate" model="ir.actions.server">
|
||||
<field name="name">Migrate</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="binding_model_id" ref="dms.model_dms_file" />
|
||||
<field name="state">code</field>
|
||||
<field name="code">records.action_migrate()</field>
|
||||
</record>
|
||||
</odoo>
|
||||
2
odoo-bringout-oca-dms-dms/dms/controllers/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from . import main
|
||||
from . import portal
|
||||
49
odoo-bringout-oca-dms-dms/dms/controllers/main.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class OnboardingController(http.Controller):
|
||||
@http.route("/dms/document_onboarding/directory", auth="user", type="json")
|
||||
def document_onboarding_directory(self):
|
||||
company = request.env.user.company_id
|
||||
closed = company.documents_onboarding_state == "closed"
|
||||
check = request.env.user.has_group("dms.group_dms_manager")
|
||||
if check and not closed:
|
||||
return {
|
||||
"html": request.env["ir.qweb"]._render(
|
||||
request.env.ref("dms.document_onboarding_directory_panel").id,
|
||||
{
|
||||
"state": company.get_and_update_documents_onboarding_state(),
|
||||
"company": company,
|
||||
},
|
||||
)
|
||||
}
|
||||
return {}
|
||||
|
||||
@http.route("/dms/document_onboarding/file", auth="user", type="json")
|
||||
def document_onboarding_file(self):
|
||||
company = request.env.user.company_id
|
||||
closed = company.documents_onboarding_state == "closed"
|
||||
check = request.env.user.has_group("dms.group_dms_manager")
|
||||
if check and not closed:
|
||||
return {
|
||||
"html": request.env["ir.qweb"]._render(
|
||||
request.env.ref("dms.document_onboarding_file_panel").id,
|
||||
{
|
||||
"state": company.get_and_update_documents_onboarding_state(),
|
||||
"company": company,
|
||||
},
|
||||
)
|
||||
}
|
||||
return {}
|
||||
|
||||
@http.route("/config/dms.forbidden_extensions", type="json", auth="user")
|
||||
def forbidden_extensions(self, **_kwargs):
|
||||
params = request.env["ir.config_parameter"].sudo()
|
||||
return {
|
||||
"forbidden_extensions": params.get_param(
|
||||
"dms.forbidden_extensions", default=""
|
||||
)
|
||||
}
|
||||
202
odoo-bringout-oca-dms-dms/dms/controllers/portal.py
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
# Copyright 2020-2021 Tecnativa - Víctor Martínez
|
||||
import base64
|
||||
|
||||
from odoo import _, http
|
||||
from odoo.http import content_disposition, request
|
||||
from odoo.osv.expression import OR
|
||||
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal
|
||||
from odoo.addons.web.controllers.utils import ensure_db
|
||||
|
||||
|
||||
class CustomerPortal(CustomerPortal):
|
||||
def _dms_check_access(self, model, res_id, access_token=None):
|
||||
item = request.env[model].browse(res_id)
|
||||
if access_token:
|
||||
item = item.sudo()
|
||||
if not item.check_access_token(access_token):
|
||||
return False
|
||||
else:
|
||||
if not item.permission_read:
|
||||
return False
|
||||
return item
|
||||
|
||||
def _prepare_home_portal_values(self, counters):
|
||||
values = super()._prepare_home_portal_values(counters)
|
||||
if "dms_directory_count" in counters:
|
||||
ids = request.env["dms.directory"]._get_own_root_directories()
|
||||
values["dms_directory_count"] = len(ids)
|
||||
return values
|
||||
|
||||
@http.route(["/my/dms"], type="http", auth="user", website=True)
|
||||
def portal_my_dms(
|
||||
self, sortby=None, filterby=None, search=None, search_in="name", **kw
|
||||
):
|
||||
values = self._prepare_portal_layout_values()
|
||||
searchbar_sortings = {"name": {"label": _("Name"), "order": "name asc"}}
|
||||
# default sortby br
|
||||
if not sortby:
|
||||
sortby = "name"
|
||||
sort_br = searchbar_sortings[sortby]["order"]
|
||||
# search
|
||||
searchbar_inputs = {
|
||||
"name": {"input": "name", "label": _("Name")},
|
||||
}
|
||||
if not filterby:
|
||||
filterby = "name"
|
||||
# domain
|
||||
domain = [
|
||||
(
|
||||
"id",
|
||||
"in",
|
||||
request.env["dms.directory"]._get_own_root_directories(),
|
||||
)
|
||||
]
|
||||
# search
|
||||
if search and search_in:
|
||||
search_domain = []
|
||||
if search_in == "name":
|
||||
search_domain = OR([search_domain, [("name", "ilike", search)]])
|
||||
domain += search_domain
|
||||
# content according to pager and archive selected
|
||||
items = request.env["dms.directory"].search(domain, order=sort_br)
|
||||
request.session["my_dms_folder_history"] = items.ids
|
||||
# values
|
||||
values.update(
|
||||
{
|
||||
"dms_directories": items,
|
||||
"page_name": "dms_directory",
|
||||
"default_url": "/my/dms",
|
||||
"searchbar_sortings": searchbar_sortings,
|
||||
"searchbar_inputs": searchbar_inputs,
|
||||
"search_in": search_in,
|
||||
"sortby": sortby,
|
||||
"filterby": filterby,
|
||||
"access_token": None,
|
||||
}
|
||||
)
|
||||
return request.render("dms.portal_my_dms", values)
|
||||
|
||||
@http.route(
|
||||
["/my/dms/directory/<int:dms_directory_id>"],
|
||||
type="http",
|
||||
auth="public",
|
||||
website=True,
|
||||
)
|
||||
def portal_my_dms_directory(
|
||||
self,
|
||||
dms_directory_id=False,
|
||||
sortby=None,
|
||||
filterby=None,
|
||||
search=None,
|
||||
search_in="name",
|
||||
access_token=None,
|
||||
**kw
|
||||
):
|
||||
ensure_db()
|
||||
# operations
|
||||
searchbar_sortings = {"name": {"label": _("Name"), "order": "name asc"}}
|
||||
# default sortby br
|
||||
if not sortby:
|
||||
sortby = "name"
|
||||
sort_br = searchbar_sortings[sortby]["order"]
|
||||
# search
|
||||
searchbar_inputs = {
|
||||
"name": {"input": "name", "label": _("Name")},
|
||||
}
|
||||
if not filterby:
|
||||
filterby = "name"
|
||||
# domain
|
||||
domain = [("is_hidden", "=", False), ("parent_id", "=", dms_directory_id)]
|
||||
# search
|
||||
if search and search_in:
|
||||
search_domain = []
|
||||
if search_in == "name":
|
||||
search_domain = OR([search_domain, [("name", "ilike", search)]])
|
||||
domain += search_domain
|
||||
# content according to pager and archive selected
|
||||
if access_token:
|
||||
dms_directory_items = (
|
||||
request.env["dms.directory"].sudo().search(domain, order=sort_br)
|
||||
)
|
||||
else:
|
||||
dms_directory_items = request.env["dms.directory"].search(
|
||||
domain, order=sort_br
|
||||
)
|
||||
request.session["my_dms_folder_history"] = dms_directory_items.ids
|
||||
res = self._dms_check_access("dms.directory", dms_directory_id, access_token)
|
||||
if not res:
|
||||
if access_token:
|
||||
return request.redirect("/")
|
||||
else:
|
||||
return request.redirect("/my")
|
||||
dms_directory_sudo = res
|
||||
# dms_files_count
|
||||
domain = [
|
||||
("is_hidden", "=", False),
|
||||
("directory_id", "=", dms_directory_id),
|
||||
]
|
||||
# search
|
||||
if search and search_in:
|
||||
search_domain = []
|
||||
if search_in == "name":
|
||||
search_domain = OR([search_domain, [("name", "ilike", search)]])
|
||||
domain += search_domain
|
||||
# items
|
||||
if access_token:
|
||||
dms_file_items = (
|
||||
request.env["dms.file"].sudo().search(domain, order=sort_br)
|
||||
)
|
||||
else:
|
||||
dms_file_items = request.env["dms.file"].search(domain, order=sort_br)
|
||||
request.session["my_dms_file_history"] = dms_file_items.ids
|
||||
dms_parent_categories = dms_directory_sudo.sudo()._get_parent_categories(
|
||||
access_token
|
||||
)
|
||||
# values
|
||||
values = {
|
||||
"dms_directories": dms_directory_items,
|
||||
"page_name": "dms_directory",
|
||||
"default_url": "/my/dms",
|
||||
"searchbar_sortings": searchbar_sortings,
|
||||
"searchbar_inputs": searchbar_inputs,
|
||||
"search_in": search_in,
|
||||
"sortby": sortby,
|
||||
"filterby": filterby,
|
||||
"access_token": access_token,
|
||||
"dms_directory": dms_directory_sudo,
|
||||
"dms_files": dms_file_items,
|
||||
"dms_parent_categories": dms_parent_categories,
|
||||
}
|
||||
return request.render("dms.portal_my_dms", values)
|
||||
|
||||
@http.route(
|
||||
["/my/dms/file/<int:dms_file_id>/download"],
|
||||
type="http",
|
||||
auth="public",
|
||||
website=True,
|
||||
)
|
||||
def portal_my_dms_file_download(self, dms_file_id, access_token=None, **kw):
|
||||
"""Process user's consent acceptance or rejection."""
|
||||
ensure_db()
|
||||
# operations
|
||||
res = self._dms_check_access("dms.file", dms_file_id, access_token)
|
||||
if not res:
|
||||
if access_token:
|
||||
return request.redirect("/")
|
||||
else:
|
||||
return request.redirect("/my")
|
||||
|
||||
dms_file_sudo = res
|
||||
# It's necessary to prevent AccessError in ir_attachment .check() function
|
||||
if dms_file_sudo.attachment_id and request.env.user.has_group(
|
||||
"base.group_portal"
|
||||
):
|
||||
dms_file_sudo = dms_file_sudo.sudo()
|
||||
filecontent = base64.b64decode(dms_file_sudo.content)
|
||||
content_type = ["Content-Type", "application/octet-stream"]
|
||||
disposition_content = [
|
||||
"Content-Disposition",
|
||||
content_disposition(dms_file_sudo.name),
|
||||
]
|
||||
return request.make_response(filecontent, [content_type, disposition_content])
|
||||
24
odoo-bringout-oca-dms-dms/dms/demo/access_group.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="1">
|
||||
<record id="access_group_01_demo" model="dms.access.group">
|
||||
<field name="name">Admin</field>
|
||||
<field name="perm_create">True</field>
|
||||
<field name="perm_write">True</field>
|
||||
<field name="perm_unlink">True</field>
|
||||
<field
|
||||
name="explicit_user_ids"
|
||||
eval="[(6, 0, [ref('base.user_admin'), ref('base.user_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="access_group_02_demo" model="dms.access.group">
|
||||
<field name="name">Portal</field>
|
||||
<field name="group_ids" eval="[(6, 0, [ref('base.group_portal')])]" />
|
||||
</record>
|
||||
<record id="access_group_03_demo" model="dms.access.group">
|
||||
<field name="name">Only admin user</field>
|
||||
<field name="perm_create">True</field>
|
||||
<field name="perm_write">True</field>
|
||||
<field name="perm_unlink">True</field>
|
||||
<field name="explicit_user_ids" eval="[(6, 0, [ref('base.user_admin')])]" />
|
||||
</record>
|
||||
</odoo>
|
||||
31
odoo-bringout-oca-dms-dms/dms/demo/category.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="category_01_demo" model="dms.category">
|
||||
<field name="name">Internal</field>
|
||||
</record>
|
||||
<record id="category_02_demo" model="dms.category">
|
||||
<field name="name">Human Resource</field>
|
||||
<field name="parent_id" ref="dms.category_01_demo" />
|
||||
</record>
|
||||
<record id="category_03_demo" model="dms.category">
|
||||
<field name="name">Contracts</field>
|
||||
<field name="parent_id" ref="dms.category_02_demo" />
|
||||
</record>
|
||||
<record id="category_04_demo" model="dms.category">
|
||||
<field name="name">Traveling</field>
|
||||
<field name="parent_id" ref="dms.category_02_demo" />
|
||||
</record>
|
||||
<record id="category_05_demo" model="dms.category">
|
||||
<field name="name">External</field>
|
||||
</record>
|
||||
<record id="category_06_demo" model="dms.category">
|
||||
<field name="name">News</field>
|
||||
<field name="parent_id" ref="dms.category_05_demo" />
|
||||
</record>
|
||||
</odoo>
|
||||
147
odoo-bringout-oca-dms-dms/dms/demo/directory.xml
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="directory_01_demo" model="dms.directory">
|
||||
<field name="name">Documents</field>
|
||||
<field name="is_root_directory" eval="True" />
|
||||
<field name="parent_id" eval="False" />
|
||||
<field name="color" eval="1" />
|
||||
<field name="storage_id" ref="dms.storage_demo" />
|
||||
<field name="category_id" ref="dms.category_01_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_05_demo')])]"
|
||||
/>
|
||||
<field name="group_ids" eval="[(6, 0, [ref('dms.access_group_01_demo')])]" />
|
||||
</record>
|
||||
<record id="directory_02_demo" model="dms.directory">
|
||||
<field name="name">Media</field>
|
||||
<field name="is_root_directory" eval="True" />
|
||||
<field name="parent_id" eval="False" />
|
||||
<field name="color" eval="2" />
|
||||
<field name="storage_id" ref="dms.storage_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
<field name="group_ids" eval="[(6, 0, [ref('dms.access_group_01_demo')])]" />
|
||||
</record>
|
||||
<record id="directory_03_demo" model="dms.directory">
|
||||
<field name="name">Sheets</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="1" />
|
||||
<field name="parent_id" ref="dms.directory_01_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_04_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="directory_04_demo" model="dms.directory">
|
||||
<field name="name">Templates</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="1" />
|
||||
<field name="parent_id" ref="dms.directory_01_demo" />
|
||||
<field name="category_id" ref="dms.category_01_demo" />
|
||||
<field name="tag_ids" eval="[(6, 0, [ref('dms.tag_07_demo')])]" />
|
||||
</record>
|
||||
<record id="directory_05_demo" model="dms.directory">
|
||||
<field name="name">Photos</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="2" />
|
||||
<field name="category_id" ref="dms.category_02_demo" />
|
||||
<field name="parent_id" ref="dms.directory_02_demo" />
|
||||
<field
|
||||
name="group_ids"
|
||||
eval="[(6, 0, [ref('dms.access_group_01_demo'), ref('dms.access_group_02_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="directory_06_demo" model="dms.directory">
|
||||
<field name="name">2017</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="2" />
|
||||
<field name="parent_id" ref="dms.directory_05_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_02_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="directory_07_demo" model="dms.directory">
|
||||
<field name="name">2018</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="2" />
|
||||
<field name="parent_id" ref="dms.directory_05_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_02_demo'), ref('dms.tag_06_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="directory_08_demo" model="dms.directory">
|
||||
<field name="name">Videos</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="2" />
|
||||
<field name="parent_id" ref="dms.directory_02_demo" />
|
||||
</record>
|
||||
<record id="directory_09_demo" model="dms.directory">
|
||||
<field name="name">Music</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="2" />
|
||||
<field name="parent_id" ref="dms.directory_02_demo" />
|
||||
</record>
|
||||
<record id="directory_10_demo" model="dms.directory">
|
||||
<field name="name">Graphics</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="parent_id" ref="dms.directory_02_demo" />
|
||||
</record>
|
||||
<record id="directory_11_demo" model="dms.directory">
|
||||
<field name="name">Mails</field>
|
||||
<field name="is_root_directory" eval="True" />
|
||||
<field name="parent_id" eval="False" />
|
||||
<field name="color" eval="3" />
|
||||
<field name="storage_id" ref="dms.storage_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_04_demo'), ref('dms.tag_05_demo')])]"
|
||||
/>
|
||||
<field
|
||||
name="group_ids"
|
||||
eval="[(6, 0, [ref('dms.access_group_01_demo'), ref('dms.access_group_02_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="directory_12_demo" model="dms.directory">
|
||||
<field name="name">Data</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="1" />
|
||||
<field name="parent_id" ref="dms.directory_01_demo" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_06_demo'), ref('dms.tag_07_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="directory_13_demo" model="dms.directory">
|
||||
<field name="name">Code</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="color" eval="1" />
|
||||
<field name="category_id" ref="dms.category_01_demo" />
|
||||
<field name="parent_id" ref="dms.directory_01_demo" />
|
||||
</record>
|
||||
<record id="directory_14_demo" model="dms.directory">
|
||||
<field name="name">Slides</field>
|
||||
<field name="is_root_directory" eval="False" />
|
||||
<field name="category_id" ref="dms.category_01_demo" />
|
||||
<field name="parent_id" ref="dms.directory_01_demo" />
|
||||
</record>
|
||||
<record id="directory_root_res_partner_demo" model="dms.directory">
|
||||
<field name="name">Partners</field>
|
||||
<field name="is_root_directory" eval="True" />
|
||||
<field name="color" eval="1" />
|
||||
<field name="storage_id" ref="dms.storage_attachment_demo" />
|
||||
<field name="category_id" ref="dms.category_01_demo" />
|
||||
<field name="model_id" ref="base.model_res_partner" />
|
||||
<field name="res_model">res.partner</field>
|
||||
</record>
|
||||
</odoo>
|
||||
241
odoo-bringout-oca-dms-dms/dms/demo/file.xml
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="file_01_demo" model="dms.file">
|
||||
<field name="name">Sydney.jpg</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_06_demo" />
|
||||
<field name="content" type="base64" file="dms/test/image01.jpg" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_05_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_02_demo" model="dms.file">
|
||||
<field name="name">Logo_01.jpg</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_07_demo" />
|
||||
<field name="content" type="base64" file="dms/test/image02.jpg" />
|
||||
</record>
|
||||
<record id="file_03_demo" model="dms.file">
|
||||
<field name="name">Logo_02.jpg</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_07_demo" />
|
||||
<field name="category_id" ref="dms.category_02_demo" />
|
||||
<field name="content" type="base64" file="dms/test/image03.jpg" />
|
||||
</record>
|
||||
<record id="file_04_demo" model="dms.file">
|
||||
<field name="name">Logo_03.jpg</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_07_demo" />
|
||||
<field name="content" type="base64" file="dms/test/image04.jpg" />
|
||||
</record>
|
||||
<record id="file_05_demo" model="dms.file">
|
||||
<field name="name">Logo.svg</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_10_demo" />
|
||||
<field name="category_id" ref="dms.category_03_demo" />
|
||||
<field name="content" type="base64" file="dms/test/vector.svg" />
|
||||
</record>
|
||||
<record id="file_06_demo" model="dms.file">
|
||||
<field name="name">Loop_01.wav</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_09_demo" />
|
||||
<field name="content" type="base64" file="dms/test/audio01.wav" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_07_demo" model="dms.file">
|
||||
<field name="name">Loop_02.wav</field>
|
||||
<field name="color" eval="2" />
|
||||
<field name="directory_id" ref="dms.directory_09_demo" />
|
||||
<field name="content" type="base64" file="dms/test/audio02.wav" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_08_demo" model="dms.file">
|
||||
<field name="name">Loop_03.mp3</field>
|
||||
<field name="color" eval="2" />
|
||||
<field name="directory_id" ref="dms.directory_09_demo" />
|
||||
<field name="content" type="base64" file="dms/test/audio03.mp3" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_09_demo" model="dms.file">
|
||||
<field name="name">Loop_04.mp3</field>
|
||||
<field name="color" eval="2" />
|
||||
<field name="directory_id" ref="dms.directory_09_demo" />
|
||||
<field name="content" type="base64" file="dms/test/audio04.mp3" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_01_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_10_demo" model="dms.file">
|
||||
<field name="name">Video.mp4</field>
|
||||
<field name="color" eval="3" />
|
||||
<field name="directory_id" ref="dms.directory_08_demo" />
|
||||
<field name="content" type="base64" file="dms/test/video.mp4" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_02_demo'), ref('dms.tag_03_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_11_demo" model="dms.file">
|
||||
<field name="name">Mail_01.eml</field>
|
||||
<field name="color" eval="4" />
|
||||
<field name="directory_id" ref="dms.directory_11_demo" />
|
||||
<field name="content" type="base64" file="dms/test/mail01.eml" />
|
||||
<field name="category_id" ref="dms.category_03_demo" />
|
||||
</record>
|
||||
<record id="file_12_demo" model="dms.file">
|
||||
<field name="name">Mail_02.eml</field>
|
||||
<field name="color" eval="4" />
|
||||
<field name="directory_id" ref="dms.directory_11_demo" />
|
||||
<field name="content" type="base64" file="dms/test/mail02.eml" />
|
||||
</record>
|
||||
<record id="file_13_demo" model="dms.file">
|
||||
<field name="name">Text.txt</field>
|
||||
<field name="directory_id" ref="dms.directory_12_demo" />
|
||||
<field name="content" type="base64" file="dms/test/text.txt" />
|
||||
<field
|
||||
name="tag_ids"
|
||||
eval="[(6, 0, [ref('dms.tag_05_demo'), ref('dms.tag_06_demo')])]"
|
||||
/>
|
||||
</record>
|
||||
<record id="file_14_demo" model="dms.file">
|
||||
<field name="name">ASPECTJ.aj</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code01.aj" />
|
||||
<field name="category_id" ref="dms.category_01_demo" />
|
||||
</record>
|
||||
<record id="file_15_demo" model="dms.file">
|
||||
<field name="name">Bash.sh</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code02.sh" />
|
||||
</record>
|
||||
<record id="file_16_demo" model="dms.file">
|
||||
<field name="name">C.c</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code03.c" />
|
||||
</record>
|
||||
<record id="file_17_demo" model="dms.file">
|
||||
<field name="name">Cplusplus.cc</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code04.cc" />
|
||||
</record>
|
||||
<record id="file_18_demo" model="dms.file">
|
||||
<field name="name">CSharp.cs</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code05.cs" />
|
||||
</record>
|
||||
<record id="file_19_demo" model="dms.file">
|
||||
<field name="name">COBOL.cbl</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code06.cbl" />
|
||||
</record>
|
||||
<record id="file_20_demo" model="dms.file">
|
||||
<field name="name">CoffeeScript.coffee</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code07.coffee" />
|
||||
</record>
|
||||
<record id="file_21_demo" model="dms.file">
|
||||
<field name="name">Fortran.f</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code08.f" />
|
||||
</record>
|
||||
<record id="file_22_demo" model="dms.file">
|
||||
<field name="name">Go.go</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code09.go" />
|
||||
</record>
|
||||
<record id="file_23_demo" model="dms.file">
|
||||
<field name="name">Groovy.groovy</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code10.groovy" />
|
||||
</record>
|
||||
<record id="file_24_demo" model="dms.file">
|
||||
<field name="name">Java.java</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code11.java" />
|
||||
</record>
|
||||
<record id="file_25_demo" model="dms.file">
|
||||
<field name="name">Scala.sc</field>
|
||||
<field name="directory_id" ref="dms.directory_13_demo" />
|
||||
<field name="content" type="base64" file="dms/test/code12.sc" />
|
||||
</record>
|
||||
<record id="file_26_demo" model="dms.file">
|
||||
<field name="name">Sample.md</field>
|
||||
<field name="directory_id" ref="dms.directory_04_demo" />
|
||||
<field name="content" type="base64" file="dms/test/markdown.md" />
|
||||
</record>
|
||||
<record id="file_27_demo" model="dms.file">
|
||||
<field name="name">Document_05.pdf</field>
|
||||
<field name="color" eval="1" />
|
||||
<field name="directory_id" ref="dms.directory_12_demo" />
|
||||
<field name="content" type="base64" file="dms/test/document01.pdf" />
|
||||
</record>
|
||||
<record id="file_28_demo" model="dms.file">
|
||||
<field name="name">Slide_01.odp</field>
|
||||
<field name="directory_id" ref="dms.directory_14_demo" />
|
||||
<field name="content" type="base64" file="dms/test/slide01.odp" />
|
||||
</record>
|
||||
<record id="file_29_demo" model="dms.file">
|
||||
<field name="name">Slide_02.ppt</field>
|
||||
<field name="directory_id" ref="dms.directory_14_demo" />
|
||||
<field name="content" type="base64" file="dms/test/slide02.ppt" />
|
||||
</record>
|
||||
<record id="file_30_demo" model="dms.file">
|
||||
<field name="name">Document_02.doc</field>
|
||||
<field name="color" eval="5" />
|
||||
<field name="directory_id" ref="dms.directory_12_demo" />
|
||||
<field name="content" type="base64" file="dms/test/document02.doc" />
|
||||
</record>
|
||||
<record id="file_31_demo" model="dms.file">
|
||||
<field name="name">Document_03.odt</field>
|
||||
<field name="color" eval="5" />
|
||||
<field name="directory_id" ref="dms.directory_12_demo" />
|
||||
<field name="content" type="base64" file="dms/test/document03.odt" />
|
||||
</record>
|
||||
<record id="file_32_demo" model="dms.file">
|
||||
<field name="name">Sheet_01.xls</field>
|
||||
<field name="color" eval="6" />
|
||||
<field name="directory_id" ref="dms.directory_03_demo" />
|
||||
<field name="content" type="base64" file="dms/test/sheet01.xls" />
|
||||
</record>
|
||||
<record id="file_33_demo" model="dms.file">
|
||||
<field name="name">Sheet_02.csv</field>
|
||||
<field name="color" eval="6" />
|
||||
<field name="directory_id" ref="dms.directory_03_demo" />
|
||||
<field name="content" type="base64" file="dms/test/sheet02.csv" />
|
||||
</record>
|
||||
<record id="file_34_demo" model="dms.file">
|
||||
<field name="name">Sheet_03.ods</field>
|
||||
<field name="color" eval="6" />
|
||||
<field name="directory_id" ref="dms.directory_03_demo" />
|
||||
<field name="content" type="base64" file="dms/test/sheet03.ods" />
|
||||
</record>
|
||||
<record id="file_35_demo" model="dms.file">
|
||||
<field name="name">Document_04.rtf</field>
|
||||
<field name="color" eval="6" />
|
||||
<field name="directory_id" ref="dms.directory_03_demo" />
|
||||
<field name="content" type="base64" file="dms/test/document04.rtf" />
|
||||
</record>
|
||||
<record id="file_36_demo" model="dms.file">
|
||||
<field name="name">Text.rst</field>
|
||||
<field name="color" eval="3" />
|
||||
<field name="directory_id" ref="dms.directory_02_demo" />
|
||||
<field name="content" type="base64" file="dms/test/text.rst" />
|
||||
</record>
|
||||
</odoo>
|
||||
12
odoo-bringout-oca-dms-dms/dms/demo/res_users.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field eval="[(4, ref('dms.group_dms_user'))]" name="groups_id" />
|
||||
</record>
|
||||
</odoo>
|
||||
20
odoo-bringout-oca-dms-dms/dms/demo/storage.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="storage_demo" model="dms.storage">
|
||||
<field name="name">Documents Storage</field>
|
||||
<field name="save_type">database</field>
|
||||
</record>
|
||||
<record id="storage_attachment_demo" model="dms.storage">
|
||||
<field name="name">Attachment Storage</field>
|
||||
<field name="save_type">attachment</field>
|
||||
<field name="inherit_access_from_parent_record" eval="True" />
|
||||
<field name="include_message_attachments" eval="True" />
|
||||
<field name="model_ids" eval="[(6, 0, [ref('base.model_res_partner')])]" />
|
||||
</record>
|
||||
</odoo>
|
||||
64
odoo-bringout-oca-dms-dms/dms/demo/tag.xml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
<record id="tag_01_demo" model="dms.tag">
|
||||
<field name="name">Customer</field>
|
||||
<field name="color">1</field>
|
||||
<field name="category_id" ref="category_03_demo" />
|
||||
</record>
|
||||
<record id="tag_02_demo" model="dms.tag">
|
||||
<field name="name">Partner</field>
|
||||
<field name="color">2</field>
|
||||
<field name="category_id" ref="category_03_demo" />
|
||||
</record>
|
||||
<record id="tag_03_demo" model="dms.tag">
|
||||
<field name="name">Project</field>
|
||||
<field name="color">3</field>
|
||||
<field name="category_id" ref="category_04_demo" />
|
||||
</record>
|
||||
<record id="tag_04_demo" model="dms.tag">
|
||||
<field name="name">Sales</field>
|
||||
<field name="color">4</field>
|
||||
<field name="category_id" ref="category_05_demo" />
|
||||
</record>
|
||||
<record id="tag_05_demo" model="dms.tag">
|
||||
<field name="name">Portal</field>
|
||||
<field name="color">5</field>
|
||||
<field name="category_id" ref="category_05_demo" />
|
||||
</record>
|
||||
<record id="tag_06_demo" model="dms.tag">
|
||||
<field name="name">Apps</field>
|
||||
<field name="color">6</field>
|
||||
<field name="category_id" ref="category_05_demo" />
|
||||
</record>
|
||||
<record id="tag_07_demo" model="dms.tag">
|
||||
<field name="name">Accounting</field>
|
||||
<field name="color">7</field>
|
||||
<field name="category_id" ref="category_05_demo" />
|
||||
</record>
|
||||
<record id="tag_08_demo" model="dms.tag">
|
||||
<field name="name">Customer Invoice</field>
|
||||
<field name="color">8</field>
|
||||
<field name="category_id" ref="category_05_demo" />
|
||||
</record>
|
||||
<record id="tag_09_demo" model="dms.tag">
|
||||
<field name="name">Vendor Bill</field>
|
||||
<field name="color">9</field>
|
||||
<field name="category_id" ref="category_05_demo" />
|
||||
</record>
|
||||
<record id="tag_10_demo" model="dms.tag">
|
||||
<field name="name">Product</field>
|
||||
<field name="color">10</field>
|
||||
<field name="category_id" ref="category_06_demo" />
|
||||
</record>
|
||||
<record id="tag_11_demo" model="dms.tag">
|
||||
<field name="name">Contract</field>
|
||||
<field name="color">11</field>
|
||||
<field name="category_id" ref="category_01_demo" />
|
||||
</record>
|
||||
</odoo>
|
||||
2276
odoo-bringout-oca-dms-dms/dms/i18n/bs.po
Normal file
2298
odoo-bringout-oca-dms-dms/dms/i18n/ca.po
Normal file
2404
odoo-bringout-oca-dms-dms/dms/i18n/de.po
Normal file
2276
odoo-bringout-oca-dms-dms/dms/i18n/dms.pot
Normal file
2401
odoo-bringout-oca-dms-dms/dms/i18n/es.po
Normal file
2406
odoo-bringout-oca-dms-dms/dms/i18n/fa.po
Normal file
2277
odoo-bringout-oca-dms-dms/dms/i18n/fa_IR.po
Normal file
2469
odoo-bringout-oca-dms-dms/dms/i18n/fr.po
Normal file
2380
odoo-bringout-oca-dms-dms/dms/i18n/he_IL.po
Normal file
2402
odoo-bringout-oca-dms-dms/dms/i18n/it.po
Normal file
2282
odoo-bringout-oca-dms-dms/dms/i18n/nl.po
Normal file
2396
odoo-bringout-oca-dms-dms/dms/i18n/pt.po
Normal file
2400
odoo-bringout-oca-dms-dms/dms/i18n/pt_BR.po
Normal file
2281
odoo-bringout-oca-dms-dms/dms/i18n/ru.po
Normal file
17
odoo-bringout-oca-dms-dms/dms/models/__init__.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
from . import access_groups
|
||||
from . import base
|
||||
from . import mixins_thumbnail
|
||||
from . import dms_security_mixin
|
||||
from . import abstract_dms_mixin
|
||||
|
||||
from . import storage
|
||||
from . import directory
|
||||
from . import dms_file
|
||||
|
||||
from . import category
|
||||
from . import tag
|
||||
|
||||
from . import res_company
|
||||
from . import res_config_settings
|
||||
from . import ir_attachment
|
||||
from . import mail_thread
|
||||
57
odoo-bringout-oca-dms-dms/dms/models/abstract_dms_mixin.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class AbstractDmsMixin(models.AbstractModel):
|
||||
_name = "abstract.dms.mixin"
|
||||
_description = "Abstract Dms Mixin"
|
||||
|
||||
name = fields.Char(required=True, index="btree")
|
||||
# Only defined to prevent error in other fields that related it
|
||||
storage_id = fields.Many2one(
|
||||
comodel_name="dms.storage", string="Storage", store=True, copy=True
|
||||
)
|
||||
is_hidden = fields.Boolean(
|
||||
string="Storage is Hidden",
|
||||
related="storage_id.is_hidden",
|
||||
readonly=True,
|
||||
store=True,
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
related="storage_id.company_id",
|
||||
comodel_name="res.company",
|
||||
string="Company",
|
||||
readonly=True,
|
||||
store=True,
|
||||
index="btree",
|
||||
)
|
||||
storage_id_save_type = fields.Selection(related="storage_id.save_type", store=False)
|
||||
color = fields.Integer(default=0)
|
||||
category_id = fields.Many2one(
|
||||
comodel_name="dms.category",
|
||||
context="{'dms_category_show_path': True}",
|
||||
string="Category",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def search_panel_select_range(self, field_name, **kwargs):
|
||||
"""Add context to display short folder name."""
|
||||
_self = self.with_context(
|
||||
directory_short_name=True, skip_sanitized_parent_hierarchy=True
|
||||
)
|
||||
return super(AbstractDmsMixin, _self).search_panel_select_range(
|
||||
field_name, **kwargs
|
||||
)
|
||||
|
||||
def _search_panel_sanitized_parent_hierarchy(self, records, parent_name, ids):
|
||||
if self.env.context.get("skip_sanitized_parent_hierarchy"):
|
||||
all_ids = [value["id"] for value in records]
|
||||
# Prevent error if user not access to parent record
|
||||
for value in records:
|
||||
if value["parent_id"] and value["parent_id"][0] not in all_ids:
|
||||
value["parent_id"] = False
|
||||
return records
|
||||
return super()._search_panel_sanitized_parent_hierarchy(
|
||||
records=records, parent_name=parent_name, ids=ids
|
||||
)
|
||||
169
odoo-bringout-oca-dms-dms/dms/models/access_groups.py
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# Copyright 2020 RGB Consulting
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class DmsAccessGroups(models.Model):
|
||||
_name = "dms.access.group"
|
||||
_description = "Record Access Groups"
|
||||
_parent_store = True
|
||||
_parent_name = "parent_group_id"
|
||||
|
||||
name = fields.Char(string="Group Name", required=True, translate=True)
|
||||
parent_path = fields.Char(index="btree", unaccent=False)
|
||||
|
||||
# Permissions written directly on this group
|
||||
perm_create = fields.Boolean(string="Create Access")
|
||||
perm_write = fields.Boolean(string="Write Access")
|
||||
perm_unlink = fields.Boolean(string="Unlink Access")
|
||||
|
||||
# Permissions computed including parent group
|
||||
perm_inclusive_create = fields.Boolean(
|
||||
string="Inherited Create Access",
|
||||
compute="_compute_inclusive_permissions",
|
||||
store=True,
|
||||
recursive=True,
|
||||
)
|
||||
perm_inclusive_write = fields.Boolean(
|
||||
string="Inherited Write Access",
|
||||
compute="_compute_inclusive_permissions",
|
||||
store=True,
|
||||
recursive=True,
|
||||
)
|
||||
perm_inclusive_unlink = fields.Boolean(
|
||||
string="Inherited Unlink Access",
|
||||
compute="_compute_inclusive_permissions",
|
||||
store=True,
|
||||
recursive=True,
|
||||
)
|
||||
|
||||
directory_ids = fields.Many2many(
|
||||
comodel_name="dms.directory",
|
||||
relation="dms_directory_groups_rel",
|
||||
string="Directories",
|
||||
column1="gid",
|
||||
column2="aid",
|
||||
auto_join=True,
|
||||
readonly=True,
|
||||
)
|
||||
complete_directory_ids = fields.Many2many(
|
||||
comodel_name="dms.directory",
|
||||
relation="dms_directory_complete_groups_rel",
|
||||
column1="gid",
|
||||
column2="aid",
|
||||
string="Complete directories",
|
||||
auto_join=True,
|
||||
readonly=True,
|
||||
)
|
||||
count_users = fields.Integer(compute="_compute_users", store=True)
|
||||
count_directories = fields.Integer(compute="_compute_count_directories")
|
||||
parent_group_id = fields.Many2one(
|
||||
comodel_name="dms.access.group",
|
||||
string="Parent Group",
|
||||
ondelete="cascade",
|
||||
index="btree",
|
||||
)
|
||||
|
||||
child_group_ids = fields.One2many(
|
||||
comodel_name="dms.access.group",
|
||||
inverse_name="parent_group_id",
|
||||
string="Child Groups",
|
||||
)
|
||||
group_ids = fields.Many2many(
|
||||
comodel_name="res.groups",
|
||||
relation="dms_access_group_groups_rel",
|
||||
column1="gid",
|
||||
column2="rid",
|
||||
string="Groups",
|
||||
)
|
||||
explicit_user_ids = fields.Many2many(
|
||||
comodel_name="res.users",
|
||||
relation="dms_access_group_explicit_users_rel",
|
||||
column1="gid",
|
||||
column2="uid",
|
||||
string="Explicit Users",
|
||||
)
|
||||
users = fields.Many2many(
|
||||
comodel_name="res.users",
|
||||
relation="dms_access_group_users_rel",
|
||||
column1="gid",
|
||||
column2="uid",
|
||||
string="Group Users",
|
||||
compute="_compute_users",
|
||||
auto_join=True,
|
||||
store=True,
|
||||
recursive=True,
|
||||
)
|
||||
|
||||
@api.depends("directory_ids")
|
||||
def _compute_count_directories(self):
|
||||
for record in self:
|
||||
record.count_directories = len(record.directory_ids)
|
||||
|
||||
_sql_constraints = [
|
||||
("name_uniq", "unique (name)", "The name of the group must be unique!")
|
||||
]
|
||||
|
||||
@api.depends(
|
||||
"parent_group_id.perm_inclusive_create",
|
||||
"parent_group_id.perm_inclusive_unlink",
|
||||
"parent_group_id.perm_inclusive_write",
|
||||
"parent_path",
|
||||
"perm_create",
|
||||
"perm_unlink",
|
||||
"perm_write",
|
||||
)
|
||||
def _compute_inclusive_permissions(self):
|
||||
"""Provide full permissions inheriting from parent recursively."""
|
||||
for one in self:
|
||||
one.update(
|
||||
{
|
||||
"perm_inclusive_%s"
|
||||
% perm: (
|
||||
one["perm_%s" % perm]
|
||||
or one.parent_group_id["perm_inclusive_%s" % perm]
|
||||
)
|
||||
for perm in ("create", "unlink", "write")
|
||||
}
|
||||
)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = super(DmsAccessGroups, self).default_get(fields_list)
|
||||
if "explicit_user_ids" in res and res["explicit_user_ids"]:
|
||||
res["explicit_user_ids"] = res["explicit_user_ids"] + [self.env.uid]
|
||||
else:
|
||||
res["explicit_user_ids"] = [(6, 0, [self.env.uid])]
|
||||
return res
|
||||
|
||||
@api.depends(
|
||||
"parent_group_id",
|
||||
"parent_group_id.users",
|
||||
"group_ids",
|
||||
"group_ids.users",
|
||||
"explicit_user_ids",
|
||||
)
|
||||
def _compute_users(self):
|
||||
for record in self:
|
||||
users = record.mapped("group_ids.users")
|
||||
users |= record.mapped("explicit_user_ids")
|
||||
users |= record.mapped("parent_group_id.users")
|
||||
record.update({"users": users, "count_users": len(users)})
|
||||
|
||||
@api.constrains("parent_path")
|
||||
def _check_parent_recursiveness(self):
|
||||
"""Forbid recursive relationships."""
|
||||
for one in self:
|
||||
if not one.parent_group_id:
|
||||
continue
|
||||
if str(one.id) in one.parent_path.split("/"):
|
||||
raise ValidationError(
|
||||
_("Parent group '%(parent)s' is child of '%(current)s'.")
|
||||
% {
|
||||
"parent": one.parent_group_id.display_name,
|
||||
"current": one.display_name,
|
||||
}
|
||||
)
|
||||
24
odoo-bringout-oca-dms-dms/dms/models/base.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2021 Tecnativa - Jairo Llopis
|
||||
# Copyright 2024 Tecnativa - Víctor Martínez
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class Base(models.AbstractModel):
|
||||
_inherit = "base"
|
||||
|
||||
def unlink(self):
|
||||
"""Cascade DMS related resources removal.
|
||||
Avoid executing in ir.* models (ir.mode, ir.model.fields, etc), in transient
|
||||
models and in the models we want to check."""
|
||||
result = super().unlink()
|
||||
if (
|
||||
not self._name.startswith("ir.")
|
||||
and not self.is_transient()
|
||||
and self._name not in ("dms.file", "dms.directory")
|
||||
):
|
||||
domain = [("res_model", "=", self._name), ("res_id", "in", self.ids)]
|
||||
self.env["dms.file"].sudo().search(domain).unlink()
|
||||
self.env["dms.directory"].sudo().search(domain).unlink()
|
||||
return result
|
||||
136
odoo-bringout-oca-dms-dms/dms/models/category.py
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# Copyright 2020 Creu Blanca
|
||||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
_name = "dms.category"
|
||||
_description = "Document Category"
|
||||
|
||||
_parent_store = True
|
||||
_parent_name = "parent_id"
|
||||
|
||||
_order = "complete_name asc"
|
||||
_rec_name = "complete_name"
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Database
|
||||
# ----------------------------------------------------------
|
||||
|
||||
name = fields.Char(required=True, translate=True)
|
||||
|
||||
active = fields.Boolean(
|
||||
default=True,
|
||||
help="The active field allows you to hide the category without removing it.",
|
||||
)
|
||||
complete_name = fields.Char(
|
||||
compute="_compute_complete_name", store=True, recursive=True
|
||||
)
|
||||
parent_id = fields.Many2one(
|
||||
comodel_name="dms.category",
|
||||
string="Parent Category",
|
||||
ondelete="cascade",
|
||||
index="btree",
|
||||
)
|
||||
|
||||
child_category_ids = fields.One2many(
|
||||
comodel_name="dms.category",
|
||||
inverse_name="parent_id",
|
||||
string="Child Categories",
|
||||
)
|
||||
|
||||
parent_path = fields.Char(index="btree", unaccent=False)
|
||||
tag_ids = fields.One2many(
|
||||
comodel_name="dms.tag", inverse_name="category_id", string="Tags"
|
||||
)
|
||||
directory_ids = fields.One2many(
|
||||
comodel_name="dms.directory",
|
||||
inverse_name="category_id",
|
||||
string="Directories",
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
file_ids = fields.One2many(
|
||||
comodel_name="dms.file",
|
||||
inverse_name="category_id",
|
||||
string="Files",
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
count_categories = fields.Integer(
|
||||
compute="_compute_count_categories", string="Count Subcategories"
|
||||
)
|
||||
|
||||
count_tags = fields.Integer(compute="_compute_count_tags")
|
||||
|
||||
count_directories = fields.Integer(compute="_compute_count_directories")
|
||||
|
||||
count_files = fields.Integer(compute="_compute_count_files")
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Constrains
|
||||
# ----------------------------------------------------------
|
||||
|
||||
_sql_constraints = [
|
||||
("name_uniq", "unique (name)", "Category name already exists!"),
|
||||
]
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Read
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.depends("name", "parent_id.complete_name")
|
||||
def _compute_complete_name(self):
|
||||
for category in self:
|
||||
if category.parent_id:
|
||||
category.complete_name = "{} / {}".format(
|
||||
category.parent_id.complete_name,
|
||||
category.name,
|
||||
)
|
||||
else:
|
||||
category.complete_name = category.name
|
||||
|
||||
@api.depends("child_category_ids")
|
||||
def _compute_count_categories(self):
|
||||
for record in self:
|
||||
record.count_categories = len(record.child_category_ids)
|
||||
|
||||
@api.depends("tag_ids")
|
||||
def _compute_count_tags(self):
|
||||
for record in self:
|
||||
record.count_tags = len(record.tag_ids)
|
||||
|
||||
@api.depends("directory_ids")
|
||||
def _compute_count_directories(self):
|
||||
for record in self:
|
||||
record.count_directories = len(record.directory_ids)
|
||||
|
||||
@api.depends("file_ids")
|
||||
def _compute_count_files(self):
|
||||
for record in self:
|
||||
record.count_files = len(record.file_ids)
|
||||
|
||||
def name_get(self):
|
||||
if not self.env.context.get("category_short_name", False):
|
||||
return super().name_get()
|
||||
vals = []
|
||||
for record in self:
|
||||
vals.append(tuple([record.id, record.name]))
|
||||
return vals
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Create
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.constrains("parent_id")
|
||||
def _check_category_recursion(self):
|
||||
if not self._check_recursion():
|
||||
raise ValidationError(_("Error! You cannot create recursive categories."))
|
||||
return True
|
||||
800
odoo-bringout-oca-dms-dms/dms/models/directory.py
Normal file
|
|
@ -0,0 +1,800 @@
|
|||
# Copyright 2017-2019 MuK IT GmbH.
|
||||
# Copyright 2020 Creu Blanca
|
||||
# Copyright 2021 Tecnativa - Víctor Martínez
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import ast
|
||||
import base64
|
||||
import logging
|
||||
from ast import literal_eval
|
||||
from collections import defaultdict
|
||||
|
||||
from odoo import _, api, fields, models, tools
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.osv.expression import AND, OR
|
||||
from odoo.tools import consteq, human_size
|
||||
|
||||
from odoo.addons.http_routing.models.ir_http import slugify
|
||||
|
||||
from ..tools.file import check_name, unique_name
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DmsDirectory(models.Model):
|
||||
_name = "dms.directory"
|
||||
_description = "Directory"
|
||||
|
||||
_inherit = [
|
||||
"portal.mixin",
|
||||
"dms.security.mixin",
|
||||
"dms.mixins.thumbnail",
|
||||
"mail.thread",
|
||||
"mail.activity.mixin",
|
||||
"mail.alias.mixin",
|
||||
"abstract.dms.mixin",
|
||||
]
|
||||
|
||||
_rec_name = "complete_name"
|
||||
_order = "complete_name"
|
||||
|
||||
_parent_store = True
|
||||
_parent_name = "parent_id"
|
||||
_directory_field = _parent_name
|
||||
|
||||
parent_path = fields.Char(index="btree", unaccent=False)
|
||||
is_root_directory = fields.Boolean(
|
||||
default=False,
|
||||
help="""Indicates if the directory is a root directory.
|
||||
A root directory has a settings object, while a directory with a set
|
||||
parent inherits the settings form its parent.""",
|
||||
)
|
||||
|
||||
# Override acording to defined in AbstractDmsMixin
|
||||
storage_id = fields.Many2one(
|
||||
compute="_compute_storage_id",
|
||||
compute_sudo=True,
|
||||
readonly=False,
|
||||
comodel_name="dms.storage",
|
||||
string="Storage",
|
||||
ondelete="restrict",
|
||||
auto_join=True,
|
||||
store=True,
|
||||
)
|
||||
parent_id = fields.Many2one(
|
||||
comodel_name="dms.directory",
|
||||
string="Parent Directory",
|
||||
domain="[('permission_create', '=', True)]",
|
||||
ondelete="restrict",
|
||||
# Access to a directory doesn't necessarily mean access its parent, so
|
||||
# prefetching this field could lead to misleading access errors
|
||||
prefetch=False,
|
||||
index="btree",
|
||||
store=True,
|
||||
readonly=False,
|
||||
compute="_compute_parent_id",
|
||||
copy=True,
|
||||
default=lambda self: self._default_parent_id(),
|
||||
)
|
||||
|
||||
root_directory_id = fields.Many2one(
|
||||
"dms.directory", "Root Directory", compute="_compute_root_id", store=True
|
||||
)
|
||||
|
||||
def _default_parent_id(self):
|
||||
context = self.env.context
|
||||
if context.get("active_model") == self._name and context.get("active_id"):
|
||||
return context["active_id"]
|
||||
else:
|
||||
return False
|
||||
|
||||
group_ids = fields.Many2many(
|
||||
comodel_name="dms.access.group",
|
||||
relation="dms_directory_groups_rel",
|
||||
column1="aid",
|
||||
column2="gid",
|
||||
string="Groups",
|
||||
)
|
||||
complete_group_ids = fields.Many2many(
|
||||
comodel_name="dms.access.group",
|
||||
relation="dms_directory_complete_groups_rel",
|
||||
column1="aid",
|
||||
column2="gid",
|
||||
string="Complete Groups",
|
||||
compute="_compute_groups",
|
||||
readonly=True,
|
||||
store=True,
|
||||
compute_sudo=True,
|
||||
recursive=True,
|
||||
)
|
||||
complete_name = fields.Char(
|
||||
compute="_compute_complete_name", store=True, recursive=True
|
||||
)
|
||||
child_directory_ids = fields.One2many(
|
||||
comodel_name="dms.directory",
|
||||
inverse_name="parent_id",
|
||||
string="Subdirectories",
|
||||
auto_join=False,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
tag_ids = fields.Many2many(
|
||||
comodel_name="dms.tag",
|
||||
relation="dms_directory_tag_rel",
|
||||
domain="""[
|
||||
'|', ['category_id', '=', False],
|
||||
['category_id', 'child_of', category_id]]
|
||||
""",
|
||||
column1="did",
|
||||
column2="tid",
|
||||
string="Tags",
|
||||
compute="_compute_tags",
|
||||
readonly=False,
|
||||
store=True,
|
||||
)
|
||||
|
||||
user_star_ids = fields.Many2many(
|
||||
comodel_name="res.users",
|
||||
relation="dms_directory_star_rel",
|
||||
column1="did",
|
||||
column2="uid",
|
||||
string="Stars",
|
||||
)
|
||||
|
||||
starred = fields.Boolean(
|
||||
compute="_compute_starred",
|
||||
inverse="_inverse_starred",
|
||||
search="_search_starred",
|
||||
)
|
||||
|
||||
file_ids = fields.One2many(
|
||||
comodel_name="dms.file",
|
||||
inverse_name="directory_id",
|
||||
string="Files",
|
||||
auto_join=False,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
count_directories = fields.Integer(
|
||||
compute="_compute_count_directories", string="Count Subdirectories Title"
|
||||
)
|
||||
|
||||
count_files = fields.Integer(
|
||||
compute="_compute_count_files", string="Count Files Title"
|
||||
)
|
||||
|
||||
count_directories_title = fields.Char(
|
||||
compute="_compute_count_directories", string="Count Subdirectories"
|
||||
)
|
||||
|
||||
count_files_title = fields.Char(
|
||||
compute="_compute_count_files", string="Count Files"
|
||||
)
|
||||
|
||||
count_elements = fields.Integer(compute="_compute_count_elements")
|
||||
|
||||
count_total_directories = fields.Integer(
|
||||
compute="_compute_count_total_directories", string="Total Subdirectories"
|
||||
)
|
||||
|
||||
count_total_files = fields.Integer(
|
||||
compute="_compute_count_total_files", string="Total Files"
|
||||
)
|
||||
|
||||
count_total_elements = fields.Integer(
|
||||
compute="_compute_count_total_elements", string="Total Elements"
|
||||
)
|
||||
|
||||
size = fields.Float(compute="_compute_size")
|
||||
human_size = fields.Char(
|
||||
compute="_compute_human_size", string="Size (human readable)"
|
||||
)
|
||||
|
||||
inherit_group_ids = fields.Boolean(string="Inherit Groups", default=True)
|
||||
|
||||
alias_process = fields.Selection(
|
||||
selection=[("files", "Single Files"), ("directory", "Subdirectory")],
|
||||
required=True,
|
||||
default="directory",
|
||||
string="Unpack Emails as",
|
||||
help="""\
|
||||
Define how incoming emails are processed:\n
|
||||
- Single Files: The email gets attached to the directory and
|
||||
all attachments are created as files.\n
|
||||
- Subdirectory: A new subdirectory is created for each email
|
||||
and the mail is attached to this subdirectory. The attachments
|
||||
are created as files of the subdirectory.
|
||||
""",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_domain_by_access_groups(self, operation):
|
||||
"""Special rules for directories."""
|
||||
self_filter = [
|
||||
("storage_id_inherit_access_from_parent_record", "=", False),
|
||||
("id", "inselect", self._get_access_groups_query(operation)),
|
||||
]
|
||||
# Upstream only filters by parent directory
|
||||
result = super()._get_domain_by_access_groups(operation)
|
||||
if operation == "create":
|
||||
# When creating, I need create access in parent directory, or
|
||||
# self-create permission if it's a root directory
|
||||
result = OR(
|
||||
[
|
||||
[("is_root_directory", "=", False)] + result,
|
||||
[("is_root_directory", "=", True)] + self_filter,
|
||||
]
|
||||
)
|
||||
else:
|
||||
# In other operations, I only need self access
|
||||
result = self_filter
|
||||
return result
|
||||
|
||||
def _compute_access_url(self):
|
||||
res = super()._compute_access_url()
|
||||
for item in self:
|
||||
item.access_url = "/my/dms/directory/%s" % (item.id)
|
||||
return res
|
||||
|
||||
def check_access_token(self, access_token=False):
|
||||
res = False
|
||||
if access_token:
|
||||
items = (
|
||||
self.env["dms.directory"]
|
||||
.sudo()
|
||||
.search([("access_token", "=", access_token)])
|
||||
)
|
||||
if items:
|
||||
item = items[0]
|
||||
if item.id == self.id:
|
||||
return True
|
||||
else:
|
||||
directory_item = self
|
||||
while directory_item.parent_id:
|
||||
if directory_item.id == item.id:
|
||||
return True
|
||||
directory_item = directory_item.parent_id
|
||||
# Fix last level
|
||||
if directory_item.id == item.id:
|
||||
return True
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_parent_categories(self, access_token):
|
||||
self.ensure_one()
|
||||
directories = []
|
||||
current_directory = self
|
||||
while current_directory:
|
||||
directories.insert(0, current_directory)
|
||||
if (
|
||||
(
|
||||
access_token
|
||||
and current_directory.access_token
|
||||
and consteq(current_directory.access_token, access_token)
|
||||
)
|
||||
or not access_token
|
||||
and current_directory.check_access_rights("read")
|
||||
):
|
||||
return directories
|
||||
current_directory = current_directory.parent_id
|
||||
if access_token:
|
||||
# Reaching here means we didn't find the directory accessible by this token
|
||||
return [self]
|
||||
return directories
|
||||
|
||||
def _get_own_root_directories(self):
|
||||
res = self.env["dms.directory"].search_read(
|
||||
[("is_hidden", "=", False)], ["parent_id"]
|
||||
)
|
||||
all_ids = [value["id"] for value in res]
|
||||
res_ids = []
|
||||
for item in res:
|
||||
if not item["parent_id"] or item["parent_id"][0] not in all_ids:
|
||||
res_ids.append(item["id"])
|
||||
return res_ids
|
||||
|
||||
allowed_model_ids = fields.Many2many(
|
||||
related="storage_id.model_ids",
|
||||
comodel_name="ir.model",
|
||||
)
|
||||
model_id = fields.Many2one(
|
||||
comodel_name="ir.model",
|
||||
domain="[('id', 'in', allowed_model_ids)]",
|
||||
compute="_compute_model_id",
|
||||
inverse="_inverse_model_id",
|
||||
string="Model",
|
||||
store=True,
|
||||
)
|
||||
storage_id_save_type = fields.Selection(
|
||||
related="storage_id.save_type",
|
||||
related_sudo=True,
|
||||
readonly=True,
|
||||
store=False,
|
||||
prefetch=False,
|
||||
)
|
||||
storage_id_inherit_access_from_parent_record = fields.Boolean(
|
||||
related="storage_id.inherit_access_from_parent_record",
|
||||
related_sudo=True,
|
||||
store=True,
|
||||
)
|
||||
|
||||
@api.depends("res_model")
|
||||
def _compute_model_id(self):
|
||||
for record in self:
|
||||
if not record.res_model:
|
||||
record.model_id = False
|
||||
continue
|
||||
record.model_id = (
|
||||
self.env["ir.model"].sudo().search([("model", "=", record.res_model)])
|
||||
)
|
||||
|
||||
def _inverse_model_id(self):
|
||||
for record in self:
|
||||
record.res_model = record.model_id.model
|
||||
|
||||
def name_get(self):
|
||||
if not self.env.context.get("directory_short_name", False):
|
||||
return super().name_get()
|
||||
vals = []
|
||||
for record in self:
|
||||
vals.append(tuple([record.id, record.name]))
|
||||
return vals
|
||||
|
||||
def toggle_starred(self):
|
||||
updates = defaultdict(set)
|
||||
for record in self:
|
||||
vals = {"starred": not record.starred}
|
||||
updates[tools.frozendict(vals)].add(record.id)
|
||||
with self.env.norecompute():
|
||||
for vals, ids in updates.items():
|
||||
self.browse(ids).write(dict(vals))
|
||||
self.flush_recordset()
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# SearchPanel
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def search_panel_select_range(self, field_name, **kwargs):
|
||||
context = {}
|
||||
if field_name == "parent_id":
|
||||
context["directory_short_name"] = True
|
||||
return super(
|
||||
DmsDirectory, self.with_context(**context)
|
||||
).search_panel_select_range(field_name, **kwargs)
|
||||
|
||||
@api.model
|
||||
def search_panel_select_multi_range(self, field_name, **kwargs):
|
||||
return super(
|
||||
DmsDirectory, self.with_context(category_short_name=True)
|
||||
).search_panel_select_multi_range(field_name, **kwargs)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Actions
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def action_save_onboarding_directory_step(self):
|
||||
self.env.user.company_id.set_onboarding_step_done(
|
||||
"documents_onboarding_directory_state"
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# SearchPanel
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _search_panel_directory(self, **kwargs):
|
||||
search_domain = (kwargs.get("search_domain", []),)
|
||||
if search_domain and len(search_domain):
|
||||
for domain in search_domain[0]:
|
||||
if domain[0] == "parent_id":
|
||||
return domain[1], domain[2]
|
||||
return None, None
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Search
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _search_starred(self, operator, operand):
|
||||
if operator == "=" and operand:
|
||||
return [("user_star_ids", "in", [self.env.uid])]
|
||||
return [("user_star_ids", "not in", [self.env.uid])]
|
||||
|
||||
@api.depends("name", "parent_id.complete_name")
|
||||
def _compute_complete_name(self):
|
||||
for category in self:
|
||||
if category.parent_id:
|
||||
category.complete_name = "{} / {}".format(
|
||||
category.parent_id.complete_name,
|
||||
category.name,
|
||||
)
|
||||
else:
|
||||
category.complete_name = category.name
|
||||
|
||||
@api.depends("parent_id")
|
||||
def _compute_storage_id(self):
|
||||
for record in self:
|
||||
if record.parent_id:
|
||||
record.storage_id = record.parent_id.storage_id
|
||||
else:
|
||||
# HACK: Not needed in v14 due to odoo/odoo#64359
|
||||
record.storage_id = record.storage_id
|
||||
|
||||
@api.depends("user_star_ids")
|
||||
def _compute_starred(self):
|
||||
for record in self:
|
||||
record.starred = self.env.user in record.user_star_ids
|
||||
|
||||
@api.depends("child_directory_ids")
|
||||
def _compute_count_directories(self):
|
||||
for record in self:
|
||||
directories = len(record.child_directory_ids)
|
||||
record.count_directories = directories
|
||||
record.count_directories_title = _("%s Subdirectories") % directories
|
||||
|
||||
@api.depends("file_ids")
|
||||
def _compute_count_files(self):
|
||||
for record in self:
|
||||
files = len(record.file_ids)
|
||||
record.count_files = files
|
||||
record.count_files_title = _("%s Files") % files
|
||||
|
||||
@api.depends("child_directory_ids", "file_ids")
|
||||
def _compute_count_elements(self):
|
||||
for record in self:
|
||||
elements = record.count_files
|
||||
elements += record.count_directories
|
||||
record.count_elements = elements
|
||||
|
||||
def _compute_count_total_directories(self):
|
||||
for record in self:
|
||||
count = (
|
||||
self.search_count([("id", "child_of", record.id)]) if record.id else 0
|
||||
)
|
||||
record.count_total_directories = count - 1 if count > 0 else 0
|
||||
|
||||
def _compute_count_total_files(self):
|
||||
model = self.env["dms.file"]
|
||||
for record in self:
|
||||
# Prevent error in some NewId cases
|
||||
record.count_total_files = (
|
||||
model.search_count([("directory_id", "child_of", record.id)])
|
||||
if record.id
|
||||
else 0
|
||||
)
|
||||
|
||||
def _compute_count_total_elements(self):
|
||||
for record in self:
|
||||
total_elements = record.count_total_files
|
||||
total_elements += record.count_total_directories
|
||||
record.count_total_elements = total_elements
|
||||
|
||||
def _compute_size(self):
|
||||
sudo_model = self.env["dms.file"].sudo()
|
||||
for record in self:
|
||||
# Avoid NewId
|
||||
if not record.id:
|
||||
record.size = 0
|
||||
continue
|
||||
recs = sudo_model.search_read(
|
||||
domain=[("directory_id", "child_of", record.id)],
|
||||
fields=["size"],
|
||||
)
|
||||
record.size = sum(rec.get("size", 0) for rec in recs)
|
||||
|
||||
@api.depends("size")
|
||||
def _compute_human_size(self):
|
||||
for item in self:
|
||||
item.human_size = human_size(item.size) if item.size else False
|
||||
|
||||
@api.depends(
|
||||
"group_ids",
|
||||
"inherit_group_ids",
|
||||
"parent_id.complete_group_ids",
|
||||
"parent_path",
|
||||
)
|
||||
def _compute_groups(self):
|
||||
"""Get all DMS security groups affecting this directory."""
|
||||
for one in self:
|
||||
groups = one.group_ids
|
||||
if one.inherit_group_ids:
|
||||
groups |= one.parent_id.complete_group_ids
|
||||
self.complete_group_ids = groups
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# View
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.depends("is_root_directory")
|
||||
def _compute_parent_id(self):
|
||||
for record in self:
|
||||
if record.is_root_directory:
|
||||
record.parent_id = None
|
||||
else:
|
||||
# HACK: Not needed in v14 due to odoo/odoo#64359
|
||||
record.parent_id = record.parent_id
|
||||
|
||||
@api.depends("is_root_directory", "parent_id")
|
||||
def _compute_root_id(self):
|
||||
for record in self:
|
||||
if record.is_root_directory:
|
||||
record.root_directory_id = record
|
||||
else:
|
||||
# recursively check all parent nodes up to the root directory
|
||||
if not record.parent_id.root_directory_id:
|
||||
record.parent_id._compute_root_id()
|
||||
record.root_directory_id = record.parent_id.root_directory_id
|
||||
|
||||
@api.depends("category_id")
|
||||
def _compute_tags(self):
|
||||
for record in self:
|
||||
tags = record.tag_ids.filtered(
|
||||
lambda rec: not rec.category_id or rec.category_id == record.category_id
|
||||
)
|
||||
record.tag_ids = tags
|
||||
|
||||
@api.onchange("storage_id")
|
||||
def _onchange_storage_id(self):
|
||||
for record in self:
|
||||
if (
|
||||
record.storage_id.save_type == "attachment"
|
||||
and record.storage_id.inherit_access_from_parent_record
|
||||
):
|
||||
record.group_ids = False
|
||||
|
||||
@api.onchange("model_id")
|
||||
def _onchange_model_id(self):
|
||||
self._inverse_model_id()
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Constrains
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.constrains("parent_id")
|
||||
def _check_directory_recursion(self):
|
||||
if not self._check_recursion():
|
||||
raise ValidationError(_("Error! You cannot create recursive directories."))
|
||||
return True
|
||||
|
||||
@api.constrains("storage_id", "model_id")
|
||||
def _check_storage_id_attachment_model_id(self):
|
||||
for record in self:
|
||||
if record.storage_id.save_type != "attachment":
|
||||
continue
|
||||
if not record.model_id:
|
||||
raise ValidationError(
|
||||
_("A directory has to have model in attachment storage.")
|
||||
)
|
||||
if not record.is_root_directory and not record.res_id:
|
||||
raise ValidationError(
|
||||
_("This directory needs to be associated to a record.")
|
||||
)
|
||||
|
||||
@api.constrains("is_root_directory", "storage_id")
|
||||
def _check_directory_storage(self):
|
||||
for record in self:
|
||||
if record.is_root_directory and not record.storage_id:
|
||||
raise ValidationError(_("A root directory has to have a storage."))
|
||||
|
||||
@api.constrains("is_root_directory", "parent_id")
|
||||
def _check_directory_parent(self):
|
||||
for record in self:
|
||||
if record.is_root_directory and record.parent_id:
|
||||
raise ValidationError(
|
||||
_("A directory can't be a root and have a parent directory.")
|
||||
)
|
||||
if not record.is_root_directory and not record.parent_id:
|
||||
raise ValidationError(_("A directory has to have a parent directory."))
|
||||
|
||||
@api.constrains("name")
|
||||
def _check_name(self):
|
||||
for record in self:
|
||||
if self.env.context.get("check_name", True) and not check_name(record.name):
|
||||
raise ValidationError(_("The directory name is invalid."))
|
||||
if record.is_root_directory:
|
||||
childs = record.sudo().storage_id.root_directory_ids.name_get()
|
||||
else:
|
||||
childs = record.sudo().parent_id.child_directory_ids.name_get()
|
||||
if list(
|
||||
filter(
|
||||
lambda child: child[1] == record.name and child[0] != record.id,
|
||||
childs,
|
||||
)
|
||||
):
|
||||
raise ValidationError(
|
||||
_("A directory with the same name already exists.")
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Create, Update, Delete
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def _inverse_starred(self):
|
||||
starred_records = self.env["dms.directory"].sudo()
|
||||
not_starred_records = self.env["dms.directory"].sudo()
|
||||
for record in self:
|
||||
if not record.starred and self.env.user in record.user_star_ids:
|
||||
starred_records |= record
|
||||
elif record.starred and self.env.user not in record.user_star_ids:
|
||||
not_starred_records |= record
|
||||
not_starred_records.write({"user_star_ids": [(4, self.env.uid)]})
|
||||
starred_records.write({"user_star_ids": [(3, self.env.uid)]})
|
||||
|
||||
def copy(self, default=None):
|
||||
self.ensure_one()
|
||||
default = dict(default or [])
|
||||
if "parent_id" in default:
|
||||
parent_directory = self.browse(default["parent_id"])
|
||||
names = parent_directory.sudo().child_directory_ids.mapped("name")
|
||||
elif self.is_root_directory:
|
||||
names = self.sudo().storage_id.root_directory_ids.mapped("name")
|
||||
else:
|
||||
names = self.sudo().parent_id.child_directory_ids.mapped("name")
|
||||
default.update({"name": unique_name(self.name, names)})
|
||||
new = super().copy(default)
|
||||
for record in self.file_ids:
|
||||
record.copy({"directory_id": new.id})
|
||||
for record in self.child_directory_ids:
|
||||
record.copy({"parent_id": new.id})
|
||||
return new
|
||||
|
||||
def _alias_get_creation_values(self):
|
||||
values = super()._alias_get_creation_values()
|
||||
values["alias_model_id"] = self.env["ir.model"].sudo()._get("dms.directory").id
|
||||
if self.id:
|
||||
values["alias_defaults"] = defaults = ast.literal_eval(
|
||||
self.alias_defaults or "{}"
|
||||
)
|
||||
defaults["parent_id"] = self.id
|
||||
return values
|
||||
|
||||
@api.model
|
||||
def message_new(self, msg_dict, custom_values=None):
|
||||
custom_values = custom_values if custom_values is not None else {}
|
||||
parent_directory_id = custom_values.get("parent_id", None)
|
||||
parent_directory = self.sudo().browse(parent_directory_id)
|
||||
if not parent_directory_id or not parent_directory.exists():
|
||||
raise ValueError("No directory could be found!")
|
||||
if parent_directory.alias_process == "files":
|
||||
parent_directory._process_message(msg_dict)
|
||||
return parent_directory
|
||||
names = parent_directory.child_directory_ids.mapped("name")
|
||||
subject = slugify(msg_dict.get("subject", _("Alias-Mail-Extraction")))
|
||||
defaults = dict(
|
||||
{"name": unique_name(subject, names, escape_suffix=True)}, **custom_values
|
||||
)
|
||||
directory = super().message_new(msg_dict, custom_values=defaults)
|
||||
directory._process_message(msg_dict)
|
||||
return directory
|
||||
|
||||
def message_update(self, msg_dict, update_vals=None):
|
||||
self._process_message(msg_dict, extra_values=update_vals)
|
||||
return super().message_update(msg_dict, update_vals=update_vals)
|
||||
|
||||
def _process_message(self, msg_dict, extra_values=False):
|
||||
names = self.sudo().file_ids.mapped("name")
|
||||
for attachment in msg_dict["attachments"]:
|
||||
uname = unique_name(attachment.fname, names, escape_suffix=True)
|
||||
vals = {
|
||||
"directory_id": self.id,
|
||||
"name": uname,
|
||||
}
|
||||
try:
|
||||
vals["content"] = base64.b64encode(attachment.content)
|
||||
except Exception:
|
||||
vals["content"] = attachment.content
|
||||
self.env["dms.file"].sudo().create(vals)
|
||||
names.append(uname)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
if vals.get("parent_id", False):
|
||||
parent = self.browse([vals["parent_id"]])
|
||||
data = next(iter(parent.sudo().read(["storage_id"])), {})
|
||||
vals["storage_id"] = self._convert_to_write(data).get("storage_id")
|
||||
# Hack to prevent error related to mail_message parent not exists in some cases
|
||||
ctx = dict(self.env.context).copy()
|
||||
ctx.update({"default_parent_id": False})
|
||||
res = super(DmsDirectory, self.with_context(**ctx)).create(vals_list)
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
if any([k in vals.keys() for k in ["storage_id", "parent_id"]]):
|
||||
for item in self:
|
||||
new_storage_id = vals.get("storage_id", item.storage_id.id)
|
||||
new_parent_id = vals.get("parent_id", item.parent_id.id)
|
||||
old_storage_id = (
|
||||
item.storage_id or item.root_directory_id.storage_id
|
||||
).id
|
||||
if new_parent_id:
|
||||
if old_storage_id != self.browse(new_parent_id).storage_id.id:
|
||||
raise UserError(
|
||||
_("It is not possible to change parent to other storage.")
|
||||
)
|
||||
elif old_storage_id != new_storage_id:
|
||||
raise UserError(_("It is not possible to change the storage."))
|
||||
# Groups part
|
||||
if any(key in vals for key in ["group_ids", "inherit_group_ids"]):
|
||||
with self.env.norecompute():
|
||||
res = super(DmsDirectory, self).write(vals)
|
||||
domain = [("id", "child_of", self.ids)]
|
||||
records = self.sudo().search(domain)
|
||||
records.modified(["group_ids"])
|
||||
records.flush_recordset()
|
||||
else:
|
||||
res = super().write(vals)
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
"""Custom cascade unlink.
|
||||
|
||||
Cannot rely on DB backend's cascade because subfolder and subfile unlinks
|
||||
must check custom permissions implementation.
|
||||
"""
|
||||
self.file_ids.unlink()
|
||||
if self.child_directory_ids:
|
||||
self.child_directory_ids.unlink()
|
||||
return super().unlink()
|
||||
|
||||
@api.model
|
||||
def _search_panel_domain_image(
|
||||
self, field_name, domain, set_count=False, limit=False
|
||||
):
|
||||
"""We need to overwrite function from directories because odoo only return
|
||||
records with childs (very weird for user perspective).
|
||||
All records are returned now.
|
||||
"""
|
||||
if field_name == "parent_id":
|
||||
res = {}
|
||||
for item in self.search_read(
|
||||
domain=domain, fields=["id", "name", "count_directories"]
|
||||
):
|
||||
res[item["id"]] = {
|
||||
"id": item["id"],
|
||||
"display_name": item["name"],
|
||||
"__count": item["count_directories"],
|
||||
}
|
||||
return res
|
||||
return super()._search_panel_domain_image(
|
||||
field_name=field_name, domain=domain, set_count=set_count, limit=limit
|
||||
)
|
||||
|
||||
def action_dms_directories_all_directory(self):
|
||||
self.ensure_one()
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"dms.action_dms_directory"
|
||||
)
|
||||
domain = AND(
|
||||
[
|
||||
literal_eval(action["domain"].strip()),
|
||||
[("parent_id", "child_of", self.id)],
|
||||
]
|
||||
)
|
||||
action["display_name"] = self.name
|
||||
action["domain"] = domain
|
||||
action["context"] = dict(
|
||||
self.env.context,
|
||||
default_parent_id=self.id,
|
||||
searchpanel_default_parent_id=self.id,
|
||||
)
|
||||
return action
|
||||
|
||||
def action_dms_files_all_directory(self):
|
||||
self.ensure_one()
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id("dms.action_dms_file")
|
||||
domain = AND(
|
||||
[
|
||||
literal_eval(action["domain"].strip()),
|
||||
[("directory_id", "child_of", self.id)],
|
||||
]
|
||||
)
|
||||
action["display_name"] = self.name
|
||||
action["domain"] = domain
|
||||
action["context"] = dict(
|
||||
self.env.context,
|
||||
default_directory_id=self.id,
|
||||
searchpanel_default_directory_id=self.id,
|
||||
)
|
||||
return action
|
||||
690
odoo-bringout-oca-dms-dms/dms/models/dms_file.py
Normal file
|
|
@ -0,0 +1,690 @@
|
|||
# Copyright 2020 Antoni Romera
|
||||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# Copyright 2021 Tecnativa - Víctor Martínez
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from odoo import _, api, fields, models, tools
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import consteq, human_size
|
||||
from odoo.tools.mimetypes import guess_mimetype
|
||||
|
||||
from ..tools import file
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class File(models.Model):
|
||||
_name = "dms.file"
|
||||
_description = "File"
|
||||
|
||||
_inherit = [
|
||||
"portal.mixin",
|
||||
"dms.security.mixin",
|
||||
"dms.mixins.thumbnail",
|
||||
"mail.thread",
|
||||
"mail.activity.mixin",
|
||||
"abstract.dms.mixin",
|
||||
]
|
||||
|
||||
_order = "name asc"
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Database
|
||||
# ----------------------------------------------------------
|
||||
|
||||
active = fields.Boolean(
|
||||
string="Archived",
|
||||
default=True,
|
||||
help="If a file is set to archived, it is not displayed, but still exists.",
|
||||
)
|
||||
directory_id = fields.Many2one(
|
||||
comodel_name="dms.directory",
|
||||
string="Directory",
|
||||
domain="[('permission_create', '=', True)]",
|
||||
context="{'dms_directory_show_path': True}",
|
||||
ondelete="restrict",
|
||||
auto_join=True,
|
||||
required=True,
|
||||
index="btree",
|
||||
tracking=True, # Leave log if "moved" to another directory
|
||||
)
|
||||
root_directory_id = fields.Many2one(related="directory_id.root_directory_id")
|
||||
# Override acording to defined in AbstractDmsMixin
|
||||
storage_id = fields.Many2one(
|
||||
related="directory_id.storage_id",
|
||||
readonly=True,
|
||||
store=True,
|
||||
prefetch=False,
|
||||
)
|
||||
|
||||
path_names = fields.Char(
|
||||
compute="_compute_path",
|
||||
compute_sudo=True,
|
||||
readonly=True,
|
||||
store=False,
|
||||
)
|
||||
|
||||
path_json = fields.Text(
|
||||
compute="_compute_path",
|
||||
compute_sudo=True,
|
||||
readonly=True,
|
||||
store=False,
|
||||
)
|
||||
|
||||
tag_ids = fields.Many2many(
|
||||
comodel_name="dms.tag",
|
||||
relation="dms_file_tag_rel",
|
||||
column1="fid",
|
||||
column2="tid",
|
||||
domain="['|', ('category_id', '=', False),('category_id', '=?', category_id)]",
|
||||
string="Tags",
|
||||
)
|
||||
|
||||
content = fields.Binary(
|
||||
compute="_compute_content",
|
||||
inverse="_inverse_content",
|
||||
attachment=False,
|
||||
prefetch=False,
|
||||
required=True,
|
||||
store=False,
|
||||
)
|
||||
|
||||
extension = fields.Char(compute="_compute_extension", readonly=True, store=True)
|
||||
|
||||
mimetype = fields.Char(
|
||||
compute="_compute_mimetype", string="Type", readonly=True, store=True
|
||||
)
|
||||
|
||||
size = fields.Float(readonly=True)
|
||||
human_size = fields.Char(
|
||||
readonly=True,
|
||||
string="Size (human readable)",
|
||||
compute="_compute_human_size",
|
||||
store=True,
|
||||
)
|
||||
|
||||
checksum = fields.Char(string="Checksum/SHA1", readonly=True, index="btree")
|
||||
|
||||
content_binary = fields.Binary(attachment=False, prefetch=False, invisible=True)
|
||||
|
||||
save_type = fields.Char(
|
||||
compute="_compute_save_type",
|
||||
string="Current Save Type",
|
||||
invisible=True,
|
||||
prefetch=False,
|
||||
)
|
||||
|
||||
migration = fields.Char(
|
||||
compute="_compute_migration",
|
||||
string="Migration Status",
|
||||
readonly=True,
|
||||
prefetch=False,
|
||||
compute_sudo=True,
|
||||
)
|
||||
require_migration = fields.Boolean(
|
||||
compute="_compute_migration", store=True, compute_sudo=True
|
||||
)
|
||||
|
||||
content_file = fields.Binary(attachment=True, prefetch=False, invisible=True)
|
||||
|
||||
# Extend inherited field(s)
|
||||
image_1920 = fields.Image(compute="_compute_image_1920", store=True, readonly=False)
|
||||
|
||||
@api.depends("mimetype", "content")
|
||||
def _compute_image_1920(self):
|
||||
"""Provide thumbnail automatically if possible."""
|
||||
for one in self.filtered("mimetype"):
|
||||
# Image.MIME provides a dict of mimetypes supported by Pillow,
|
||||
# SVG is not present in the dict but is also a supported image format
|
||||
# lacking a better solution, it's being added manually
|
||||
# Some component modifies the PIL dictionary by adding PDF as a valid
|
||||
# image type, so it must be explicitly excluded.
|
||||
if one.mimetype != "application/pdf" and one.mimetype in (
|
||||
*Image.MIME.values(),
|
||||
"image/svg+xml",
|
||||
):
|
||||
one.image_1920 = one.content
|
||||
|
||||
def check_access_rule(self, operation):
|
||||
self.mapped("directory_id").check_access_rule(operation)
|
||||
return super().check_access_rule(operation)
|
||||
|
||||
def _compute_access_url(self):
|
||||
res = super()._compute_access_url()
|
||||
for item in self:
|
||||
item.access_url = "/my/dms/file/%s/download" % (item.id)
|
||||
return res
|
||||
|
||||
def check_access_token(self, access_token=False):
|
||||
res = False
|
||||
if access_token:
|
||||
if self.access_token and consteq(self.access_token, access_token):
|
||||
return True
|
||||
else:
|
||||
items = (
|
||||
self.env["dms.directory"]
|
||||
.sudo()
|
||||
.search([("access_token", "=", access_token)])
|
||||
)
|
||||
if items:
|
||||
item = items[0]
|
||||
if self.directory_id.id == item.id:
|
||||
return True
|
||||
else:
|
||||
directory_item = self.directory_id
|
||||
while directory_item.parent_id:
|
||||
if directory_item.id == self.directory_id.id:
|
||||
return True
|
||||
directory_item = directory_item.parent_id
|
||||
# Fix last level
|
||||
if directory_item.id == self.directory_id.id:
|
||||
return True
|
||||
return res
|
||||
|
||||
res_model = fields.Char(
|
||||
string="Linked attachments model", related="directory_id.res_model"
|
||||
)
|
||||
res_id = fields.Integer(
|
||||
string="Linked attachments record ID", related="directory_id.res_id"
|
||||
)
|
||||
attachment_id = fields.Many2one(
|
||||
comodel_name="ir.attachment",
|
||||
string="Attachment File",
|
||||
prefetch=False,
|
||||
invisible=True,
|
||||
ondelete="cascade",
|
||||
index=True,
|
||||
)
|
||||
|
||||
def get_human_size(self):
|
||||
return human_size(self.size)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Helper
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _get_checksum(self, binary):
|
||||
return hashlib.sha1(binary or b"").hexdigest()
|
||||
|
||||
@api.model
|
||||
def _get_content_inital_vals(self):
|
||||
return {"content_binary": False, "content_file": False}
|
||||
|
||||
def _update_content_vals(self, vals, binary):
|
||||
new_vals = vals.copy()
|
||||
new_vals.update(
|
||||
{
|
||||
"checksum": self._get_checksum(binary),
|
||||
"size": binary and len(binary) or 0,
|
||||
}
|
||||
)
|
||||
if self.storage_id.save_type in ["file", "attachment"]:
|
||||
new_vals["content_file"] = self.content
|
||||
else:
|
||||
new_vals["content_binary"] = self.content and binary
|
||||
return new_vals
|
||||
|
||||
@api.model
|
||||
def _get_binary_max_size(self):
|
||||
return int(
|
||||
self.env["ir.config_parameter"]
|
||||
.sudo()
|
||||
.get_param("dms.binary_max_size", default=25)
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_forbidden_extensions(self):
|
||||
get_param = self.env["ir.config_parameter"].sudo().get_param
|
||||
extensions = get_param("dms.forbidden_extensions", default="")
|
||||
return [extension.strip() for extension in extensions.split(",")]
|
||||
|
||||
def _get_icon_placeholder_name(self):
|
||||
return self.extension and "file_%s.svg" % self.extension or ""
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Actions
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def action_migrate(self, logging=True):
|
||||
record_count = len(self)
|
||||
index = 1
|
||||
for dms_file in self:
|
||||
if logging:
|
||||
_logger.info(
|
||||
_(
|
||||
"Migrate File %(index)s of %(record_count)s [ %(dms_file_migration)s ]"
|
||||
)
|
||||
% {
|
||||
"index": index,
|
||||
"record_count": record_count,
|
||||
"dms_file_migration": dms_file.migration,
|
||||
}
|
||||
)
|
||||
index += 1
|
||||
dms_file.write({"content": dms_file.with_context(**{}).content})
|
||||
|
||||
def action_save_onboarding_file_step(self):
|
||||
self.env.user.company_id.set_onboarding_step_done(
|
||||
"documents_onboarding_file_state"
|
||||
)
|
||||
|
||||
def action_wizard_dms_file_move(self):
|
||||
items = self.browse(self.env.context.get("active_ids"))
|
||||
root_directories = items.mapped("root_directory_id")
|
||||
if len(root_directories) > 1:
|
||||
raise UserError(_("Only files in the same root directory can be moved."))
|
||||
result = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"dms.wizard_dms_file_move_act_window"
|
||||
)
|
||||
result["context"] = dict(self.env.context)
|
||||
return result
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# SearchPanel
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _search_panel_directory(self, **kwargs):
|
||||
search_domain = (kwargs.get("search_domain", []),)
|
||||
category_domain = kwargs.get("category_domain", [])
|
||||
if category_domain and len(category_domain):
|
||||
return "=", category_domain[0][2]
|
||||
if search_domain and len(search_domain):
|
||||
for domain in search_domain[0]:
|
||||
if domain[0] == "directory_id":
|
||||
return domain[1], domain[2]
|
||||
return None, None
|
||||
|
||||
@api.model
|
||||
def _search_panel_domain(self, field, operator, directory_id, comodel_domain=False):
|
||||
if not comodel_domain:
|
||||
comodel_domain = []
|
||||
files_ids = self.search([("directory_id", operator, directory_id)]).ids
|
||||
return expression.AND([comodel_domain, [(field, "in", files_ids)]])
|
||||
|
||||
@api.model
|
||||
def search_panel_select_range(self, field_name, **kwargs):
|
||||
"""This method is overwritten to make it 'similar' to v13.
|
||||
The goal is that the directory searchpanel shows all directories
|
||||
(even if some folders have no files)."""
|
||||
if field_name == "directory_id":
|
||||
domain = [["is_hidden", "=", False]]
|
||||
# If we pass by context something, we filter more about it we filter
|
||||
# the directories of the files or we show all of them
|
||||
if self.env.context.get("active_model", False) == "dms.directory":
|
||||
active_id = self.env.context.get("active_id")
|
||||
# para saber que directorios, buscamos las posibles carpetas que nos interesan
|
||||
files = self.env["dms.file"].search(
|
||||
[["directory_id", "child_of", active_id]]
|
||||
)
|
||||
all_directories = files.mapped("directory_id")
|
||||
all_directories += files.mapped("directory_id.parent_id")
|
||||
domain.append(["id", "in", all_directories.ids])
|
||||
# Get all possible directories
|
||||
comodel_records = (
|
||||
self.env["dms.directory"]
|
||||
.with_context(directory_short_name=True)
|
||||
.search_read(domain, ["display_name", "parent_id"])
|
||||
)
|
||||
all_record_ids = [rec["id"] for rec in comodel_records]
|
||||
field_range = {}
|
||||
enable_counters = kwargs.get("enable_counters")
|
||||
for record in comodel_records:
|
||||
record_id = record["id"]
|
||||
parent = record["parent_id"]
|
||||
record_values = {
|
||||
"id": record_id,
|
||||
"display_name": record["display_name"],
|
||||
# If the parent directory is not in all the records we should not
|
||||
# set parent_id because the user does not have access to parent.
|
||||
"parent_id": (
|
||||
parent[0] if parent and parent[0] in all_record_ids else False
|
||||
),
|
||||
}
|
||||
if enable_counters:
|
||||
record_values["__count"] = 0
|
||||
field_range[record_id] = record_values
|
||||
if enable_counters:
|
||||
res = super().search_panel_select_range(field_name, **kwargs)
|
||||
for item in res["values"]:
|
||||
if item["id"] in field_range:
|
||||
field_range[item["id"]]["__count"] = item["__count"]
|
||||
return {"parent_field": "parent_id", "values": list(field_range.values())}
|
||||
context = {}
|
||||
if field_name == "category_id":
|
||||
context["category_short_name"] = True
|
||||
return super(File, self.with_context(**context)).search_panel_select_range(
|
||||
field_name, **kwargs
|
||||
)
|
||||
|
||||
@api.model
|
||||
def search_panel_select_multi_range(self, field_name, **kwargs):
|
||||
operator, directory_id = self._search_panel_directory(**kwargs)
|
||||
if field_name == "tag_ids":
|
||||
sql_query = """
|
||||
SELECT t.name AS name, t.id AS id, c.name AS group_name,
|
||||
c.id AS group_id, COUNT(r.fid) AS count
|
||||
FROM dms_tag t
|
||||
JOIN dms_category c ON t.category_id = c.id
|
||||
LEFT JOIN dms_file_tag_rel r ON t.id = r.tid
|
||||
WHERE %(filter_by_file_ids)s IS FALSE OR r.fid = ANY(%(file_ids)s)
|
||||
GROUP BY c.name, c.id, t.name, t.id
|
||||
ORDER BY c.name, c.id, t.name, t.id;
|
||||
"""
|
||||
file_ids = []
|
||||
if directory_id:
|
||||
file_ids = self.search([("directory_id", operator, directory_id)]).ids
|
||||
self.env.cr.execute(
|
||||
sql_query,
|
||||
{"file_ids": file_ids, "filter_by_file_ids": bool(directory_id)},
|
||||
)
|
||||
return self.env.cr.dictfetchall()
|
||||
if directory_id and field_name in ["directory_id", "category_id"]:
|
||||
comodel_domain = kwargs.pop("comodel_domain", [])
|
||||
directory_comodel_domain = self._search_panel_domain(
|
||||
"file_ids", operator, directory_id, comodel_domain
|
||||
)
|
||||
return super(
|
||||
File, self.with_context(directory_short_name=True)
|
||||
).search_panel_select_multi_range(
|
||||
field_name, comodel_domain=directory_comodel_domain, **kwargs
|
||||
)
|
||||
return super(
|
||||
File, self.with_context(directory_short_name=True)
|
||||
).search_panel_select_multi_range(field_name, **kwargs)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Read
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.depends("name", "directory_id", "directory_id.parent_path")
|
||||
def _compute_path(self):
|
||||
model = self.env["dms.directory"]
|
||||
for record in self:
|
||||
path_names = [record.display_name]
|
||||
path_json = [
|
||||
{
|
||||
"model": record._name,
|
||||
"name": record.display_name,
|
||||
"id": isinstance(record.id, int) and record.id or 0,
|
||||
}
|
||||
]
|
||||
current_dir = record.directory_id
|
||||
while current_dir:
|
||||
path_names.insert(0, current_dir.name)
|
||||
path_json.insert(
|
||||
0,
|
||||
{
|
||||
"model": model._name,
|
||||
"name": current_dir.name,
|
||||
"id": current_dir._origin.id,
|
||||
},
|
||||
)
|
||||
current_dir = current_dir.parent_id
|
||||
record.update(
|
||||
{
|
||||
"path_names": "/".join(path_names),
|
||||
"path_json": json.dumps(path_json),
|
||||
}
|
||||
)
|
||||
|
||||
@api.depends("name", "mimetype", "content")
|
||||
def _compute_extension(self):
|
||||
for record in self:
|
||||
record.extension = file.guess_extension(
|
||||
record.name, record.mimetype, record.content
|
||||
)
|
||||
|
||||
@api.depends("content")
|
||||
def _compute_mimetype(self):
|
||||
for record in self:
|
||||
binary = base64.b64decode(record.content or "")
|
||||
record.mimetype = guess_mimetype(binary)
|
||||
|
||||
@api.depends("size")
|
||||
def _compute_human_size(self):
|
||||
for item in self:
|
||||
item.human_size = human_size(item.size)
|
||||
|
||||
@api.depends("content_binary", "content_file", "attachment_id")
|
||||
def _compute_content(self):
|
||||
bin_size = self.env.context.get("bin_size", False)
|
||||
for record in self:
|
||||
if record.content_file:
|
||||
context = {"human_size": True} if bin_size else {"base64": True}
|
||||
record.content = record.with_context(**context).content_file
|
||||
elif record.content_binary:
|
||||
record.content = (
|
||||
record.content_binary
|
||||
if bin_size
|
||||
else base64.b64encode(record.content_binary)
|
||||
)
|
||||
elif record.attachment_id:
|
||||
context = {"human_size": True} if bin_size else {"base64": True}
|
||||
record.content = record.with_context(**context).attachment_id.datas
|
||||
|
||||
@api.depends("content_binary", "content_file")
|
||||
def _compute_save_type(self):
|
||||
for record in self:
|
||||
if record.content_file:
|
||||
record.save_type = "file"
|
||||
else:
|
||||
record.save_type = "database"
|
||||
|
||||
@api.depends("storage_id", "storage_id.save_type")
|
||||
def _compute_migration(self):
|
||||
storage_model = self.env["dms.storage"]
|
||||
save_field = storage_model._fields["save_type"]
|
||||
values = save_field._description_selection(self.env)
|
||||
selection = {value[0]: value[1] for value in values}
|
||||
for record in self:
|
||||
storage_type = record.storage_id.save_type
|
||||
if storage_type == "attachment" or storage_type == record.save_type:
|
||||
record.migration = selection.get(storage_type)
|
||||
record.require_migration = False
|
||||
else:
|
||||
storage_label = selection.get(storage_type)
|
||||
file_label = selection.get(record.save_type)
|
||||
record.migration = "{} > {}".format(file_label, storage_label)
|
||||
record.require_migration = True
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# View
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.onchange("category_id")
|
||||
def _change_category(self):
|
||||
self.tag_ids = self.tag_ids.filtered(
|
||||
lambda rec: not rec.category_id or rec.category_id == self.category_id
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Constrains
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.constrains("storage_id", "res_model", "res_id")
|
||||
def _check_storage_id_attachment_res_model(self):
|
||||
for record in self:
|
||||
if record.storage_id.save_type == "attachment" and not (
|
||||
record.res_model and record.res_id
|
||||
):
|
||||
raise ValidationError(
|
||||
_("A file must have model and resource ID in attachment storage.")
|
||||
)
|
||||
|
||||
@api.constrains("name")
|
||||
def _check_name(self):
|
||||
for record in self:
|
||||
if not file.check_name(record.name):
|
||||
raise ValidationError(_("The file name is invalid."))
|
||||
files = record.sudo().directory_id.file_ids.name_get()
|
||||
if list(
|
||||
filter(
|
||||
lambda file: file[1] == record.name and file[0] != record.id, files
|
||||
)
|
||||
):
|
||||
raise ValidationError(_("A file with the same name already exists."))
|
||||
|
||||
@api.constrains("extension")
|
||||
def _check_extension(self):
|
||||
for record in self:
|
||||
if (
|
||||
record.extension
|
||||
and record.extension in self._get_forbidden_extensions()
|
||||
):
|
||||
raise ValidationError(_("The file has a forbidden file extension."))
|
||||
|
||||
@api.constrains("size")
|
||||
def _check_size(self):
|
||||
for record in self:
|
||||
if record.size and record.size > self._get_binary_max_size() * 1024 * 1024:
|
||||
raise ValidationError(
|
||||
_("The maximum upload size is %s MB.") % self._get_binary_max_size()
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Create, Update, Delete
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def _inverse_content(self):
|
||||
updates = defaultdict(set)
|
||||
for record in self:
|
||||
values = self._get_content_inital_vals()
|
||||
binary = base64.b64decode(record.content or "")
|
||||
values = record._update_content_vals(values, binary)
|
||||
updates[tools.frozendict(values)].add(record.id)
|
||||
with self.env.norecompute():
|
||||
for vals, ids in updates.items():
|
||||
self.browse(ids).write(dict(vals))
|
||||
|
||||
def _create_model_attachment(self, vals):
|
||||
res_vals = vals.copy()
|
||||
if "directory_id" in res_vals:
|
||||
directory_id = res_vals["directory_id"]
|
||||
elif self.env.context.get("active_id"):
|
||||
directory_id = self.env.context.get("active_id")
|
||||
elif self.env.context.get("default_directory_id"):
|
||||
directory_id = self.env.context.get("default_directory_id")
|
||||
directory = self.env["dms.directory"].browse(directory_id)
|
||||
if (
|
||||
directory.res_model
|
||||
and directory.res_id
|
||||
and directory.storage_id_save_type == "attachment"
|
||||
):
|
||||
attachment = (
|
||||
self.env["ir.attachment"]
|
||||
.with_context(dms_file=True)
|
||||
.create(
|
||||
{
|
||||
"name": vals["name"],
|
||||
"datas": vals["content"],
|
||||
"res_model": directory.res_model,
|
||||
"res_id": directory.res_id,
|
||||
}
|
||||
)
|
||||
)
|
||||
res_vals["attachment_id"] = attachment.id
|
||||
res_vals["res_model"] = attachment.res_model
|
||||
res_vals["res_id"] = attachment.res_id
|
||||
del res_vals["content"]
|
||||
return res_vals
|
||||
|
||||
def copy(self, default=None):
|
||||
self.ensure_one()
|
||||
default = dict(default or [])
|
||||
if "directory_id" in default:
|
||||
model = self.env["dms.directory"]
|
||||
directory = model.browse(default["directory_id"])
|
||||
names = directory.sudo().file_ids.mapped("name")
|
||||
else:
|
||||
names = self.sudo().directory_id.file_ids.mapped("name")
|
||||
default.update({"name": file.unique_name(self.name, names, self.extension)})
|
||||
return super(File, self).copy(default)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
new_vals_list = []
|
||||
for vals in vals_list:
|
||||
if "attachment_id" not in vals:
|
||||
vals = self._create_model_attachment(vals)
|
||||
new_vals_list.append(vals)
|
||||
return super(File, self).create(new_vals_list)
|
||||
|
||||
def unlink(self):
|
||||
attachments = self.mapped("attachment_id")
|
||||
res = super().unlink()
|
||||
if not self.env.context.get("dms_file"):
|
||||
attachments.with_context(dms_file=True).unlink()
|
||||
return res
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Locking fields and functions
|
||||
# ----------------------------------------------------------
|
||||
|
||||
locked_by = fields.Many2one(comodel_name="res.users")
|
||||
|
||||
is_locked = fields.Boolean(compute="_compute_locked", string="Locked")
|
||||
|
||||
is_lock_editor = fields.Boolean(compute="_compute_locked", string="Editor")
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Locking
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def lock(self):
|
||||
self.write({"locked_by": self.env.uid})
|
||||
|
||||
def unlock(self):
|
||||
self.write({"locked_by": None})
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Read, View
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.depends("locked_by")
|
||||
def _compute_locked(self):
|
||||
for record in self:
|
||||
if record.locked_by.exists():
|
||||
record.update(
|
||||
{
|
||||
"is_locked": True,
|
||||
"is_lock_editor": record.locked_by.id == record.env.uid,
|
||||
}
|
||||
)
|
||||
else:
|
||||
record.update({"is_locked": False, "is_lock_editor": False})
|
||||
|
||||
def get_attachment_object(self, attachment):
|
||||
return {
|
||||
"name": attachment.name,
|
||||
"datas": attachment.datas,
|
||||
"res_model": attachment.res_model,
|
||||
"mimetype": attachment.mimetype,
|
||||
}
|
||||
|
||||
def get_dms_files_from_attachments(self, attachment_ids=None):
|
||||
"""Get the dms files from uploaded attachments.
|
||||
:return: An Array of dms files.
|
||||
"""
|
||||
if not attachment_ids:
|
||||
raise UserError(_("No attachment was provided"))
|
||||
|
||||
attachments = self.env["ir.attachment"].browse(attachment_ids)
|
||||
|
||||
if any(
|
||||
attachment.res_id or attachment.res_model != "dms.file"
|
||||
for attachment in attachments
|
||||
):
|
||||
raise UserError(_("Invalid attachments!"))
|
||||
|
||||
return [self.get_attachment_object(attachment) for attachment in attachments]
|
||||
259
odoo-bringout-oca-dms-dms/dms/models/dms_security_mixin.py
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
# Copyright 2020 Creu Blanca
|
||||
# Copyright 2021 Tecnativa - Víctor Martínez
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.osv.expression import FALSE_DOMAIN, NEGATIVE_TERM_OPERATORS, OR, TRUE_DOMAIN
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
|
||||
|
||||
class DmsSecurityMixin(models.AbstractModel):
|
||||
_name = "dms.security.mixin"
|
||||
_description = "DMS Security Mixin"
|
||||
|
||||
# Submodels must define this field that points to the owner dms.directory
|
||||
_directory_field = "directory_id"
|
||||
|
||||
res_model = fields.Char(
|
||||
string="Linked attachments model", index="btree", store=True
|
||||
)
|
||||
res_id = fields.Integer(
|
||||
string="Linked attachments record ID", index="btree", store=True
|
||||
)
|
||||
record_ref = fields.Reference(
|
||||
string="Record Referenced",
|
||||
compute="_compute_record_ref",
|
||||
selection=lambda self: self._get_ref_selection(),
|
||||
)
|
||||
permission_read = fields.Boolean(
|
||||
compute="_compute_permissions",
|
||||
search="_search_permission_read",
|
||||
string="Read Access",
|
||||
)
|
||||
permission_create = fields.Boolean(
|
||||
compute="_compute_permissions",
|
||||
search="_search_permission_create",
|
||||
string="Create Access",
|
||||
)
|
||||
permission_write = fields.Boolean(
|
||||
compute="_compute_permissions",
|
||||
search="_search_permission_write",
|
||||
string="Write Access",
|
||||
)
|
||||
permission_unlink = fields.Boolean(
|
||||
compute="_compute_permissions",
|
||||
search="_search_permission_unlink",
|
||||
string="Delete Access",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_ref_selection(self):
|
||||
models = self.env["ir.model"].sudo().search([])
|
||||
return [(model.model, model.name) for model in models]
|
||||
|
||||
@api.depends("res_model", "res_id")
|
||||
def _compute_record_ref(self):
|
||||
for record in self:
|
||||
record.record_ref = False
|
||||
if record.res_model and record.res_id:
|
||||
record.record_ref = "{},{}".format(record.res_model, record.res_id)
|
||||
|
||||
def _compute_permissions(self):
|
||||
"""Get permissions for the current record.
|
||||
|
||||
⚠ Not very performant; only display field on form views.
|
||||
"""
|
||||
# Superuser unrestricted 🦸
|
||||
if self.env.su:
|
||||
self.update(
|
||||
{
|
||||
"permission_create": True,
|
||||
"permission_read": True,
|
||||
"permission_unlink": True,
|
||||
"permission_write": True,
|
||||
}
|
||||
)
|
||||
return
|
||||
# Update according to presence when applying ir.rule
|
||||
creatable = self._filter_access_rules("create")
|
||||
readable = self._filter_access_rules("read")
|
||||
unlinkable = self._filter_access_rules("unlink")
|
||||
writeable = self._filter_access_rules("write")
|
||||
for one in self:
|
||||
one.update(
|
||||
{
|
||||
"permission_create": bool(one & creatable),
|
||||
"permission_read": bool(one & readable),
|
||||
"permission_unlink": bool(one & unlinkable),
|
||||
"permission_write": bool(one & writeable),
|
||||
}
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_domain_by_inheritance(self, operation):
|
||||
"""Get domain for inherited accessible records."""
|
||||
if self.env.su:
|
||||
return []
|
||||
inherited_access_field = "storage_id_inherit_access_from_parent_record"
|
||||
if self._name != "dms.directory":
|
||||
inherited_access_field = "{}.{}".format(
|
||||
self._directory_field,
|
||||
inherited_access_field,
|
||||
)
|
||||
inherited_access_domain = [
|
||||
("storage_id_save_type", "=", "attachment"),
|
||||
(inherited_access_field, "=", True),
|
||||
]
|
||||
domains = []
|
||||
# Get all used related records
|
||||
related_groups = self.sudo().read_group(
|
||||
domain=inherited_access_domain + [("res_model", "!=", False)],
|
||||
fields=["res_id:array_agg"],
|
||||
groupby=["res_model"],
|
||||
)
|
||||
for group in related_groups:
|
||||
try:
|
||||
model = self.env[group["res_model"]]
|
||||
except KeyError:
|
||||
# Model not registered. This is normal if you are upgrading the
|
||||
# database. Otherwise, you probably have garbage DMS data.
|
||||
# These records will be accessible by DB users only.
|
||||
domains.append(
|
||||
[
|
||||
("res_model", "=", group["res_model"]),
|
||||
(True, "=", self.env.user.has_group("base.group_user")),
|
||||
]
|
||||
)
|
||||
continue
|
||||
# Check model access only once per batch
|
||||
if not model.check_access_rights(operation, raise_exception=False):
|
||||
continue
|
||||
domains.append([("res_model", "=", model._name), ("res_id", "=", False)])
|
||||
# Check record access in batch too
|
||||
res_ids = [i for i in group["res_id"] if i] # Hack to remove None res_id
|
||||
# Apply exists to skip records that do not exist. (e.g. a res.partner deleted
|
||||
# by database).
|
||||
model_records = model.browse(res_ids).exists()
|
||||
related_ok = model_records._filter_access_rules_python(operation)
|
||||
if not related_ok:
|
||||
continue
|
||||
domains.append(
|
||||
[("res_model", "=", model._name), ("res_id", "in", related_ok.ids)]
|
||||
)
|
||||
result = inherited_access_domain + OR(domains)
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def _get_access_groups_query(self, operation):
|
||||
"""Return the query to select access groups."""
|
||||
operation_check = {
|
||||
"create": "AND dag.perm_inclusive_create",
|
||||
"read": "",
|
||||
"unlink": "AND dag.perm_inclusive_unlink",
|
||||
"write": "AND dag.perm_inclusive_write",
|
||||
}[operation]
|
||||
select = """
|
||||
SELECT
|
||||
dir_group_rel.aid
|
||||
FROM
|
||||
dms_directory_complete_groups_rel AS dir_group_rel
|
||||
INNER JOIN dms_access_group AS dag
|
||||
ON dir_group_rel.gid = dag.id
|
||||
INNER JOIN dms_access_group_users_rel AS users
|
||||
ON users.gid = dag.id
|
||||
WHERE
|
||||
users.uid = %s {}
|
||||
""".format(
|
||||
operation_check
|
||||
)
|
||||
return (select, (self.env.uid,))
|
||||
|
||||
@api.model
|
||||
def _get_domain_by_access_groups(self, operation):
|
||||
"""Get domain for records accessible applying DMS access groups."""
|
||||
result = [
|
||||
(
|
||||
"%s.storage_id_inherit_access_from_parent_record"
|
||||
% self._directory_field,
|
||||
"=",
|
||||
False,
|
||||
),
|
||||
(
|
||||
self._directory_field,
|
||||
"inselect",
|
||||
self._get_access_groups_query(operation),
|
||||
),
|
||||
]
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def _get_permission_domain(self, operator, value, operation):
|
||||
"""Abstract logic for searching computed permission fields."""
|
||||
_self = self
|
||||
# HACK ir.rule domain is always computed with sudo, so if this check is
|
||||
# true, we can assume safely that you're checking permissions
|
||||
if self.env.su and value == self.env.uid:
|
||||
_self = self.sudo(False)
|
||||
value = bool(value)
|
||||
# Tricky one, to know if you want to search
|
||||
# positive or negative access
|
||||
positive = (operator not in NEGATIVE_TERM_OPERATORS) == bool(value)
|
||||
if _self.env.su:
|
||||
# You're SUPERUSER_ID
|
||||
return TRUE_DOMAIN if positive else FALSE_DOMAIN
|
||||
# Obtain and combine domains
|
||||
result = OR(
|
||||
[
|
||||
_self._get_domain_by_access_groups(operation),
|
||||
_self._get_domain_by_inheritance(operation),
|
||||
]
|
||||
)
|
||||
if not positive:
|
||||
result.insert(0, "!")
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def _search_permission_create(self, operator, value):
|
||||
return self._get_permission_domain(operator, value, "create")
|
||||
|
||||
@api.model
|
||||
def _search_permission_read(self, operator, value):
|
||||
return self._get_permission_domain(operator, value, "read")
|
||||
|
||||
@api.model
|
||||
def _search_permission_unlink(self, operator, value):
|
||||
return self._get_permission_domain(operator, value, "unlink")
|
||||
|
||||
@api.model
|
||||
def _search_permission_write(self, operator, value):
|
||||
return self._get_permission_domain(operator, value, "write")
|
||||
|
||||
def _filter_access_rules_python(self, operation):
|
||||
# Only kept to not break inheritance; see next comment
|
||||
result = super()._filter_access_rules_python(operation)
|
||||
# HACK Always fall back to applying rules by SQL.
|
||||
# Upstream `_filter_acccess_rules_python()` doesn't use computed fields
|
||||
# search methods. Thus, it will take the `[('permission_{operation}',
|
||||
# '=', user.id)]` rule literally. Obviously that will always fail
|
||||
# because `self[f"permission_{operation}"]` will always be a `bool`,
|
||||
# while `user.id` will always be an `int`.
|
||||
result |= self._filter_access_rules(operation)
|
||||
return result
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
# Create as sudo to avoid testing creation permissions before DMS security
|
||||
# groups are attached (otherwise nobody would be able to create)
|
||||
res = super(DmsSecurityMixin, self.sudo()).create(vals_list)
|
||||
# Need to flush now, so all groups are stored in DB and the SELECT used
|
||||
# to check access works
|
||||
res.flush_recordset()
|
||||
# Go back to original sudo state and check we really had creation permission
|
||||
res = res.sudo(self.env.su)
|
||||
res.check_access_rights("create")
|
||||
res.check_access_rule("create")
|
||||
return res
|
||||
109
odoo-bringout-oca-dms-dms/dms/models/ir_attachment.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# Copyright 2021-2025 Tecnativa - Víctor Martínez
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
from odoo import api, models
|
||||
from odoo.tools import ormcache
|
||||
|
||||
|
||||
class IrAttachment(models.Model):
|
||||
|
||||
_inherit = "ir.attachment"
|
||||
|
||||
def _get_dms_directories(self, res_model, res_id):
|
||||
domain = [
|
||||
("res_model", "=", res_model),
|
||||
("res_id", "=", res_id),
|
||||
("storage_id.save_type", "=", "attachment"),
|
||||
]
|
||||
if self.env.context.get("attaching_to_record"):
|
||||
domain += [("storage_id.include_message_attachments", "=", True)]
|
||||
return self.env["dms.directory"].search(domain)
|
||||
|
||||
def _dms_directories_create(self):
|
||||
items = self.sudo()._get_dms_directories(self.res_model, False)
|
||||
for item in items:
|
||||
model_item = self.env[self.res_model].browse(self.res_id)
|
||||
ir_model_item = (
|
||||
self.env["ir.model"].sudo().search([("model", "=", self.res_model)])
|
||||
)
|
||||
self.env["dms.directory"].sudo().with_context(check_name=False).create(
|
||||
{
|
||||
"name": model_item.display_name,
|
||||
"model_id": ir_model_item.id,
|
||||
"res_model": self.res_model,
|
||||
"res_id": self.res_id,
|
||||
"parent_id": item.id,
|
||||
"storage_id": item.storage_id.id,
|
||||
}
|
||||
)
|
||||
|
||||
@ormcache("model")
|
||||
def _dms_operations_from_model(self, model):
|
||||
# Apply sudo to prevent ir.rule from being applied.
|
||||
item = self.env["dms.storage"].sudo().search([("model_ids.model", "=", model)])
|
||||
return bool(item)
|
||||
|
||||
def _dms_operations(self):
|
||||
"""Perform the operation only if there is a storage with linked models.
|
||||
The directory (dms.directory) linked to the record (if it does not exist)
|
||||
and the file (dms.file) with the linked attachment would be created.
|
||||
"""
|
||||
for attachment in self:
|
||||
if (
|
||||
not attachment.res_model
|
||||
or not attachment.res_id
|
||||
or (
|
||||
attachment.res_model
|
||||
and not self._dms_operations_from_model(attachment.res_model)
|
||||
)
|
||||
):
|
||||
continue
|
||||
directories = attachment._get_dms_directories(
|
||||
attachment.res_model, attachment.res_id
|
||||
)
|
||||
if not directories:
|
||||
attachment._dms_directories_create()
|
||||
# Get dms_directories again (with items previously created)
|
||||
directories = attachment._get_dms_directories(
|
||||
attachment.res_model, attachment.res_id
|
||||
)
|
||||
# Auto-create_files (if not exists)
|
||||
for directory in directories:
|
||||
dms_file_model = self.env["dms.file"].sudo()
|
||||
dms_file = dms_file_model.search(
|
||||
[
|
||||
("attachment_id", "=", attachment.id),
|
||||
("directory_id", "=", directory.id),
|
||||
]
|
||||
)
|
||||
if not dms_file:
|
||||
dms_file_model.create(
|
||||
{
|
||||
"name": attachment.name,
|
||||
"directory_id": directory.id,
|
||||
"attachment_id": attachment.id,
|
||||
"res_model": attachment.res_model,
|
||||
"res_id": attachment.res_id,
|
||||
}
|
||||
)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
records = super().create(vals_list)
|
||||
if not self.env.context.get("dms_file"):
|
||||
records._dms_operations()
|
||||
return records
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if not self.env.context.get("dms_file") and self.env.context.get(
|
||||
"attaching_to_record"
|
||||
):
|
||||
self._dms_operations()
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
if not self.env.context.get("dms_file"):
|
||||
self.env["dms.file"].search(
|
||||
[("attachment_id", "in", self.ids)]
|
||||
).with_context(dms_file=True).unlink()
|
||||
return super().unlink()
|
||||
17
odoo-bringout-oca-dms-dms/dms/models/mail_thread.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright 2021 Tecnativa - Jairo Llopis
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class MailThread(models.AbstractModel):
|
||||
_inherit = "mail.thread"
|
||||
|
||||
def _message_post_process_attachments(
|
||||
self, attachments, attachment_ids, message_data
|
||||
):
|
||||
"""Indicate to DMS that we're attaching a message to a record."""
|
||||
_self = self.with_context(attaching_to_record=True)
|
||||
return super(MailThread, _self)._message_post_process_attachments(
|
||||
attachments, attachment_ids, message_data
|
||||
)
|
||||
44
odoo-bringout-oca-dms-dms/dms/models/mixins_thumbnail.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright 2017-2019 MuK IT GmbH.
|
||||
# Copyright 2020 Creu Blanca
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import os
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.modules.module import get_resource_path
|
||||
|
||||
|
||||
class Thumbnail(models.AbstractModel):
|
||||
|
||||
_name = "dms.mixins.thumbnail"
|
||||
_inherit = "image.mixin"
|
||||
_description = "DMS thumbnail and icon mixin"
|
||||
|
||||
icon_url = fields.Char(string="Icon URL", compute="_compute_icon_url")
|
||||
|
||||
def _get_icon_disk_path(self):
|
||||
"""Obtain local disk path to record icon."""
|
||||
folders = ["static", "icons"]
|
||||
name = self._get_icon_placeholder_name()
|
||||
path = get_resource_path("dms", *folders, name)
|
||||
return path or get_resource_path("dms", *folders, "file_unknown.svg")
|
||||
|
||||
def _get_icon_placeholder_name(self):
|
||||
return "folder.svg"
|
||||
|
||||
def _get_icon_url(self):
|
||||
"""Obtain URL to record icon."""
|
||||
local_path = self._get_icon_disk_path()
|
||||
icon_name = os.path.basename(local_path)
|
||||
return "/dms/static/icons/%s" % icon_name
|
||||
|
||||
@api.depends("image_128")
|
||||
def _compute_icon_url(self):
|
||||
"""Get icon static file URL."""
|
||||
for one in self:
|
||||
# Get URL to thumbnail or to the default icon by file extension
|
||||
one.icon_url = (
|
||||
"/web/image/{}/{}/image_128/128x128?crop=1".format(one._name, one.id)
|
||||
if one.image_128
|
||||
else one._get_icon_url()
|
||||
)
|
||||
111
odoo-bringout-oca-dms-dms/dms/models/res_company.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Copyright 2020 Creu Blanca
|
||||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
|
||||
_inherit = "res.company"
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Database
|
||||
# ----------------------------------------------------------
|
||||
|
||||
documents_onboarding_state = fields.Selection(
|
||||
selection=[
|
||||
("not_done", "Not done"),
|
||||
("just_done", "Just done"),
|
||||
("done", "Done"),
|
||||
("closed", "Closed"),
|
||||
],
|
||||
default="not_done",
|
||||
)
|
||||
|
||||
documents_onboarding_storage_state = fields.Selection(
|
||||
selection=[
|
||||
("not_done", "Not done"),
|
||||
("just_done", "Just done"),
|
||||
("done", "Done"),
|
||||
("closed", "Closed"),
|
||||
],
|
||||
default="not_done",
|
||||
)
|
||||
|
||||
documents_onboarding_directory_state = fields.Selection(
|
||||
selection=[
|
||||
("not_done", "Not done"),
|
||||
("just_done", "Just done"),
|
||||
("done", "Done"),
|
||||
("closed", "Closed"),
|
||||
],
|
||||
default="not_done",
|
||||
)
|
||||
|
||||
documents_onboarding_file_state = fields.Selection(
|
||||
selection=[
|
||||
("not_done", "Not done"),
|
||||
("just_done", "Just done"),
|
||||
("done", "Done"),
|
||||
("closed", "Closed"),
|
||||
],
|
||||
default="not_done",
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Functions
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def get_and_update_documents_onboarding_state(self):
|
||||
return self._get_and_update_onboarding_state(
|
||||
"documents_onboarding_state", self.get_documents_steps_states_names()
|
||||
)
|
||||
|
||||
def get_documents_steps_states_names(self):
|
||||
return [
|
||||
"documents_onboarding_storage_state",
|
||||
"documents_onboarding_directory_state",
|
||||
"documents_onboarding_file_state",
|
||||
]
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Actions
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def action_open_documents_onboarding_storage(self):
|
||||
return self.env.ref("dms.action_dms_storage_new").read()[0]
|
||||
|
||||
@api.model
|
||||
def action_open_documents_onboarding_directory(self):
|
||||
storage = self.env["dms.storage"].search([], order="create_date desc", limit=1)
|
||||
action = self.env.ref("dms.action_dms_directory_new").read()[0]
|
||||
action["context"] = {
|
||||
**self.env.context,
|
||||
**{
|
||||
"default_is_root_directory": True,
|
||||
"default_storage_id": storage and storage.id,
|
||||
},
|
||||
}
|
||||
return action
|
||||
|
||||
@api.model
|
||||
def action_open_documents_onboarding_file(self):
|
||||
directory = self.env["dms.directory"].search(
|
||||
[], order="create_date desc", limit=1
|
||||
)
|
||||
action = self.env.ref("dms.action_dms_file_new").read()[0]
|
||||
action["context"] = {
|
||||
**self.env.context,
|
||||
**{"default_directory_id": directory and directory.id},
|
||||
}
|
||||
return action
|
||||
|
||||
@api.model
|
||||
def action_close_documents_onboarding(self):
|
||||
self.env.user.company_id.documents_onboarding_state = "closed"
|
||||
22
odoo-bringout-oca-dms-dms/dms/models/res_config_settings.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright 2020 Creu Blanca
|
||||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
documents_binary_max_size = fields.Integer(
|
||||
string="Size",
|
||||
help="Defines the maximum upload size in MB. Default (25MB)",
|
||||
config_parameter="dms.binary_max_size",
|
||||
)
|
||||
|
||||
documents_forbidden_extensions = fields.Char(
|
||||
string="Extensions",
|
||||
help="Defines a list of forbidden file extensions. (Example: 'exe,msi')",
|
||||
config_parameter="dms.forbidden_extensions",
|
||||
)
|
||||
153
odoo-bringout-oca-dms-dms/dms/models/storage.py
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
# Copyright 2017-2019 MuK IT GmbH.
|
||||
# Copyright 2020 Creu Blanca
|
||||
# Copyright 2021 Tecnativa - Víctor Martínez
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import AccessError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Storage(models.Model):
|
||||
|
||||
_name = "dms.storage"
|
||||
_description = "Storage"
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Database
|
||||
# ----------------------------------------------------------
|
||||
|
||||
name = fields.Char(required=True)
|
||||
|
||||
save_type = fields.Selection(
|
||||
selection=[
|
||||
("database", _("Database")),
|
||||
("file", _("Filestore")),
|
||||
("attachment", _("Attachment")),
|
||||
],
|
||||
default="database",
|
||||
required=True,
|
||||
help="""The save type is used to determine how a file is saved by the
|
||||
system. If you change this setting, you can migrate existing files
|
||||
manually by triggering the action.""",
|
||||
)
|
||||
|
||||
company_id = fields.Many2one(
|
||||
comodel_name="res.company",
|
||||
string="Company",
|
||||
default=lambda self: self.env.company,
|
||||
help="If set, directories and files will only be available for "
|
||||
"the selected company.",
|
||||
)
|
||||
|
||||
is_hidden = fields.Boolean(
|
||||
string="Storage is Hidden",
|
||||
default=False,
|
||||
help="Indicates if directories and files are hidden by default.",
|
||||
)
|
||||
|
||||
root_directory_ids = fields.One2many(
|
||||
comodel_name="dms.directory",
|
||||
inverse_name="storage_id",
|
||||
string="Root Directories",
|
||||
auto_join=False,
|
||||
readonly=False,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
storage_directory_ids = fields.One2many(
|
||||
comodel_name="dms.directory",
|
||||
inverse_name="storage_id",
|
||||
string="Directories",
|
||||
auto_join=False,
|
||||
readonly=True,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
storage_file_ids = fields.One2many(
|
||||
comodel_name="dms.file",
|
||||
inverse_name="storage_id",
|
||||
string="Files",
|
||||
auto_join=False,
|
||||
readonly=True,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
count_storage_directories = fields.Integer(
|
||||
compute="_compute_count_storage_directories", string="Count Directories"
|
||||
)
|
||||
|
||||
count_storage_files = fields.Integer(
|
||||
compute="_compute_count_storage_files", string="Count Files"
|
||||
)
|
||||
|
||||
model_ids = fields.Many2many("ir.model", string="Linked Models")
|
||||
inherit_access_from_parent_record = fields.Boolean(
|
||||
string="Inherit permissions from related record",
|
||||
default=False,
|
||||
help="Indicate if directories and files access work only with "
|
||||
"related model access (for example, if some directories are related "
|
||||
"with any sale, only users with read access to these sale can acess)",
|
||||
)
|
||||
include_message_attachments = fields.Boolean(
|
||||
string="Create files from message attachments",
|
||||
default=False,
|
||||
help="Indicate if directories and files auto-create in mail "
|
||||
"composition process too",
|
||||
)
|
||||
model = fields.Char(search="_search_model", store=False)
|
||||
|
||||
def _search_model(self, operator, value):
|
||||
allowed_items = self.env["ir.model"].sudo().search([("model", operator, value)])
|
||||
return [("model_ids", "in", allowed_items.ids)]
|
||||
|
||||
@api.onchange("save_type")
|
||||
def _onchange_save_type(self):
|
||||
for record in self:
|
||||
if record.save_type == "attachment":
|
||||
record.inherit_access_from_parent_record = True
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Actions
|
||||
# ----------------------------------------------------------
|
||||
|
||||
def action_storage_migrate(self):
|
||||
if self.save_type != "attachment":
|
||||
if not self.env.user.has_group("dms.group_dms_manager"):
|
||||
raise AccessError(_("Only managers can execute this action."))
|
||||
files = self.env["dms.file"].with_context(active_test=False).sudo()
|
||||
|
||||
for record in self:
|
||||
domain = [
|
||||
("require_migration", "=", True),
|
||||
("storage_id", "=", record.id),
|
||||
]
|
||||
files.search(domain).action_migrate()
|
||||
|
||||
def action_save_onboarding_storage_step(self):
|
||||
self.env.user.company_id.set_onboarding_step_done(
|
||||
"documents_onboarding_storage_state"
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Read, View
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@api.depends("storage_directory_ids")
|
||||
def _compute_count_storage_directories(self):
|
||||
for record in self:
|
||||
record.count_storage_directories = len(record.storage_directory_ids)
|
||||
|
||||
@api.depends("storage_file_ids")
|
||||
def _compute_count_storage_files(self):
|
||||
for record in self:
|
||||
record.count_storage_files = len(record.storage_file_ids)
|
||||
|
||||
def write(self, values):
|
||||
res = super().write(values)
|
||||
if "model_ids" in values:
|
||||
self.env["ir.attachment"].clear_caches()
|
||||
return res
|
||||
59
odoo-bringout-oca-dms-dms/dms/models/tag.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Copyright 2020 RGB Consulting
|
||||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Tag(models.Model):
|
||||
_name = "dms.tag"
|
||||
_description = "Document Tag"
|
||||
|
||||
name = fields.Char(required=True, translate=True)
|
||||
active = fields.Boolean(
|
||||
default=True,
|
||||
help="The active field allows you " "to hide the tag without removing it.",
|
||||
)
|
||||
category_id = fields.Many2one(
|
||||
comodel_name="dms.category",
|
||||
context="{'dms_category_show_path': True}",
|
||||
string="Category",
|
||||
ondelete="set null",
|
||||
)
|
||||
color = fields.Integer(string="Color Index", default=10)
|
||||
directory_ids = fields.Many2many(
|
||||
comodel_name="dms.directory",
|
||||
relation="dms_directory_tag_rel",
|
||||
column1="tid",
|
||||
column2="did",
|
||||
string="Directories",
|
||||
readonly=True,
|
||||
)
|
||||
file_ids = fields.Many2many(
|
||||
comodel_name="dms.file",
|
||||
relation="dms_file_tag_rel",
|
||||
column1="tid",
|
||||
column2="fid",
|
||||
string="Files",
|
||||
readonly=True,
|
||||
)
|
||||
count_directories = fields.Integer(compute="_compute_count_directories")
|
||||
count_files = fields.Integer(compute="_compute_count_files")
|
||||
|
||||
_sql_constraints = [
|
||||
("name_uniq", "unique (name, category_id)", "Tag name already exists!"),
|
||||
]
|
||||
|
||||
@api.depends("directory_ids")
|
||||
def _compute_count_directories(self):
|
||||
for rec in self:
|
||||
rec.count_directories = len(rec.directory_ids)
|
||||
|
||||
@api.depends("file_ids")
|
||||
def _compute_count_files(self):
|
||||
for rec in self:
|
||||
rec.count_files = len(rec.file_ids)
|
||||
40
odoo-bringout-oca-dms-dms/dms/readme/CONFIGURE.rst
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
To configure this module, you need to:
|
||||
|
||||
#. Go to *Documents -> Configuration -> Storages*.
|
||||
#. Create a new document storage. You can choose between two options on `Save Type`:
|
||||
* `Database`: Store the files on the database as a field
|
||||
* `Attachment`: Store the files as attachments
|
||||
#. Next create an administrative access group. Go to *Configuration -> Access Groups*.
|
||||
* Create a new group, name it appropriately, and turn on all three permissions (Create, Write and Unlink - Read is implied and always enabled).
|
||||
* Add any other top-level administrative users to the group if needed (your user should already be there).
|
||||
* You can create other groups in here later for fine grained access control.
|
||||
#. Afterwards go to *Documents -> Directories*.
|
||||
#. Create a new directory, mark it as root and select the previously created setting.
|
||||
* Select the *Groups* tab and add your administrative group created above.
|
||||
#. On the Directory you can also add other access groups (created above) that will be able to:
|
||||
* read
|
||||
* create
|
||||
* write
|
||||
* delete
|
||||
|
||||
|
||||
Migration
|
||||
~~~~~~~~~
|
||||
|
||||
If you need to modify the storage Save Type you might want to migrate the file data.
|
||||
In order to achieve it you need to:
|
||||
|
||||
#. Go to *Documents -> Configuration -> Storage* and select the storage you want to modify
|
||||
#. Modify the save type
|
||||
#. Press the button `Migrate files` if you want to migrate all the files at once
|
||||
#. Press the button `Manual File Migration` in order to specify files one by one
|
||||
|
||||
You can check all the files that still needs to be migrated from all storages
|
||||
and migrate them manually on *Documents -> Configuration -> Migration*
|
||||
|
||||
|
||||
File Wizard Selection
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There is an action called `action_dms_file_wizard_selector` to open a wizard to list files in kanban view.
|
||||
This can be used (example `dms_attachment_link` module) to add a button in kanban view with the action we need.
|
||||
16
odoo-bringout-oca-dms-dms/dms/readme/CONTRIBUTORS.rst
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
* Mathias Markl <mathias.markl@mukit.at>
|
||||
* Enric Tobella <etobella@creublanca.es>
|
||||
* Antoni Romera
|
||||
* Gelu Boros <gelu.boros@rgbconsulting.com>
|
||||
|
||||
* `Tecnativa <https://www.tecnativa.com>`_:
|
||||
|
||||
* Víctor Martínez
|
||||
* Pedro M. Baeza
|
||||
* Jairo Llopis
|
||||
|
||||
* `Elego <https://www.elegosoft.com>`_:
|
||||
|
||||
* Yu Weng <yweng@elegosoft.com>
|
||||
* Philip Witte <phillip.witte@elegosoft.com>
|
||||
* Khanh Bui <khanh.bui@mail.elegosoft.com>
|
||||
6
odoo-bringout-oca-dms-dms/dms/readme/CREDITS.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
The migration of this module from 15.0 to 16.0 was financially supported by `AgentERP <https://www.agenterp.com>`_
|
||||
|
||||
Some pictures are based on or inspired by:
|
||||
|
||||
* `Roundicons <https://www.flaticon.com/authors/roundicons>`_
|
||||
* `Smashicons <https://www.flaticon.com/authors/smashicons>`_
|
||||
6
odoo-bringout-oca-dms-dms/dms/readme/DESCRIPTION.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
DMS is a module for creating, managing and viewing document files directly
|
||||
within Odoo.
|
||||
This module is only the basis for an entire ecosystem of apps that extend and
|
||||
seamlessly integrate with the document management system.
|
||||
|
||||
This module adds portal functionality for directories and files for allowed users, both portal or internal users. You can get as well a tokenized link from a directory or a file for sharing it with any anonymous user.
|
||||
9
odoo-bringout-oca-dms-dms/dms/readme/INSTALL.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Preview
|
||||
~~~~~~~
|
||||
|
||||
``mail_preview_base`` is required for DMS but it is recommended to install all
|
||||
the other `mail_preview` modules from `social` OCA repository
|
||||
in order to improve the preview of files.
|
||||
|
||||
``python-magic`` library is recommended to be installed for having whole support
|
||||
to get proper file types and file preview.
|
||||
9
odoo-bringout-oca-dms-dms/dms/readme/ROADMAP.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
- Files preview in portal
|
||||
- Allow to download folder in portal and create zip file with all content
|
||||
- Save in cache own_root directories and update in every create/write/unlink function
|
||||
- Add a migration procedure for converting an storage to attachment one for populating existing records with attachments as folders
|
||||
- Add a link from attachment view in chatter to linked documents
|
||||
- If Inherit permissions from related record (the inherit_access_from_parent_record field from storage) is changed when directories already exist, inconsistencies may occur because groups defined in the directories and subdirectories will still exist, all groups in these directories should be removed before changing.
|
||||
- Since portal users can read ``dms.storage`` records, if your module extends this model to another storage backend that needs using secrets, remember to forbid access to the secrets fields by other means. It would be nice to be able to remove that rule at some point.
|
||||
- Searchpanel in files: Highlight items (shading) without records when filtering something (by name for example).
|
||||
- Accessing the clipboard (for example copy share link of file/directory) is limited to secure connections. It also happens in any part of Odoo.
|
||||
8
odoo-bringout-oca-dms-dms/dms/readme/USAGE.rst
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
The best way to manage the documents is to switch to the Documents view.
|
||||
Existing documents can be managed there and new documents can be created.
|
||||
|
||||
Portal functionality
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can add any portal user to DMS access groups, and then allow that group in directories, so they will see in the portal such directories and their files.
|
||||
Another possibility is to click on "Share" button inside a directory or a file for obtaining a tokenized link for single access to that resource, no matter if logged or not.
|
||||
27
odoo-bringout-oca-dms-dms/dms/security/ir.model.access.csv
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
|
||||
|
||||
access_dms_tag_user,dms_tag_user,model_dms_tag,group_dms_user,1,1,1,1
|
||||
access_dms_category_user,dms_category_user,model_dms_category,group_dms_user,1,1,1,1
|
||||
|
||||
access_dms_storage_base_user,dms_storage_base_user,model_dms_storage,base.group_user,1,0,0,0
|
||||
access_dms_storage_portal,dms_storage_portal,model_dms_storage,base.group_portal,1,0,0,0
|
||||
access_dms_storage_user,dms_storage_user,model_dms_storage,group_dms_user,1,0,0,0
|
||||
access_dms_storage_manager,dms_storage_manager,model_dms_storage,group_dms_manager,1,1,1,1
|
||||
|
||||
access_dms_directory_public,dms_directory_public,model_dms_directory,base.group_public,1,0,0,0
|
||||
access_dms_directory_portal,dms_directory_portal,model_dms_directory,base.group_portal,1,0,0,0
|
||||
access_dms_directory_base_user,dms_directory_base_user,model_dms_directory,base.group_user,1,0,0,0
|
||||
access_dms_directory_user,dms_directory_user,model_dms_directory,group_dms_user,1,1,1,1
|
||||
|
||||
access_dms_file_public,dms_file_public,model_dms_file,base.group_public,1,0,0,0
|
||||
access_dms_file_portal,dms_file_portal,model_dms_file,base.group_portal,1,0,0,0
|
||||
access_dms_file_base_user,dms_file_base_user,model_dms_file,base.group_user,1,0,0,0
|
||||
access_dms_file_user,dms_file_user,model_dms_file,group_dms_user,1,1,1,1
|
||||
|
||||
access_dms_access_group_public,access_dms_access_group_public,model_dms_access_group,base.group_public,1,0,0,0
|
||||
access_dms_access_group_portal,access_dms_access_group_portal,model_dms_access_group,base.group_portal,1,0,0,0
|
||||
access_security_access_groups_user,access_security_access_groups_user,model_dms_access_group,base.group_user,1,0,0,0
|
||||
access_security_access_groups_dms_user,access_security_access_groups_dms_user,model_dms_access_group,group_dms_user,1,1,1,1
|
||||
|
||||
access_wizard_dms_file_move,access_wizard_dms_file_move,model_wizard_dms_file_move,group_dms_user,1,1,1,1
|
||||
access_wizard_dms_share,access_wizard_dms_share,model_wizard_dms_share,group_dms_manager,1,1,1,0
|
||||
|
190
odoo-bringout-oca-dms-dms/dms/security/security.xml
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
Copyright 2020 Creu Blanca
|
||||
Copyright 2021 Tecnativa - Víctor Martínez
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<odoo>
|
||||
<record id="category_dms_security" model="ir.module.category">
|
||||
<field name="name">Documents</field>
|
||||
</record>
|
||||
<record id="group_dms_user" model="res.groups">
|
||||
<field name="name">User</field>
|
||||
<field name="category_id" ref="category_dms_security" />
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]" />
|
||||
</record>
|
||||
<record id="group_dms_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="implied_ids" eval="[(4, ref('group_dms_user'))]" />
|
||||
<field name="category_id" ref="category_dms_security" />
|
||||
<field
|
||||
name="users"
|
||||
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
|
||||
/>
|
||||
</record>
|
||||
<record id="rule_multi_company_storage" model="ir.rule">
|
||||
<field name="name">DMS Storage multi-company</field>
|
||||
<field name="model_id" ref="model_dms_storage" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
|
||||
</record>
|
||||
<record id="rule_multi_company_directory" model="ir.rule">
|
||||
<field name="name">DMS Directory multi-company</field>
|
||||
<field name="model_id" ref="model_dms_directory" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
|
||||
</record>
|
||||
<record id="rule_multi_company_file" model="ir.rule">
|
||||
<field name="name">File multi-company</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
|
||||
</record>
|
||||
<record id="rule_file_locked" model="ir.rule">
|
||||
<field name="name">Locked files are only modified by locker user.</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="groups" eval="[(4, ref('base.group_user'))]" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|', ('locked_by', '=', False), ('locked_by', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_security_groups_user" model="ir.rule">
|
||||
<field name="name">DMS users can only edit and delete their own groups.</field>
|
||||
<field name="model_id" ref="model_dms_access_group" />
|
||||
<field name="groups" eval="[(4, ref('group_dms_user'))]" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field name="domain_force">[('create_uid','=',user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_security_groups_manager" model="ir.rule">
|
||||
<field name="name">DMS Managers can edit and delete all groups.</field>
|
||||
<field name="model_id" ref="model_dms_access_group" />
|
||||
<field name="groups" eval="[(4, ref('group_dms_manager'))]" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field name="domain_force">[(1 ,'=', 1)]</field>
|
||||
</record>
|
||||
<!-- Forbid lower groups access to hidden storage -->
|
||||
<record id="rule_forbid_hidden_storage" model="ir.rule">
|
||||
<field name="name">Basic users cannot access hidden storage</field>
|
||||
<field name="model_id" ref="model_dms_storage" />
|
||||
<field
|
||||
name="groups"
|
||||
eval="[(4, ref('base.group_portal')), (4, ref('group_dms_user'))]"
|
||||
/>
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field name="domain_force">[('is_hidden', '=', False)]</field>
|
||||
</record>
|
||||
<record id="rule_allow_hidden_storage" model="ir.rule">
|
||||
<field name="name">Managers can access hidden storage</field>
|
||||
<field name="model_id" ref="model_dms_storage" />
|
||||
<field name="groups" eval="[(4, ref('group_dms_manager'))]" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field name="domain_force">[('is_hidden', '=', True)]</field>
|
||||
</record>
|
||||
<!-- These rules leverage computed permission management -->
|
||||
<record id="rule_directory_computed_create" model="ir.rule">
|
||||
<field name="name">Apply computed create permissions.</field>
|
||||
<field name="model_id" ref="model_dms_directory" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
<field name="domain_force">[('permission_create', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_directory_computed_read" model="ir.rule">
|
||||
<field name="name">Apply computed read permissions.</field>
|
||||
<field name="model_id" ref="model_dms_directory" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
<field name="domain_force">[('permission_read', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_directory_computed_unlink" model="ir.rule">
|
||||
<field name="name">Apply computed unlink permissions.</field>
|
||||
<field name="model_id" ref="model_dms_directory" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field name="domain_force">[('permission_unlink', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_directory_computed_write" model="ir.rule">
|
||||
<field name="name">Apply computed write permissions.</field>
|
||||
<field name="model_id" ref="model_dms_directory" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
<field name="domain_force">[('permission_write', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_file_computed_create" model="ir.rule">
|
||||
<field name="name">Apply computed create permissions.</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="1" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
<field name="domain_force">[('permission_create', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_file_computed_read" model="ir.rule">
|
||||
<field name="name">Apply computed read permissions.</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
<field name="domain_force">[('permission_read', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_file_computed_unlink" model="ir.rule">
|
||||
<field name="name">Apply computed unlink permissions.</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="1" />
|
||||
<field name="domain_force">[('permission_unlink', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_file_computed_write" model="ir.rule">
|
||||
<field name="name">Apply computed write permissions.</field>
|
||||
<field name="model_id" ref="model_dms_file" />
|
||||
<field name="global" eval="True" />
|
||||
<field name="perm_read" eval="0" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="1" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
<field name="domain_force">[('permission_write', '=', user.id)]</field>
|
||||
</record>
|
||||
</odoo>
|
||||
BIN
odoo-bringout-oca-dms-dms/dms/static/description/icon.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
566
odoo-bringout-oca-dms-dms/dms/static/description/index.html
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||
<title>Document Management System</title>
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
:Author: David Goodger (goodger@python.org)
|
||||
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
Despite the name, some widely supported CSS2 features are used.
|
||||
|
||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||
customize this style sheet.
|
||||
*/
|
||||
|
||||
/* used to remove borders from tables and images */
|
||||
.borderless, table.borderless td, table.borderless th {
|
||||
border: 0 }
|
||||
|
||||
table.borderless td, table.borderless th {
|
||||
/* Override padding for "table.docutils td" with "! important".
|
||||
The right padding separates the table cells. */
|
||||
padding: 0 0.5em 0 0 ! important }
|
||||
|
||||
.first {
|
||||
/* Override more specific margin styles with "! important". */
|
||||
margin-top: 0 ! important }
|
||||
|
||||
.last, .with-subtitle {
|
||||
margin-bottom: 0 ! important }
|
||||
|
||||
.hidden {
|
||||
display: none }
|
||||
|
||||
.subscript {
|
||||
vertical-align: sub;
|
||||
font-size: smaller }
|
||||
|
||||
.superscript {
|
||||
vertical-align: super;
|
||||
font-size: smaller }
|
||||
|
||||
a.toc-backref {
|
||||
text-decoration: none ;
|
||||
color: black }
|
||||
|
||||
blockquote.epigraph {
|
||||
margin: 2em 5em ; }
|
||||
|
||||
dl.docutils dd {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Uncomment (and remove this text!) to get bold-faced definition list terms
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
*/
|
||||
|
||||
div.abstract {
|
||||
margin: 2em 5em }
|
||||
|
||||
div.abstract p.topic-title {
|
||||
font-weight: bold ;
|
||||
text-align: center }
|
||||
|
||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
||||
div.hint, div.important, div.note, div.tip, div.warning {
|
||||
margin: 2em ;
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
||||
div.important p.admonition-title, div.note p.admonition-title,
|
||||
div.tip p.admonition-title {
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
||||
div.danger p.admonition-title, div.error p.admonition-title,
|
||||
div.warning p.admonition-title, .code .error {
|
||||
color: red ;
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
||||
compound paragraphs.
|
||||
div.compound .compound-first, div.compound .compound-middle {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.compound .compound-last, div.compound .compound-middle {
|
||||
margin-top: 0.5em }
|
||||
*/
|
||||
|
||||
div.dedication {
|
||||
margin: 2em 5em ;
|
||||
text-align: center ;
|
||||
font-style: italic }
|
||||
|
||||
div.dedication p.topic-title {
|
||||
font-weight: bold ;
|
||||
font-style: normal }
|
||||
|
||||
div.figure {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
div.footer, div.header {
|
||||
clear: both;
|
||||
font-size: smaller }
|
||||
|
||||
div.line-block {
|
||||
display: block ;
|
||||
margin-top: 1em ;
|
||||
margin-bottom: 1em }
|
||||
|
||||
div.line-block div.line-block {
|
||||
margin-top: 0 ;
|
||||
margin-bottom: 0 ;
|
||||
margin-left: 1.5em }
|
||||
|
||||
div.sidebar {
|
||||
margin: 0 0 0.5em 1em ;
|
||||
border: medium outset ;
|
||||
padding: 1em ;
|
||||
background-color: #ffffee ;
|
||||
width: 40% ;
|
||||
float: right ;
|
||||
clear: right }
|
||||
|
||||
div.sidebar p.rubric {
|
||||
font-family: sans-serif ;
|
||||
font-size: medium }
|
||||
|
||||
div.system-messages {
|
||||
margin: 5em }
|
||||
|
||||
div.system-messages h1 {
|
||||
color: red }
|
||||
|
||||
div.system-message {
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.system-message p.system-message-title {
|
||||
color: red ;
|
||||
font-weight: bold }
|
||||
|
||||
div.topic {
|
||||
margin: 2em }
|
||||
|
||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
||||
margin-top: 0.4em }
|
||||
|
||||
h1.title {
|
||||
text-align: center }
|
||||
|
||||
h2.subtitle {
|
||||
text-align: center }
|
||||
|
||||
hr.docutils {
|
||||
width: 75% }
|
||||
|
||||
img.align-left, .figure.align-left, object.align-left, table.align-left {
|
||||
clear: left ;
|
||||
float: left ;
|
||||
margin-right: 1em }
|
||||
|
||||
img.align-right, .figure.align-right, object.align-right, table.align-right {
|
||||
clear: right ;
|
||||
float: right ;
|
||||
margin-left: 1em }
|
||||
|
||||
img.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left }
|
||||
|
||||
.align-center {
|
||||
clear: both ;
|
||||
text-align: center }
|
||||
|
||||
.align-right {
|
||||
text-align: right }
|
||||
|
||||
/* reset inner alignment in figures */
|
||||
div.align-right {
|
||||
text-align: inherit }
|
||||
|
||||
/* div.align-center * { */
|
||||
/* text-align: left } */
|
||||
|
||||
.align-top {
|
||||
vertical-align: top }
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle }
|
||||
|
||||
.align-bottom {
|
||||
vertical-align: bottom }
|
||||
|
||||
ol.simple, ul.simple {
|
||||
margin-bottom: 1em }
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal }
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha }
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha }
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman }
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman }
|
||||
|
||||
p.attribution {
|
||||
text-align: right ;
|
||||
margin-left: 50% }
|
||||
|
||||
p.caption {
|
||||
font-style: italic }
|
||||
|
||||
p.credits {
|
||||
font-style: italic ;
|
||||
font-size: smaller }
|
||||
|
||||
p.label {
|
||||
white-space: nowrap }
|
||||
|
||||
p.rubric {
|
||||
font-weight: bold ;
|
||||
font-size: larger ;
|
||||
color: maroon ;
|
||||
text-align: center }
|
||||
|
||||
p.sidebar-title {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold ;
|
||||
font-size: larger }
|
||||
|
||||
p.sidebar-subtitle {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
p.topic-title {
|
||||
font-weight: bold }
|
||||
|
||||
pre.address {
|
||||
margin-bottom: 0 ;
|
||||
margin-top: 0 ;
|
||||
font: inherit }
|
||||
|
||||
pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
pre.code .ln { color: gray; } /* line numbers */
|
||||
pre.code, code { background-color: #eeeeee }
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
span.classifier {
|
||||
font-family: sans-serif ;
|
||||
font-style: oblique }
|
||||
|
||||
span.classifier-delimiter {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
span.interpreted {
|
||||
font-family: sans-serif }
|
||||
|
||||
span.option {
|
||||
white-space: nowrap }
|
||||
|
||||
span.pre {
|
||||
white-space: pre }
|
||||
|
||||
span.problematic, pre.problematic {
|
||||
color: red }
|
||||
|
||||
span.section-subtitle {
|
||||
/* font-size relative to parent (h1..h6 element) */
|
||||
font-size: 80% }
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docinfo {
|
||||
margin: 2em 4em }
|
||||
|
||||
table.docutils {
|
||||
margin-top: 0.5em ;
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
table.footnote {
|
||||
border-left: solid 1px black;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docutils td, table.docutils th,
|
||||
table.docinfo td, table.docinfo th {
|
||||
padding-left: 0.5em ;
|
||||
padding-right: 0.5em ;
|
||||
vertical-align: top }
|
||||
|
||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
||||
font-weight: bold ;
|
||||
text-align: left ;
|
||||
white-space: nowrap ;
|
||||
padding-left: 0 }
|
||||
|
||||
/* "booktabs" style (no vertical lines) */
|
||||
table.docutils.booktabs {
|
||||
border: 0px;
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.docutils.booktabs * {
|
||||
border: 0px;
|
||||
}
|
||||
table.docutils.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
|
||||
font-size: 100% }
|
||||
|
||||
ul.auto-toc {
|
||||
list-style-type: none }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="document-management-system">
|
||||
<h1 class="title">Document Management System</h1>
|
||||
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:4ca37da84fb902307a08168a40a5048ba34c2af01b05c97a139cca5eb19b8301
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/dms/tree/16.0/dms"><img alt="OCA/dms" src="https://img.shields.io/badge/github-OCA%2Fdms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/dms-16-0/dms-16-0-dms"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/dms&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||
<p>DMS is a module for creating, managing and viewing document files directly
|
||||
within Odoo.
|
||||
This module is only the basis for an entire ecosystem of apps that extend and
|
||||
seamlessly integrate with the document management system.</p>
|
||||
<p>This module adds portal functionality for directories and files for allowed users, both portal or internal users. You can get as well a tokenized link from a directory or a file for sharing it with any anonymous user.</p>
|
||||
<p><strong>Table of contents</strong></p>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a><ul>
|
||||
<li><a class="reference internal" href="#preview" id="toc-entry-2">Preview</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#configuration" id="toc-entry-3">Configuration</a><ul>
|
||||
<li><a class="reference internal" href="#migration" id="toc-entry-4">Migration</a></li>
|
||||
<li><a class="reference internal" href="#file-wizard-selection" id="toc-entry-5">File Wizard Selection</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#usage" id="toc-entry-6">Usage</a><ul>
|
||||
<li><a class="reference internal" href="#portal-functionality" id="toc-entry-7">Portal functionality</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-8">Known issues / Roadmap</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-9">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="toc-entry-10">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="toc-entry-11">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="toc-entry-12">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#other-credits" id="toc-entry-13">Other credits</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-14">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="installation">
|
||||
<h1><a class="toc-backref" href="#toc-entry-1">Installation</a></h1>
|
||||
<div class="section" id="preview">
|
||||
<h2><a class="toc-backref" href="#toc-entry-2">Preview</a></h2>
|
||||
<p><tt class="docutils literal">mail_preview_base</tt> is required for DMS but it is recommended to install all
|
||||
the other <cite>mail_preview</cite> modules from <cite>social</cite> OCA repository
|
||||
in order to improve the preview of files.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">python-magic</span></tt> library is recommended to be installed for having whole support
|
||||
to get proper file types and file preview.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="configuration">
|
||||
<h1><a class="toc-backref" href="#toc-entry-3">Configuration</a></h1>
|
||||
<p>To configure this module, you need to:</p>
|
||||
<ol class="arabic simple">
|
||||
<li>Go to <em>Documents -> Configuration -> Storages</em>.</li>
|
||||
<li><dl class="first docutils">
|
||||
<dt>Create a new document storage. You can choose between two options on <cite>Save Type</cite>:</dt>
|
||||
<dd><ul class="first last">
|
||||
<li><cite>Database</cite>: Store the files on the database as a field</li>
|
||||
<li><cite>Attachment</cite>: Store the files as attachments</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li><dl class="first docutils">
|
||||
<dt>Next create an administrative access group. Go to <em>Configuration -> Access Groups</em>.</dt>
|
||||
<dd><ul class="first last">
|
||||
<li>Create a new group, name it appropriately, and turn on all three permissions (Create, Write and Unlink - Read is implied and always enabled).</li>
|
||||
<li>Add any other top-level administrative users to the group if needed (your user should already be there).</li>
|
||||
<li>You can create other groups in here later for fine grained access control.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li>Afterwards go to <em>Documents -> Directories</em>.</li>
|
||||
<li><dl class="first docutils">
|
||||
<dt>Create a new directory, mark it as root and select the previously created setting.</dt>
|
||||
<dd><ul class="first last">
|
||||
<li>Select the <em>Groups</em> tab and add your administrative group created above.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li><dl class="first docutils">
|
||||
<dt>On the Directory you can also add other access groups (created above) that will be able to:</dt>
|
||||
<dd><ul class="first last">
|
||||
<li>read</li>
|
||||
<li>create</li>
|
||||
<li>write</li>
|
||||
<li>delete</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ol>
|
||||
<div class="section" id="migration">
|
||||
<h2><a class="toc-backref" href="#toc-entry-4">Migration</a></h2>
|
||||
<p>If you need to modify the storage Save Type you might want to migrate the file data.
|
||||
In order to achieve it you need to:</p>
|
||||
<ol class="arabic simple">
|
||||
<li>Go to <em>Documents -> Configuration -> Storage</em> and select the storage you want to modify</li>
|
||||
<li>Modify the save type</li>
|
||||
<li>Press the button <cite>Migrate files</cite> if you want to migrate all the files at once</li>
|
||||
<li>Press the button <cite>Manual File Migration</cite> in order to specify files one by one</li>
|
||||
</ol>
|
||||
<p>You can check all the files that still needs to be migrated from all storages
|
||||
and migrate them manually on <em>Documents -> Configuration -> Migration</em></p>
|
||||
</div>
|
||||
<div class="section" id="file-wizard-selection">
|
||||
<h2><a class="toc-backref" href="#toc-entry-5">File Wizard Selection</a></h2>
|
||||
<p>There is an action called <cite>action_dms_file_wizard_selector</cite> to open a wizard to list files in kanban view.
|
||||
This can be used (example <cite>dms_attachment_link</cite> module) to add a button in kanban view with the action we need.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h1><a class="toc-backref" href="#toc-entry-6">Usage</a></h1>
|
||||
<p>The best way to manage the documents is to switch to the Documents view.
|
||||
Existing documents can be managed there and new documents can be created.</p>
|
||||
<div class="section" id="portal-functionality">
|
||||
<h2><a class="toc-backref" href="#toc-entry-7">Portal functionality</a></h2>
|
||||
<p>You can add any portal user to DMS access groups, and then allow that group in directories, so they will see in the portal such directories and their files.
|
||||
Another possibility is to click on “Share” button inside a directory or a file for obtaining a tokenized link for single access to that resource, no matter if logged or not.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="known-issues-roadmap">
|
||||
<h1><a class="toc-backref" href="#toc-entry-8">Known issues / Roadmap</a></h1>
|
||||
<ul class="simple">
|
||||
<li>Files preview in portal</li>
|
||||
<li>Allow to download folder in portal and create zip file with all content</li>
|
||||
<li>Save in cache own_root directories and update in every create/write/unlink function</li>
|
||||
<li>Add a migration procedure for converting an storage to attachment one for populating existing records with attachments as folders</li>
|
||||
<li>Add a link from attachment view in chatter to linked documents</li>
|
||||
<li>If Inherit permissions from related record (the inherit_access_from_parent_record field from storage) is changed when directories already exist, inconsistencies may occur because groups defined in the directories and subdirectories will still exist, all groups in these directories should be removed before changing.</li>
|
||||
<li>Since portal users can read <tt class="docutils literal">dms.storage</tt> records, if your module extends this model to another storage backend that needs using secrets, remember to forbid access to the secrets fields by other means. It would be nice to be able to remove that rule at some point.</li>
|
||||
<li>Searchpanel in files: Highlight items (shading) without records when filtering something (by name for example).</li>
|
||||
<li>Accessing the clipboard (for example copy share link of file/directory) is limited to secure connections. It also happens in any part of Odoo.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h1><a class="toc-backref" href="#toc-entry-9">Bug Tracker</a></h1>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/dms/issues">GitHub Issues</a>.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||
<a class="reference external" href="https://github.com/OCA/dms/issues/new?body=module:%20dms%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h1><a class="toc-backref" href="#toc-entry-10">Credits</a></h1>
|
||||
<div class="section" id="authors">
|
||||
<h2><a class="toc-backref" href="#toc-entry-11">Authors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>MuK IT</li>
|
||||
<li>Tecnativa</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h2><a class="toc-backref" href="#toc-entry-12">Contributors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>Mathias Markl <<a class="reference external" href="mailto:mathias.markl@mukit.at">mathias.markl@mukit.at</a>></li>
|
||||
<li>Enric Tobella <<a class="reference external" href="mailto:etobella@creublanca.es">etobella@creublanca.es</a>></li>
|
||||
<li>Antoni Romera</li>
|
||||
<li>Gelu Boros <<a class="reference external" href="mailto:gelu.boros@rgbconsulting.com">gelu.boros@rgbconsulting.com</a>></li>
|
||||
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
|
||||
<li>Víctor Martínez</li>
|
||||
<li>Pedro M. Baeza</li>
|
||||
<li>Jairo Llopis</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference external" href="https://www.elegosoft.com">Elego</a>:<ul>
|
||||
<li>Yu Weng <<a class="reference external" href="mailto:yweng@elegosoft.com">yweng@elegosoft.com</a>></li>
|
||||
<li>Philip Witte <<a class="reference external" href="mailto:phillip.witte@elegosoft.com">phillip.witte@elegosoft.com</a>></li>
|
||||
<li>Khanh Bui <<a class="reference external" href="mailto:khanh.bui@mail.elegosoft.com">khanh.bui@mail.elegosoft.com</a>></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="other-credits">
|
||||
<h2><a class="toc-backref" href="#toc-entry-13">Other credits</a></h2>
|
||||
<p>The migration of this module from 15.0 to 16.0 was financially supported by <a class="reference external" href="https://www.agenterp.com">AgentERP</a></p>
|
||||
<p>Some pictures are based on or inspired by:</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="https://www.flaticon.com/authors/roundicons">Roundicons</a></li>
|
||||
<li><a class="reference external" href="https://www.flaticon.com/authors/smashicons">Smashicons</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h2><a class="toc-backref" href="#toc-entry-14">Maintainers</a></h2>
|
||||
<p>This module is maintained by the OCA.</p>
|
||||
<a class="reference external image-reference" href="https://odoo-community.org">
|
||||
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
||||
</a>
|
||||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.</p>
|
||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/dms/tree/16.0/dms">OCA/dms</a> project on GitHub.</p>
|
||||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_ai.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_DIUxPpL1A4o6jIKxrY3KVZ5F1CHA2mKL"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_DIUxPpL1A4o6jIKxrY3KVZ5F1CHA2mKL)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(255,193,79)"/><path d=" M 128.095 203.746 L 126.023 197.594 L 115.236 197.594 L 113.186 203.746 L 106.644 203.746 L 117.759 173.887 L 123.46 173.887 L 134.637 203.746 L 128.095 203.746 L 128.095 203.746 Z M 120.609 181.434 L 116.897 192.61 L 124.362 192.61 L 120.609 181.434 L 120.609 181.434 Z M 143.968 173.887 L 143.968 203.746 L 137.815 203.746 L 137.815 173.887 L 143.968 173.887 L 143.968 173.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/><path d=" M 157.857 74.571 L 157.857 76.02 C 148.205 79.063 140.562 86.649 137.422 96.26 C 135.263 94.516 132.557 93.429 129.571 93.429 C 123.729 93.429 118.851 97.451 117.446 102.857 L 107.571 102.857 L 107.571 96.571 L 88.714 96.571 L 88.714 115.429 L 107.571 115.429 L 107.571 109.143 L 116.752 109.143 C 115.696 117.512 110.513 124.788 102.958 128.512 C 100.858 124.493 96.697 121.714 91.857 121.714 C 84.924 121.714 79.286 127.353 79.286 134.286 C 79.286 141.219 84.924 146.857 91.857 146.857 C 98.602 146.857 104.077 141.508 104.372 134.836 C 112.716 131.218 118.977 124.191 121.733 115.749 C 123.889 117.487 126.592 118.571 129.571 118.571 C 135.414 118.571 140.292 114.549 141.697 109.143 L 151.571 109.143 L 151.571 115.429 L 170.429 115.429 L 170.429 96.571 L 151.571 96.571 L 151.571 102.857 L 142.36 102.857 C 143.551 93.369 150.041 85.527 158.772 82.372 C 160.632 87.001 165.142 90.286 170.429 90.286 C 177.362 90.286 183 84.647 183 77.714 L 183 74.571 L 157.857 74.571 Z M 101.286 109.143 L 95 109.143 L 95 102.857 L 101.286 102.857 L 101.286 109.143 Z M 91.857 140.571 C 88.391 140.571 85.571 137.752 85.571 134.286 C 85.571 130.819 88.391 128 91.857 128 C 95.324 128 98.143 130.819 98.143 134.286 C 98.143 137.752 95.324 140.571 91.857 140.571 Z M 157.857 102.857 L 164.143 102.857 L 164.143 109.143 L 157.857 109.143 L 157.857 102.857 Z M 129.571 112.286 C 126.105 112.286 123.286 109.467 123.286 106 C 123.286 102.533 126.105 99.714 129.571 99.714 C 133.038 99.714 135.857 102.533 135.857 106 C 135.857 109.467 133.038 112.286 129.571 112.286 Z M 170.429 84 C 168.156 84 166.176 82.777 165.073 80.97 C 165.802 80.904 166.538 80.857 167.286 80.857 L 175.869 80.857 C 174.785 82.733 172.751 84 170.429 84 Z " fill="rgb(200,189,184)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_aj.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_6nAp4GoljLPqc74aMxxhpy3ZhrUJqOMK"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_6nAp4GoljLPqc74aMxxhpy3ZhrUJqOMK)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(93,93,93)"/><g><path d=" M 112.936 91.207 C 111.707 89.978 109.721 89.978 108.492 91.207 L 89.635 110.064 C 88.406 111.293 88.406 113.279 89.635 114.508 L 108.492 133.365 C 109.105 133.978 109.91 134.286 110.714 134.286 C 111.519 134.286 112.323 133.978 112.936 133.365 C 114.165 132.136 114.165 130.15 112.936 128.921 L 96.301 112.286 L 112.936 95.651 C 114.165 94.422 114.165 92.435 112.936 91.207 Z " fill="rgb(93,93,93)"/><path d=" M 169.508 110.064 L 161.722 102.278 L 150.651 91.207 C 149.422 89.978 147.435 89.978 146.207 91.207 C 144.978 92.435 144.978 94.422 146.207 95.651 L 162.842 112.286 L 146.207 128.921 C 144.978 130.15 144.978 132.136 146.207 133.365 C 146.819 133.978 147.624 134.286 148.429 134.286 C 149.233 134.286 150.038 133.978 150.651 133.365 L 169.508 114.508 C 170.737 113.279 170.737 111.293 169.508 110.064 Z " fill="rgb(93,93,93)"/></g></g></g><path d=" M 122.595 203.746 L 120.523 197.594 L 109.736 197.594 L 107.686 203.746 L 101.144 203.746 L 112.259 173.887 L 117.96 173.887 L 129.137 203.746 L 122.595 203.746 L 122.595 203.746 Z M 115.109 181.434 L 111.397 192.61 L 118.862 192.61 L 115.109 181.434 L 115.109 181.434 Z M 143.964 194.559 L 143.964 173.887 L 150.116 173.887 L 150.116 194.559 L 150.116 194.559 Q 150.116 197.409 148.855 199.593 L 148.855 199.593 L 148.855 199.593 Q 147.594 201.777 145.297 202.967 L 145.297 202.967 L 145.297 202.967 Q 143 204.156 140.108 204.156 L 140.108 204.156 L 140.108 204.156 Q 135.371 204.156 132.726 201.747 L 132.726 201.747 L 132.726 201.747 Q 130.08 199.337 130.08 194.928 L 130.08 194.928 L 136.273 194.928 L 136.273 194.928 Q 136.273 197.122 137.196 198.168 L 137.196 198.168 L 137.196 198.168 Q 138.119 199.214 140.108 199.214 L 140.108 199.214 L 140.108 199.214 Q 141.872 199.214 142.918 198.004 L 142.918 198.004 L 142.918 198.004 Q 143.964 196.794 143.964 194.559 L 143.964 194.559 L 143.964 194.559 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_avi.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_FLHZ43wzdKFmTHD21bIUvTuw3Pzi3Qlw"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_FLHZ43wzdKFmTHD21bIUvTuw3Pzi3Qlw)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(215,94,114)"/><path d=" M 114.595 203.746 L 112.523 197.594 L 101.736 197.594 L 99.686 203.746 L 93.144 203.746 L 104.259 173.887 L 109.96 173.887 L 121.137 203.746 L 114.595 203.746 L 114.595 203.746 Z M 107.109 181.434 L 103.397 192.61 L 110.862 192.61 L 107.109 181.434 L 107.109 181.434 Z M 128.232 173.887 L 134.959 196.343 L 141.727 173.887 L 148.576 173.887 L 138.179 203.746 L 131.76 203.746 L 121.403 173.887 L 128.232 173.887 L 128.232 173.887 Z M 157.928 173.887 L 157.928 203.746 L 151.775 203.746 L 151.775 173.887 L 157.928 173.887 L 157.928 173.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/><path d=" M 113.857 128 L 113.857 105.855 L 113.857 84 L 148.429 106 L 113.857 128 Z " fill="rgb(200,189,184)"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_c.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_QDq7UHuMAP1DndjZvSJ7oBHBPdwuwQhy"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_QDq7UHuMAP1DndjZvSJ7oBHBPdwuwQhy)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(128,140,155)"/></g></g><path d=" M 132.954 195.8 L 139.106 195.8 L 139.106 195.8 Q 138.758 200.619 135.548 203.388 L 135.548 203.388 L 135.548 203.388 Q 132.339 206.156 127.089 206.156 L 127.089 206.156 L 127.089 206.156 Q 121.347 206.156 118.055 202.291 L 118.055 202.291 L 118.055 202.291 Q 114.764 198.425 114.764 191.678 L 114.764 191.678 L 114.764 189.853 L 114.764 189.853 Q 114.764 185.546 116.281 182.265 L 116.281 182.265 L 116.281 182.265 Q 117.799 178.983 120.619 177.23 L 120.619 177.23 L 120.619 177.23 Q 123.438 175.477 127.171 175.477 L 127.171 175.477 L 127.171 175.477 Q 132.339 175.477 135.497 178.245 L 135.497 178.245 L 135.497 178.245 Q 138.655 181.014 139.147 186.018 L 139.147 186.018 L 132.995 186.018 L 132.995 186.018 Q 132.77 183.126 131.385 181.824 L 131.385 181.824 L 131.385 181.824 Q 130.001 180.521 127.171 180.521 L 127.171 180.521 L 127.171 180.521 Q 124.095 180.521 122.567 182.726 L 122.567 182.726 L 122.567 182.726 Q 121.039 184.931 120.998 189.565 L 120.998 189.565 L 120.998 191.821 L 120.998 191.821 Q 120.998 196.661 122.464 198.896 L 122.464 198.896 L 122.464 198.896 Q 123.931 201.132 127.089 201.132 L 127.089 201.132 L 127.089 201.132 Q 129.939 201.132 131.344 199.83 L 131.344 199.83 L 131.344 199.83 Q 132.749 198.527 132.954 195.8 L 132.954 195.8 L 132.954 195.8 Z " fill="rgb(255,255,255)"/><path d=" M 131.94 106.301 L 131.94 106.301 L 131.94 106.301 Q 127.32 106.301 124.86 109.121 L 124.86 109.121 L 124.86 109.121 Q 122.4 111.941 122.4 117.101 L 122.4 117.101 L 122.4 117.101 Q 122.4 122.321 125.13 125.141 L 125.13 125.141 L 125.13 125.141 Q 127.86 127.961 132.48 127.961 L 132.48 127.961 L 132.48 127.961 Q 134.94 127.961 136.65 127.301 L 136.65 127.301 L 136.65 127.301 Q 138.36 126.641 139.92 125.801 L 139.92 125.801 L 139.92 125.801 Q 140.94 126.641 141.51 127.811 L 141.51 127.811 L 141.51 127.811 Q 142.08 128.981 142.08 130.541 L 142.08 130.541 L 142.08 130.541 Q 142.08 133.001 139.35 134.711 L 139.35 134.711 L 139.35 134.711 Q 136.62 136.421 131.04 136.421 L 131.04 136.421 L 131.04 136.421 Q 127.02 136.421 123.48 135.281 L 123.48 135.281 L 123.48 135.281 Q 119.94 134.141 117.3 131.771 L 117.3 131.771 L 117.3 131.771 Q 114.66 129.401 113.13 125.771 L 113.13 125.771 L 113.13 125.771 Q 111.6 122.141 111.6 117.101 L 111.6 117.101 L 111.6 117.101 Q 111.6 112.421 113.07 108.851 L 113.07 108.851 L 113.07 108.851 Q 114.54 105.281 117.09 102.821 L 117.09 102.821 L 117.09 102.821 Q 119.64 100.361 123.06 99.101 L 123.06 99.101 L 123.06 99.101 Q 126.48 97.841 130.38 97.841 L 130.38 97.841 L 130.38 97.841 Q 135.9 97.841 138.93 99.641 L 138.93 99.641 L 138.93 99.641 Q 141.96 101.441 141.96 104.261 L 141.96 104.261 L 141.96 104.261 Q 141.96 105.821 141.18 106.961 L 141.18 106.961 L 141.18 106.961 Q 140.4 108.101 139.38 108.761 L 139.38 108.761 L 139.38 108.761 Q 137.82 107.741 136.05 107.021 L 136.05 107.021 L 136.05 107.021 Q 134.28 106.301 131.94 106.301 Z " fill="rgb(128,140,155)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_cbl.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_TQmEGhsjtrLEyjf6zmhvf3bpAZU65XHf"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_TQmEGhsjtrLEyjf6zmhvf3bpAZU65XHf)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(93,93,93)"/><g><path d=" M 112.936 91.207 C 111.707 89.978 109.721 89.978 108.492 91.207 L 89.635 110.064 C 88.406 111.293 88.406 113.279 89.635 114.508 L 108.492 133.365 C 109.105 133.978 109.91 134.286 110.714 134.286 C 111.519 134.286 112.323 133.978 112.936 133.365 C 114.165 132.136 114.165 130.15 112.936 128.921 L 96.301 112.286 L 112.936 95.651 C 114.165 94.422 114.165 92.435 112.936 91.207 Z " fill="rgb(93,93,93)"/><path d=" M 169.508 110.064 L 161.722 102.278 L 150.651 91.207 C 149.422 89.978 147.435 89.978 146.207 91.207 C 144.978 92.435 144.978 94.422 146.207 95.651 L 162.842 112.286 L 146.207 128.921 C 144.978 130.15 144.978 132.136 146.207 133.365 C 146.819 133.978 147.624 134.286 148.429 134.286 C 149.233 134.286 150.038 133.978 150.651 133.365 L 169.508 114.508 C 170.737 113.279 170.737 111.293 169.508 110.064 Z " fill="rgb(93,93,93)"/></g></g></g><path d=" M 107.954 195.8 L 114.106 195.8 L 114.106 195.8 Q 113.758 200.619 110.548 203.388 L 110.548 203.388 L 110.548 203.388 Q 107.339 206.156 102.089 206.156 L 102.089 206.156 L 102.089 206.156 Q 96.347 206.156 93.055 202.291 L 93.055 202.291 L 93.055 202.291 Q 89.764 198.425 89.764 191.678 L 89.764 191.678 L 89.764 189.853 L 89.764 189.853 Q 89.764 185.546 91.281 182.265 L 91.281 182.265 L 91.281 182.265 Q 92.799 178.983 95.619 177.23 L 95.619 177.23 L 95.619 177.23 Q 98.438 175.477 102.171 175.477 L 102.171 175.477 L 102.171 175.477 Q 107.339 175.477 110.497 178.245 L 110.497 178.245 L 110.497 178.245 Q 113.655 181.014 114.147 186.018 L 114.147 186.018 L 107.995 186.018 L 107.995 186.018 Q 107.77 183.126 106.385 181.824 L 106.385 181.824 L 106.385 181.824 Q 105.001 180.521 102.171 180.521 L 102.171 180.521 L 102.171 180.521 Q 99.095 180.521 97.567 182.726 L 97.567 182.726 L 97.567 182.726 Q 96.039 184.931 95.998 189.565 L 95.998 189.565 L 95.998 191.821 L 95.998 191.821 Q 95.998 196.661 97.464 198.896 L 97.464 198.896 L 97.464 198.896 Q 98.931 201.132 102.089 201.132 L 102.089 201.132 L 102.089 201.132 Q 104.939 201.132 106.344 199.83 L 106.344 199.83 L 106.344 199.83 Q 107.749 198.527 107.954 195.8 L 107.954 195.8 L 107.954 195.8 Z M 129.754 205.746 L 118.146 205.746 L 118.146 175.887 L 128.605 175.887 L 128.605 175.887 Q 134.04 175.887 136.85 177.968 L 136.85 177.968 L 136.85 177.968 Q 139.659 180.05 139.659 184.069 L 139.659 184.069 L 139.659 184.069 Q 139.659 186.264 138.531 187.935 L 138.531 187.935 L 138.531 187.935 Q 137.403 189.606 135.394 190.386 L 135.394 190.386 L 135.394 190.386 Q 137.69 190.96 139.013 192.703 L 139.013 192.703 L 139.013 192.703 Q 140.336 194.446 140.336 196.969 L 140.336 196.969 L 140.336 196.969 Q 140.336 201.275 137.588 203.49 L 137.588 203.49 L 137.588 203.49 Q 134.84 205.705 129.754 205.746 L 129.754 205.746 L 129.754 205.746 Z M 129.938 192.744 L 124.299 192.744 L 124.299 200.804 L 129.569 200.804 L 129.569 200.804 Q 131.743 200.804 132.963 199.768 L 132.963 199.768 L 132.963 199.768 Q 134.184 198.732 134.184 196.907 L 134.184 196.907 L 134.184 196.907 Q 134.184 192.806 129.938 192.744 L 129.938 192.744 L 129.938 192.744 Z M 124.299 180.87 L 124.299 188.396 L 128.852 188.396 L 128.852 188.396 Q 133.507 188.314 133.507 184.685 L 133.507 184.685 L 133.507 184.685 Q 133.507 182.654 132.328 181.762 L 132.328 181.762 L 132.328 181.762 Q 131.148 180.87 128.605 180.87 L 128.605 180.87 L 124.299 180.87 L 124.299 180.87 Z M 151.103 175.887 L 151.103 200.804 L 164.166 200.804 L 164.166 205.746 L 144.95 205.746 L 144.95 175.887 L 151.103 175.887 L 151.103 175.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_cc.svg
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_cs.svg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_css.svg
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_csv.svg
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_dbf.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_AC8gC2Fy7eYKCxX4InFHVsjb6C7TwY0y"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_AC8gC2Fy7eYKCxX4InFHVsjb6C7TwY0y)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(233,99,96)"/><path d=" M 117 90.286 L 117 77.714 L 79.286 77.714 L 79.286 90.286 L 79.286 96.571 L 79.286 102.857 L 79.286 109.143 L 79.286 115.429 L 79.286 121.714 L 79.286 128 L 79.286 134.286 L 79.286 146.857 L 110.714 146.857 L 117 146.857 L 183 146.857 L 183 134.286 L 183 128 L 183 121.714 L 183 115.429 L 183 109.143 L 183 102.857 L 183 90.286 L 117 90.286 Z M 85.571 84 L 110.714 84 L 110.714 90.286 L 85.571 90.286 L 85.571 84 Z M 85.571 96.571 L 110.714 96.571 L 110.714 102.857 L 85.571 102.857 L 85.571 96.571 Z M 85.571 109.143 L 110.714 109.143 L 110.714 115.429 L 85.571 115.429 L 85.571 109.143 Z M 85.571 121.714 L 110.714 121.714 L 110.714 128 L 85.571 128 L 85.571 121.714 Z M 110.714 140.571 L 85.571 140.571 L 85.571 134.286 L 110.714 134.286 L 110.714 140.571 Z M 176.714 140.571 L 117 140.571 L 117 134.286 L 176.714 134.286 L 176.714 140.571 Z M 176.714 128 L 117 128 L 117 121.714 L 176.714 121.714 L 176.714 128 Z M 176.714 115.429 L 117 115.429 L 117 109.143 L 176.714 109.143 L 176.714 115.429 Z M 117 102.857 L 117 96.571 L 176.714 96.571 L 176.714 102.857 L 117 102.857 Z " fill="rgb(200,189,184)"/></g></g><path d=" M 99.915 205.746 L 90.666 205.746 L 90.666 175.887 L 99.854 175.887 L 99.854 175.887 Q 103.791 175.887 106.898 177.661 L 106.898 177.661 L 106.898 177.661 Q 110.005 179.435 111.748 182.706 L 111.748 182.706 L 111.748 182.706 Q 113.491 185.977 113.491 190.14 L 113.491 190.14 L 113.491 191.514 L 113.491 191.514 Q 113.491 195.677 111.779 198.917 L 111.779 198.917 L 111.779 198.917 Q 110.066 202.157 106.949 203.941 L 106.949 203.941 L 106.949 203.941 Q 103.832 205.726 99.915 205.746 L 99.915 205.746 L 99.915 205.746 Z M 99.854 180.87 L 96.818 180.87 L 96.818 200.804 L 99.792 200.804 L 99.792 200.804 Q 103.401 200.804 105.309 198.445 L 105.309 198.445 L 105.309 198.445 Q 107.216 196.087 107.257 191.698 L 107.257 191.698 L 107.257 190.119 L 107.257 190.119 Q 107.257 185.566 105.37 183.218 L 105.37 183.218 L 105.37 183.218 Q 103.483 180.87 99.854 180.87 L 99.854 180.87 L 99.854 180.87 Z M 129.569 205.746 L 117.962 205.746 L 117.962 175.887 L 128.421 175.887 L 128.421 175.887 Q 133.855 175.887 136.665 177.968 L 136.665 177.968 L 136.665 177.968 Q 139.475 180.05 139.475 184.069 L 139.475 184.069 L 139.475 184.069 Q 139.475 186.264 138.347 187.935 L 138.347 187.935 L 138.347 187.935 Q 137.219 189.606 135.209 190.386 L 135.209 190.386 L 135.209 190.386 Q 137.506 190.96 138.829 192.703 L 138.829 192.703 L 138.829 192.703 Q 140.151 194.446 140.151 196.969 L 140.151 196.969 L 140.151 196.969 Q 140.151 201.275 137.403 203.49 L 137.403 203.49 L 137.403 203.49 Q 134.655 205.705 129.569 205.746 L 129.569 205.746 L 129.569 205.746 Z M 129.754 192.744 L 124.114 192.744 L 124.114 200.804 L 129.385 200.804 L 129.385 200.804 Q 131.559 200.804 132.779 199.768 L 132.779 199.768 L 132.779 199.768 Q 133.999 198.732 133.999 196.907 L 133.999 196.907 L 133.999 196.907 Q 133.999 192.806 129.754 192.744 L 129.754 192.744 L 129.754 192.744 Z M 124.114 180.87 L 124.114 188.396 L 128.667 188.396 L 128.667 188.396 Q 133.322 188.314 133.322 184.685 L 133.322 184.685 L 133.322 184.685 Q 133.322 182.654 132.143 181.762 L 132.143 181.762 L 132.143 181.762 Q 130.964 180.87 128.421 180.87 L 128.421 180.87 L 124.114 180.87 L 124.114 180.87 Z M 162.73 188.581 L 162.73 193.544 L 150.918 193.544 L 150.918 205.746 L 144.766 205.746 L 144.766 175.887 L 164.207 175.887 L 164.207 180.87 L 150.918 180.87 L 150.918 188.581 L 162.73 188.581 L 162.73 188.581 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_dll.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_JRbDI2Nk1iQLWnj5TvFr9peayMg5GuJ2"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_JRbDI2Nk1iQLWnj5TvFr9peayMg5GuJ2)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 38 L 65.027 38 C 62.487 38 60.429 40.059 60.429 44.053 L 60.429 210.857 C 60.429 211.941 62.487 214 65.027 214 L 190.973 214 C 193.513 214 195.571 211.941 195.571 210.857 L 195.571 78.788 C 195.571 76.601 195.279 75.897 194.764 75.378 L 158.193 38.808 C 157.675 38.292 156.971 38 156.239 38 Z " fill="rgb(233,233,224)"/><path d=" M 190.973 214 L 65.027 214 C 62.487 214 60.429 211.941 60.429 209.402 L 60.429 160.571 L 195.571 160.571 L 195.571 209.402 C 195.571 211.941 193.513 214 190.973 214 Z " fill="rgb(62,71,83)"/><path d=" M 157.857 38.475 L 157.857 75.714 L 195.097 75.714 L 157.857 38.475 Z " fill="rgb(217,215,202)"/></g></g><path d=" M 102.415 203.746 L 93.166 203.746 L 93.166 173.887 L 102.354 173.887 L 102.354 173.887 Q 106.291 173.887 109.398 175.661 L 109.398 175.661 L 109.398 175.661 Q 112.505 177.435 114.248 180.706 L 114.248 180.706 L 114.248 180.706 Q 115.991 183.977 115.991 188.14 L 115.991 188.14 L 115.991 189.514 L 115.991 189.514 Q 115.991 193.677 114.279 196.917 L 114.279 196.917 L 114.279 196.917 Q 112.566 200.157 109.449 201.941 L 109.449 201.941 L 109.449 201.941 Q 106.332 203.726 102.415 203.746 L 102.415 203.746 L 102.415 203.746 Z M 102.354 178.87 L 99.318 178.87 L 99.318 198.804 L 102.292 198.804 L 102.292 198.804 Q 105.901 198.804 107.809 196.445 L 107.809 196.445 L 107.809 196.445 Q 109.716 194.087 109.757 189.698 L 109.757 189.698 L 109.757 188.119 L 109.757 188.119 Q 109.757 183.566 107.87 181.218 L 107.87 181.218 L 107.87 181.218 Q 105.983 178.87 102.354 178.87 L 102.354 178.87 L 102.354 178.87 Z M 126.614 173.887 L 126.614 198.804 L 139.678 198.804 L 139.678 203.746 L 120.462 203.746 L 120.462 173.887 L 126.614 173.887 L 126.614 173.887 Z M 149.357 173.887 L 149.357 198.804 L 162.421 198.804 L 162.421 203.746 L 143.205 203.746 L 143.205 173.887 L 149.357 173.887 L 149.357 173.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/><g><g><g><g><path d=" M 128 98.25 C 122.625 98.25 118.25 102.625 118.25 108 C 118.25 113.375 122.625 117.75 128 117.75 C 133.375 117.75 137.75 113.375 137.75 108 C 137.75 102.625 133.375 98.25 128 98.25 Z " fill="rgb(200,189,184)"/><path d=" M 164.364 101.37 L 160.061 100.541 C 158.134 100.174 156.623 98.913 155.905 97.093 C 155.186 95.263 155.44 93.31 156.603 91.727 L 159.304 88.042 C 160.253 86.752 160.113 84.958 158.979 83.827 L 153.146 77.993 C 152.047 76.891 150.312 76.729 149.028 77.6 L 145.398 80.053 C 143.779 81.155 141.823 81.334 140.019 80.554 C 138.222 79.767 137.016 78.207 136.72 76.267 L 136.025 71.756 C 135.78 70.17 134.415 69 132.81 69 L 124.561 69 C 123.005 69 121.666 70.105 121.37 71.636 L 120.301 77.193 C 119.94 79.075 118.718 80.576 116.947 81.308 C 115.175 82.046 113.245 81.847 111.659 80.771 L 106.972 77.6 C 105.689 76.729 103.96 76.891 102.855 77.993 L 97.021 83.827 C 95.887 84.958 95.747 86.752 96.696 88.042 L 99.397 91.73 C 100.56 93.31 100.814 95.263 100.096 97.093 C 99.377 98.913 97.866 100.174 95.936 100.541 L 91.636 101.37 C 90.105 101.666 89 103.005 89 104.561 L 89 112.81 C 89 114.415 90.17 115.78 91.756 116.024 L 96.267 116.72 C 98.207 117.015 99.767 118.221 100.554 120.018 C 101.337 121.816 101.155 123.775 100.053 125.4 L 97.6 129.027 C 96.725 130.314 96.891 132.043 97.993 133.145 L 103.827 138.979 C 104.961 140.116 106.752 140.246 108.042 139.304 L 111.73 136.603 C 113.31 135.443 115.26 135.192 117.093 135.904 C 118.913 136.622 120.174 138.134 120.541 140.064 L 121.37 144.364 C 121.666 145.895 123.005 147 124.561 147 L 132.81 147 C 134.415 147 135.78 145.83 136.024 144.244 L 136.512 141.072 C 136.817 139.086 138.055 137.51 139.908 136.746 C 141.747 135.979 143.746 136.217 145.368 137.406 L 147.958 139.304 C 149.242 140.247 151.039 140.117 152.173 138.979 L 158.007 133.145 C 159.109 132.044 159.275 130.315 158.4 129.028 L 155.947 125.398 C 154.845 123.776 154.663 121.816 155.446 120.019 C 156.233 118.222 157.793 117.016 159.733 116.72 L 164.244 116.025 C 165.83 115.781 167 114.416 167 112.81 L 167 104.562 C 167 103.005 165.895 101.666 164.364 101.37 Z M 128 124.25 C 119.04 124.25 111.75 116.96 111.75 108 C 111.75 99.04 119.04 91.75 128 91.75 C 136.96 91.75 144.25 99.04 144.25 108 C 144.25 116.96 136.96 124.25 128 124.25 Z " fill="rgb(200,189,184)"/></g></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_doc.svg
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_docx.svg
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_dwg.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_D4Sj8YJrR0Fd21hr8GyZRcCPEVvEhAsA"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_D4Sj8YJrR0Fd21hr8GyZRcCPEVvEhAsA)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(134,151,203)"/><rect x="79.286" y="80.857" width="47.143" height="47.347" transform="matrix(1,0,0,1,0,0)" fill="rgb(200,189,184)"/><rect x="148.429" y="84" width="6.286" height="22" transform="matrix(1,0,0,1,0,0)" fill="rgb(173,162,158)"/><rect x="148.429" y="131.143" width="6.286" height="22" transform="matrix(1,0,0,1,0,0)" fill="rgb(173,162,158)"/><path d=" M 167.286 134.286 L 135.857 134.286 L 135.857 102.857 L 167.286 102.857 L 167.286 134.286 Z M 142.143 128 L 161 128 L 161 109.143 L 142.143 109.143 L 142.143 128 Z " fill="rgb(173,162,158)"/><rect x="164.143" y="115.429" width="22" height="6.286" transform="matrix(1,0,0,1,0,0)" fill="rgb(173,162,158)"/><rect x="117" y="115.429" width="22" height="6.286" transform="matrix(1,0,0,1,0,0)" fill="rgb(173,162,158)"/></g></g><path d=" M 92.415 203.746 L 83.166 203.746 L 83.166 173.887 L 92.354 173.887 L 92.354 173.887 Q 96.291 173.887 99.398 175.661 L 99.398 175.661 L 99.398 175.661 Q 102.505 177.435 104.248 180.706 L 104.248 180.706 L 104.248 180.706 Q 105.991 183.977 105.991 188.14 L 105.991 188.14 L 105.991 189.514 L 105.991 189.514 Q 105.991 193.677 104.279 196.917 L 104.279 196.917 L 104.279 196.917 Q 102.566 200.157 99.449 201.941 L 99.449 201.941 L 99.449 201.941 Q 96.332 203.726 92.415 203.746 L 92.415 203.746 L 92.415 203.746 Z M 92.354 178.87 L 89.318 178.87 L 89.318 198.804 L 92.292 198.804 L 92.292 198.804 Q 95.901 198.804 97.809 196.445 L 97.809 196.445 L 97.809 196.445 Q 99.716 194.087 99.757 189.698 L 99.757 189.698 L 99.757 188.119 L 99.757 188.119 Q 99.757 183.566 97.87 181.218 L 97.87 181.218 L 97.87 181.218 Q 95.983 178.87 92.354 178.87 L 92.354 178.87 L 92.354 178.87 Z M 128.816 173.887 L 133.718 195.133 L 137.737 173.887 L 143.869 173.887 L 137.245 203.746 L 131.052 203.746 L 126.191 183.771 L 121.331 203.746 L 115.138 203.746 L 108.514 173.887 L 114.646 173.887 L 118.686 195.092 L 123.607 173.887 L 128.816 173.887 L 128.816 173.887 Z M 170.816 188.058 L 170.816 199.973 L 170.816 199.973 Q 169.155 201.962 166.12 203.059 L 166.12 203.059 L 166.12 203.059 Q 163.085 204.156 159.394 204.156 L 159.394 204.156 L 159.394 204.156 Q 155.518 204.156 152.595 202.464 L 152.595 202.464 L 152.595 202.464 Q 149.673 200.772 148.083 197.553 L 148.083 197.553 L 148.083 197.553 Q 146.494 194.333 146.453 189.985 L 146.453 189.985 L 146.453 187.955 L 146.453 187.955 Q 146.453 183.484 147.96 180.213 L 147.96 180.213 L 147.96 180.213 Q 149.468 176.942 152.308 175.209 L 152.308 175.209 L 152.308 175.209 Q 155.148 173.477 158.963 173.477 L 158.963 173.477 L 158.963 173.477 Q 164.274 173.477 167.269 176.009 L 167.269 176.009 L 167.269 176.009 Q 170.263 178.542 170.816 183.382 L 170.816 183.382 L 164.828 183.382 L 164.828 183.382 Q 164.418 180.818 163.013 179.629 L 163.013 179.629 L 163.013 179.629 Q 161.608 178.439 159.147 178.439 L 159.147 178.439 L 159.147 178.439 Q 156.01 178.439 154.369 180.798 L 154.369 180.798 L 154.369 180.798 Q 152.729 183.156 152.708 187.812 L 152.708 187.812 L 152.708 189.719 L 152.708 189.719 Q 152.708 194.415 154.492 196.814 L 154.492 196.814 L 154.492 196.814 Q 156.276 199.214 159.722 199.214 L 159.722 199.214 L 159.722 199.214 Q 163.188 199.214 164.664 197.737 L 164.664 197.737 L 164.664 192.59 L 159.065 192.59 L 159.065 188.058 L 170.816 188.058 L 170.816 188.058 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_eml.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_eMGLtDmIvhgzWzMJn5Zi3pkjzRQYkoFv"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_eMGLtDmIvhgzWzMJn5Zi3pkjzRQYkoFv)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(74,134,232)"/><path d=" M 157.767 134.37 L 157.767 104.603 Q 156.526 105.999 155.092 107.161 Q 144.705 115.146 138.581 120.262 Q 136.604 121.929 135.364 122.859 Q 134.124 123.789 132.012 124.739 Q 129.899 125.688 128.039 125.688 L 127.961 125.688 Q 126.101 125.688 123.988 124.739 Q 121.876 123.789 120.636 122.859 Q 119.396 121.929 117.419 120.262 Q 111.295 115.146 100.908 107.161 Q 99.474 105.999 98.233 104.603 L 98.233 134.37 Q 98.233 134.874 98.602 135.242 Q 98.97 135.61 99.474 135.61 L 156.526 135.61 Q 157.03 135.61 157.398 135.242 Q 157.767 134.874 157.767 134.37 Z M 157.767 93.635 L 157.767 92.685 L 157.747 92.181 L 157.631 91.697 L 157.418 91.348 L 157.069 91.057 L 156.526 90.96 L 99.474 90.96 Q 98.97 90.96 98.602 91.329 Q 98.233 91.697 98.233 92.201 Q 98.233 98.712 103.931 103.208 Q 111.411 109.099 119.473 115.495 Q 119.706 115.688 120.83 116.638 Q 121.954 117.588 122.613 118.091 Q 123.271 118.595 124.337 119.312 Q 125.403 120.029 126.295 120.378 Q 127.186 120.727 127.961 120.727 L 128.039 120.727 Q 128.814 120.727 129.705 120.378 Q 130.597 120.029 131.663 119.312 Q 132.729 118.595 133.387 118.091 Q 134.046 117.588 135.17 116.638 Q 136.294 115.688 136.527 115.495 Q 144.589 109.099 152.069 103.208 Q 154.162 101.541 155.964 98.731 Q 157.767 95.921 157.767 93.635 Z M 162.728 92.201 L 162.728 134.37 Q 162.728 136.928 160.906 138.75 Q 159.084 140.571 156.526 140.571 L 99.474 140.571 Q 96.916 140.571 95.094 138.75 Q 93.272 136.928 93.272 134.37 L 93.272 92.201 Q 93.272 89.643 95.094 87.821 Q 96.916 85.999 99.474 85.999 L 156.526 85.999 Q 159.084 85.999 160.906 87.821 Q 162.728 89.643 162.728 92.201 Z " fill="rgb(74,134,232)"/><path d=" M 105.631 185.881 L 105.631 190.701 L 93.818 190.701 L 93.818 198.699 L 107.682 198.699 L 107.682 203.641 L 87.666 203.641 L 87.666 173.782 L 107.641 173.782 L 107.641 178.765 L 93.818 178.765 L 93.818 185.881 L 105.631 185.881 L 105.631 185.881 Z M 111.291 173.782 L 119.33 173.782 L 127 195.438 L 134.629 173.782 L 142.709 173.782 L 142.709 203.641 L 136.536 203.641 L 136.536 195.479 L 137.151 181.39 L 129.092 203.641 L 124.867 203.641 L 116.828 181.411 L 117.443 195.479 L 117.443 203.641 L 111.291 203.641 L 111.291 173.782 L 111.291 173.782 Z M 154.234 173.782 L 154.234 198.699 L 167.298 198.699 L 167.298 203.641 L 148.082 203.641 L 148.082 173.782 L 154.234 173.782 L 154.234 173.782 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_eps.svg
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_exe.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_fuCqdWSzYoowVCmecSUlBS0SWUOdLKXJ"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_fuCqdWSzYoowVCmecSUlBS0SWUOdLKXJ)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(151,119,168)"/><path d=" M 145.286 140.571 C 144.975 140.571 144.657 140.524 144.346 140.427 C 142.69 139.908 141.766 138.145 142.284 136.489 L 157.999 86.203 C 158.517 84.547 160.28 83.623 161.937 84.141 C 163.593 84.66 164.517 86.423 163.998 88.079 L 148.284 138.365 C 147.866 139.71 146.625 140.571 145.286 140.571 Z " fill="rgb(151,119,168)"/><circle vector-effect="non-scaling-stroke" cx="131.14285714285717" cy="101.28571428571428" r="4.714285714285722" fill="rgb(151,119,168)"/><circle vector-effect="non-scaling-stroke" cx="131.14285714285717" cy="123.28571428571428" r="4.714285714285722" fill="rgb(151,119,168)"/><path d=" M 113.857 134.286 L 107.571 134.286 C 95.44 134.286 85.571 124.417 85.571 112.286 C 85.571 100.154 95.44 90.286 107.571 90.286 L 113.857 90.286 C 115.592 90.286 117 91.694 117 93.429 C 117 95.163 115.592 96.571 113.857 96.571 L 107.571 96.571 C 98.907 96.571 91.857 103.621 91.857 112.286 C 91.857 120.951 98.907 128 107.571 128 L 113.857 128 C 115.592 128 117 129.408 117 131.143 C 117 132.878 115.592 134.286 113.857 134.286 Z " fill="rgb(151,119,168)"/></g></g><path d=" M 110.631 185.986 L 110.631 190.806 L 98.818 190.806 L 98.818 198.804 L 112.682 198.804 L 112.682 203.746 L 92.666 203.746 L 92.666 173.887 L 112.641 173.887 L 112.641 178.87 L 98.818 178.87 L 98.818 185.986 L 110.631 185.986 L 110.631 185.986 Z M 121.377 173.887 L 126.976 184.182 L 132.574 173.887 L 139.649 173.887 L 130.954 188.693 L 139.875 203.746 L 132.718 203.746 L 126.976 193.287 L 121.233 203.746 L 114.076 203.746 L 122.997 188.693 L 114.302 173.887 L 121.377 173.887 L 121.377 173.887 Z M 160.937 185.986 L 160.937 190.806 L 149.124 190.806 L 149.124 198.804 L 162.987 198.804 L 162.987 203.746 L 142.972 203.746 L 142.972 173.887 L 162.946 173.887 L 162.946 178.87 L 149.124 178.87 L 149.124 185.986 L 160.937 185.986 L 160.937 185.986 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_f.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_5oTXkrN31uMQuyZv3FF9Doe4IqTHZzDZ"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_5oTXkrN31uMQuyZv3FF9Doe4IqTHZzDZ)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(93,93,93)"/><g><path d=" M 112.936 91.207 C 111.707 89.978 109.721 89.978 108.492 91.207 L 89.635 110.064 C 88.406 111.293 88.406 113.279 89.635 114.508 L 108.492 133.365 C 109.105 133.978 109.91 134.286 110.714 134.286 C 111.519 134.286 112.323 133.978 112.936 133.365 C 114.165 132.136 114.165 130.15 112.936 128.921 L 96.301 112.286 L 112.936 95.651 C 114.165 94.422 114.165 92.435 112.936 91.207 Z " fill="rgb(93,93,93)"/><path d=" M 169.508 110.064 L 161.722 102.278 L 150.651 91.207 C 149.422 89.978 147.435 89.978 146.207 91.207 C 144.978 92.435 144.978 94.422 146.207 95.651 L 162.842 112.286 L 146.207 128.921 C 144.978 130.15 144.978 132.136 146.207 133.365 C 146.819 133.978 147.624 134.286 148.429 134.286 C 149.233 134.286 150.038 133.978 150.651 133.365 L 169.508 114.508 C 170.737 113.279 170.737 111.293 169.508 110.064 Z " fill="rgb(93,93,93)"/></g></g></g><path d=" M 135.631 188.581 L 135.631 193.544 L 123.818 193.544 L 123.818 205.746 L 117.666 205.746 L 117.666 175.887 L 137.107 175.887 L 137.107 180.87 L 123.818 180.87 L 123.818 188.581 L 135.631 188.581 L 135.631 188.581 Z " fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_fla.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_2IuqJwMePGGPEksxk56V3JdmHKDktmlJ"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_2IuqJwMePGGPEksxk56V3JdmHKDktmlJ)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(206,60,59)"/><circle vector-effect="non-scaling-stroke" cx="120.14285714285714" cy="90.28571428571439" r="6.285714285714278" fill="rgb(200,189,184)"/><g><path d=" M 149.953 83.777 L 147.731 81.555 C 141.203 75.024 132.519 71.429 123.286 71.429 C 114.052 71.429 105.368 75.024 98.841 81.555 C 92.31 88.083 88.714 96.766 88.714 106 C 88.714 115.234 92.31 123.917 98.841 130.445 C 105.368 136.976 114.052 140.571 123.286 140.571 C 132.519 140.571 141.203 136.976 147.731 130.445 L 149.953 128.223 L 127.73 106 L 149.953 83.777 Z M 140.942 128.101 C 135.945 132.111 129.782 134.286 123.286 134.286 C 115.73 134.286 108.627 131.344 103.285 126.001 C 97.942 120.658 95 113.555 95 106 C 95 98.445 97.942 91.342 103.285 85.999 C 108.627 80.656 115.73 77.714 123.286 77.714 C 129.782 77.714 135.945 79.889 140.942 83.899 L 118.842 106 L 140.942 128.101 Z " fill="rgb(200,189,184)"/><path d=" M 151.571 102.857 L 142.143 102.857 C 140.405 102.857 139 104.262 139 106 C 139 107.738 140.405 109.143 142.143 109.143 L 151.571 109.143 C 153.309 109.143 154.714 107.738 154.714 106 C 154.714 104.262 153.309 102.857 151.571 102.857 Z " fill="rgb(200,189,184)"/><path d=" M 170.429 102.857 L 164.143 102.857 C 162.405 102.857 161 104.262 161 106 C 161 107.738 162.405 109.143 164.143 109.143 L 170.429 109.143 C 172.167 109.143 173.571 107.738 173.571 106 C 173.571 104.262 172.167 102.857 170.429 102.857 Z " fill="rgb(200,189,184)"/></g></g></g><path d=" M 110.131 186.581 L 110.131 191.544 L 98.318 191.544 L 98.318 203.746 L 92.166 203.746 L 92.166 173.887 L 111.607 173.887 L 111.607 178.87 L 98.318 178.87 L 98.318 186.581 L 110.131 186.581 L 110.131 186.581 Z M 121.328 173.887 L 121.328 198.804 L 134.392 198.804 L 134.392 203.746 L 115.176 203.746 L 115.176 173.887 L 121.328 173.887 L 121.328 173.887 Z M 156.848 203.746 L 154.776 197.594 L 143.989 197.594 L 141.938 203.746 L 135.396 203.746 L 146.512 173.887 L 152.213 173.887 L 163.39 203.746 L 156.848 203.746 L 156.848 203.746 Z M 149.362 181.434 L 145.65 192.61 L 153.115 192.61 L 149.362 181.434 L 149.362 181.434 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_gif.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_qJ4JQ2vHPl9yNMOIFjFdX7hbAxrDctK3"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_qJ4JQ2vHPl9yNMOIFjFdX7hbAxrDctK3)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><circle vector-effect="non-scaling-stroke" cx="99.49742857142849" cy="85.35457142857132" r="14.35971428571429" fill="rgb(243,213,91)"/><path d=" M 60.429 162.571 L 95 162.571 L 195.571 162.571 L 195.571 128 L 164.143 98.143 L 131.143 134.286 L 113.911 117.053 L 60.429 162.571 Z " fill="rgb(38,114,185)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(24,94,159)"/></g></g><path d=" M 121.291 188.058 L 121.291 199.973 L 121.291 199.973 Q 119.63 201.962 116.595 203.059 L 116.595 203.059 L 116.595 203.059 Q 113.56 204.156 109.868 204.156 L 109.868 204.156 L 109.868 204.156 Q 105.992 204.156 103.07 202.464 L 103.07 202.464 L 103.07 202.464 Q 100.147 200.772 98.558 197.553 L 98.558 197.553 L 98.558 197.553 Q 96.969 194.333 96.928 189.985 L 96.928 189.985 L 96.928 187.955 L 96.928 187.955 Q 96.928 183.484 98.435 180.213 L 98.435 180.213 L 98.435 180.213 Q 99.942 176.942 102.783 175.209 L 102.783 175.209 L 102.783 175.209 Q 105.623 173.477 109.438 173.477 L 109.438 173.477 L 109.438 173.477 Q 114.749 173.477 117.743 176.009 L 117.743 176.009 L 117.743 176.009 Q 120.737 178.542 121.291 183.382 L 121.291 183.382 L 115.303 183.382 L 115.303 183.382 Q 114.893 180.818 113.488 179.629 L 113.488 179.629 L 113.488 179.629 Q 112.083 178.439 109.622 178.439 L 109.622 178.439 L 109.622 178.439 Q 106.484 178.439 104.844 180.798 L 104.844 180.798 L 104.844 180.798 Q 103.203 183.156 103.183 187.812 L 103.183 187.812 L 103.183 189.719 L 103.183 189.719 Q 103.183 194.415 104.967 196.814 L 104.967 196.814 L 104.967 196.814 Q 106.751 199.214 110.196 199.214 L 110.196 199.214 L 110.196 199.214 Q 113.662 199.214 115.139 197.737 L 115.139 197.737 L 115.139 192.59 L 109.54 192.59 L 109.54 188.058 L 121.291 188.058 L 121.291 188.058 Z M 132.816 173.887 L 132.816 203.746 L 126.664 203.746 L 126.664 173.887 L 132.816 173.887 L 132.816 173.887 Z M 156.482 186.581 L 156.482 191.544 L 144.67 191.544 L 144.67 203.746 L 138.518 203.746 L 138.518 173.887 L 157.959 173.887 L 157.959 178.87 L 144.67 178.87 L 144.67 186.581 L 156.482 186.581 L 156.482 186.581 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_go.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_g24Gte2OrG30DAPUumNJM7BCqXYtetjX"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_g24Gte2OrG30DAPUumNJM7BCqXYtetjX)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(116,206,221)"/><g><path d=" M 112.936 91.207 C 111.707 89.978 109.721 89.978 108.492 91.207 L 89.635 110.064 C 88.406 111.293 88.406 113.279 89.635 114.508 L 108.492 133.365 C 109.105 133.978 109.91 134.286 110.714 134.286 C 111.519 134.286 112.323 133.978 112.936 133.365 C 114.165 132.136 114.165 130.15 112.936 128.921 L 96.301 112.286 L 112.936 95.651 C 114.165 94.422 114.165 92.435 112.936 91.207 Z " fill="rgb(116,206,221)"/><path d=" M 169.508 110.064 L 161.722 102.278 L 150.651 91.207 C 149.422 89.978 147.435 89.978 146.207 91.207 C 144.978 92.435 144.978 94.422 146.207 95.651 L 162.842 112.286 L 146.207 128.921 C 144.978 130.15 144.978 132.136 146.207 133.365 C 146.819 133.978 147.624 134.286 148.429 134.286 C 149.233 134.286 150.038 133.978 150.651 133.365 L 169.508 114.508 C 170.737 113.279 170.737 111.293 169.508 110.064 Z " fill="rgb(116,206,221)"/></g></g></g><path d=" M 124.291 189.058 L 124.291 200.973 L 124.291 200.973 Q 122.63 202.962 119.595 204.059 L 119.595 204.059 L 119.595 204.059 Q 116.56 205.156 112.868 205.156 L 112.868 205.156 L 112.868 205.156 Q 108.992 205.156 106.07 203.464 L 106.07 203.464 L 106.07 203.464 Q 103.147 201.772 101.558 198.553 L 101.558 198.553 L 101.558 198.553 Q 99.969 195.333 99.928 190.985 L 99.928 190.985 L 99.928 188.955 L 99.928 188.955 Q 99.928 184.484 101.435 181.213 L 101.435 181.213 L 101.435 181.213 Q 102.942 177.942 105.783 176.209 L 105.783 176.209 L 105.783 176.209 Q 108.623 174.477 112.438 174.477 L 112.438 174.477 L 112.438 174.477 Q 117.749 174.477 120.743 177.009 L 120.743 177.009 L 120.743 177.009 Q 123.737 179.542 124.291 184.382 L 124.291 184.382 L 118.303 184.382 L 118.303 184.382 Q 117.893 181.818 116.488 180.629 L 116.488 180.629 L 116.488 180.629 Q 115.083 179.439 112.622 179.439 L 112.622 179.439 L 112.622 179.439 Q 109.484 179.439 107.844 181.798 L 107.844 181.798 L 107.844 181.798 Q 106.203 184.156 106.183 188.812 L 106.183 188.812 L 106.183 190.719 L 106.183 190.719 Q 106.183 195.415 107.967 197.814 L 107.967 197.814 L 107.967 197.814 Q 109.751 200.214 113.196 200.214 L 113.196 200.214 L 113.196 200.214 Q 116.662 200.214 118.139 198.737 L 118.139 198.737 L 118.139 193.59 L 112.54 193.59 L 112.54 189.058 L 124.291 189.058 L 124.291 189.058 Z M 153.802 189.16 L 153.802 190.493 L 153.802 190.493 Q 153.802 194.902 152.243 198.225 L 152.243 198.225 L 152.243 198.225 Q 150.685 201.547 147.783 203.352 L 147.783 203.352 L 147.783 203.352 Q 144.881 205.156 141.128 205.156 L 141.128 205.156 L 141.128 205.156 Q 137.416 205.156 134.504 203.372 L 134.504 203.372 L 134.504 203.372 Q 131.592 201.588 129.992 198.276 L 129.992 198.276 L 129.992 198.276 Q 128.393 194.964 128.372 190.657 L 128.372 190.657 L 128.372 189.181 L 128.372 189.181 Q 128.372 184.771 129.961 181.418 L 129.961 181.418 L 129.961 181.418 Q 131.551 178.065 134.453 176.271 L 134.453 176.271 L 134.453 176.271 Q 137.354 174.477 141.087 174.477 L 141.087 174.477 L 141.087 174.477 Q 144.819 174.477 147.721 176.271 L 147.721 176.271 L 147.721 176.271 Q 150.623 178.065 152.212 181.418 L 152.212 181.418 L 152.212 181.418 Q 153.802 184.771 153.802 189.16 L 153.802 189.16 L 153.802 189.16 Z M 147.567 190.596 L 147.567 189.14 L 147.567 189.14 Q 147.567 184.443 145.886 182.003 L 145.886 182.003 L 145.886 182.003 Q 144.204 179.563 141.087 179.563 L 141.087 179.563 L 141.087 179.563 Q 137.99 179.563 136.309 181.972 L 136.309 181.972 L 136.309 181.972 Q 134.627 184.382 134.606 189.037 L 134.606 189.037 L 134.606 190.493 L 134.606 190.493 Q 134.606 195.066 136.288 197.589 L 136.288 197.589 L 136.288 197.589 Q 137.97 200.111 141.128 200.111 L 141.128 200.111 L 141.128 200.111 Q 144.225 200.111 145.886 197.681 L 145.886 197.681 L 145.886 197.681 Q 147.547 195.251 147.567 190.596 L 147.567 190.596 L 147.567 190.596 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_html.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_rhplHpdI3DTbrTRaojPyWupcuif0b6PM"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_rhplHpdI3DTbrTRaojPyWupcuif0b6PM)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(236,102,48)"/><g><path d=" M 112.936 91.207 C 111.707 89.978 109.721 89.978 108.492 91.207 L 89.635 110.064 C 88.406 111.293 88.406 113.279 89.635 114.508 L 108.492 133.365 C 109.105 133.978 109.91 134.286 110.714 134.286 C 111.519 134.286 112.323 133.978 112.936 133.365 C 114.165 132.136 114.165 130.15 112.936 128.921 L 96.301 112.286 L 112.936 95.651 C 114.165 94.422 114.165 92.435 112.936 91.207 Z " fill="rgb(236,102,48)"/><path d=" M 169.508 110.064 L 150.651 91.207 C 149.422 89.978 147.435 89.978 146.207 91.207 C 144.978 92.435 144.978 94.422 146.207 95.651 L 162.842 112.286 L 146.207 128.921 C 144.978 130.15 144.978 132.136 146.207 133.365 C 146.819 133.978 147.624 134.286 148.429 134.286 C 149.233 134.286 150.038 133.978 150.651 133.365 L 169.508 114.508 C 170.737 113.279 170.737 111.293 169.508 110.064 Z " fill="rgb(236,102,48)"/></g></g></g><path d=" M 95.968 173.887 L 95.968 203.746 L 89.815 203.746 L 89.815 190.949 L 77.818 190.949 L 77.818 203.746 L 71.666 203.746 L 71.666 173.887 L 77.818 173.887 L 77.818 185.986 L 89.815 185.986 L 89.815 173.887 L 95.968 173.887 L 95.968 173.887 Z M 123.817 173.887 L 123.817 178.87 L 114.671 178.87 L 114.671 203.746 L 108.519 203.746 L 108.519 178.87 L 99.495 178.87 L 99.495 173.887 L 123.817 173.887 L 123.817 173.887 Z M 127.324 173.887 L 135.363 173.887 L 143.033 195.543 L 150.662 173.887 L 158.742 173.887 L 158.742 203.746 L 152.569 203.746 L 152.569 195.584 L 153.185 181.495 L 145.125 203.746 L 140.9 203.746 L 132.861 181.516 L 133.477 195.584 L 133.477 203.746 L 127.324 203.746 L 127.324 173.887 L 127.324 173.887 Z M 170.268 173.887 L 170.268 198.804 L 183.331 198.804 L 183.331 203.746 L 164.115 203.746 L 164.115 173.887 L 170.268 173.887 L 170.268 173.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_iso.svg
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_java.svg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_jpg.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_cfbSQzBKfRUXVWtELZ5utsl7ZhZ3mlDk"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_cfbSQzBKfRUXVWtELZ5utsl7ZhZ3mlDk)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><circle vector-effect="non-scaling-stroke" cx="99.49742857142849" cy="85.35457142857132" r="14.35971428571429" fill="rgb(243,213,91)"/><path d=" M 60.429 162.571 L 95 162.571 L 195.571 162.571 L 195.571 128 L 164.143 98.143 L 131.143 134.286 L 113.911 117.053 L 60.429 162.571 Z " fill="rgb(38,185,154)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(20,160,133)"/></g></g><path d=" M 101.704 194.559 L 101.704 173.887 L 107.856 173.887 L 107.856 194.559 L 107.856 194.559 Q 107.856 197.409 106.595 199.593 L 106.595 199.593 L 106.595 199.593 Q 105.334 201.777 103.037 202.967 L 103.037 202.967 L 103.037 202.967 Q 100.74 204.156 97.849 204.156 L 97.849 204.156 L 97.849 204.156 Q 93.111 204.156 90.466 201.747 L 90.466 201.747 L 90.466 201.747 Q 87.82 199.337 87.82 194.928 L 87.82 194.928 L 94.014 194.928 L 94.014 194.928 Q 94.014 197.122 94.937 198.168 L 94.937 198.168 L 94.937 198.168 Q 95.859 199.214 97.849 199.214 L 97.849 199.214 L 97.849 199.214 Q 99.612 199.214 100.658 198.004 L 100.658 198.004 L 100.658 198.004 Q 101.704 196.794 101.704 194.559 L 101.704 194.559 L 101.704 194.559 Z M 124.673 193.226 L 119.279 193.226 L 119.279 203.746 L 113.127 203.746 L 113.127 173.887 L 124.775 173.887 L 124.775 173.887 Q 128.139 173.887 130.692 175.117 L 130.692 175.117 L 130.692 175.117 Q 133.245 176.348 134.619 178.614 L 134.619 178.614 L 134.619 178.614 Q 135.993 180.88 135.993 183.771 L 135.993 183.771 L 135.993 183.771 Q 135.993 188.16 132.989 190.693 L 132.989 190.693 L 132.989 190.693 Q 129.984 193.226 124.673 193.226 L 124.673 193.226 L 124.673 193.226 Z M 119.279 178.87 L 119.279 188.242 L 124.775 188.242 L 124.775 188.242 Q 127.216 188.242 128.498 187.094 L 128.498 187.094 L 128.498 187.094 Q 129.779 185.945 129.779 183.813 L 129.779 183.813 L 129.779 183.813 Q 129.779 181.618 128.487 180.265 L 128.487 180.265 L 128.487 180.265 Q 127.195 178.911 124.919 178.87 L 124.919 178.87 L 119.279 178.87 L 119.279 178.87 Z M 163.843 188.058 L 163.843 199.973 L 163.843 199.973 Q 162.182 201.962 159.146 203.059 L 159.146 203.059 L 159.146 203.059 Q 156.111 204.156 152.42 204.156 L 152.42 204.156 L 152.42 204.156 Q 148.544 204.156 145.622 202.464 L 145.622 202.464 L 145.622 202.464 Q 142.699 200.772 141.11 197.553 L 141.11 197.553 L 141.11 197.553 Q 139.521 194.333 139.479 189.985 L 139.479 189.985 L 139.479 187.955 L 139.479 187.955 Q 139.479 183.484 140.987 180.213 L 140.987 180.213 L 140.987 180.213 Q 142.494 176.942 145.334 175.209 L 145.334 175.209 L 145.334 175.209 Q 148.175 173.477 151.989 173.477 L 151.989 173.477 L 151.989 173.477 Q 157.301 173.477 160.295 176.009 L 160.295 176.009 L 160.295 176.009 Q 163.289 178.542 163.843 183.382 L 163.843 183.382 L 157.854 183.382 L 157.854 183.382 Q 157.444 180.818 156.04 179.629 L 156.04 179.629 L 156.04 179.629 Q 154.635 178.439 152.174 178.439 L 152.174 178.439 L 152.174 178.439 Q 149.036 178.439 147.396 180.798 L 147.396 180.798 L 147.396 180.798 Q 145.755 183.156 145.734 187.812 L 145.734 187.812 L 145.734 189.719 L 145.734 189.719 Q 145.734 194.415 147.519 196.814 L 147.519 196.814 L 147.519 196.814 Q 149.303 199.214 152.748 199.214 L 152.748 199.214 L 152.748 199.214 Q 156.214 199.214 157.69 197.737 L 157.69 197.737 L 157.69 192.59 L 152.092 192.59 L 152.092 188.058 L 163.843 188.058 L 163.843 188.058 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_js.svg
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_json.svg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_less.svg
Normal file
|
After Width: | Height: | Size: 12 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_md.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_I1G28y1htKKMJgcF7pHEbsBWAMJckYyY"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_I1G28y1htKKMJgcF7pHEbsBWAMJckYyY)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(149,203,165)"/></g></g><path d=" M 97.333 174.887 L 105.372 174.887 L 113.042 196.543 L 120.671 174.887 L 128.751 174.887 L 128.751 204.746 L 122.578 204.746 L 122.578 196.584 L 123.193 182.495 L 115.133 204.746 L 110.909 204.746 L 102.87 182.516 L 103.485 196.584 L 103.485 204.746 L 97.333 204.746 L 97.333 174.887 L 97.333 174.887 Z M 143.373 204.746 L 134.124 204.746 L 134.124 174.887 L 143.311 174.887 L 143.311 174.887 Q 147.249 174.887 150.356 176.661 L 150.356 176.661 L 150.356 176.661 Q 153.463 178.435 155.206 181.706 L 155.206 181.706 L 155.206 181.706 Q 156.949 184.977 156.949 189.14 L 156.949 189.14 L 156.949 190.514 L 156.949 190.514 Q 156.949 194.677 155.236 197.917 L 155.236 197.917 L 155.236 197.917 Q 153.524 201.157 150.407 202.941 L 150.407 202.941 L 150.407 202.941 Q 147.29 204.726 143.373 204.746 L 143.373 204.746 L 143.373 204.746 Z M 143.311 179.87 L 140.276 179.87 L 140.276 199.804 L 143.25 199.804 L 143.25 199.804 Q 146.859 199.804 148.766 197.445 L 148.766 197.445 L 148.766 197.445 Q 150.674 195.087 150.715 190.698 L 150.715 190.698 L 150.715 189.119 L 150.715 189.119 Q 150.715 184.566 148.828 182.218 L 148.828 182.218 L 148.828 182.218 Q 146.941 179.87 143.311 179.87 L 143.311 179.87 L 143.311 179.87 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/><g><path d="M 93.808 90.667 L 162.192 90.667 C 164.312 90.667 166.034 92.388 166.034 94.508 L 166.034 132.158 C 166.034 134.279 164.312 136 162.192 136 L 93.808 136 C 91.688 136 89.966 134.279 89.966 132.158 L 89.966 94.508 C 89.966 92.388 91.688 90.667 93.808 90.667 Z" style="fill:none;stroke:#95CBA5;stroke-width:4;"/><path d=" M 99.737 126.395 L 99.737 100.271 L 107.421 100.271 L 115.105 109.876 L 122.788 100.271 L 130.472 100.271 L 130.472 126.395 L 122.788 126.395 L 122.788 111.412 L 115.105 121.017 L 107.421 111.412 L 107.421 126.395 L 99.737 126.395 Z M 147.76 126.395 L 136.234 113.718 L 143.918 113.718 L 143.918 100.271 L 151.602 100.271 L 151.602 113.718 L 159.285 113.718 L 147.76 126.395 Z " fill="rgb(149,203,165)"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_mov.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_asVcXb5ArovgRsAnstkkJMmj7NXPC138"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_asVcXb5ArovgRsAnstkkJMmj7NXPC138)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(215,94,114)"/><path d=" M 82.666 173.887 L 90.705 173.887 L 98.375 195.543 L 106.004 173.887 L 114.084 173.887 L 114.084 203.746 L 107.911 203.746 L 107.911 195.584 L 108.526 181.495 L 100.467 203.746 L 96.242 203.746 L 88.203 181.516 L 88.818 195.584 L 88.818 203.746 L 82.666 203.746 L 82.666 173.887 L 82.666 173.887 Z M 143.984 188.16 L 143.984 189.493 L 143.984 189.493 Q 143.984 193.902 142.426 197.225 L 142.426 197.225 L 142.426 197.225 Q 140.867 200.547 137.965 202.352 L 137.965 202.352 L 137.965 202.352 Q 135.063 204.156 131.311 204.156 L 131.311 204.156 L 131.311 204.156 Q 127.599 204.156 124.687 202.372 L 124.687 202.372 L 124.687 202.372 Q 121.774 200.588 120.175 197.276 L 120.175 197.276 L 120.175 197.276 Q 118.575 193.964 118.555 189.657 L 118.555 189.657 L 118.555 188.181 L 118.555 188.181 Q 118.555 183.771 120.144 180.418 L 120.144 180.418 L 120.144 180.418 Q 121.733 177.065 124.635 175.271 L 124.635 175.271 L 124.635 175.271 Q 127.537 173.477 131.27 173.477 L 131.27 173.477 L 131.27 173.477 Q 135.002 173.477 137.904 175.271 L 137.904 175.271 L 137.904 175.271 Q 140.806 177.065 142.395 180.418 L 142.395 180.418 L 142.395 180.418 Q 143.984 183.771 143.984 188.16 L 143.984 188.16 L 143.984 188.16 Z M 137.75 189.596 L 137.75 188.14 L 137.75 188.14 Q 137.75 183.443 136.068 181.003 L 136.068 181.003 L 136.068 181.003 Q 134.387 178.562 131.27 178.562 L 131.27 178.562 L 131.27 178.562 Q 128.173 178.562 126.491 180.972 L 126.491 180.972 L 126.491 180.972 Q 124.81 183.382 124.789 188.037 L 124.789 188.037 L 124.789 189.493 L 124.789 189.493 Q 124.789 194.066 126.471 196.589 L 126.471 196.589 L 126.471 196.589 Q 128.152 199.111 131.311 199.111 L 131.311 199.111 L 131.311 199.111 Q 134.407 199.111 136.068 196.681 L 136.068 196.681 L 136.068 196.681 Q 137.729 194.251 137.75 189.596 L 137.75 189.596 L 137.75 189.596 Z M 152.762 173.887 L 159.488 196.343 L 166.256 173.887 L 173.105 173.887 L 162.708 203.746 L 156.289 203.746 L 145.933 173.887 L 152.762 173.887 L 152.762 173.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/><path d=" M 113.857 128 L 113.857 105.855 L 113.857 84 L 148.429 106 L 113.857 128 Z " fill="rgb(200,189,184)"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_mp3.svg
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_mp4.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_noUtHHGzPYvyzCKWl55c2UQn5veEgJAP"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_noUtHHGzPYvyzCKWl55c2UQn5veEgJAP)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(255,83,100)"/><path d=" M 117 128 C 116.478 128 115.96 127.871 115.488 127.613 C 114.483 127.06 113.857 126.004 113.857 124.857 L 113.857 80.857 C 113.857 79.71 114.483 78.654 115.488 78.101 C 116.497 77.551 117.72 77.592 118.691 78.205 L 153.262 100.205 C 154.164 100.783 154.714 101.782 154.714 102.857 C 154.714 103.932 154.164 104.931 153.259 105.51 L 118.688 127.51 C 118.175 127.833 117.588 128 117 128 Z M 120.143 86.58 L 120.143 119.131 L 145.716 102.857 L 120.143 86.58 Z " fill="rgb(200,189,184)"/><path d=" M 129.571 150 C 103.577 150 82.429 128.852 82.429 102.857 C 82.429 76.863 103.577 55.714 129.571 55.714 C 155.566 55.714 176.714 76.863 176.714 102.857 C 176.714 128.852 155.566 150 129.571 150 Z M 129.571 62 C 107.043 62 88.714 80.329 88.714 102.857 C 88.714 125.385 107.043 143.714 129.571 143.714 C 152.099 143.714 170.429 125.385 170.429 102.857 C 170.429 80.329 152.099 62 129.571 62 Z " fill="rgb(200,189,184)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/></g></g><path d=" M 85.666 173.887 L 93.705 173.887 L 101.375 195.543 L 109.004 173.887 L 117.084 173.887 L 117.084 203.746 L 110.911 203.746 L 110.911 195.584 L 111.526 181.495 L 103.467 203.746 L 99.242 203.746 L 91.203 181.516 L 91.818 195.584 L 91.818 203.746 L 85.666 203.746 L 85.666 173.887 L 85.666 173.887 Z M 134.003 193.226 L 128.609 193.226 L 128.609 203.746 L 122.457 203.746 L 122.457 173.887 L 134.105 173.887 L 134.105 173.887 Q 137.469 173.887 140.022 175.117 L 140.022 175.117 L 140.022 175.117 Q 142.575 176.348 143.949 178.614 L 143.949 178.614 L 143.949 178.614 Q 145.323 180.88 145.323 183.771 L 145.323 183.771 L 145.323 183.771 Q 145.323 188.16 142.319 190.693 L 142.319 190.693 L 142.319 190.693 Q 139.314 193.226 134.003 193.226 L 134.003 193.226 L 134.003 193.226 Z M 128.609 178.87 L 128.609 188.242 L 134.105 188.242 L 134.105 188.242 Q 136.546 188.242 137.828 187.094 L 137.828 187.094 L 137.828 187.094 Q 139.109 185.945 139.109 183.813 L 139.109 183.813 L 139.109 183.813 Q 139.109 181.618 137.817 180.265 L 137.817 180.265 L 137.817 180.265 Q 136.525 178.911 134.249 178.87 L 134.249 178.87 L 128.609 178.87 L 128.609 178.87 Z M 166.446 173.887 L 166.446 192.508 L 169.83 192.508 L 169.83 197.286 L 166.446 197.286 L 166.446 203.746 L 160.52 203.746 L 160.52 197.286 L 148.276 197.286 L 148.01 193.554 L 160.458 173.887 L 166.446 173.887 L 166.446 173.887 Z M 160.13 182.644 L 153.916 192.508 L 160.52 192.508 L 160.52 181.967 L 160.13 182.644 L 160.13 182.644 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_odp.svg
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_ods.svg
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_odt.svg
Normal file
|
After Width: | Height: | Size: 7 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_pdf.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_T4lYH0jQ4ugwp6GLbfIkOPUBVBRKI4bF"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_T4lYH0jQ4ugwp6GLbfIkOPUBVBRKI4bF)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 101.33 144.733 L 101.33 144.733 C 100.236 144.733 99.186 144.377 98.291 143.708 C 95.019 141.253 94.579 138.522 94.786 136.662 C 95.358 131.545 101.685 126.19 113.596 120.734 C 118.323 110.375 122.821 97.612 125.501 86.948 C 122.365 80.122 119.316 71.265 121.538 66.07 C 122.318 64.25 123.289 62.855 125.102 62.251 C 125.819 62.013 127.629 61.711 128.295 61.711 C 129.879 61.711 131.272 63.751 132.259 65.008 C 133.186 66.189 135.288 68.694 131.086 86.385 C 135.323 95.135 141.326 104.048 147.077 110.152 C 151.197 109.407 154.743 109.027 157.631 109.027 C 162.553 109.027 165.535 110.174 166.751 112.537 C 167.757 114.492 167.345 116.777 165.526 119.326 C 163.775 121.774 161.361 123.069 158.549 123.069 C 154.727 123.069 150.277 120.655 145.314 115.887 C 136.398 117.751 125.985 121.076 117.569 124.757 C 114.941 130.332 112.424 134.823 110.079 138.117 C 106.858 142.627 104.08 144.733 101.33 144.733 Z M 109.696 128.622 C 102.98 132.397 100.242 135.499 100.044 137.246 C 100.013 137.535 99.928 138.296 101.399 139.421 C 101.867 139.273 104.601 138.026 109.696 128.622 Z M 152.555 114.662 C 155.117 116.632 155.742 117.629 157.417 117.629 C 158.153 117.629 160.249 117.597 161.22 116.243 C 161.688 115.586 161.871 115.165 161.943 114.938 C 161.556 114.734 161.044 114.319 158.25 114.319 C 156.663 114.322 154.667 114.391 152.555 114.662 Z M 129.078 93.975 C 126.831 101.751 123.864 110.145 120.674 117.748 C 127.243 115.199 134.383 112.974 141.09 111.399 C 136.847 106.471 132.607 100.318 129.078 93.975 Z M 127.17 67.381 C 126.862 67.484 122.99 72.903 127.472 77.488 C 130.455 70.841 127.305 67.337 127.17 67.381 Z " fill="rgb(204,75,76)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(204,75,76)"/></g></g><path d=" M 102.212 193.226 L 96.818 193.226 L 96.818 203.746 L 90.666 203.746 L 90.666 173.887 L 102.314 173.887 L 102.314 173.887 Q 105.678 173.887 108.231 175.117 L 108.231 175.117 L 108.231 175.117 Q 110.784 176.348 112.158 178.614 L 112.158 178.614 L 112.158 178.614 Q 113.532 180.88 113.532 183.771 L 113.532 183.771 L 113.532 183.771 Q 113.532 188.16 110.528 190.693 L 110.528 190.693 L 110.528 190.693 Q 107.523 193.226 102.212 193.226 L 102.212 193.226 L 102.212 193.226 Z M 96.818 178.87 L 96.818 188.242 L 102.314 188.242 L 102.314 188.242 Q 104.755 188.242 106.037 187.094 L 106.037 187.094 L 106.037 187.094 Q 107.318 185.945 107.318 183.813 L 107.318 183.813 L 107.318 183.813 Q 107.318 181.618 106.026 180.265 L 106.026 180.265 L 106.026 180.265 Q 104.734 178.911 102.458 178.87 L 102.458 178.87 L 96.818 178.87 L 96.818 178.87 Z M 127.006 203.746 L 117.757 203.746 L 117.757 173.887 L 126.944 173.887 L 126.944 173.887 Q 130.882 173.887 133.989 175.661 L 133.989 175.661 L 133.989 175.661 Q 137.096 177.435 138.839 180.706 L 138.839 180.706 L 138.839 180.706 Q 140.582 183.977 140.582 188.14 L 140.582 188.14 L 140.582 189.514 L 140.582 189.514 Q 140.582 193.677 138.87 196.917 L 138.87 196.917 L 138.87 196.917 Q 137.157 200.157 134.04 201.941 L 134.04 201.941 L 134.04 201.941 Q 130.923 203.726 127.006 203.746 L 127.006 203.746 L 127.006 203.746 Z M 126.944 178.87 L 123.909 178.87 L 123.909 198.804 L 126.883 198.804 L 126.883 198.804 Q 130.492 198.804 132.399 196.445 L 132.399 196.445 L 132.399 196.445 Q 134.307 194.087 134.348 189.698 L 134.348 189.698 L 134.348 188.119 L 134.348 188.119 Q 134.348 183.566 132.461 181.218 L 132.461 181.218 L 132.461 181.218 Q 130.574 178.87 126.944 178.87 L 126.944 178.87 L 126.944 178.87 Z M 163.018 186.581 L 163.018 191.544 L 151.205 191.544 L 151.205 203.746 L 145.053 203.746 L 145.053 173.887 L 164.494 173.887 L 164.494 178.87 L 151.205 178.87 L 151.205 186.581 L 163.018 186.581 L 163.018 186.581 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_php.svg
Normal file
|
After Width: | Height: | Size: 12 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_ppt.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_aHGuroPPSn3bQvMdTobuKZlOp1kZ4lEM"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_aHGuroPPSn3bQvMdTobuKZlOp1kZ4lEM)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(246,113,46)"/><path d=" M 164.143 134.286 L 88.714 134.286 L 88.714 84 L 164.143 84 L 164.143 134.286 Z M 95 128 L 157.857 128 L 157.857 90.286 L 95 90.286 L 95 128 Z " fill="rgb(200,189,184)"/><path d=" M 104.425 150 C 103.875 150 103.316 149.855 102.81 149.551 C 101.32 148.658 100.839 146.728 101.732 145.239 L 111.161 129.524 C 112.053 128.035 113.983 127.554 115.473 128.446 C 116.962 129.339 117.443 131.269 116.551 132.758 L 107.122 148.473 C 106.534 149.456 105.494 150 104.425 150 Z " fill="rgb(200,189,184)"/><path d=" M 148.432 150 C 147.363 150 146.323 149.456 145.735 148.476 L 136.307 132.761 C 135.414 131.272 135.895 129.342 137.385 128.449 C 138.874 127.56 140.804 128.038 141.697 129.527 L 151.125 145.242 C 152.018 146.731 151.537 148.661 150.047 149.554 C 149.541 149.855 148.982 150 148.432 150 Z " fill="rgb(200,189,184)"/><path d=" M 126.429 90.286 C 124.694 90.286 123.286 88.881 123.286 87.143 L 123.286 77.714 C 123.286 75.976 124.694 74.571 126.429 74.571 C 128.163 74.571 129.571 75.976 129.571 77.714 L 129.571 87.143 C 129.571 88.881 128.163 90.286 126.429 90.286 Z " fill="rgb(200,189,184)"/><rect x="95" y="90.286" width="62.857" height="37.714" transform="matrix(1,0,0,1,0,0)" fill="rgb(211,204,201)"/></g></g><path d=" M 100.712 193.226 L 95.318 193.226 L 95.318 203.746 L 89.166 203.746 L 89.166 173.887 L 100.814 173.887 L 100.814 173.887 Q 104.178 173.887 106.731 175.117 L 106.731 175.117 L 106.731 175.117 Q 109.284 176.348 110.658 178.614 L 110.658 178.614 L 110.658 178.614 Q 112.032 180.88 112.032 183.771 L 112.032 183.771 L 112.032 183.771 Q 112.032 188.16 109.028 190.693 L 109.028 190.693 L 109.028 190.693 Q 106.023 193.226 100.712 193.226 L 100.712 193.226 L 100.712 193.226 Z M 95.318 178.87 L 95.318 188.242 L 100.814 188.242 L 100.814 188.242 Q 103.255 188.242 104.537 187.094 L 104.537 187.094 L 104.537 187.094 Q 105.818 185.945 105.818 183.813 L 105.818 183.813 L 105.818 183.813 Q 105.818 181.618 104.526 180.265 L 104.526 180.265 L 104.526 180.265 Q 103.234 178.911 100.958 178.87 L 100.958 178.87 L 95.318 178.87 L 95.318 178.87 Z M 127.803 193.226 L 122.409 193.226 L 122.409 203.746 L 116.257 203.746 L 116.257 173.887 L 127.905 173.887 L 127.905 173.887 Q 131.269 173.887 133.822 175.117 L 133.822 175.117 L 133.822 175.117 Q 136.375 176.348 137.749 178.614 L 137.749 178.614 L 137.749 178.614 Q 139.123 180.88 139.123 183.771 L 139.123 183.771 L 139.123 183.771 Q 139.123 188.16 136.119 190.693 L 136.119 190.693 L 136.119 190.693 Q 133.114 193.226 127.803 193.226 L 127.803 193.226 L 127.803 193.226 Z M 122.409 178.87 L 122.409 188.242 L 127.905 188.242 L 127.905 188.242 Q 130.346 188.242 131.627 187.094 L 131.627 187.094 L 131.627 187.094 Q 132.909 185.945 132.909 183.813 L 132.909 183.813 L 132.909 183.813 Q 132.909 181.618 131.617 180.265 L 131.617 180.265 L 131.617 180.265 Q 130.325 178.911 128.049 178.87 L 128.049 178.87 L 122.409 178.87 L 122.409 178.87 Z M 165.824 173.887 L 165.824 178.87 L 156.678 178.87 L 156.678 203.746 L 150.525 203.746 L 150.525 178.87 L 141.502 178.87 L 141.502 173.887 L 165.824 173.887 L 165.824 173.887 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_pptx.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_lMyuGubRIotblXMnQ7jMCoNnqqKJSGxl"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_lMyuGubRIotblXMnQ7jMCoNnqqKJSGxl)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(246,113,46)"/><path d=" M 164.143 134.286 L 88.714 134.286 L 88.714 84 L 164.143 84 L 164.143 134.286 Z M 95 128 L 157.857 128 L 157.857 90.286 L 95 90.286 L 95 128 Z " fill="rgb(200,189,184)"/><path d=" M 104.425 150 C 103.875 150 103.316 149.855 102.81 149.551 C 101.32 148.658 100.839 146.728 101.732 145.239 L 111.161 129.524 C 112.053 128.035 113.983 127.554 115.473 128.446 C 116.962 129.339 117.443 131.269 116.551 132.758 L 107.122 148.473 C 106.534 149.456 105.494 150 104.425 150 Z " fill="rgb(200,189,184)"/><path d=" M 148.432 150 C 147.363 150 146.323 149.456 145.735 148.476 L 136.307 132.761 C 135.414 131.272 135.895 129.342 137.385 128.449 C 138.874 127.56 140.804 128.038 141.697 129.527 L 151.125 145.242 C 152.018 146.731 151.537 148.661 150.047 149.554 C 149.541 149.855 148.982 150 148.432 150 Z " fill="rgb(200,189,184)"/><path d=" M 126.429 90.286 C 124.694 90.286 123.286 88.881 123.286 87.143 L 123.286 77.714 C 123.286 75.976 124.694 74.571 126.429 74.571 C 128.163 74.571 129.571 75.976 129.571 77.714 L 129.571 87.143 C 129.571 88.881 128.163 90.286 126.429 90.286 Z " fill="rgb(200,189,184)"/><rect x="95" y="90.286" width="62.857" height="37.714" transform="matrix(1,0,0,1,0,0)" fill="rgb(211,204,201)"/></g></g><path d=" M 87.712 193.444 L 82.318 193.444 L 82.318 203.965 L 76.166 203.965 L 76.166 174.105 L 87.814 174.105 L 87.814 174.105 Q 91.178 174.105 93.731 175.336 L 93.731 175.336 L 93.731 175.336 Q 96.284 176.566 97.658 178.833 L 97.658 178.833 L 97.658 178.833 Q 99.032 181.099 99.032 183.99 L 99.032 183.99 L 99.032 183.99 Q 99.032 188.379 96.028 190.912 L 96.028 190.912 L 96.028 190.912 Q 93.023 193.444 87.712 193.444 L 87.712 193.444 L 87.712 193.444 Z M 82.318 179.089 L 82.318 188.461 L 87.814 188.461 L 87.814 188.461 Q 90.255 188.461 91.537 187.313 L 91.537 187.313 L 91.537 187.313 Q 92.818 186.164 92.818 184.031 L 92.818 184.031 L 92.818 184.031 Q 92.818 181.837 91.526 180.483 L 91.526 180.483 L 91.526 180.483 Q 90.234 179.13 87.958 179.089 L 87.958 179.089 L 82.318 179.089 L 82.318 179.089 Z M 114.803 193.444 L 109.409 193.444 L 109.409 203.965 L 103.257 203.965 L 103.257 174.105 L 114.905 174.105 L 114.905 174.105 Q 118.269 174.105 120.822 175.336 L 120.822 175.336 L 120.822 175.336 Q 123.375 176.566 124.749 178.833 L 124.749 178.833 L 124.749 178.833 Q 126.123 181.099 126.123 183.99 L 126.123 183.99 L 126.123 183.99 Q 126.123 188.379 123.119 190.912 L 123.119 190.912 L 123.119 190.912 Q 120.114 193.444 114.803 193.444 L 114.803 193.444 L 114.803 193.444 Z M 109.409 179.089 L 109.409 188.461 L 114.905 188.461 L 114.905 188.461 Q 117.346 188.461 118.627 187.313 L 118.627 187.313 L 118.627 187.313 Q 119.909 186.164 119.909 184.031 L 119.909 184.031 L 119.909 184.031 Q 119.909 181.837 118.617 180.483 L 118.617 180.483 L 118.617 180.483 Q 117.325 179.13 115.049 179.089 L 115.049 179.089 L 109.409 179.089 L 109.409 179.089 Z M 152.824 174.105 L 152.824 179.089 L 143.678 179.089 L 143.678 203.965 L 137.525 203.965 L 137.525 179.089 L 128.502 179.089 L 128.502 174.105 L 152.824 174.105 L 152.824 174.105 Z M 161.417 174.105 L 167.016 184.4 L 172.614 174.105 L 179.689 174.105 L 170.994 188.912 L 179.915 203.965 L 172.758 203.965 L 167.016 193.506 L 161.273 203.965 L 154.116 203.965 L 163.037 188.912 L 154.342 174.105 L 161.417 174.105 L 161.417 174.105 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_psd.svg
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_py.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_2OU59RX26Z25RRKMSSLcaTTjFJr3xE4G"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_2OU59RX26Z25RRKMSSLcaTTjFJr3xE4G)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(248,198,61)"/><path d=" M 114.212 193.121 L 108.818 193.121 L 108.818 203.641 L 102.666 203.641 L 102.666 173.782 L 114.314 173.782 L 114.314 173.782 Q 117.678 173.782 120.231 175.012 L 120.231 175.012 L 120.231 175.012 Q 122.784 176.243 124.158 178.509 L 124.158 178.509 L 124.158 178.509 Q 125.532 180.775 125.532 183.667 L 125.532 183.667 L 125.532 183.667 Q 125.532 188.055 122.528 190.588 L 122.528 190.588 L 122.528 190.588 Q 119.523 193.121 114.212 193.121 L 114.212 193.121 L 114.212 193.121 Z M 108.818 178.765 L 108.818 188.137 L 114.314 188.137 L 114.314 188.137 Q 116.755 188.137 118.037 186.989 L 118.037 186.989 L 118.037 186.989 Q 119.318 185.84 119.318 183.708 L 119.318 183.708 L 119.318 183.708 Q 119.318 181.513 118.026 180.16 L 118.026 180.16 L 118.026 180.16 Q 116.734 178.806 114.458 178.765 L 114.458 178.765 L 108.818 178.765 L 108.818 178.765 Z M 133.879 173.782 L 140.052 187.235 L 146.266 173.782 L 152.992 173.782 L 143.189 192.813 L 143.189 203.641 L 136.935 203.641 L 136.935 192.813 L 127.132 173.782 L 133.879 173.782 L 133.879 173.782 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/><g><g><linearGradient id="_lgradient_0" x1="0.12959359372586665" y1="0.1169963052650701" x2="0.7956443961566904" y2="0.7852749007964104" gradientTransform="matrix(51.243,0,0,51.358,93.449,75.258)" gradientUnits="userSpaceOnUse"><stop offset="0%" stop-opacity="1" style="stop-color:rgb(56,126,184)"/><stop offset="100%" stop-opacity="1" style="stop-color:rgb(54,105,148)"/></linearGradient><path d=" M 127.751 75.258 C 110.209 75.258 111.304 82.866 111.304 82.866 L 111.324 90.747 L 128.064 90.747 L 128.064 93.113 L 104.675 93.113 C 104.675 93.113 93.449 91.84 93.449 109.54 C 93.449 127.241 103.247 126.613 103.247 126.613 L 109.094 126.613 L 109.094 118.399 C 109.094 118.399 108.779 108.602 118.735 108.602 C 128.692 108.602 135.339 108.602 135.339 108.602 C 135.339 108.602 144.667 108.752 144.667 99.586 C 144.667 90.42 144.667 84.43 144.667 84.43 C 144.667 84.43 146.083 75.258 127.751 75.258 Z M 118.52 80.558 C 120.186 80.558 121.532 81.904 121.532 83.57 C 121.532 85.235 120.186 86.581 118.52 86.581 C 116.855 86.581 115.509 85.235 115.509 83.57 C 115.509 81.904 116.855 80.558 118.52 80.558 Z " fill="url(#_lgradient_0)"/><linearGradient id="_lgradient_1" x1="0.19127525011261282" y1="0.20315845977702884" x2="0.9066531095995977" y2="0.8885264992652997" gradientTransform="matrix(51.243,0,0,51.358,111.308,92.642)" gradientUnits="userSpaceOnUse"><stop offset="0%" stop-opacity="1" style="stop-color:rgb(255,224,82)"/><stop offset="100%" stop-opacity="1" style="stop-color:rgb(255,195,49)"/></linearGradient><path d=" M 128.249 144 C 145.791 144 144.696 136.393 144.696 136.393 L 144.676 128.511 L 127.936 128.511 L 127.936 126.145 L 151.325 126.145 C 151.325 126.145 162.551 127.418 162.551 109.718 C 162.551 92.018 152.753 92.645 152.753 92.645 L 146.906 92.645 L 146.906 100.859 C 146.906 100.859 147.221 110.657 137.265 110.657 C 127.308 110.657 120.661 110.657 120.661 110.657 C 120.661 110.657 111.333 110.506 111.333 119.672 C 111.333 128.838 111.333 134.828 111.333 134.828 C 111.333 134.828 109.917 144 128.249 144 Z M 137.48 138.7 C 135.814 138.7 134.468 137.354 134.468 135.689 C 134.468 134.023 135.814 132.677 137.48 132.677 C 139.145 132.677 140.491 134.023 140.491 135.689 C 140.491 137.354 139.145 138.7 137.48 138.7 Z " fill="url(#_lgradient_1)"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
1
odoo-bringout-oca-dms-dms/dms/static/icons/file_rar.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 256 256" width="256" height="256"><defs><clipPath id="_clipPath_vTXj1UBRlX1G4H8YXsC5CxDRBKjcj0iC"><rect width="256" height="256"/></clipPath></defs><g clip-path="url(#_clipPath_vTXj1UBRlX1G4H8YXsC5CxDRBKjcj0iC)"><rect width="256" height="256" style="fill:rgb(0,0,0)" fill-opacity="0"/><g><g><path d=" M 156.239 40 L 65.027 40 C 62.487 40 60.429 42.059 60.429 46.053 L 60.429 212.857 C 60.429 213.941 62.487 216 65.027 216 L 190.973 216 C 193.513 216 195.571 213.941 195.571 212.857 L 195.571 80.788 C 195.571 78.601 195.279 77.897 194.764 77.378 L 158.193 40.808 C 157.675 40.292 156.971 40 156.239 40 Z " fill="rgb(233,233,224)"/><path d=" M 157.857 40.475 L 157.857 77.714 L 195.097 77.714 L 157.857 40.475 Z " fill="rgb(217,215,202)"/><path d=" M 190.973 216 L 65.027 216 C 62.487 216 60.429 213.941 60.429 211.402 L 60.429 162.571 L 195.571 162.571 L 195.571 211.402 C 195.571 213.941 193.513 216 190.973 216 Z " fill="rgb(85,96,128)"/><g><path d=" M 129.571 115.429 L 129.571 109.143 L 135.857 109.143 L 135.857 102.857 L 129.571 102.857 L 129.571 96.571 L 135.857 96.571 L 135.857 90.286 L 129.571 90.286 L 129.571 84 L 135.857 84 L 135.857 77.714 L 129.571 77.714 L 129.571 71.429 L 135.857 71.429 L 135.857 65.143 L 129.571 65.143 L 129.571 58.857 L 123.286 58.857 L 123.286 65.143 L 117 65.143 L 117 71.429 L 123.286 71.429 L 123.286 77.714 L 117 77.714 L 117 84 L 123.286 84 L 123.286 90.286 L 117 90.286 L 117 96.571 L 123.286 96.571 L 123.286 102.857 L 117 102.857 L 117 109.143 L 123.286 109.143 L 123.286 115.429 L 110.714 115.429 L 110.714 131.143 C 110.714 139.808 117.764 146.857 126.429 146.857 C 135.093 146.857 142.143 139.808 142.143 131.143 L 142.143 115.429 L 129.571 115.429 Z M 135.857 131.143 C 135.857 136.341 131.627 140.571 126.429 140.571 C 121.23 140.571 117 136.341 117 131.143 L 117 121.714 L 135.857 121.714 L 135.857 131.143 Z " fill="rgb(200,189,184)"/><path d=" M 123.286 134.286 L 129.571 134.286 C 131.306 134.286 132.714 132.881 132.714 131.143 C 132.714 129.405 131.306 128 129.571 128 L 123.286 128 C 121.551 128 120.143 129.405 120.143 131.143 C 120.143 132.881 121.551 134.286 123.286 134.286 Z " fill="rgb(200,189,184)"/></g></g></g><path d=" M 105.318 203.746 L 99.72 192.815 L 94.818 192.815 L 94.818 203.746 L 88.666 203.746 L 88.666 173.887 L 99.761 173.887 L 99.761 173.887 Q 105.052 173.887 107.923 176.245 L 107.923 176.245 L 107.923 176.245 Q 110.794 178.604 110.794 182.91 L 110.794 182.91 L 110.794 182.91 Q 110.794 185.966 109.471 188.006 L 109.471 188.006 L 109.471 188.006 Q 108.148 190.047 105.462 191.257 L 105.462 191.257 L 111.922 203.459 L 111.922 203.746 L 105.318 203.746 L 105.318 203.746 Z M 94.818 178.87 L 94.818 187.832 L 99.781 187.832 L 99.781 187.832 Q 102.099 187.832 103.37 186.653 L 103.37 186.653 L 103.37 186.653 Q 104.642 185.474 104.642 183.402 L 104.642 183.402 L 104.642 183.402 Q 104.642 181.29 103.442 180.08 L 103.442 180.08 L 103.442 180.08 Q 102.242 178.87 99.761 178.87 L 99.761 178.87 L 94.818 178.87 L 94.818 178.87 Z M 134.398 203.746 L 132.327 197.594 L 121.54 197.594 L 119.489 203.746 L 112.947 203.746 L 124.063 173.887 L 129.764 173.887 L 140.94 203.746 L 134.398 203.746 L 134.398 203.746 Z M 126.913 181.434 L 123.201 192.61 L 130.666 192.61 L 126.913 181.434 L 126.913 181.434 Z M 160.382 203.746 L 154.783 192.815 L 149.882 192.815 L 149.882 203.746 L 143.729 203.746 L 143.729 173.887 L 154.824 173.887 L 154.824 173.887 Q 160.115 173.887 162.986 176.245 L 162.986 176.245 L 162.986 176.245 Q 165.857 178.604 165.857 182.91 L 165.857 182.91 L 165.857 182.91 Q 165.857 185.966 164.535 188.006 L 164.535 188.006 L 164.535 188.006 Q 163.212 190.047 160.525 191.257 L 160.525 191.257 L 166.985 203.459 L 166.985 203.746 L 160.382 203.746 L 160.382 203.746 Z M 149.882 178.87 L 149.882 187.832 L 154.845 187.832 L 154.845 187.832 Q 157.162 187.832 158.434 186.653 L 158.434 186.653 L 158.434 186.653 Q 159.705 185.474 159.705 183.402 L 159.705 183.402 L 159.705 183.402 Q 159.705 181.29 158.505 180.08 L 158.505 180.08 L 158.505 180.08 Q 157.306 178.87 154.824 178.87 L 154.824 178.87 L 149.882 178.87 L 149.882 178.87 Z " fill-rule="evenodd" fill="rgb(255,255,255)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |