diff --git a/dms_storage/README.rst b/dms_storage/README.rst new file mode 100644 index 000000000..87c8b93c2 --- /dev/null +++ b/dms_storage/README.rst @@ -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 `_. +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 `_. + +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 `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/dms_storage/__init__.py b/dms_storage/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/dms_storage/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/dms_storage/__manifest__.py b/dms_storage/__manifest__.py new file mode 100644 index 000000000..55deeb17c --- /dev/null +++ b/dms_storage/__manifest__.py @@ -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", + ], +} diff --git a/dms_storage/models/__init__.py b/dms_storage/models/__init__.py new file mode 100644 index 000000000..1d2155838 --- /dev/null +++ b/dms_storage/models/__init__.py @@ -0,0 +1,2 @@ +from . import dms_storage +from . import dms_file diff --git a/dms_storage/models/dms_file.py b/dms_storage/models/dms_file.py new file mode 100644 index 000000000..77ca26e4c --- /dev/null +++ b/dms_storage/models/dms_file.py @@ -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 diff --git a/dms_storage/models/dms_storage.py b/dms_storage/models/dms_storage.py new file mode 100644 index 000000000..9c9f62dc0 --- /dev/null +++ b/dms_storage/models/dms_storage.py @@ -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") diff --git a/dms_storage/readme/CONTRIBUTORS.rst b/dms_storage/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..85004765b --- /dev/null +++ b/dms_storage/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Enric Tobella diff --git a/dms_storage/readme/DESCRIPTION.rst b/dms_storage/readme/DESCRIPTION.rst new file mode 100644 index 000000000..603ea696a --- /dev/null +++ b/dms_storage/readme/DESCRIPTION.rst @@ -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) diff --git a/dms_storage/static/description/icon.png b/dms_storage/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/dms_storage/static/description/icon.png differ diff --git a/dms_storage/static/description/index.html b/dms_storage/static/description/index.html new file mode 100644 index 000000000..c28a82a90 --- /dev/null +++ b/dms_storage/static/description/index.html @@ -0,0 +1,423 @@ + + + + + + +Dms Storage + + + +
+

Dms Storage

+ + +

Beta License: AGPL-3 OCA/dms Translate me on Weblate Try me on Runboat

+

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

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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.

+Odoo Community Association +

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 project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/dms_storage/tests/__init__.py b/dms_storage/tests/__init__.py new file mode 100644 index 000000000..8f3fb899e --- /dev/null +++ b/dms_storage/tests/__init__.py @@ -0,0 +1 @@ +from . import test_storage diff --git a/dms_storage/tests/test_storage.py b/dms_storage/tests/test_storage.py new file mode 100644 index 000000000..6fbefaa94 --- /dev/null +++ b/dms_storage/tests/test_storage.py @@ -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"), + ) diff --git a/dms_storage/views/dms_storage.xml b/dms_storage/views/dms_storage.xml new file mode 100644 index 000000000..925d4e09f --- /dev/null +++ b/dms_storage/views/dms_storage.xml @@ -0,0 +1,18 @@ + + + + + dms.storage.form (in dms_storage) + dms.storage + + + + + + + + diff --git a/setup/dms_storage/odoo/addons/dms_storage b/setup/dms_storage/odoo/addons/dms_storage new file mode 120000 index 000000000..feb348b67 --- /dev/null +++ b/setup/dms_storage/odoo/addons/dms_storage @@ -0,0 +1 @@ +../../../../dms_storage \ No newline at end of file diff --git a/setup/dms_storage/setup.py b/setup/dms_storage/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/dms_storage/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)