Add oca-dms submodule with 10 DMS modules

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ernad Husremovic 2025-08-30 17:46:17 +02:00
parent c674eb0508
commit ae2c6775ba
569 changed files with 63341 additions and 0 deletions

View file

@ -0,0 +1,45 @@
# Dms Storage
Odoo addon: dms_storage
## Installation
```bash
pip install odoo-bringout-oca-dms-dms_storage
```
## Dependencies
This addon depends on:
- dms
- fs_storage
## Manifest Information
- **Name**: Dms Storage
- **Version**: 16.0.1.0.0
- **Category**: N/A
- **License**: AGPL-3
- **Installable**: False
## Source
Based on [OCA/dms](https://github.com/OCA/dms) branch 16.0, addon `dms_storage`.
## License
This package maintains the original AGPL-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

View file

@ -0,0 +1,80 @@
===========
Dms Storage
===========
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:0bc9e984f4e8846f73e2366a15a8bf47ca8e7f7ecde0bd6ab3987096f8844e34
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-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_storage
: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_storage
: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|
Use OCA storages in order to store DMS documents.
It allows us to create store outside our systems.
They will be stored using the same system used on DMS System (Path and Name)
**Table of contents**
.. contents::
:local:
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_storage%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
~~~~~~~
* CreuBlanca
Contributors
~~~~~~~~~~~~
* Enric Tobella
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_storage>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1 @@
from . import models

View file

@ -0,0 +1,16 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Dms Storage",
"summary": """
Integrate DMS with external Storages""",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "CreuBlanca,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/dms",
"depends": ["dms", "fs_storage"],
"data": [
"views/dms_storage.xml",
],
}

View file

@ -0,0 +1,49 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * dms_storage
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: dms_storage
#: model:ir.model,name:dms_storage.model_dms_file
msgid "File"
msgstr "Datoteka"
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_storage__save_type
msgid "Save Type"
msgstr "Tip spremanja"
#. module: dms_storage
#: model:ir.model,name:dms_storage.model_dms_storage
#: model:ir.model.fields.selection,name:dms_storage.selection__dms_storage__save_type__storage
msgid "Storage"
msgstr "Skladište"
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_file__storage_backend_id
#: model:ir.model.fields,field_description:dms_storage.field_dms_storage__storage_backend_id
msgid "Storage Backend"
msgstr "Pozadina skladišta"
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_file__storage_path
msgid "Storage Path"
msgstr "Putanja skladišta"
#. module: dms_storage
#: model:ir.model.fields,help:dms_storage.field_dms_storage__save_type
msgid ""
"The save type is used to determine how a file is saved by the\n"
" system. If you change this setting, you can migrate existing files\n"
" manually by triggering the action."
msgstr ""

View file

@ -0,0 +1,49 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * dms_storage
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: dms_storage
#: model:ir.model,name:dms_storage.model_dms_file
msgid "File"
msgstr ""
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_storage__save_type
msgid "Save Type"
msgstr ""
#. module: dms_storage
#: model:ir.model,name:dms_storage.model_dms_storage
#: model:ir.model.fields.selection,name:dms_storage.selection__dms_storage__save_type__storage
msgid "Storage"
msgstr ""
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_file__storage_backend_id
#: model:ir.model.fields,field_description:dms_storage.field_dms_storage__storage_backend_id
msgid "Storage Backend"
msgstr ""
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_file__storage_path
msgid "Storage Path"
msgstr ""
#. module: dms_storage
#: model:ir.model.fields,help:dms_storage.field_dms_storage__save_type
msgid ""
"The save type is used to determine how a file is saved by the\n"
" system. If you change this setting, you can migrate existing files\n"
" manually by triggering the action."
msgstr ""

View file

@ -0,0 +1,57 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * dms_storage
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-07-29 10:58+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: dms_storage
#: model:ir.model,name:dms_storage.model_dms_file
msgid "File"
msgstr "File"
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_storage__save_type
msgid "Save Type"
msgstr "Tipo salvataggio"
#. module: dms_storage
#: model:ir.model,name:dms_storage.model_dms_storage
#: model:ir.model.fields.selection,name:dms_storage.selection__dms_storage__save_type__storage
msgid "Storage"
msgstr "Deposito"
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_file__storage_backend_id
#: model:ir.model.fields,field_description:dms_storage.field_dms_storage__storage_backend_id
msgid "Storage Backend"
msgstr "Backend deposito"
#. module: dms_storage
#: model:ir.model.fields,field_description:dms_storage.field_dms_file__storage_path
msgid "Storage Path"
msgstr "Percorso deposito"
#. module: dms_storage
#: model:ir.model.fields,help:dms_storage.field_dms_storage__save_type
msgid ""
"The save type is used to determine how a file is saved by the\n"
" system. If you change this setting, you can migrate existing files\n"
" manually by triggering the action."
msgstr ""
"Il tipo di salvataggio viene utilizzato per determinare come un file viene "
"salvato dal sistema.\n"
" Se si modifica questa impostazione, si può eseguire la migrazione "
"dei file esistenti\n"
" manualmente attivando l'azione."

View file

@ -0,0 +1,2 @@
from . import dms_storage
from . import dms_file

View file

@ -0,0 +1,36 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class DmsFile(models.Model):
_inherit = "dms.file"
storage_path = fields.Char(invisible=True, readonly=True)
storage_backend_id = fields.Many2one("fs.storage")
def _update_content_vals(self, vals, binary):
result = super(DmsFile, self)._update_content_vals(vals, binary)
result.update(
{
"storage_path": False,
"storage_backend_id": False,
}
)
if self.storage_id.save_type == "storage":
storage_path = self.path_names
if self.storage_path:
self.storage_id.storage_backend_id.delete(self.storage_path)
self.storage_id.storage_backend_id.add(storage_path, binary)
result["storage_path"] = storage_path
result["storage_backend_id"] = self.storage_id.storage_backend_id.id
return result
@api.depends("storage_path")
def _compute_content(self):
res = super(DmsFile, self)._compute_content()
for record in self.filtered(lambda r: r.storage_path):
record.content = self.storage_backend_id.get(
record.storage_path, binary=False
)
return res

View file

@ -0,0 +1,13 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class DmsStorage(models.Model):
_inherit = "dms.storage"
save_type = fields.Selection(
selection_add=[("storage", "Storage")], ondelete={"storage": "cascade"}
)
storage_backend_id = fields.Many2one("fs.storage")

View file

@ -0,0 +1 @@
* Enric Tobella

View file

@ -0,0 +1,5 @@
Use OCA storages in order to store DMS documents.
It allows us to create store outside our systems.
They will be stored using the same system used on DMS System (Path and Name)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -0,0 +1,423 @@
<?xml version="1.0" encoding="utf-8"?>
<!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>Dms Storage</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
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: grey; } /* 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 {
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="dms-storage">
<h1 class="title">Dms Storage</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:0bc9e984f4e8846f73e2366a15a8bf47ca8e7f7ecde0bd6ab3987096f8844e34
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/dms/tree/16.0/dms_storage"><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_storage"><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&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Use OCA storages in order to store DMS documents.</p>
<p>It allows us to create store outside our systems.</p>
<p>They will be stored using the same system used on DMS System (Path and Name)</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">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_storage%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-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>CreuBlanca</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Enric Tobella</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">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_storage">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>

View file

@ -0,0 +1 @@
from . import test_storage

View file

@ -0,0 +1,85 @@
# Copyright 2020 Creu Blanca
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
import base64
import uuid
from odoo.tests.common import Form
from odoo.tools import human_size
from odoo.addons.fs_storage.tests.common import TestFSStorageCase
class TestDmsField(TestFSStorageCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.access_group = cls.env["dms.access.group"].create(
{
"name": "Access Group",
"group_ids": [(4, cls.env.ref("base.group_user").id)],
}
)
cls.storage = cls.env["dms.storage"].create(
{
"name": "DMS Storage",
"save_type": "storage",
"storage_backend_id": cls.backend.id,
}
)
cls.storage_database = cls.env["dms.storage"].create(
{
"name": "DMS Database",
"save_type": "database",
}
)
cls.directory = cls.env["dms.directory"].create(
{"storage_id": cls.storage.id, "is_root_directory": True, "name": "MY DIR"}
)
cls.directory_database = cls.env["dms.directory"].create(
{
"storage_id": cls.storage_database.id,
"is_root_directory": True,
"name": "MY DIR",
}
)
def content_base64(self):
return base64.b64encode(b"\xff data")
def create_file(self, directory, content=False, sudo=False):
model = self.env["dms.file"].sudo() if sudo else self.env["dms.file"]
record = Form(model)
record.name = uuid.uuid4().hex
record.directory_id = directory
record.content = content or self.content_base64()
return record.save()
def test_storage_file_migration(self):
file = self.create_file(self.directory)
self.assertTrue(file.storage_backend_id)
self.assertTrue(file.storage_path)
path = file.storage_path.rsplit("/", 1)[0]
self.assertTrue(self.backend.list_files(path))
file.directory_id = self.directory_database
self.assertTrue(file.storage_backend_id)
file.action_migrate()
self.assertFalse(file.storage_backend_id)
self.assertFalse(file.storage_path)
def test_storage_file_move(self):
file = self.create_file(self.directory)
self.assertTrue(file.storage_backend_id)
self.assertTrue(file.storage_path)
path = file.storage_path
self.assertEqual(
self.content_base64(), base64.b64encode(self.backend.get(path))
)
file.name = uuid.uuid4()
file.write({"content": self.content_base64()})
with self.assertRaises(FileNotFoundError):
self.backend.get(path)
self.assertEqual(
human_size(len(base64.b64decode(self.content_base64()))),
file.with_context(bin_size=True).content.decode("utf-8"),
)

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 CreuBlanca
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="dms_storage_form_view">
<field name="name">dms.storage.form (in dms_storage)</field>
<field name="model">dms.storage</field>
<field name="inherit_id" ref="dms.view_dms_storage_form" />
<field name="arch" type="xml">
<group name="save_storage_right" position="inside">
<field
name="storage_backend_id"
attrs="{'required': [('save_type', '=', 'storage')], 'invisible': [('save_type', '!=', 'storage')]}"
/>
</group>
</field>
</record>
</odoo>

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Dms_storage Module - dms_storage
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for dms_storage. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,6 @@
# Dependencies
This addon depends on:
- [dms](https://github.com/bringout/oca-technical)
- [fs_storage](https://github.com/bringout/oca-storage)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon dms_storage or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-dms-dms_storage"
# or
uv pip install odoo-bringout-oca-dms-dms_storage"
```

View file

@ -0,0 +1,13 @@
# Models
Detected core models and extensions in dms_storage.
```mermaid
classDiagram
class dms_file
class dms_storage
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: dms_storage. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon dms_storage
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon dms_storage
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,44 @@
[project]
name = "odoo-bringout-oca-dms-dms_storage"
version = "16.0.0"
description = "Dms Storage -
Integrate DMS with external Storages"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-dms-dms>=16.0.0",
"odoo-bringout-oca-dms-fs_storage>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["dms_storage"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]