Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13.0][IMP] Attachment Integration #9

Closed
wants to merge 17 commits into from

Conversation

luismalta
Copy link
Contributor

This feature aims to integrate dms with ir.attachment. That way, every time a new attachment is created, a dms.file is also created with a category according to the model the attachment is in.

@pedrobaeza
Copy link
Member

Thanks for the improvement, but not sure if this should go in the base module. @etobella what do you think? In any case, better documentation about this (in the README) and UI tips are needed.

@mileo
Copy link
Member

mileo commented Aug 13, 2020

Hi, This feature is related with my comments in #2

I was talking to @luismalta a few hours ago about this feature and he has already developed this proof of concept to open this PR so that you can also suggest ideas. We are thinking about the following features:

  1. User can configure a model at dms.category (Category / Folder), each attachment created in this template is automatically created in this folder. For example:
    - HR (dms.category) related to hr.employee;
    - HR / Files here;
  2. Create a boolean field at dms.category to create a sub-folder with the record model name; ( This behavior can be the default behavior, and we remove the boolean and avoiding the example above that you have multiple files from multiple records in the same folder.)
    - HR / Michel Admin / Files;
    2.1 If you create a new file at HR / Michel Admin i'ts automatically attached to hr.employee record of Michel Admin;
  3. In the folder or in the files you can click in a link to go to the record.
  4. We can have a default folder to the attachments that don't have the model defined in dms.category be saved.

Any suggestions are welcome. Best regards

@etobella
Copy link
Member

@luismalta interesting approach, but I think this should go on a new module, like dms_attachment.

When we integrated the module muk_dms_attachment directly to dms was about storing dms files using attachments, not creating dms files from attachments.

However, what will happen if two categories or two directories exists for this model?

If you are interested, we are currently working on a new dms module called dms_field. This module will allow to define directories related to records and define a way to show this directories and its files. @jarroyomorales

The main idea would be to relate one or more storages to a model, so, each root folder of the storage will be related to a single record, now, we will be able to show all the related folders in a simple way. So, a record could have different folders related to it and a user will be able to see the files that its permissions allow.

@etobella
Copy link
Member

The only problem is that we are developing it on 12.0, but it will be ported to 13.0 as soon as it is approved 😉

@keshrath
Copy link
Member

muk_dms_attachment (https://github.com/muk-it/muk_dms/tree/12.0/muk_dms_attachment) does not store dms files as attachments. It allows attachments to be stored as dms files.

muk_dms_field (https://github.com/muk-it/muk_dms/tree/12.0/muk_dms_field) is similar to the binary field with attachment=True but stores the data as a file instead of an attachment.

@etobella
Copy link
Member

Sorry for the misunderstanding, we crossed the information between muk_dms_file and muk_dms_attachment.

Our module has nothing to do with muk_dms_field, it is a different approach of how to relate dms.files and records.
One way is to relate each file to a record like the approach of this PR or muk_dms_attachment.
Our proposal is to relate a root directory to a record, this way we can create a structure of folders inside this record. It might be interesting in cases like customers or employees of different systems of files and classification folders could exist and we could see some of them depending on the permissions.

@mileo
Copy link
Member

mileo commented Aug 14, 2020

Hi Guys,

Talking with @luismalta I found that I made a mistake.

I specified it to be implemented in the dms.category model instead of the dms.directory model.

@etobella did you see my comment about the roadmap of this feature?

Interesting your idea of verifying the user's permissions to the directory model, we can implement it. Do attachments no longer do this automatically? @luismalta is going to test this case.

@mileo
Copy link
Member

mileo commented Aug 14, 2020

About the multiple directories per model, in my opinion, this should not be allowed. This will keep the feature very simple and minimalist avoiding we to have to create one module per model.

We can create a default behavior to create a directory per model, with model _description automatically too.

Do you think we really need a separate module for this feature? Is it not simpler to leave it in the same DMS and create some settings.

dms/models/__init__.py Outdated Show resolved Hide resolved
@mileo
Copy link
Member

mileo commented Aug 18, 2020

@luismalta luismalta marked this pull request as ready for review August 20, 2020 12:28
@luismalta
Copy link
Contributor Author

The last commits put the PR in the way suggested by @mileo, missing only the errors of Travis' tests, which I'm working on at the moment. Therefore, I would like to request the review of the PR again.
Best regards.
@etobella @pedrobaeza @keshrath

@pedrobaeza pedrobaeza mentioned this pull request Aug 27, 2020
@etobella
Copy link
Member

We tried a different approach in order to make a similar behavior on #12. Now, we can assign one or more directories to a record and we can use the inherited structure there. I think this simplifies a lot how to manage it. Can you check? Also, a new view has been added in order to make it easy enough

@etobella
Copy link
Member

Maybe we can create a unified view, like:
Use the dms_field as a view and this module in order to store the attachments in the first directory. WDYT?

@etobella etobella added this to the 13.0 milestone Aug 28, 2020
@etobella
Copy link
Member

dms_field should be migrated in another PR, not here, but it would be interesting to make it work properly together 😉
However, just as a comment of this approach, I think we are losing one of the biggest parts of dms with the attachment as the permissions are not useful anymore, but this is just my comment. If this is an option there might be no issues with that

@pedrobaeza
Copy link
Member

Yes, being optional fields, if you want, you don't fill those fields and let that integration. You are right about permissions, but the aim of this is to fill flows that are done by lots of persons in one place, and summarize them automatically in the DMS by others.

@luismalta
Copy link
Contributor Author

I created a migration to dms_field: PR # 17.
I am currently working on integrating dms_field with the attachments features and will soon update this PR with a proposal.

@victoralmau
Copy link
Member

Hi,

Maybe need to make some changes to aprrove this PR:

  • Add [IMP] in subject (this change is an Implementation)
  • Update description to add more info (description, usage, demo images, Video link). It's important to know about this functionalitty to review changes.
  • Only 1 commit per PR

This functionallity is very interesting, good job!!
Now, i check patiently to try solved travis errors and help it.

Copy link
Member

@victoralmau victoralmau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this changes, travis OK

Comment on lines 583 to 585
default_directory_id = self.env["dms.directory"].search(
[("id", "=", self._context["default_directory_id"])]
)
Copy link
Member

@victoralmau victoralmau Oct 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change is necessary to solved travis

            default_directory_id = self.env["dms.directory"].with_user(SUPERUSER_ID).browse(self._context["default_directory_id"])

IMO this is a problem with _search function in directory that is not correct (isn't override and is needed) because not apply groups correctlly (not in this PR).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why searching instead of a browse?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why searching instead of a browse?

Thanks, update my comments

Comment on lines 589 to 591
directory_id = self.env["dms.directory"].search(
[("id", "=", vals["directory_id"])]
)
Copy link
Member

@victoralmau victoralmau Oct 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change is necessary to solved travis

        directory_id = self.env["dms.directory"].with_user(SUPERUSER_ID).browse(vals["directory_id"])

IMO this is a problem with _search function in directory that is not correct (isn't override and is needed) because not apply groups correctlly (not in this PR).

@luismalta luismalta changed the title [13.0] Attachment Integration [13.0][IMP] Attachment Integration Oct 5, 2020
@luismalta
Copy link
Contributor Author

@victoralmau Thanks a lot for the help. I will work on these changes to make PR approvable

@victoralmau
Copy link
Member

Add exactly same functionallity in V12: #24

@victoralmau
Copy link
Member

Add test in similar PR #24 and maybe is interesting to add it and increase codecov results.

directory_fields = {
"name": attachment_id.res_name.replace("/", "-"),
"is_root_directory": True,
"parent_id": False,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldnt it be better to add all these directories under a common model directory Contacts Root for example instead of making every record root directory?

Comment on lines 185 to +188
if self.storage_id.save_type == "file":
new_vals["content_file"] = self.content
elif self.storage_id.save_type == "attachment":
new_vals["attachment_id"] = self.content
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very strange because in V12 don't work #24 (comment).
Solved (V12) with this changes:

Suggested change
if self.storage_id.save_type == "file":
new_vals["content_file"] = self.content
elif self.storage_id.save_type == "attachment":
new_vals["attachment_id"] = self.content
if self.storage_id.save_type in ["file", "attachment"]:
new_vals["content_file"] = self.content

Comment on lines +31 to +32
if dms_field and dms_field.state == "installed":
directory_fields["res_id"] = attachment_id.res_id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's unnecessary because of (in the future) other addon use it, it's not necessary to add new field res_id in directory because record_ref contain it already.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the standard is to have res_model and res_id field. The record_ref can be a computed one, composed over the other 2.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, but actually don't exists this fields.
Do you think that it's necessary to remove record_ref and add: res_model and res_id fields?
It's necessary to add this fields only in directory or in file too? (now group all attachment in only one directory, it's enought?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to go with res_model and res_id fields, and the other one computed (stored). If res_model can be computed stored as well from the dms.directory, perfect. I understand that dms.directory can contain res_model and optionally res_id, isn't it?

Comment on lines +21 to +34
def _create_record_dir(self, storage_id, attachment_id):
dms_field = self.env["ir.module.module"].search([("name", "=", "dms_field")])

directory_fields = {
"name": attachment_id.res_name.replace("/", "-"),
"is_root_directory": True,
"parent_id": False,
"root_storage_id": storage_id.id,
}

if dms_field and dms_field.state == "installed":
directory_fields["res_id"] = attachment_id.res_id

return self.env["dms.directory"].create(directory_fields)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's unnecessary but need to change some things in _create

Comment on lines +36 to +85
@api.model
def create(self, vals):
if "dms_file" in vals and vals["dms_file"]:
del vals["dms_file"]
return super(IrAttachment, self).create(vals)
else:
attachment_id = super(IrAttachment, self).create(vals)
if "res_model" in vals:
storage_id = self.env["dms.storage"].search(
[("model_id", "=", vals["res_model"])]
)

if storage_id and storage_id.save_type == "attachment":
record_directory = self.env["dms.directory"].search(
[("complete_name", "=", attachment_id.res_name)]
)
if not record_directory:
record_directory = self._create_record_dir(
storage_id, attachment_id
)

attachments_dir_id = record_directory.child_directory_ids.filtered(
lambda r: r.name == "Attachments"
)

if not attachments_dir_id:
attachments_dir_id = self.env["dms.directory"].create(
{
"name": "Attachments",
"parent_id": record_directory.id,
"storage_id": storage_id.id,
"record_ref": "{},{}".format(
attachment_id.res_model, attachment_id.res_id
),
}
)
file_name = self._dms_file_name(attachments_dir_id, vals["name"])

self.env["dms.file"].create(
{
"name": file_name,
"directory_id": attachments_dir_id.id,
"attachment_id": attachment_id.id,
"record_ref": "{},{}".format(
attachment_id.res_model, attachment_id.res_id
),
}
)

return attachment_id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In V12 change it for some reasons:

  • It's possible to exists some attachment storage
  • It's necessary to auto-create root directory related to model and storage
  • It's necessary to create sub directory (related to root directory previously auto-create) related to model and res_id with record_ref field.
  • Dms fIeld need to related to previous directory.
Suggested change
@api.model
def create(self, vals):
if "dms_file" in vals and vals["dms_file"]:
del vals["dms_file"]
return super(IrAttachment, self).create(vals)
else:
attachment_id = super(IrAttachment, self).create(vals)
if "res_model" in vals:
storage_id = self.env["dms.storage"].search(
[("model_id", "=", vals["res_model"])]
)
if storage_id and storage_id.save_type == "attachment":
record_directory = self.env["dms.directory"].search(
[("complete_name", "=", attachment_id.res_name)]
)
if not record_directory:
record_directory = self._create_record_dir(
storage_id, attachment_id
)
attachments_dir_id = record_directory.child_directory_ids.filtered(
lambda r: r.name == "Attachments"
)
if not attachments_dir_id:
attachments_dir_id = self.env["dms.directory"].create(
{
"name": "Attachments",
"parent_id": record_directory.id,
"storage_id": storage_id.id,
"record_ref": "{},{}".format(
attachment_id.res_model, attachment_id.res_id
),
}
)
file_name = self._dms_file_name(attachments_dir_id, vals["name"])
self.env["dms.file"].create(
{
"name": file_name,
"directory_id": attachments_dir_id.id,
"attachment_id": attachment_id.id,
"record_ref": "{},{}".format(
attachment_id.res_model, attachment_id.res_id
),
}
)
return attachment_id
@api.model
def create(self, vals):
if "dms_file" in vals and vals["dms_file"]:
del vals["dms_file"]
return super(IrAttachment, self).create(vals)
else:
attachment_id = super(IrAttachment, self).create(vals)
if attachment_id.res_model and attachment_id.res_id:
storage_ids = self.env["dms.storage"].search(
[
("model_id.model", "=", attachment_id.res_model),
("save_type", "=", "attachment"),
]
)
if storage_ids:
record_ref = "{},{}".format(
attachment_id.res_model, attachment_id.res_id,
)
directory_ids = self.env["dms.directory"].search(
[
("storage_id", "in", storage_ids.ids),
("record_ref", "=", record_ref),
]
)
if directory_ids:
directory_id = directory_ids[0]
else:
root_directory_ids = self.env["dms.directory"].search(
[
("storage_id", "=", storage_ids[0].id),
("is_root_directory", "=", True),
]
)
if root_directory_ids:
root_directory_id = root_directory_ids[0]
else:
root_directory_id = self.env["dms.directory"].create(
{
"name": attachment_id.res_model,
"is_root_directory": True,
"storage_id": storage_ids[0].id,
"root_storage_id": storage_ids[0].id,
}
)
# Create directory related to record_ref
directory_id = self.env["dms.directory"].create(
{
"name": attachment_id.res_name,
"parent_id": root_directory_id.id,
"storage_id": root_directory_id.storage_id.id,
"record_ref": record_ref,
}
)
# File operations + dms_file create
file_name = self._dms_file_name(directory_id, vals["name"])
self.env["dms.file"].create(
{
"name": file_name,
"directory_id": directory_id.id,
"attachment_id": attachment_id.id,
"record_ref": record_ref,
}
)
return attachment_id

Copy link
Member

@victoralmau victoralmau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally need to create test about it with some checks:

  • Migration process

  • Create dms_file and check if attachment create it and related it

  • Create attachment related to model previously configured in storage and check if dms_file work fine

In V12 #24 exists test about it.

@Rad0van
Copy link
Sponsor

Rad0van commented Oct 18, 2020

I was just going to ask in contributors mailing list about existence of module that would allow to categorize and/or add tags to attachments. This PR serves nicely for that purpose I guess. What I miss would be integration back to attachment list. What I mean is that I would like to have let's say product.template's attachments displayed in a tree view with category and tags visible/editable. I'd like to use the category and/or tags later to selectively display some of the attachments to e-commerce for example (which would be up to its own module). Is this feasible?

@victoralmau
Copy link
Member

I was just going to ask in contributors mailing list about existence of module that would allow to categorize and/or add tags to attachments. This PR serves nicely for that purpose I guess. What I miss would be integration back to attachment list. What I mean is that I would like to have let's say product.template's attachments displayed in a tree view with category and tags visible/editable. I'd like to use the category and/or tags later to selectively display some of the attachments to e-commerce for example (which would be up to its own module). Is this feasible?

If i understand it correctly this PR don't allow it.
Only integrate with attachment files but don't appear in e-commerce (for example).

Maybe, if you prefer create a new issue about it and explain a lot and everybody comment about it and the best way to do.

@victoralmau
Copy link
Member

About this functionality apply now in V12 in this PR #24

IMO the best way to add this functionality to V13 is close this PR, create new PR and apply cherry-pick about #24

What do you think about it?

@etobella
Copy link
Member

etobella commented Nov 1, 2020

I guess @victoralmau is right.

What do you think @luismalta ?

@pedrobaeza
Copy link
Member

@luismalta @mileo do you agree then to supersed this with #37 ?

@mileo
Copy link
Member

mileo commented Nov 9, 2020

@luismalta @mileo do you agree then to supersed this with #37 ?

Yes, Would it be possible to put @luismalta as a contributor on #37?

@pedrobaeza
Copy link
Member

It's already included with all its content on the first commit of that PR 😃

Closing then this as continuing in #37

Thanks all

@pedrobaeza pedrobaeza closed this Nov 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants