TIP: You can type at any time to perform a new search.
Document Management System
dms · OCA/dms
- Repository
- OCA/dms · module folder · Try on Runboat
- Module version
- Category
- Document Management
- Folder size
- 17.27 MB
- License
- LGPL-3
- Application
- Yes
- Auto-installable
- No
- Website
- https://github.com/OCA/dms
- Last tracking update
- 2026-08-20 11:14:39
- Authors
- Odoo Community Association (OCA), Tecnativa, MuK IT
- Maintainers
- Odoo Community Association (OCA), Tecnativa, MuK IT
- Committers
- root, Víctor Martínez, CarlosRoca13, Weblate, OCA-git-bot, oca-ci, Matteo Mircoli, Houzéfa Abbasbhay, christian-ramos-tecnativa
- Odoo dependencies
- Python dependencies
- None
- System dependencies
- None
- Required by
- dms_auto_classification, dms_field, dms_user_role, web_editor_media_dialog_dms
- Description
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.
Code Analysis ⓘ
Views touched (34)
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
portal_my_dms |
My DMS | ir.ui.view | qweb | New |
portal_my_dms_breadcrumbs |
My DMS: Breadcrumbs | ir.ui.view | qweb | Inherits portal.portal_breadcrumbs |
portal_my_home_dms |
Portal My Home : dms entries | ir.ui.view | qweb | Inherits portal.portal_my_home |
res_config_settings_view_form |
res.config.settings.view.form.inherit.dms | res.config.settings | form | Inherits base.res_config_settings_view_form |
search_dms_directory |
dms_directory.search | dms.directory | search | New |
search_dms_file |
dms_file.search | dms.file | search | New |
search_dms_file_migration |
dms_file.search | dms.file | search | New |
view_dms_access_groups_form |
dms_access.group.form | dms.access.group | form | New |
view_dms_access_groups_tree |
dms_access_groups.list | dms.access.group | list | New |
view_dms_category_form |
dms_category.form | dms.category | form | New |
view_dms_category_search |
dms_category.search | dms.category | search | New |
view_dms_category_tree |
dms_category.list | dms.category | list | New |
view_dms_directory_form |
dms_directory.form | dms.directory | form | New |
view_dms_directory_kanban |
dms_directory.kanban | dms.directory | kanban | New |
view_dms_directory_new_form |
dms_directory.form | dms.directory | form | Inherits view_dms_directory_form |
view_dms_directory_tree |
dms_directory.list | dms.directory | list | New |
view_dms_file_form |
dms_file.form | dms.file | form | New |
view_dms_file_graph |
dms_file.graph | dms.file | graph | New |
view_dms_file_kanban |
dms_file.kanban | dms.file | kanban | New |
view_dms_file_kanban_wizard_selection |
dms_file.kanban.wizard.selection | dms.file | kanban | Inherits dms.view_dms_file_kanban |
view_dms_file_migration_tree |
dms_file.list | dms.file | list | New |
view_dms_file_new_form |
dms_file.form | dms.file | form | Inherits view_dms_file_form |
view_dms_file_pivot |
dms_file.pivot | dms.file | pivot | New |
view_dms_file_tree |
dms_file.list | dms.file | list | New |
view_dms_storage_form |
dms_storage.form | dms.storage | form | New |
view_dms_storage_new_form |
dms_storage.form | dms.storage | form | Inherits view_dms_storage_form |
view_dms_storage_search |
dms_storage.search | dms.storage | search | New |
view_dms_storage_tree |
dms_storage.list | dms.storage | list | New |
view_dms_tag_form |
dms_tag.form | dms.tag | form | New |
view_dms_tag_kanban |
dms_tag.kanban | dms.tag | kanban | New |
view_dms_tag_search |
dms_tag.search | dms.tag | search | New |
view_dms_tag_tree |
dms_tag.list | dms.tag | list | New |
wizard_dms_file_move_form_view |
wizard.dms.file.move.form | wizard.dms.file.move | form | New |
wizard_dms_share_form |
wizard.dms.share.form | wizard.dms.share | form | Inherits portal.portal_share_wizard |
HTTP endpoints (5)
| Route(s) | Handler | Auth | Type | Methods | Flags |
|---|---|---|---|---|---|
/my/dms |
CustomerPortal.portal_my_dms |
user | http | ALL | website |
/my/dms/directory/<int:dms_directory_id> |
CustomerPortal.portal_my_dms_directory |
public | http | ALL | sudo website |
/my/dms/file/<int:dms_file_id>/download |
CustomerPortal.portal_my_dms_file_download |
public | http | ALL | sudo website |
/config/dms.forbidden_extensions |
OnboardingController.forbidden_extensions |
user | json | ALL | sudo |
/web/binary/upload_dms_file |
OnboardingController.upload_dms_file |
user | http | ALL |
Models touched (19)
New fields (7)
-
category_idMany2one → dms.categorycomodel_name='dms.category'context={'dms_category_show_path': True}string='Category' -
colorIntegerdefault=0 -
company_idMany2one → res.companycomodel_name='res.company'index='btree'readonly=Truerelated='storage_id.company_id'store=Truestring='Company' -
is_hiddenBooleanreadonly=Truerelated='storage_id.is_hidden'store=Truestring='Storage is Hidden' -
nameCharindex='btree'required=True -
storage_idMany2one → dms.storagecomodel_name='dms.storage'copy=Truestore=Truestring='Storage' -
storage_id_save_typeSelectionrelated='storage_id.save_type'store=False
-
search_panel_select_range(self, field_name, **kwargs)@api.modelAdd context to display short folder name.
New fields (0)
No new fields.
Public methods (1)-
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.
New fields (17)
-
child_group_idsOne2many → dms.access.groupcomodel_name='dms.access.group'inverse_name='parent_group_id'string='Child Groups' -
complete_directory_idsMany2many → dms.directoryauto_join=Truecolumn1='gid'column2='aid'comodel_name='dms.directory'readonly=Truerelation='dms_directory_complete_groups_rel'string='Complete directories' -
count_directoriesIntegercompute='_compute_count_directories' -
count_usersIntegercompute='_compute_users'store=True -
directory_idsMany2many → dms.directoryauto_join=Truecolumn1='gid'column2='aid'comodel_name='dms.directory'readonly=Truerelation='dms_directory_groups_rel'string='Directories' -
explicit_user_idsMany2many → res.userscolumn1='gid'column2='uid'comodel_name='res.users'relation='dms_access_group_explicit_users_rel'string='Explicit Users' -
group_idsMany2many → res.groupscolumn1='gid'column2='rid'comodel_name='res.groups'relation='dms_access_group_groups_rel'string='Groups' -
nameCharrequired=Truestring='Group Name'translate=True -
parent_group_idMany2one → dms.access.groupcomodel_name='dms.access.group'index='btree'ondelete='cascade'string='Parent Group' -
parent_pathCharindex='btree' -
perm_createBooleanstring='Create Access' -
perm_inclusive_createBooleancompute='_compute_inclusive_permissions'recursive=Truestore=Truestring='Inherited Create Access' -
perm_inclusive_unlinkBooleancompute='_compute_inclusive_permissions'recursive=Truestore=Truestring='Inherited Unlink Access' -
perm_inclusive_writeBooleancompute='_compute_inclusive_permissions'recursive=Truestore=Truestring='Inherited Write Access' -
perm_unlinkBooleanstring='Unlink Access' -
perm_writeBooleanstring='Write Access' -
usersMany2many → res.usersauto_join=Truecolumn1='gid'column2='uid'comodel_name='res.users'compute='_compute_users'recursive=Truerelation='dms_access_group_users_rel'store=Truestring='Group Users'
-
copy_data(self, default=None) -
default_get(self, fields_list)@api.model
New fields (13)
-
activeBooleandefault=Truehelp='The active field allows you to hide the category without removing it.' -
child_category_idsOne2many → dms.categorycomodel_name='dms.category'inverse_name='parent_id'string='Child Categories' -
complete_nameCharcompute='_compute_complete_name'recursive=Truestore=True -
count_categoriesIntegercompute='_compute_count_categories'string='Count Subcategories' -
count_directoriesIntegercompute='_compute_count_directories' -
count_filesIntegercompute='_compute_count_files' -
count_tagsIntegercompute='_compute_count_tags' -
directory_idsOne2many → dms.directorycomodel_name='dms.directory'inverse_name='category_id'readonly=Truestring='Directories' -
file_idsOne2many → dms.filecomodel_name='dms.file'inverse_name='category_id'readonly=Truestring='Files' -
nameCharrequired=Truetranslate=True -
parent_idMany2one → dms.categorycomodel_name='dms.category'index='btree'ondelete='cascade'string='Parent Category' -
parent_pathCharindex='btree' -
tag_idsOne2many → dms.tagcomodel_name='dms.tag'inverse_name='category_id'string='Tags'
No public methods.
New fields (29)
-
alias_processSelectiondefault='directory'help=' Define how incoming emails are processed:\n\n - Single Files: The email gets attached to the directory and\n all attachments are created as files.\n\n - Subdirectory: A new subdirectory is created for each email\n and the mail is attached to this subdirectory. The attachments\n are created as files of the subdirectory.\n 'required=Trueselection=[('files', 'Single Files'), ('directory', 'Subdirectory')]string='Unpack Emails as' -
allowed_model_idsMany2many → ir.modelcomodel_name='ir.model'related='storage_id.model_ids' -
child_directory_idsOne2many → dms.directoryauto_join=Falsecomodel_name='dms.directory'copy=Trueinverse_name='parent_id'string='Subdirectories' -
complete_group_idsMany2many → dms.access.groupcolumn1='aid'column2='gid'comodel_name='dms.access.group'compute='_compute_groups'compute_sudo=Truereadonly=Truerecursive=Truerelation='dms_directory_complete_groups_rel'store=Truestring='Complete Groups' -
complete_nameCharcompute='_compute_complete_name'recursive=Truestore=True -
count_directoriesIntegercompute='_compute_count_directories'string='Count Subdirectories Title' -
count_directories_titleCharcompute='_compute_count_directories'string='Count Subdirectories' -
count_elementsIntegercompute='_compute_count_elements' -
count_filesIntegercompute='_compute_count_files'string='Count Files Title' -
count_files_titleCharcompute='_compute_count_files'string='Count Files' -
count_total_directoriesIntegercompute='_compute_count_total_directories'string='Total Subdirectories' -
count_total_elementsIntegercompute='_compute_count_total_elements'string='Total Elements' -
count_total_filesIntegercompute='_compute_count_total_files'string='Total Files' -
file_idsOne2many → dms.fileauto_join=Falsecomodel_name='dms.file'copy=Trueinverse_name='directory_id'string='Files' -
group_idsMany2many → dms.access.groupcolumn1='aid'column2='gid'comodel_name='dms.access.group'relation='dms_directory_groups_rel'string='Groups' -
human_sizeCharcompute='_compute_human_size'string='Size (human readable)' -
inherit_group_idsBooleandefault=Truestring='Inherit Groups' -
is_root_directoryBooleandefault=Falsehelp='Indicates if the directory is a root directory.\n A root directory has a settings object, while a directory with a set\n parent inherits the settings form its parent.' -
model_idMany2one → ir.modelcomodel_name='ir.model'compute='_compute_model_id'domain="[('id', 'in', allowed_model_ids)]"inverse='_inverse_model_id'store=Truestring='Model' -
parent_idMany2one → dms.directorycomodel_name='dms.directory'compute='_compute_parent_id'copy=Truedefault=<expr>domain="[('permission_create', '=', True)]"index='btree'ondelete='restrict'prefetch=Falsereadonly=Falsestore=Truestring='Parent Directory' -
parent_pathCharindex='btree' -
root_directory_idMany2one → dms.directorycompute='_compute_root_id'store=True args: 'dms.directory', 'Root Directory' -
sizeFloatcompute='_compute_size' -
starredBooleancompute='_compute_starred'inverse='_inverse_starred'search='_search_starred' -
storage_idMany2one → dms.storageauto_join=Truecomodel_name='dms.storage'compute='_compute_storage_id'compute_sudo=Trueondelete='restrict'readonly=Falsestore=Truestring='Storage' -
storage_id_inherit_access_from_parent_recordBooleanrelated='storage_id.inherit_access_from_parent_record'related_sudo=Truestore=True -
storage_id_save_typeSelectionprefetch=Falsereadonly=Truerelated='storage_id.save_type'related_sudo=Truestore=False -
tag_idsMany2many → dms.tagcolumn1='did'column2='tid'comodel_name='dms.tag'compute='_compute_tags'domain="[\n '|', ['category_id', '=', False],\n ['category_id', 'child_of', category_id]]\n "readonly=Falserelation='dms_directory_tag_rel'store=Truestring='Tags' -
user_star_idsMany2many → res.userscolumn1='did'column2='uid'comodel_name='res.users'relation='dms_directory_star_rel'string='Stars'
-
action_dms_directories_all_directory(self) -
action_dms_files_all_directory(self) -
action_save_onboarding_directory_step(self) -
check_access_token(self, access_token=False) -
copy_data(self, default=None) -
create(self, vals_list)@api.model_create_multi -
message_new(self, msg_dict, custom_values=None)@api.model -
message_update(self, msg_dict, update_vals=None) -
search_panel_select_multi_range(self, field_name, **kwargs)@api.model -
search_panel_select_range(self, field_name, **kwargs)@api.model -
toggle_starred(self) -
unlink(self)Custom cascade unlink. Cannot rely on DB backend's cascade because subfolder and subfile unlinks must check custom permissions implementation. -
write(self, vals)
New fields (25)
-
activeBooleandefault=Truehelp='If a file is set to archived, it is not displayed, but still exists.'string='Archived' -
attachment_idMany2one → ir.attachmentcomodel_name='ir.attachment'index=Trueondelete='cascade'prefetch=Falsestring='Attachment File' -
checksumCharindex='btree'readonly=Truestring='Checksum/SHA1' -
contentBinaryattachment=Falsecompute='_compute_content'inverse='_inverse_content'prefetch=Falserequired=Truestore=False -
content_binaryBinaryattachment=Falseprefetch=False -
content_fileBinaryattachment=Trueprefetch=False -
directory_idMany2one → dms.directoryauto_join=Truecomodel_name='dms.directory'context={'dms_directory_show_path': True}domain="[('permission_create', '=', True)]"index='btree'ondelete='restrict'required=Truestring='Directory'tracking=True -
extensionCharcompute='_compute_extension'readonly=Truestore=True -
human_sizeCharcompute='_compute_human_size'readonly=Truestore=Truestring='Size (human readable)' -
image_1920Imagecompute='_compute_image_1920'readonly=Falsestore=True -
is_lock_editorBooleancompute='_compute_locked'string='Editor' -
is_lockedBooleancompute='_compute_locked'string='Locked' -
locked_byMany2one → res.userscomodel_name='res.users' -
migrationCharcompute='_compute_migration'compute_sudo=Trueprefetch=Falsereadonly=Truestore=Truestring='Migration Status' -
mimetypeCharcompute='_compute_mimetype'readonly=Truestore=Truestring='Type' -
path_jsonTextcompute='_compute_path'compute_sudo=Truereadonly=Truestore=False -
path_namesCharcompute='_compute_path'compute_sudo=Truereadonly=Truestore=False -
require_migrationBooleancompute='_compute_migration'compute_sudo=Truestore=True -
res_idIntegerrelated='directory_id.res_id'string='Linked attachments record ID' -
res_modelCharrelated='directory_id.res_model'string='Linked attachments model' -
root_directory_idMany2onerelated='directory_id.root_directory_id' -
save_typeCharcompute='_compute_save_type'prefetch=Falsestring='Current Save Type' -
sizeFloatreadonly=True -
storage_idMany2oneprefetch=Falsereadonly=Truerelated='directory_id.storage_id' -
tag_idsMany2many → dms.tagcolumn1='fid'column2='tid'comodel_name='dms.tag'domain="['|', ('category_id', '=', False),('category_id', '=?', category_id)]"relation='dms_file_tag_rel'string='Tags'
-
action_migrate(self, should_logging=True) -
action_save_onboarding_file_step(self) -
action_wizard_dms_file_move(self) -
check_access(self, operation) -
check_access_token(self, access_token=False) -
copy_data(self, default=None) -
create(self, vals_list)@api.model_create_multi -
get_human_size(self) -
lock(self) -
search_panel_select_multi_range(self, field_name, **kwargs)@api.model -
search_panel_select_range(self, field_name, **kwargs)@api.modelThis 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). -
unlink(self) -
unlock(self)
New fields (1)
-
icon_urlCharcompute='_compute_icon_url'string='Icon URL'
No public methods.
New fields (7)
-
permission_createBooleancompute='_compute_permissions'search='_search_permission_create'string='Create Access' -
permission_readBooleancompute='_compute_permissions'search='_search_permission_read'string='Read Access' -
permission_unlinkBooleancompute='_compute_permissions'search='_search_permission_unlink'string='Delete Access' -
permission_writeBooleancompute='_compute_permissions'search='_search_permission_write'string='Write Access' -
record_refReferencecompute='_compute_record_ref'selection=<expr>string='Record Referenced' -
res_idIntegerindex='btree'store=Truestring='Linked attachments record ID' -
res_modelCharindex='btree'store=Truestring='Linked attachments model'
-
create(self, vals_list)@api.model_create_multi -
filtered_domain(self, domain)This method is needed to inhibit the behavior when called from the _check_access() method with sudo() https://github.com/odoo/odoo/blob/fc737a147b9aefbd6ae5d111835ce3f4f7b4240a/odoo/models.py#L4465. It would cause the error that multiple records are not accessed to be displayed. The _filtered_access() method is also overwritten to prevent this sudo() specific behavior and to be able to access only the appropriate records. -
unlink(self) -
write(self, vals)
New fields (13)
-
company_idMany2one → res.companycomodel_name='res.company'default=<expr>help='If set, directories and files will only be available for the selected company.'string='Company' -
count_storage_directoriesIntegercompute='_compute_count_storage_directories'string='Count Directories' -
count_storage_filesIntegercompute='_compute_count_storage_files'string='Count Files' -
include_message_attachmentsBooleandefault=Falsehelp='Indicate if directories and files auto-create in mail composition process too'string='Create files from message attachments' -
inherit_access_from_parent_recordBooleandefault=Falsehelp='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 access)'string='Inherit permissions from related record' -
is_hiddenBooleandefault=Falsehelp='Indicates if directories and files are hidden by default.'string='Storage is Hidden' -
modelCharsearch='_search_model'store=False -
model_idsMany2many → ir.modelstring='Linked Models' args: 'ir.model' -
nameCharrequired=True -
root_directory_idsOne2many → dms.directoryauto_join=Falsecomodel_name='dms.directory'copy=Falseinverse_name='storage_id'readonly=Falsestring='Root Directories' -
save_typeSelectiondefault='database'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.'required=Trueselection=[('database', 'Database'), ('file', 'Filestore'), ('attachment', 'Attachment')] -
storage_directory_idsOne2many → dms.directoryauto_join=Falsecomodel_name='dms.directory'copy=Falseinverse_name='storage_id'readonly=Truestring='Directories' -
storage_file_idsOne2many → dms.fileauto_join=Falsecomodel_name='dms.file'copy=Falseinverse_name='storage_id'readonly=Truestring='Files'
-
action_save_onboarding_storage_step(self) -
action_storage_migrate(self) -
write(self, values)
New fields (8)
-
activeBooleandefault=Truehelp='The active field allows you to hide the tag without removing it.' -
category_idMany2one → dms.categorycomodel_name='dms.category'context={'dms_category_show_path': True}ondelete='set null'string='Category' -
colorIntegerdefault=10string='Color Index' -
count_directoriesIntegercompute='_compute_count_directories' -
count_filesIntegercompute='_compute_count_files' -
directory_idsMany2many → dms.directorycolumn1='tid'column2='did'comodel_name='dms.directory'readonly=Truerelation='dms_directory_tag_rel'string='Directories' -
file_idsMany2many → dms.filecolumn1='tid'column2='fid'comodel_name='dms.file'readonly=Truerelation='dms_file_tag_rel'string='Files' -
nameCharrequired=Truetranslate=True
No public methods.
New fields (0)
No new fields.
Public methods (3)-
create(self, vals_list)@api.model_create_multi -
unlink(self) -
write(self, vals)
New fields (0)
No new fields.
Public methods (0)No public methods.
New fields (0)
No new fields.
Public methods (0)No public methods.
New fields (0)
No new fields.
Public methods (1)-
action_close_panel_dms_file(self)@api.model
New fields (0)
No new fields.
Public methods (3)-
action_open_documents_onboarding_directory(self)@api.modelOpen the form to create a new directory from the onboarding panel. -
action_open_documents_onboarding_file(self)@api.modelOpen the form to create a new file from the onboarding panel. -
action_open_documents_onboarding_storage(self)@api.modelOpen the form to create a new storage from the onboarding panel.
New fields (4)
-
documents_onboarding_directory_stateSelectiondefault='not_done'selection=[('not_done', 'Not done'), ('just_done', 'Just done'), ('done', 'Done'), ('closed', 'Closed')] -
documents_onboarding_file_stateSelectiondefault='not_done'selection=[('not_done', 'Not done'), ('just_done', 'Just done'), ('done', 'Done'), ('closed', 'Closed')] -
documents_onboarding_stateSelectiondefault='not_done'selection=[('not_done', 'Not done'), ('just_done', 'Just done'), ('done', 'Done'), ('closed', 'Closed')] -
documents_onboarding_storage_stateSelectiondefault='not_done'selection=[('not_done', 'Not done'), ('just_done', 'Just done'), ('done', 'Done'), ('closed', 'Closed')]
-
action_close_documents_onboarding(self)@api.model -
get_and_update_documents_onboarding_state(self) -
set_onboarding_step_done(self, step)
New fields (2)
-
documents_binary_max_sizeIntegerconfig_parameter='dms.binary_max_size'help='Defines the maximum upload size in MB. Default (25MB)'string='Size' -
documents_forbidden_extensionsCharconfig_parameter='dms.forbidden_extensions'help="Defines a list of forbidden file extensions. (Example: 'exe,msi')"string='Extensions'
No public methods.
New fields (2)
-
count_filesIntegerreadonly=True -
directory_idMany2one → dms.directorycomodel_name='dms.directory'required=Truestring='Directory'
-
default_get(self, fields)@api.model -
process(self)
New fields (0)
No new fields.
Public methods (0)No public methods.
Loading…
Loading…
Loading…
Loading…
Loading…
Loading…
- Status
- Open migration PR — not merged yet for this version
- CI status
- green — ready to merge
- Open since
- 100 days ago
- Last activity
- 0 days ago
- Repository
- OCA/dms
- Pull request
- [19.0][MIG] dms: Migration to 19.0 (#475)