@ -0,0 +1,44 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-OPL--1-red.svg |
||||
|
:target: https://www.odoo.com/documentation/16.0/legal/licenses.html#odoo-apps |
||||
|
:alt: License: OPL-1 |
||||
|
|
||||
|
Document Management |
||||
|
=================== |
||||
|
The Document Management module provide a quick access to create, share and delete. |
||||
|
The module requires beautiful Soup python library |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
Odoo Proprietary License v1.0 (OPL-1) |
||||
|
(https://www.odoo.com/documentation/user/16.0/legal/licenses/licenses.html) |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developers: V16 Mohamed Savad, Gokul PI, Megha AP, Javid, Nisiya |
||||
|
* Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import controllers |
||||
|
from . import models |
||||
|
from . import wizard |
@ -0,0 +1,82 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
{ |
||||
|
'name': 'Document Management', |
||||
|
'version': '15.0.1.0.0', |
||||
|
'category': 'Document Management', |
||||
|
'summary': 'The Document Management module to access document tools', |
||||
|
'description': 'The Document Management module provides a quick access to ' |
||||
|
'create, share and delete.', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://cybrosys.com', |
||||
|
'depends': ['base', 'mail', 'website'], |
||||
|
'data': [ |
||||
|
'security/enhanced_document_management_groups.xml', |
||||
|
'security/enhanced_document_management_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'data/document_data.xml', |
||||
|
'data/ir_cron_data.xml', |
||||
|
'views/document_workspace_views.xml', |
||||
|
'views/document_file_views.xml', |
||||
|
'views/res_config_settings_views.xml', |
||||
|
'views/document_portal_templates.xml', |
||||
|
'views/outgoing_request_document_views.xml', |
||||
|
'views/incoming_request_document_views.xml', |
||||
|
'views/portal_document_breadcrumb_templates.xml', |
||||
|
'views/document_trash_views.xml', |
||||
|
'views/document_request_templates.xml', |
||||
|
'wizard/document_share_templates.xml', |
||||
|
'wizard/document_share_views.xml', |
||||
|
'wizard/document_url_views.xml', |
||||
|
'wizard/document_tool_views.xml', |
||||
|
'views/enhanced_document_management_menus.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_backend': [ |
||||
|
'enhanced_document_management/static/src/css/kanban.css', |
||||
|
'enhanced_document_management/static/src/xml/KanbanController.xml', |
||||
|
'enhanced_document_management/static/src/js/search_panel_extention_model.js', |
||||
|
'enhanced_document_management/static/src/js/kanbancontroller.js', |
||||
|
'enhanced_document_management/static/src/js/search_document.js', |
||||
|
'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.6/dist/jquery.fancybox.min.css', |
||||
|
'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.6/dist/jquery.fancybox.min.js' |
||||
|
], |
||||
|
'web.assets_frontend': [ |
||||
|
'enhanced_document_management/static/src/xml/KanbanController.xml', |
||||
|
'enhanced_document_management/static/src/js/portal.js', |
||||
|
'enhanced_document_management/static/src/js/portal_document_request.js', |
||||
|
], |
||||
|
'web.assets_qweb': [ |
||||
|
'enhanced_document_management/static/src/xml/KanbanController.xml', |
||||
|
], |
||||
|
}, |
||||
|
'external_dependencies': { |
||||
|
'python': ['bs4'] |
||||
|
}, |
||||
|
'images': ['/static/description/banner.jpg'], |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': True, |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import document_file |
||||
|
from . import document_portal |
||||
|
from . import document_share |
||||
|
from . import website_document |
@ -0,0 +1,102 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import http |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class DocumentPortalView(http.Controller): |
||||
|
"""Controller class for accessing documents from portal.""" |
||||
|
|
||||
|
@http.route('/my/documents', type="http", auth="user", website=True) |
||||
|
def document_in_portal(self): |
||||
|
""" |
||||
|
Http controller to all user document from portal |
||||
|
:return Http response with all Documents data |
||||
|
""" |
||||
|
document_ids = request.env['document.file'].search([ |
||||
|
('user_id.id', '=', request.uid) |
||||
|
]) |
||||
|
extensions = set(item.extension for item in document_ids) |
||||
|
groups = [[rec for rec in document_ids if rec.extension == item |
||||
|
] for item in extensions] |
||||
|
return request.render( |
||||
|
"enhanced_document_management.portal_my_documents", { |
||||
|
'extensions': extensions, |
||||
|
'base_url': request.httprequest.host_url[:-1], |
||||
|
'document_ids': groups, |
||||
|
'page_name': 'document', |
||||
|
}) |
||||
|
|
||||
|
@http.route('/my/document_request', type="http", auth="user", |
||||
|
website=True) |
||||
|
def document_request_in_portal(self): |
||||
|
""" |
||||
|
Http controller to access user requests for document from portal |
||||
|
:return Http response with all Documents data |
||||
|
""" |
||||
|
request_ids = request.env['request.document'].search([ |
||||
|
('user_id.id', '=', request.uid), |
||||
|
('state', '=', 'requested') |
||||
|
]) |
||||
|
context = [{ |
||||
|
'id': item.id, |
||||
|
'needed_doc': item.needed_doc, |
||||
|
'workspace_id': [item.workspace_id.id, item.workspace_id.name], |
||||
|
'requested_by': [item.requested_by.id, item.requested_by.name], |
||||
|
'user_id': [item.user_id.id, item.user_id.name], |
||||
|
'date': item.create_date.date() |
||||
|
} for item in request_ids] |
||||
|
return request.render( |
||||
|
"enhanced_document_management.portal_my_document_request", |
||||
|
{ |
||||
|
'requests': context, |
||||
|
'page_name': 'document_requests', |
||||
|
}) |
||||
|
|
||||
|
@http.route('/my/documents/<model("document.file"):doc>', type="http", |
||||
|
auth="user", website=True) |
||||
|
def document_view(self, doc): |
||||
|
""" |
||||
|
Http controller to access document from portal |
||||
|
:param doc: primary key of a record |
||||
|
:return Http response with the selected Documents data |
||||
|
""" |
||||
|
context = { |
||||
|
'page_name': 'document', |
||||
|
'document': True, |
||||
|
'name': doc.name, |
||||
|
'id': doc.id, |
||||
|
'owner': doc.user_id, |
||||
|
'attachment_id': doc.attachment_id.id, |
||||
|
'brochure_url': doc.brochure_url, |
||||
|
'workspace_id': doc.workspace_id.name, |
||||
|
'date': doc.date, |
||||
|
'url': f"""{request.httprequest.host_url[:-1]}/web/content/ |
||||
|
{doc.attachment_id.id}/{doc.name} |
||||
|
""".replace('\n', '').replace(" ", ""), |
||||
|
'partner_id': doc.partner_id.name, |
||||
|
'extension': doc.extension, |
||||
|
'preview': doc.preview, |
||||
|
'content_url': doc.content_url, |
||||
|
} |
||||
|
return request.render("enhanced_document_management.portal_my_document_view", |
||||
|
context) |
@ -0,0 +1,46 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo.addons.portal.controllers.portal import CustomerPortal |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class WebsiteCustomerPortal(CustomerPortal): |
||||
|
""" Functon : Prepare portal values, datas are searched from document.file |
||||
|
:return document count, request count |
||||
|
""" |
||||
|
|
||||
|
def _prepare_home_portal_values(self, counters): |
||||
|
"""Functon : Prepare portal values, |
||||
|
datas are searched from document.file""" |
||||
|
values = super( |
||||
|
WebsiteCustomerPortal, self)._prepare_home_portal_values(counters) |
||||
|
if 'document_count' in counters: |
||||
|
values['document_count'] = request.env[ |
||||
|
'document.file'].sudo().search_count([ |
||||
|
('user_id.id', '=', request.uid) |
||||
|
]) |
||||
|
values['request_count'] = request.env[ |
||||
|
'request.document'].sudo().search_count([ |
||||
|
('user_id.id', '=', request.uid), |
||||
|
('state', '=', 'requested') |
||||
|
]) |
||||
|
return values |
@ -0,0 +1,58 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import http |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class DocumentFile(http.Controller): |
||||
|
"""Http Controller to create sharable view for selected documents """ |
||||
|
|
||||
|
@http.route('/web/content/share/', type='http', auth='public', |
||||
|
website='True') |
||||
|
def document_share(self, **kwargs): |
||||
|
"""Function that returns a list of documents |
||||
|
that grouped by unique link""" |
||||
|
folder_ids = request.env['document.share'].sudo().search([ |
||||
|
('unique', '=', kwargs.get('unique')) |
||||
|
], limit=1) |
||||
|
context = ({ |
||||
|
'doc_id': document.id, |
||||
|
'doc_name': document.name, |
||||
|
'doc_extension': document.extension, |
||||
|
'doc_owner': document.user_id, |
||||
|
'doc_date': document.date, |
||||
|
'doc_url': document.content_url, |
||||
|
} for document in folder_ids.document_ids) |
||||
|
return http.request.render( |
||||
|
'enhanced_document_management.document_share_preview', |
||||
|
{'context': context} |
||||
|
) |
||||
|
|
||||
|
@http.route("/web/attachments/download", type="http") |
||||
|
def download_zip(self): |
||||
|
""" Http Controller to download selected file as a ZIP """ |
||||
|
return http.send_file( |
||||
|
filepath_or_fp='./attachments.zip', |
||||
|
mimetype="application/zip", |
||||
|
as_attachment=True, |
||||
|
filename="attachments.zip", |
||||
|
) |
@ -0,0 +1,98 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
import base64 |
||||
|
from odoo import fields |
||||
|
from odoo import http |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class WebsiteDocumentsUpload(http.Controller): |
||||
|
"""Controller for accept document upload form submission""" |
||||
|
|
||||
|
@http.route('/website/documents', type="http", auth="user", |
||||
|
website=True, csrf=False) |
||||
|
def website_docs(self, **post): |
||||
|
""" |
||||
|
Function : website form submit controller, |
||||
|
it creates a record in document.file |
||||
|
:param post: form-data |
||||
|
:return: redirect |
||||
|
""" |
||||
|
val_list = { |
||||
|
'name': post['file'].filename, |
||||
|
'attachment': base64.b64encode(post['file'].read()), |
||||
|
'workspace_id': int(post['workspace']), |
||||
|
'date': fields.Date.today(), |
||||
|
'user_id': request.uid, |
||||
|
'description': post['reason'], |
||||
|
'security': 'private', |
||||
|
'extension': post['file'].filename.split(".")[ |
||||
|
len(post['file'].filename.split(".")) - 1] |
||||
|
} |
||||
|
if post['security'] == 'Private': |
||||
|
val_list['security'] = 'private' |
||||
|
else: |
||||
|
val_list['security'] = 'managers_and_owner' |
||||
|
file_id = request.env['document.file'].create(val_list) |
||||
|
file_id.action_upload_document() |
||||
|
return request.redirect("/my/documents") |
||||
|
|
||||
|
@http.route('/website/documents_request', type="http", auth="user", |
||||
|
website=True, csrf=False) |
||||
|
def website_docs_request(self, **post): |
||||
|
""" |
||||
|
Function : website form submit controller for requested documents, |
||||
|
it creates a record in document.file |
||||
|
:param post: form-data |
||||
|
:return: redirect to /my/document_request |
||||
|
""" |
||||
|
request_id = request.env['request.document'].browse( |
||||
|
int(post['rec_id'])) |
||||
|
file_id = request.env['document.file'].sudo().create({ |
||||
|
'name': post['file'].filename, |
||||
|
'attachment': base64.b64encode(post['file'].read()), |
||||
|
'workspace_id': int(post['workspace']), |
||||
|
'date': fields.Date.today(), |
||||
|
'user_id': request.uid, |
||||
|
'description': post['reason'], |
||||
|
'security': 'specific_users', |
||||
|
'user_ids': [post['requested_by']], |
||||
|
'extension': post['file'].filename.split(".")[ |
||||
|
len(post['file'].filename.split(".")) - 1] |
||||
|
}) |
||||
|
file_id.action_upload_document() |
||||
|
request_id.state = 'accepted' |
||||
|
return request.redirect("/my/document_request") |
||||
|
|
||||
|
@http.route('/website/documents_request_reject', type="http", |
||||
|
auth="user", website=True, csrf=False) |
||||
|
def document_request_reject(self, **post): |
||||
|
""" |
||||
|
Function accept document reject and update document.request |
||||
|
:param post: form-data |
||||
|
:return: redirect to /my/document_request |
||||
|
""" |
||||
|
request_id = request.env['request.document'].browse( |
||||
|
int(post['req_id'])) |
||||
|
request_id.state = 'rejected' |
||||
|
request_id.reject_reason = post['reason'] |
||||
|
return request.redirect("/my/document_request") |
@ -0,0 +1,9 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Create a default workspace while module installation --> |
||||
|
<record id="document_workspace_default" model="document.workspace"> |
||||
|
<field name="name">My Workspace</field> |
||||
|
<field name="display_name">My Workspace</field> |
||||
|
<field name="description">The workspace here is the default</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo noupdate="1"> |
||||
|
<!-- Create a schedule action for file delete while module installation --> |
||||
|
<record id="ir_cron_schedule_delete_file" model="ir.cron"> |
||||
|
<field name="name">Document Delete</field> |
||||
|
<field name="model_id" ref="enhanced_document_management.model_document_trash"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code">model.delete_doc()</field> |
||||
|
<field name="user_id" ref="base.user_root"/> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="interval_type">days</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
</record> |
||||
|
<!-- Create a schedule action for removed file that inside trash while module installation --> |
||||
|
<record id="ir_cron_auto_delete_file" model="ir.cron"> |
||||
|
<field name="name">Auto Document Delete</field> |
||||
|
<field name="model_id" ref="enhanced_document_management.model_document_file"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code">model.auto_delete_doc()</field> |
||||
|
<field name="user_id" ref="base.user_root"/> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="interval_type">days</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,7 @@ |
|||||
|
## Module <enhanced_document_management> |
||||
|
|
||||
|
#### 13.05.2024 |
||||
|
#### Version 15.0.1.0.0 |
||||
|
#### ADD |
||||
|
|
||||
|
- Initial commit for Document Management |
@ -0,0 +1,26 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import document_file |
||||
|
from . import document_trash |
||||
|
from . import document_workspace |
||||
|
from . import request_document |
||||
|
from . import res_config_settings |
@ -0,0 +1,259 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from zipfile import ZipFile |
||||
|
from odoo import api, fields, models |
||||
|
from odoo.http import request |
||||
|
|
||||
|
|
||||
|
class Document(models.Model): |
||||
|
""" Model used to store documents, perform document related functions """ |
||||
|
_name = 'document.file' |
||||
|
_inherit = ['mail.thread', 'mail.activity.mixin'] |
||||
|
_description = 'Documents Community' |
||||
|
|
||||
|
name = fields.Char(string="Name", help="Document name") |
||||
|
attachment = fields.Binary(string='File', help="Document data") |
||||
|
date = fields.Datetime(string='Date', help="Document create date") |
||||
|
workspace_id = fields.Many2one( |
||||
|
'document.workspace', string='Workspace', |
||||
|
required=True, help="workspace name") |
||||
|
user_id = fields.Many2one( |
||||
|
'res.users', string='Owner', |
||||
|
default=lambda self: self.env.user, |
||||
|
help="""Owner name, if the document belongs to a specific partner""") |
||||
|
brochure_url = fields.Char(string="URL", help="Document sharable URL") |
||||
|
extension = fields.Char( |
||||
|
string='Extension', |
||||
|
help="""Document extension, helps to determine the file type""") |
||||
|
priority = fields.Selection( |
||||
|
[('0', 'None'), ('1', 'Favorite')], |
||||
|
string="Priority", help="Favorite button") |
||||
|
activity_ids = fields.One2many( |
||||
|
'mail.activity', string='Activities', |
||||
|
help="Created activity for this attachment") |
||||
|
attachment_id = fields.Many2one( |
||||
|
'ir.attachment', string="Data", |
||||
|
help="Used to access datas without search function") |
||||
|
content_url = fields.Char( |
||||
|
string='Content Url', help="It store the URL for url type documents") |
||||
|
content_type = fields.Selection( |
||||
|
[('file', 'File'), ('url', 'Url')], string="Content Type", |
||||
|
help="Document content type") |
||||
|
preview = fields.Char( |
||||
|
string='Preview', help="Used to show a preview for URL file type") |
||||
|
active = fields.Boolean( |
||||
|
string='Active', default=True, help="It specify archived file") |
||||
|
deleted_date = fields.Date( |
||||
|
string="Deleted Date", help="File deleted date") |
||||
|
mimetype = fields.Char( |
||||
|
string='Mime Type', help="Document mimetype") |
||||
|
description = fields.Text(string='Description', help="Short description") |
||||
|
security = fields.Selection( |
||||
|
selection=[ |
||||
|
('private', 'Private'), |
||||
|
('managers_and_owner', 'Managers & Owner'), |
||||
|
('specific_users', 'Specific Users') |
||||
|
], default='managers_and_owner', string="Security", |
||||
|
help="""Privet : only the uploaded user can view |
||||
|
Managers & Owner : Document shared with Managers """) |
||||
|
user_ids = fields.Many2many( |
||||
|
'res.users', help="Can access the documents", string="User Access") |
||||
|
partner_id = fields.Many2one( |
||||
|
'res.partner', help="Document related partner name", |
||||
|
string="Related Partner") |
||||
|
auto_delete = fields.Boolean( |
||||
|
string='Auto Delete', default=False, |
||||
|
help="Document delete status") |
||||
|
days = fields.Integer(string='Days', help="auto delete in days") |
||||
|
trash = fields.Boolean(string='Trash', help="To specify deleted items") |
||||
|
delete_date = fields.Date( |
||||
|
string='Date Delete', readonly=True, |
||||
|
help="Used to calculate file remove date from trash") |
||||
|
file_url = fields.Char( |
||||
|
string='File URL', |
||||
|
help="""it store url while adding an url document""") |
||||
|
size = fields.Char( |
||||
|
string='Size', compute='_compute_size', |
||||
|
help="it store size of the document") |
||||
|
company_id = fields.Many2one( |
||||
|
related='workspace_id.company_id', string='Company', |
||||
|
help="Company Name") |
||||
|
|
||||
|
@api.depends('attachment_id') |
||||
|
def _compute_size(self): |
||||
|
"""Function is used to fetch the file size of an attachment""" |
||||
|
for rec in self: |
||||
|
rec.size = str(rec.attachment_id.file_size/1000) + ' Kb' |
||||
|
|
||||
|
@api.onchange('days') |
||||
|
def _onchange_days(self): |
||||
|
"""Function is used to add delete date for a record , |
||||
|
it automatically deleted at the specified date""" |
||||
|
self.delete_date = fields.Date.add(fields.Date.today(), days=self.days) |
||||
|
|
||||
|
def auto_delete_doc(self): |
||||
|
"""Function to delete document automatically using schedule action""" |
||||
|
self.search([ |
||||
|
('auto_delete', '=', True), |
||||
|
('delete_date', '<=', fields.Date.today())]).unlink() |
||||
|
|
||||
|
def action_upload_document(self): |
||||
|
"""Function it works while uploading a file, and it adds some basic |
||||
|
information about the file""" |
||||
|
# important to maintain extension and name as different |
||||
|
attachment_id = self.env['ir.attachment'].sudo().create({ |
||||
|
'name': self.name, |
||||
|
'datas': self.attachment, |
||||
|
'res_model': 'document.file', |
||||
|
'res_id': self.id, |
||||
|
'public': True, |
||||
|
}) |
||||
|
self.sudo().write({ |
||||
|
'name': self.name, |
||||
|
'date': fields.Date.today(), |
||||
|
'user_id': self.env.uid, |
||||
|
'extension': self.name.split(".")[len(self.name.split(".")) - 1], |
||||
|
'content_url': |
||||
|
f"/web/content/{attachment_id.id}/{self.name}", |
||||
|
'mimetype': attachment_id.mimetype, |
||||
|
'attachment_id': attachment_id.id, |
||||
|
'brochure_url': attachment_id.local_url |
||||
|
}) |
||||
|
return { |
||||
|
'type': 'ir.actions.client', |
||||
|
'tag': 'reload' |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def archive_function(self, document_selected): |
||||
|
""" Function to download document as a ZIP """ |
||||
|
zip_obj = ZipFile('attachments.zip', 'w') |
||||
|
for doc in self.browse(document_selected): |
||||
|
zip_obj.write(doc.attachment_id._full_path( |
||||
|
doc.attachment_id.store_fname), |
||||
|
doc.attachment_id.name) |
||||
|
zip_obj.close() |
||||
|
url = f"{request.httprequest.host_url[:-1]}/web/attachments/download" |
||||
|
return { |
||||
|
'type': 'ir.actions.act_url', |
||||
|
'url': url, |
||||
|
'target': 'self', |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def document_file_delete(self, doc_ids): |
||||
|
"""Function works while deleting a document, |
||||
|
it creates a record in document.trash""" |
||||
|
for docs in self.browse(doc_ids): |
||||
|
self.env['document.trash'].create({ |
||||
|
'name': docs.name, |
||||
|
'attachment': docs.attachment, |
||||
|
'document_create_date': docs.date, |
||||
|
'workspace_id': docs.workspace_id.id, |
||||
|
'user_id': docs.user_id.id, |
||||
|
'brochure_url': docs.brochure_url, |
||||
|
'extension': docs.extension, |
||||
|
'priority': docs.priority, |
||||
|
'attachment_id': docs.attachment_id.id, |
||||
|
'content_url': docs.content_url, |
||||
|
'content_type': docs.content_type, |
||||
|
'preview': docs.preview, |
||||
|
'active': docs.active, |
||||
|
'deleted_date': fields.Date.today(), |
||||
|
'mimetype': docs.mimetype, |
||||
|
'description': docs.description, |
||||
|
'security': docs.security, |
||||
|
'user_ids': docs.user_ids.ids, |
||||
|
'partner_id': docs.partner_id.id, |
||||
|
'days': docs.days, |
||||
|
'file_url': docs.file_url, |
||||
|
}) |
||||
|
docs.unlink() |
||||
|
|
||||
|
@api.model |
||||
|
def document_file_archive(self, documents_selected): |
||||
|
"""Function to archive document, it deleted automatically |
||||
|
based on delete date""" |
||||
|
for docs in self.browse(documents_selected): |
||||
|
if docs.active: |
||||
|
docs.active = False |
||||
|
elif docs.delete_date: |
||||
|
docs.delete_date = False |
||||
|
docs.active = True |
||||
|
else: |
||||
|
docs.active = True |
||||
|
|
||||
|
@api.model |
||||
|
def on_mail_document(self, doc_ids): |
||||
|
"""Function used to send document as an email attachment""" |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': 'mail', |
||||
|
'res_model': 'mail.compose.message', |
||||
|
'view_mode': 'form', |
||||
|
'target': 'new', |
||||
|
'views': [[False, 'form']], |
||||
|
'context': { |
||||
|
'default_attachment_ids': self.browse( |
||||
|
doc_ids).mapped('attachment_id').ids, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def action_btn_create_task(self, doc): |
||||
|
"""Function used to create a task based on document """ |
||||
|
module_id = self.env['ir.module.module'].search( |
||||
|
[('name', '=', 'project')]) |
||||
|
if module_id.state == 'installed': |
||||
|
for rec in self.browse(doc): |
||||
|
task_id = self.env['project.task'].create({ |
||||
|
'name': rec['name'] |
||||
|
}) |
||||
|
rec.attachment_id.res_model = 'project.task' |
||||
|
rec.attachment_id.res_id = task_id |
||||
|
return True |
||||
|
return False |
||||
|
|
||||
|
@api.model |
||||
|
def action_btn_create_lead(self, doc): |
||||
|
"""Function to create a CRM lead based on a document """ |
||||
|
module_id = self.env['ir.module.module'].search([('name', '=', 'crm')]) |
||||
|
if module_id.state == 'installed': |
||||
|
for rec in self.browse(doc): |
||||
|
lead_id = self.env['crm.lead'].create({ |
||||
|
'name': rec['name'] |
||||
|
}) |
||||
|
rec.attachment_id.res_model = 'crm.lead' |
||||
|
rec.attachment_id.res_id = lead_id |
||||
|
return True |
||||
|
return False |
||||
|
|
||||
|
@api.model |
||||
|
def delete_doc(self): |
||||
|
"""Function to delete document from trash """ |
||||
|
limit = self.env['ir.config_parameter'].sudo().get_param( |
||||
|
'document_management.trash') |
||||
|
for rec in self.env['document.trash'].search( |
||||
|
['deleted_date', '!=', False]): |
||||
|
delta = fields.Date.today() - rec.deleted_date |
||||
|
if delta.days == limit: |
||||
|
rec.unlink() |
@ -0,0 +1,119 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class DocumentTrash(models.Model): |
||||
|
"""Module to store deleted documents for a specific time, |
||||
|
then it automatically""" |
||||
|
|
||||
|
_name = "document.trash" |
||||
|
_description = "Document Trash" |
||||
|
|
||||
|
name = fields.Char(string="Name", help="Document name") |
||||
|
attachment = fields.Binary(string="File", readonly=True, help="Document data") |
||||
|
document_create_date = fields.Datetime(string="Date", help="Document create date") |
||||
|
workspace_id = fields.Many2one( |
||||
|
"document.workspace", string="Workspace", required=True, help="workspace name" |
||||
|
) |
||||
|
user_id = fields.Many2one( |
||||
|
"res.users", |
||||
|
string="Owner", |
||||
|
default=lambda self: self.env.user, |
||||
|
help="""owner name, if the document belongs to a specific user""", |
||||
|
) |
||||
|
brochure_url = fields.Char(string="URL", store=True, help="Document sharable URL") |
||||
|
extension = fields.Char(string="Extension", help="helps to determine the file type") |
||||
|
priority = fields.Selection( |
||||
|
selection=[("0", "None"), ("1", "Favorite")], |
||||
|
string="Priority", |
||||
|
help="Favorite button", |
||||
|
) |
||||
|
attachment_id = fields.Many2one( |
||||
|
"ir.attachment", |
||||
|
string="Attachment", |
||||
|
help="Used to access datas without search function", |
||||
|
) |
||||
|
content_url = fields.Char( |
||||
|
string="Content Url", help="It store the URL for url type documents" |
||||
|
) |
||||
|
content_type = fields.Selection( |
||||
|
[("file", "File"), ("url", "Url")], |
||||
|
help="Document content type", |
||||
|
string="Content type", |
||||
|
) |
||||
|
preview = fields.Char( |
||||
|
string="Preview", help="Used to show a preview for URL file type" |
||||
|
) |
||||
|
active = fields.Boolean( |
||||
|
string="Active", default=True, help="It specify archived file" |
||||
|
) |
||||
|
days = fields.Integer(string="Days", help="auto delete in days") |
||||
|
deleted_date = fields.Date(string="Deleted Date", help="File deleted date") |
||||
|
mimetype = fields.Char(string="Mime Type", help="Document mimetype") |
||||
|
description = fields.Text(string="Description", help="Short description") |
||||
|
security = fields.Selection( |
||||
|
string="Security", |
||||
|
selection=[ |
||||
|
("private", "Private"), |
||||
|
("managers_and_owner", "Managers & Owner"), |
||||
|
("specific_users", "Specific Users"), |
||||
|
], |
||||
|
default="managers_and_owner", |
||||
|
help="""Privet : only the uploaded user can view |
||||
|
Managers & Owner : Document shared with Managers """, |
||||
|
) |
||||
|
user_ids = fields.Many2many( |
||||
|
"res.users", help="Can access the documents", string="User Access" |
||||
|
) |
||||
|
partner_id = fields.Many2one( |
||||
|
"res.partner", help="Document related partner name", string="Related Partner" |
||||
|
) |
||||
|
auto_delete = fields.Boolean( |
||||
|
string="Auto Delete", default=False, help="Document delete status" |
||||
|
) |
||||
|
delete_date = fields.Date( |
||||
|
string="Date Delete", |
||||
|
readonly=True, |
||||
|
help="Used to calculate file remove date from trash", |
||||
|
) |
||||
|
file_url = fields.Char( |
||||
|
string="File URL", help="""it store url while adding an url document""" |
||||
|
) |
||||
|
size = fields.Char(string="Size", help="it store size of the document") |
||||
|
company_id = fields.Many2one( |
||||
|
related='workspace_id.company_id', string='Company', |
||||
|
help="Company Name") |
||||
|
|
||||
|
def delete_doc(self): |
||||
|
"""Function to delete all the documents after the trash date""" |
||||
|
trash_limit = ( |
||||
|
self.env["ir.config_parameter"] |
||||
|
.sudo() |
||||
|
.get_param("document_management.trash") |
||||
|
) |
||||
|
if trash_limit: |
||||
|
for rec in self.search([]): |
||||
|
if fields.Date.today() == fields.Date.add( |
||||
|
rec.deleted_date, days=int(trash_limit) |
||||
|
): |
||||
|
rec.unlink() |
@ -0,0 +1,91 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class DocumentWorkspace(models.Model): |
||||
|
""" Module to store document workspace """ |
||||
|
_name = 'document.workspace' |
||||
|
_description = 'Document Workspace' |
||||
|
|
||||
|
name = fields.Char( |
||||
|
string='Name', required=True, help="Name of the WorkSpace.") |
||||
|
display_name = fields.Char( |
||||
|
string='Workspace', help="Name of the workSpace.", |
||||
|
compute='_compute_display_name') |
||||
|
parent_id = fields.Many2one( |
||||
|
'document.workspace', string='Parent Workspace', |
||||
|
help="Current workSpace will be under this workSpace") |
||||
|
company_id = fields.Many2one( |
||||
|
'res.company', string='Company', |
||||
|
help="WorkSpace belongs to this company", |
||||
|
default=lambda self: self.env.company) |
||||
|
description = fields.Text( |
||||
|
string='Description', help="Description about the workSpace") |
||||
|
document_count = fields.Integer( |
||||
|
compute='_compute_document_count', string='Document count', |
||||
|
help="Number of documents uploaded under this workSpace") |
||||
|
|
||||
|
def action_view_document(self): |
||||
|
"""Function to open document kanban view """ |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'document.file', |
||||
|
'name': self.name, |
||||
|
'view_mode': 'kanban,form', |
||||
|
'view_type': 'form', |
||||
|
'target': 'current', |
||||
|
'domain': [('workspace_id', '=', self.id)] |
||||
|
} |
||||
|
|
||||
|
@api.depends('name') |
||||
|
def _compute_display_name(self): |
||||
|
"""Function compute display name to view in searchpanel """ |
||||
|
for rec in self: |
||||
|
rec.display_name = rec.name |
||||
|
|
||||
|
def _compute_document_count(self): |
||||
|
"""Compute function to calculate document count under a workspace """ |
||||
|
for record in self: |
||||
|
record.document_count = self.env['document.file'].search_count( |
||||
|
[('workspace_id', '=', self.id)]) |
||||
|
|
||||
|
@api.constrains('parent_id') |
||||
|
def _onchange_parent_id(self): |
||||
|
"""Onchange function to restrict setting |
||||
|
current workspace as parent workspace""" |
||||
|
if self.parent_id.id == self.id: |
||||
|
raise ValidationError( |
||||
|
_("Cannot set current workspace as parent workspace !")) |
||||
|
return { |
||||
|
'domain': { |
||||
|
'parent_id': [('id', '!=', self.id)] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def work_spaces(self): |
||||
|
"""Function to send workspace data to friend-end """ |
||||
|
workspace_ids = self.env['document.workspace'].search([]) |
||||
|
workspace_list = [{'id': i.id, 'name': i.name} for i in workspace_ids] |
||||
|
return workspace_list |
@ -0,0 +1,74 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, fields, models, _ |
||||
|
|
||||
|
|
||||
|
class RequestDocumentUser(models.Model): |
||||
|
"""Module to store document requests """ |
||||
|
_name = 'request.document' |
||||
|
_description = 'Request document from user' |
||||
|
_rec_name = 'needed_doc' |
||||
|
|
||||
|
user_id = fields.Many2one('res.users', string='User') |
||||
|
requested_by = fields.Many2one( |
||||
|
'res.users', help="User who created request", |
||||
|
default=lambda self: self.env.user) |
||||
|
needed_doc = fields.Text(string='Document Needed', required=True, |
||||
|
help="Document needed by requestor") |
||||
|
workspace_id = fields.Many2one( |
||||
|
'document.workspace', string='Work space', required=True) |
||||
|
reject_reason = fields.Text(string='Reason', help="Reason for rejection") |
||||
|
state = fields.Selection(selection=[ |
||||
|
('requested', 'Requested'), |
||||
|
('accepted', 'Accepted'), |
||||
|
('rejected', 'Rejected')], default='requested') |
||||
|
company_id = fields.Many2one( |
||||
|
related='workspace_id.company_id', string='Company', |
||||
|
help="Company Name") |
||||
|
|
||||
|
def action_send_document_request(self): |
||||
|
"""Function to send document request through email """ |
||||
|
user_id = self.env['res.users'].browse(self.env.uid) |
||||
|
mail_content = f'Hello <br/> {user_id.name} Requested Document <br/>' \ |
||||
|
f'{self.needed_doc}' |
||||
|
|
||||
|
main_content = { |
||||
|
'subject': _('Document Request'), |
||||
|
'body_html': mail_content, |
||||
|
'email_to': self.user_id.partner_id.email, |
||||
|
} |
||||
|
self.env['mail.mail'].sudo().create(main_content).send() |
||||
|
|
||||
|
@api.model |
||||
|
def get_request(self): |
||||
|
"""Function to fetch all request for login user """ |
||||
|
request_ids = self.env['request.document'].search( |
||||
|
[('user_id', '=', self.env.uid)]) |
||||
|
context = [{ |
||||
|
'request_id': rec.id, |
||||
|
'user_id': rec.user_id.name, |
||||
|
'manager_id': rec.manager_id.name, |
||||
|
'needed_doc': rec.needed_doc, |
||||
|
'workspace': rec.workspace.name, |
||||
|
'workspace_id': rec.workspace.id, |
||||
|
} for rec in request_ids] |
||||
|
return context |
@ -0,0 +1,32 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Paid App Development Team (odoo@cybrosys.com) |
||||
|
# |
||||
|
# This program is under the terms of the Odoo Proprietary LicenseLicense v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
""" Inherited res.config.settings to add trash limit field""" |
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
trash = fields.Integer( |
||||
|
'Trash Limit', default=30, |
||||
|
help="set the time limit for the deleted files", |
||||
|
config_parameter='document_management.trash') |
@ -0,0 +1,24 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Document Management group category --> |
||||
|
<record id="module_document_management" model="ir.module.category"> |
||||
|
<field name="name">Document Management</field> |
||||
|
<field name="description">Access for Document Management</field> |
||||
|
<field name="sequence">50</field> |
||||
|
</record> |
||||
|
<!-- Document management group User --> |
||||
|
<record id="document_management_group_user" model="res.groups"> |
||||
|
<field name="name">User</field> |
||||
|
<field name="category_id" ref="module_document_management"/> |
||||
|
</record> |
||||
|
<!-- Document management group Manager --> |
||||
|
<record id="document_management_group_manager" model="res.groups"> |
||||
|
<field name="name">Manager</field> |
||||
|
<field name="category_id" ref="module_document_management"/> |
||||
|
<field name="implied_ids" eval="[(4, ref('document_management_group_user'))]"/> |
||||
|
</record> |
||||
|
<!-- Record to set default user group --> |
||||
|
<record id="base.default_user" model="res.users"> |
||||
|
<field name="groups_id" eval="[(4,ref('enhanced_document_management.document_management_group_user'))]"/> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,113 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Record rule for Document Manager he can create/update his record--> |
||||
|
<record id="document_management_rule_manager" model="ir.rule"> |
||||
|
<field name="name">Document Manager</field> |
||||
|
<field name="model_id" ref="model_document_file"/> |
||||
|
<field name="domain_force">['|', '|', ('security', '=', 'specific_users'), |
||||
|
('security', '=', 'managers_and_owner'), '&', |
||||
|
('security', '=', 'private'), |
||||
|
('user_id', '=', user.id)]</field> |
||||
|
<field name="groups" eval="[(4, ref('document_management_group_manager'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
<!-- Record rule for Document Manager he can create/update record with security --> |
||||
|
<record id="document_management_rule_user" model="ir.rule"> |
||||
|
<field name="name">View Own Document</field> |
||||
|
<field name="model_id" ref="model_document_file"/> |
||||
|
<field name="domain_force">['|', '|', '|', '|', ('user_ids', 'in', user.id), '&', |
||||
|
('security', '=', 'specific_users'), |
||||
|
('user_ids', '=', False), '&', |
||||
|
('security', '=', 'private'), |
||||
|
('user_id', '=', user.id), '&', |
||||
|
('security', '=', 'managers_and_owner'), |
||||
|
('user_id', '=', user.id), '&', |
||||
|
('user_ids', 'not in', user.id), |
||||
|
('user_id', '=', user.id)]</field> |
||||
|
<field name="groups" eval="[(4, ref('document_management_group_user'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="False"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
<!-- Record rule for Document user he can create/update his record --> |
||||
|
<record id="document_management_rule_own" model="ir.rule"> |
||||
|
<field name="name">View Own Request</field> |
||||
|
<field name="model_id" ref="model_request_document"/> |
||||
|
<field name="domain_force"> |
||||
|
['|',('requested_by', '=', user.id), |
||||
|
('user_id', '=', user.id)] |
||||
|
</field> |
||||
|
<field name="groups" eval="[(4, ref('document_management_group_user'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
<!-- Record rule for Document manager he can create/update record that shared with him --> |
||||
|
<record id="document_management_rule_all" model="ir.rule"> |
||||
|
<field name="name">View All Request</field> |
||||
|
<field name="model_id" ref="model_request_document"/> |
||||
|
<field name="domain_force">[(1, '=', 1)]</field> |
||||
|
<field name="groups" eval="[(4, ref('document_management_group_manager'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Record role for multy-company environment --> |
||||
|
<record id="document_file_multy_company" model="ir.rule"> |
||||
|
<field name="name">Documents multy-company</field> |
||||
|
<field name="model_id" ref="model_document_file"/> |
||||
|
<field name="domain_force">['|',('company_id', '=',False),('company_id', 'in', company_ids)]</field> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Record role for multy-company environment --> |
||||
|
<record id="document_workspace_multy_company" model="ir.rule"> |
||||
|
<field name="name">Document workspace multy-company</field> |
||||
|
<field name="model_id" ref="model_document_workspace"/> |
||||
|
<field name="domain_force">['|',('company_id', '=',False),('company_id', 'in', company_ids)]</field> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Record role for multy-company environment --> |
||||
|
<record id="document_trash_multy_company" model="ir.rule"> |
||||
|
<field name="name">Document trash multy-company</field> |
||||
|
<field name="model_id" ref="model_document_trash"/> |
||||
|
<field name="domain_force">['|',('company_id', '=',False),('company_id', 'in', company_ids)]</field> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- Record role for multy-company environment --> |
||||
|
<record id="document_requests_multy_company" model="ir.rule"> |
||||
|
<field name="name">Document requests multy-company</field> |
||||
|
<field name="model_id" ref="model_request_document"/> |
||||
|
<field name="domain_force">['|',('company_id', '=',False),('company_id', 'in', company_ids)]</field> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
</odoo> |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 369 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 16 KiB |
@ -0,0 +1,789 @@ |
|||||
|
<div style="background-color: #714B67; min-height: 600px; width: 100%; padding: 15px; position: relative;"> |
||||
|
<!-- TITLE BAR --> |
||||
|
<div class="d-flex align-items-center justify-content-between" |
||||
|
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;"> |
||||
|
<img src="./assets/icons/img.png" width="42" height="42" |
||||
|
style="width: 42px; height: 42px;"/> |
||||
|
<div> |
||||
|
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;" |
||||
|
class="mr-2"> |
||||
|
<i class="fa fa-check mr-1"></i>Community |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF TITLE BAR --> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12" |
||||
|
style="padding: 4rem 1rem !important; background-color: #714B67 !important; height: 600px !important; border-radius: 20px !important;"> |
||||
|
<!-- APP HERO --> |
||||
|
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;"> |
||||
|
Document Management</h1> |
||||
|
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;"> |
||||
|
The Document Management module provide quick access to |
||||
|
create, share and delete.</p> |
||||
|
<!-- END OF APP HERO --> |
||||
|
<img src="./assets/screenshots/hero.gif" |
||||
|
style="width: 75%; height: auto; position: absolute; margin-left: auto; margin-right: auto; top: 45%; left: 12%; right: auto;"/> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<!-- NAVIGATION SECTION --> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;"> |
||||
|
<div class="d-flex justify-content-center align-items-center mr-2" |
||||
|
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
||||
|
<img src="./assets/misc/compass.png"/> |
||||
|
</div> |
||||
|
<h2 class="mt-2" |
||||
|
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
||||
|
Explore This |
||||
|
Module</h2> |
||||
|
</div> |
||||
|
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;"> |
||||
|
<div class="col-sm-12 col-md-6 my-3"> |
||||
|
<a href="#overview"> |
||||
|
<div class="d-flex justify-content-between align-items-center" |
||||
|
style="background-color: #f5f5f5; padding: 30px; width: 100%;"> |
||||
|
<div> |
||||
|
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span> |
||||
|
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn More About this module</span> |
||||
|
</div> |
||||
|
<img src="./assets/misc/right-arrow.png" width="36" |
||||
|
height="36"/> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-sm-12 col-md-6 my-3"> |
||||
|
<a href="#features"> |
||||
|
<div class="d-flex justify-content-between align-items-center" |
||||
|
style="background-color: #f5f5f5; padding: 30px; width: 100%;"> |
||||
|
<div> |
||||
|
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span> |
||||
|
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View |
||||
|
features of this |
||||
|
module</span> |
||||
|
</div> |
||||
|
<img src="./assets/misc/right-arrow.png" width="36" |
||||
|
height="36"/> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-sm-12 col-md-6 my-3"> |
||||
|
<a href="#screenshots"> |
||||
|
<div class="d-flex justify-content-between align-items-center" |
||||
|
style="background-color: #f5f5f5; padding: 30px; width: 100%;"> |
||||
|
<div> |
||||
|
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span> |
||||
|
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View |
||||
|
screenshots for this |
||||
|
module</span> |
||||
|
</div> |
||||
|
<img src="./assets/misc/right-arrow.png" width="36" |
||||
|
height="36"/> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF NAVIGATION SECTION --> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" |
||||
|
id="overview"> |
||||
|
<div class="d-flex justify-content-center align-items-center mr-2" |
||||
|
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;"> |
||||
|
<img src="./assets/misc/pie-chart.png"/> |
||||
|
</div> |
||||
|
<h2 class="mt-2" |
||||
|
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
||||
|
Overview |
||||
|
</h2> |
||||
|
</div> |
||||
|
<div class="row" |
||||
|
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;"> |
||||
|
<div class="col-sm-12 py-4"> |
||||
|
The Document Management module (Version 16) offers a comprehensive range of features, |
||||
|
including document upload and storage, lead and task creation, document preview, |
||||
|
copy/move functionality, auto deletion, document privacy controls, email sharing, |
||||
|
and zip downloads. These features facilitate seamless document handling and collaboration, empowering organizations to |
||||
|
enhance productivity and streamline workflows. |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<!-- END OF OVERVIEW SECTION --> |
||||
|
<div class="container" style="padding: 2rem 1.5rem 4rem !important"> |
||||
|
|
||||
|
<div class="row" id="features"> |
||||
|
<div class="col-md-12" |
||||
|
style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important"> |
||||
|
<h2 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;"> |
||||
|
<i class="fa fa-star mr-2"></i>Features |
||||
|
</h2> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Multiple file can convert zip</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Trash feature available</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Easily to share documents to other users</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Able to create different workspace</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Document Portal View</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Portal document upload access</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Upload URL as document</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pl-3 py-3 d-flex"> |
||||
|
<div> |
||||
|
<img src="assets/icons/check.png"> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h4 |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Data Privacy</h4> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div class="row" id="screenshots"> |
||||
|
<div class="col-md-12" |
||||
|
style="border-bottom: 1px solid #d5d5d5 !important; margin: 2rem 0 !important"> |
||||
|
<h2 |
||||
|
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;"> |
||||
|
<i class="fa fa-image mr-2"></i>Screenshots |
||||
|
</h2> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Document user interface</h4> |
||||
|
|
||||
|
<img src="assets/screenshots/1.png" |
||||
|
class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto"/> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Workspace</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can categories files using workspace |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/3.png" |
||||
|
class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto"/> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Favorite option</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can make favorite their document. |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/4.png" |
||||
|
class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto"/> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Upload, Add url, Create Request</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can upload their document into document management |
||||
|
module and able to add file using url. |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/5.png" |
||||
|
class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto"/> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Upload interface</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can upload their document into document management |
||||
|
module, give access to specific users, able to choose workspace and auto delete option |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/6.png" |
||||
|
class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto"/> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Add url window</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can add file using url. |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/7.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Create Request</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can request file to other users . |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/8.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Various filters</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can easily filter files using file type and favorite |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/9.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Workspace</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can create unlimited workspace |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/10.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Trash feature</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can easily retrieve files after delete trash facility available |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/12.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
<div class="col-lg-12 my-2"> |
||||
|
<h4 class="mt-2" |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;"> |
||||
|
Request feature</h4> |
||||
|
<p |
||||
|
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;"> |
||||
|
User can request document to other users |
||||
|
</p> |
||||
|
|
||||
|
<img src="assets/screenshots/13.png" class="img-responsive img-thumbnail border" width="100%" |
||||
|
height="auto" /> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<!-- RELATED PRODUCTS --> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
||||
|
<h2 class="mt-2" |
||||
|
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
||||
|
Related |
||||
|
Products |
||||
|
</h2> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12"> |
||||
|
<div id="demo1" class="row carousel slide" data-ride="carousel"> |
||||
|
<!-- The slideshow --> |
||||
|
<div class="carousel-inner" style="padding:30px"> |
||||
|
<div class="carousel-item" style="min-height:198.656px"> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
||||
|
style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_redirect/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-radius:0px" |
||||
|
src="assets/modules/1.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
||||
|
style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/hr_payroll_community/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-radius:0px" |
||||
|
src="assets/modules/2.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
||||
|
style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/crm_dashboard/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-radius:0px" |
||||
|
src="assets/modules/3.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="carousel-item active" style="min-height:198.656px"> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
||||
|
style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/export_stockinfo_xls/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-radius:0px" |
||||
|
src="assets/modules/4.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
||||
|
style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/sale_discount_total/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-radius:0px" |
||||
|
src="assets/modules/5.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" |
||||
|
style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/16.0/fleet_rental/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-radius:0px" |
||||
|
src="assets/modules/6.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- Left and right controls --> |
||||
|
<a class="carousel-control-prev" href="#demo1" data-slide="prev" |
||||
|
style="width:35px; color:#000"> <span |
||||
|
class="carousel-control-prev-icon"><i |
||||
|
class="fa fa-chevron-left" |
||||
|
style="font-size:24px"></i></span> |
||||
|
</a> <a class="carousel-control-next" href="#demo1" |
||||
|
data-slide="next" style="width:35px; color:#000"> |
||||
|
<span class="carousel-control-next-icon"><i |
||||
|
class="fa fa-chevron-right" |
||||
|
style="font-size:24px"></i></span> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF RELATED PRODUCTS --> |
||||
|
|
||||
|
<!-- OUR SERVICES --> |
||||
|
<section class="container" style="margin-top: 6rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Our Services</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/cogs.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Customization</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/wrench.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Implementation</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/lifebuoy.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Support</h6> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/user.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Hire |
||||
|
Odoo |
||||
|
Developer</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/puzzle.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Integration</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/update.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Migration</h6> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/consultation.png" |
||||
|
class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Consultancy</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/training.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Implementation</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/license.png" class="img-responsive" |
||||
|
height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;"> |
||||
|
Odoo |
||||
|
Licensing Consultancy</h6> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- END OF OUR SERVICES --> |
||||
|
|
||||
|
<!-- OUR INDUSTRIES --> |
||||
|
<section class="container" style="margin-top: 6rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Our Industries</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/trading-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Trading |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Easily procure |
||||
|
and |
||||
|
sell your products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/pos-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
POS |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Easy |
||||
|
configuration |
||||
|
and convivial experience</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/education-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Education |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
A platform for |
||||
|
educational management</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/manufacturing-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Manufacturing |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Plan, track and |
||||
|
schedule your operations</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/ecom-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
E-commerce & Website |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Mobile |
||||
|
friendly, |
||||
|
awe-inspiring product pages</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/service-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Service Management |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Keep track of |
||||
|
services and invoice</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/restaurant-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Restaurant |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Run your bar or |
||||
|
restaurant methodically</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/hotel-black.png" |
||||
|
class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Hotel Management |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
An |
||||
|
all-inclusive |
||||
|
hotel management application</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<!-- END OF OUR INDUSTRIES --> |
||||
|
|
||||
|
<!-- FOOTER --> |
||||
|
<!-- Footer Section --> |
||||
|
<section class="container" style="margin: 5rem auto 2rem;"> |
||||
|
<div class="row" style="max-width:1540px;"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Need Help?</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #714B67 !important; background-color: #714B67 !important; width: 80px !important; margin-bottom: 2rem !important;"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Contact Cards --> |
||||
|
<div class="row d-flex justify-content-center align-items-center" |
||||
|
style="max-width:1540px; margin: 0 auto 2rem auto;"> |
||||
|
|
||||
|
<div class="col-lg-12" |
||||
|
style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; "> |
||||
|
|
||||
|
<div class="row mt-4"> |
||||
|
<div class="col-lg-6"> |
||||
|
<a href="mailto:odoo@cybrosys.com" target="_blank" |
||||
|
class="btn btn-block mb-2 deep_hover" |
||||
|
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i |
||||
|
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a> |
||||
|
</div> |
||||
|
<div class="col-lg-6"> |
||||
|
<a href="https://api.WhatsApp.com/send?phone=918606827707" |
||||
|
target="_blank" |
||||
|
class="btn btn-block mb-2 deep_hover" |
||||
|
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i |
||||
|
class="fa fa-whatsapp mr-2"></i>+91 86068 27707</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<!-- End of Contact Cards --> |
||||
|
</section> |
||||
|
<!-- Footer --> |
||||
|
<section class="oe_container" style="padding: 2rem 3rem 1rem;"> |
||||
|
<div class="row" |
||||
|
style="max-width:1540px; margin: 0 auto; margin-right: 3rem; "> |
||||
|
<!-- Logo --> |
||||
|
<div class="col-lg-12 d-flex justify-content-center align-items-center" |
||||
|
style="margin-top: 3rem;"> |
||||
|
<img src="https://www.cybrosys.com/images/logo.png" |
||||
|
width="200px" height="auto"/> |
||||
|
</div> |
||||
|
<!-- End of Logo --> |
||||
|
<div class="col-lg-12"> |
||||
|
<hr |
||||
|
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;"> |
||||
|
<!-- End of Footer Section --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- END OF FOOTER --> |
||||
|
|
||||
|
</div> |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,105 @@ |
|||||
|
.o_legacy_kanban_view.o_kanban_ungrouped |
||||
|
.o_document_kanban { |
||||
|
flex-direction: column; |
||||
|
min-height: 230px; |
||||
|
width: 166px; |
||||
|
border-radius: 10px; |
||||
|
} |
||||
|
|
||||
|
.o_kanban_attachment { |
||||
|
padding: 0; |
||||
|
height: 140px; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.o_kanban_record_title { |
||||
|
margin-bottom: 4px; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.fa { |
||||
|
display: inline-block; |
||||
|
font: normal normal normal 14px/1 FontAwesome; |
||||
|
font-size: 15px; |
||||
|
text-rendering: auto; |
||||
|
} |
||||
|
|
||||
|
.check_box { |
||||
|
margin-left: 90%; |
||||
|
} |
||||
|
|
||||
|
.o_activity_btn span.fa { |
||||
|
color: inherit; |
||||
|
font-size: large; |
||||
|
margin-right: 1px; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.new_container { |
||||
|
margin-top: 21px; |
||||
|
padding: 12px; |
||||
|
padding-top: 2px; |
||||
|
padding-left: 15px; |
||||
|
z-index: 9; |
||||
|
position: absolute; |
||||
|
margin-left: 94%; |
||||
|
align-items: center; |
||||
|
background-color: white; |
||||
|
width: fit-content; |
||||
|
} |
||||
|
|
||||
|
.new_container button { |
||||
|
padding-left: 0; |
||||
|
width: 10%; |
||||
|
font-size: 200%; |
||||
|
} |
||||
|
|
||||
|
.new_container button:hover { |
||||
|
background-color: LightGray; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* Styles */ |
||||
|
.o_document_kanban tbody, |
||||
|
.o_document_kanban table, |
||||
|
.o_document_kanban tr { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.o_document_kanban { |
||||
|
flex-wrap: wrap !important; |
||||
|
} |
||||
|
|
||||
|
.o_document_kanban .form-check-input { |
||||
|
position: relative !important; |
||||
|
margin-top: unset !important; |
||||
|
margin-left: unset !important; |
||||
|
left: -25px; |
||||
|
} |
||||
|
|
||||
|
.o_document_kanban .o_kanban_record_bottom { |
||||
|
width: 100% !important; |
||||
|
} |
||||
|
|
||||
|
.o_document_kanban .oe_kanban_global_area { |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.o_document_kanban .o_kanban_record_bottom .oe_kanban_bottom_right { |
||||
|
position: absolute; |
||||
|
right: 5px; |
||||
|
} |
||||
|
|
||||
|
.o_kanban_record_title { |
||||
|
width: 95%; |
||||
|
display: block; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
@ -0,0 +1,311 @@ |
|||||
|
odoo.define('enhanced_document_management.uploadButton', function(require) { |
||||
|
"use strict"; |
||||
|
var core = require('web.core'); |
||||
|
var Dialog = require('web.Dialog'); |
||||
|
var _t = core._t; |
||||
|
var KanbanController = require('web.KanbanController'); |
||||
|
var KanbanView = require('web.KanbanView'); |
||||
|
var viewRegistry = require('web.view_registry'); |
||||
|
var DocumentSearchPanel = require('document.search_panel'); |
||||
|
var rpc = require('web.rpc'); |
||||
|
const session = require('web.session'); |
||||
|
|
||||
|
/** |
||||
|
* Extending KanbanController to add custom functions |
||||
|
*/ |
||||
|
var KanbanButtonController = KanbanController.extend({ |
||||
|
buttons_template: 'button_in_kanban.button', |
||||
|
events: _.extend({}, KanbanController.prototype.events, { |
||||
|
'click .on_upload_doc': '_onUpload', |
||||
|
'click .on_delete_button': '_onDelete', |
||||
|
'click .on_share_button': '_onShare', |
||||
|
'click .on_add_url': '_onAddUrl', |
||||
|
'click .docs_check_box': '_onSelectDocs', |
||||
|
'click .on_download_archive': '_onDownloadArchive', |
||||
|
'click .on_archive_document': '_onArchiveDocument', |
||||
|
'click .on_mail_document': '_onMailDocument', |
||||
|
'click .on_copy_document': '_onCopyDocument', |
||||
|
'click .on_create_task': '_onCreateTask', |
||||
|
'click .on_create_lead': '_onCreateLead', |
||||
|
'click .on_add_request': '_onRequestDoc', |
||||
|
}), |
||||
|
documents_selected: [], |
||||
|
_onMailDocument:function(ev){ |
||||
|
/** |
||||
|
* Method to open email composer |
||||
|
*/ |
||||
|
var self = this; |
||||
|
rpc.query({ |
||||
|
model: 'document.file', |
||||
|
method: 'on_mail_document', |
||||
|
args: [this.documents_selected], |
||||
|
}).then(function (result){ |
||||
|
self.documents_selected = [] |
||||
|
self.do_action(result); |
||||
|
}); |
||||
|
}, |
||||
|
_onCopyDocument:function(ev){ |
||||
|
/** |
||||
|
* Method to open copy/cut wizard |
||||
|
*/ |
||||
|
session.user_has_group('enhanced_document_management.document_management_group_manager').then( |
||||
|
(has_group) => { |
||||
|
if (has_group){ |
||||
|
this.do_action({ |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': 'copy', |
||||
|
'res_model': 'document.tool', |
||||
|
'view_mode': 'form', |
||||
|
'target': 'new', |
||||
|
'views': [[false, 'form']], |
||||
|
'context': { |
||||
|
'default_doc_ids': this.documents_selected |
||||
|
} |
||||
|
}); |
||||
|
}else{ |
||||
|
this.do_action({ |
||||
|
'type': 'ir.actions.client', |
||||
|
'tag': 'display_notification', |
||||
|
'params': { |
||||
|
'message': "You don't have permission to perform this action", |
||||
|
'type': 'danger', |
||||
|
'sticky': false, |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
_onRequestDoc:function(ev){ |
||||
|
/** |
||||
|
* Method to open document request wizard |
||||
|
*/ |
||||
|
this.do_action({ |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': 'Add Document Request', |
||||
|
'res_model': 'request.document', |
||||
|
'view_mode': 'form', |
||||
|
'target': 'new', |
||||
|
'views': [[false, "form"]], |
||||
|
'context': { |
||||
|
'default_workspace_id': this.searchModel.get('selectedWorkspaceId'), |
||||
|
'form_view_ref': "enhanced_document_management.incoming_quick_request_document_view_form", |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
_onArchiveDocument: function(ev){ |
||||
|
/** |
||||
|
* Method to archive selected document |
||||
|
*/ |
||||
|
if (this.documents_selected.length != 0){ |
||||
|
var self = this; |
||||
|
rpc.query({ |
||||
|
model: 'document.file', |
||||
|
method: 'document_file_archive', |
||||
|
args: [this.documents_selected], |
||||
|
}).then(function (result){ |
||||
|
self.documents_selected = [] |
||||
|
location.reload(); |
||||
|
}); |
||||
|
}else{ |
||||
|
Dialog.alert(this, "Please select least one document"); |
||||
|
} |
||||
|
}, |
||||
|
_onSelectDocs: function(ev){ |
||||
|
/** |
||||
|
* Method to add selected document in a lisk |
||||
|
*/ |
||||
|
var self = this; |
||||
|
var toast = self.$el.find('.toast') |
||||
|
var record_id =parseInt(ev.target.dataset.id); |
||||
|
if (ev.target.checked){ |
||||
|
toast.addClass('show'); |
||||
|
this.documents_selected.push(record_id); |
||||
|
} |
||||
|
else{ |
||||
|
let index = this.documents_selected.indexOf(record_id); |
||||
|
this.documents_selected.splice(index, 1) |
||||
|
if ( this.documents_selected.length == 0){ |
||||
|
toast.removeClass('show'); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
_onDownloadArchive: function(ev){ |
||||
|
/** |
||||
|
* Method to download selected file as a Zip |
||||
|
*/ |
||||
|
var self = this; |
||||
|
if (this.documents_selected.length > 0) { |
||||
|
rpc.query({ |
||||
|
model: 'document.file', |
||||
|
method: 'archive_function', |
||||
|
args: [this.documents_selected] |
||||
|
}).then(function(res){ |
||||
|
self.do_action(res) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
_onAddUrl: function(){ |
||||
|
/** |
||||
|
* Method to open add URL wizard |
||||
|
*/ |
||||
|
return this.do_action({ |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': _('Add Url'), |
||||
|
'res_model': 'document.url', |
||||
|
'view_mode': 'form', |
||||
|
'target': 'new', |
||||
|
'views': [[false, "form"]], |
||||
|
'context': { |
||||
|
'default_workspace_id': this.searchModel.get('selectedWorkspaceId'), |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
_onCreateTask: function(){ |
||||
|
/** |
||||
|
* Method to create task based on selected document |
||||
|
*/ |
||||
|
var self = this; |
||||
|
rpc.query({ |
||||
|
model: 'document.file', |
||||
|
method: 'action_btn_create_task', |
||||
|
args: [this.documents_selected] |
||||
|
}).then(function (result){ |
||||
|
if (result) { |
||||
|
self.documents_selected = [] |
||||
|
location.reload(); |
||||
|
} |
||||
|
else { |
||||
|
self.do_action({ |
||||
|
'type': 'ir.actions.client', |
||||
|
'tag': 'display_notification', |
||||
|
'params': { |
||||
|
'message': "Install Project Module to use this function", |
||||
|
'type': 'info', |
||||
|
'sticky': false, |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
_onCreateLead: function(){ |
||||
|
/** |
||||
|
* Method to create lead based on selected document |
||||
|
*/ |
||||
|
var self = this; |
||||
|
rpc.query({ |
||||
|
model: 'document.file', |
||||
|
method: 'action_btn_create_lead', |
||||
|
args: [this.documents_selected] |
||||
|
}).then(function (result){ |
||||
|
if (result) { |
||||
|
self.documents_selected = [] |
||||
|
location.reload(); |
||||
|
}else { |
||||
|
self.do_action({ |
||||
|
'type': 'ir.actions.client', |
||||
|
'tag': 'display_notification', |
||||
|
'params': { |
||||
|
'message': "Install CRM Module to use this function", |
||||
|
'type': 'info', |
||||
|
'sticky': false, |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
_onDelete: function(ev){ |
||||
|
/** |
||||
|
* Method to delete selected records |
||||
|
*/ |
||||
|
session.user_has_group('enhanced_document_management.document_management_group_manager').then( |
||||
|
(has_group) => { |
||||
|
if (has_group){ |
||||
|
var self = this; |
||||
|
var record_id = parseInt(ev.target.dataset.id) |
||||
|
rpc.query({ |
||||
|
model: 'document.file', |
||||
|
method: 'document_file_delete', |
||||
|
args: [this.documents_selected], |
||||
|
}).then(function (result){ |
||||
|
self.documents_selected = [] |
||||
|
location.reload(); |
||||
|
}); |
||||
|
}else{ |
||||
|
this.do_action({ |
||||
|
'type': 'ir.actions.client', |
||||
|
'tag': 'display_notification', |
||||
|
'params': { |
||||
|
'message': "You don't have permission to perform this action", |
||||
|
'type': 'danger', |
||||
|
'sticky': false, |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
_onShare: function(ev){ |
||||
|
/** |
||||
|
* Method to create sharable url based on selected document |
||||
|
*/ |
||||
|
var self = this; |
||||
|
rpc.query({ |
||||
|
model: 'document.share', |
||||
|
method: 'create_url', |
||||
|
args: [this.documents_selected], |
||||
|
}).then(function (result){ |
||||
|
self.do_action(result) |
||||
|
}); |
||||
|
}, |
||||
|
_onUpload: function(){ |
||||
|
/** |
||||
|
* Method to open file upload wizard |
||||
|
*/ |
||||
|
this.do_action({ |
||||
|
name: "Upload Documents", |
||||
|
type: 'ir.actions.act_window', |
||||
|
res_model: 'document.file', |
||||
|
view_mode: 'form', |
||||
|
views: [[false, 'form']], |
||||
|
target: 'new', |
||||
|
context: { |
||||
|
default_workspace_id: this.searchModel.get('selectedWorkspaceId'), |
||||
|
default_content_type: 'file', |
||||
|
}, |
||||
|
}) |
||||
|
}, |
||||
|
updateButtons() { |
||||
|
/** |
||||
|
* Method to restrict button click |
||||
|
*/ |
||||
|
const selectedWorkspaceId = this.searchModel.get('selectedWorkspaceId'); |
||||
|
this.$buttons.find('.on_upload_doc').prop('disabled', !selectedWorkspaceId); |
||||
|
this.$buttons.find('.on_add_url').prop('disabled', !selectedWorkspaceId); |
||||
|
this.$buttons.find('.on_add_request').prop('disabled', !selectedWorkspaceId); |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
var DocumentKanbanView = KanbanView.extend({ |
||||
|
config: _.extend({}, KanbanView.prototype.config, { |
||||
|
Controller: KanbanButtonController, |
||||
|
SearchPanel: DocumentSearchPanel, |
||||
|
}), |
||||
|
}); |
||||
|
viewRegistry.add('document_kanban_view', DocumentKanbanView); |
||||
|
Dialog.link = function (owner, message, options) { |
||||
|
var buttons = [{ |
||||
|
text: _t("Ok"), |
||||
|
close: true, |
||||
|
click: options && options.confirm_callback, |
||||
|
}]; |
||||
|
return new Dialog(owner, _.extend({ |
||||
|
size: 'medium', |
||||
|
buttons: buttons, |
||||
|
$content: $('<main/>', { |
||||
|
role: 'alert', |
||||
|
text: message, |
||||
|
}), |
||||
|
title: _t("Here's your Link !"), |
||||
|
onForceClose: options && (options.onForceClose || options.confirm_callback), |
||||
|
}, options)).open({shouldFocusButtons:true}); |
||||
|
}; |
||||
|
}); |
@ -0,0 +1,44 @@ |
|||||
|
odoo.define("document.my_portal", function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var publicWidget = require('web.public.widget'); |
||||
|
publicWidget.registry.DocumentPortal = publicWidget.Widget.extend({ |
||||
|
selector: 'div[id="document_portal"]', |
||||
|
events: { |
||||
|
'click .fa-share': '_onShare', |
||||
|
'click .re-upload': '_onRequestAccept', |
||||
|
'click .re-reject': '_onRequestReject', |
||||
|
}, |
||||
|
_onShare: function(ev){ |
||||
|
/** |
||||
|
* Method to copy sharable link |
||||
|
*/ |
||||
|
var record_url = ev.target.dataset.url |
||||
|
var $temp = $("<input>"); |
||||
|
$("body").append($temp); |
||||
|
$temp.val(record_url).select(); |
||||
|
document.execCommand("copy"); |
||||
|
$temp.remove(); |
||||
|
this.$el.find('.toast').addClass('show'); |
||||
|
this.$el.find('.toast-body').text(record_url) |
||||
|
}, |
||||
|
_onRequestAccept: function(ev){ |
||||
|
/** |
||||
|
* Function to open file upload modal |
||||
|
*/ |
||||
|
this.$el.find('#req_upload_form').modal('show'); |
||||
|
this.$el.find('#workspace').val(ev.target.dataset.workspace) |
||||
|
this.$el.find('#requested_by').val(ev.target.dataset.requested_by) |
||||
|
this.$el.find('#workspace_id').val(ev.target.dataset.workspace_id) |
||||
|
this.$el.find('#rec_id').val(ev.target.dataset.id) |
||||
|
}, |
||||
|
_onRequestReject: function(ev){ |
||||
|
/** |
||||
|
* Function to reject file upload request |
||||
|
*/ |
||||
|
this.$el.find('#req_id').val(ev.target.dataset.id) |
||||
|
this.$el.find('#req_reject_form').modal('show'); |
||||
|
} |
||||
|
|
||||
|
}) |
||||
|
}) |
@ -0,0 +1,32 @@ |
|||||
|
odoo.define('website_documents', function (require) { |
||||
|
"use strict"; |
||||
|
var publicWidget = require('web.public.widget'); |
||||
|
var rpc = require('web.rpc'); |
||||
|
|
||||
|
publicWidget.registry.documentUploadButton = publicWidget.Widget.extend({ |
||||
|
selector: 'div[id="document_upload_button"]', |
||||
|
events: { |
||||
|
'click #web_docs_upload': '_onUploadButtonClick', |
||||
|
}, |
||||
|
_onUploadButtonClick: function(){ |
||||
|
/** |
||||
|
* Method to open the document upload modal |
||||
|
* $('#docs_upload_form').modal('show'); this method will open the modal |
||||
|
* the modal located in another template, so that we used JQUERY to open modal |
||||
|
*/ |
||||
|
var self = this; |
||||
|
this.$el.find('#docs_upload_form').modal('show'); |
||||
|
rpc.query({ |
||||
|
model : 'document.workspace', |
||||
|
method : 'work_spaces', |
||||
|
args : [] |
||||
|
}).then(function(result){ |
||||
|
result.forEach(element =>{ |
||||
|
self.$el.find('#workspace').append(` |
||||
|
<option value="${element['id']}">${element['name']}</option>` |
||||
|
) |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}) |
@ -0,0 +1,11 @@ |
|||||
|
odoo.define("document.search_panel", function (require) { |
||||
|
"use strict"; |
||||
|
const searchPanel = require("web.searchPanel"); |
||||
|
|
||||
|
/** |
||||
|
* Extended searchPanel to add custom |
||||
|
*/ |
||||
|
class DocumentSearchPanel extends searchPanel {} |
||||
|
DocumentSearchPanel.modelExtension = 'CustomDocumentsSearchPanel'; |
||||
|
return DocumentSearchPanel; |
||||
|
}); |
@ -0,0 +1,39 @@ |
|||||
|
odoo.define("document.search_panel_extension", function (require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
const ActionModel = require("web.ActionModel"); |
||||
|
const SearchPanelModelExtension = require("web.searchPanelModelExtension"); |
||||
|
|
||||
|
const isFolderCategory = (s) => s.fieldName === "workspace_id"; |
||||
|
|
||||
|
/** |
||||
|
* SearchPanelModelExtension inherited to updated custom searchPanel |
||||
|
*/ |
||||
|
class CustomDocumentSearchPanelModelExtension extends SearchPanelModelExtension { |
||||
|
constructor() { |
||||
|
super(...arguments); |
||||
|
} |
||||
|
get(property) { |
||||
|
/** |
||||
|
* Get function that return selected workspace id |
||||
|
*/ |
||||
|
switch (property) { |
||||
|
|
||||
|
case "selectedWorkspaceId": return this.getSections(isFolderCategory)[0]['activeValueId']; |
||||
|
|
||||
|
} |
||||
|
return super.get(...arguments); |
||||
|
} |
||||
|
|
||||
|
getFolders() { |
||||
|
/** |
||||
|
* Get function to return sub-folders (workspace) |
||||
|
*/ |
||||
|
const { values } = this.getSections(isFolderCategory)[0]; |
||||
|
return [...values.values()]; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
ActionModel.registry.add("CustomDocumentsSearchPanel", CustomDocumentSearchPanelModelExtension, 30); |
||||
|
return CustomDocumentSearchPanelModelExtension; |
||||
|
}); |
@ -0,0 +1,95 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
<!-- Extended kanbanView button template to add custom buttons --> |
||||
|
<t t-extend="KanbanView.buttons" t-name="button_in_kanban.button"> |
||||
|
<t t-jquery="button" t-operation="replace"> |
||||
|
<button t-if="widget.modelName == 'document.file'" |
||||
|
name="upload_button" type="button" |
||||
|
title="Upload document" |
||||
|
class="btn btn-primary on_upload_doc oe_highlight"> |
||||
|
Upload |
||||
|
</button> |
||||
|
<button |
||||
|
name="download_button" type="button" |
||||
|
title="Add Url" |
||||
|
class="btn btn-secondary on_add_url"> |
||||
|
Add url |
||||
|
</button> |
||||
|
<button |
||||
|
name="download_button" type="button" |
||||
|
title="Create Request" |
||||
|
class="btn btn-secondary on_add_request"> |
||||
|
Create Request |
||||
|
</button> |
||||
|
<div class="new_container toast" style="max-height: 389px;overflow-x: hidden;"> |
||||
|
<br/> |
||||
|
<button type="button" name="cl" |
||||
|
class="btn btn-secondary fa fa-share-alt btn-sm on_share_button" |
||||
|
style="width: 43px; padding-top: 10px; padding-left: 11px; |
||||
|
padding-right: 13px; padding-bottom: 8px; |
||||
|
border-radius: 11px; background: #e60023; |
||||
|
color: white; font-size: 23px;" |
||||
|
title="Share"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button name="create_task" type="button" title="Create Task" |
||||
|
class="btn btn-secondary btn-sm fa fa-tasks on_create_task" |
||||
|
style="width: 43px; padding-top: 10px; padding-left: 9px; |
||||
|
padding-right: 13px; padding-bottom: 5px; |
||||
|
border-radius: 11px; background: #0e76a8; |
||||
|
color: white; font-size: 23px;"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button type="button" name="archive_" |
||||
|
class="btn btn-secondary btn-sm on_download_archive fa fa-file-archive-o" |
||||
|
style="width: 43px; padding-top: 10px; padding-left: 11px; |
||||
|
padding-right: 13px; padding-bottom: 8px; |
||||
|
border-radius: 11px; background: #ff0000; |
||||
|
color: white; font-size: 23px;" |
||||
|
title="Zip File"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button name="create_lead" type="button" title="Create Lead" |
||||
|
class="btn btn-secondary btn-sm fa fa-level-up on_create_lead" |
||||
|
style="width: 43px; padding-top: 10px; padding-left: 11px; |
||||
|
padding-right: 13px; padding-bottom: 8px; |
||||
|
border-radius: 11px; background: #ea4689; |
||||
|
color: white; font-size: 23px;"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button type="button" name="mail" title='Mail' |
||||
|
class="btn btn-secondary btn-sm fa fa-envelope on_mail_document" |
||||
|
style="width: 43px; padding-top: 9px; padding-left: 9px; |
||||
|
padding-right: 13px; padding-bottom: 8px; |
||||
|
border-radius: 11px; background: #4267b2; |
||||
|
color: white; font-size: 23px;"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button type="button" name="copy" title='Copy/Move' |
||||
|
class="btn btn-secondary btn-sm fa fa-clone on_copy_document" |
||||
|
style="width: 43px; padding-top: 10px; padding-left: 10px; |
||||
|
padding-right: 13px; padding-bottom: 7px; |
||||
|
border-radius: 11px; background: #1da1f2; |
||||
|
color: white; font-size: 23px;"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button type="button" |
||||
|
class="btn btn-secondary btn-sm fa fa-archive on_archive_document" |
||||
|
style="width: 43px; padding-top: 9px; padding-left: 9px; |
||||
|
padding-right: 13px; padding-bottom: 7px; |
||||
|
border-radius: 11px; background: #e60023; |
||||
|
color: white; font-size: 23px;" |
||||
|
data-bs-dismiss="toast" title="Archive/Unarchive"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<button type="button" name="cl" |
||||
|
class="btn btn-secondary fa fa-trash on_delete_button" |
||||
|
title="Delete" |
||||
|
style="width: 43px; padding-top: 10px; padding-left: 11px; |
||||
|
padding-right: 13px; padding-bottom: 8px; |
||||
|
border-radius: 11px; background: #ea4689; |
||||
|
color: white; font-size: 23px;"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,241 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Window Action to show data from document.file module--> |
||||
|
<record id="document_file_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Documents</field> |
||||
|
<field name="res_model">document.file</field> |
||||
|
<field name="view_mode">kanban,form,activity</field> |
||||
|
<field name="help" type="html"> |
||||
|
<p class="o_view_nocontent_empty_folder"> |
||||
|
Save your documents... |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Document Kanban view --> |
||||
|
<record id="document_file_view_kanban" model="ir.ui.view"> |
||||
|
<field name="name">document.file.view.kanban</field> |
||||
|
<field name="model">document.file</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<kanban js_class="document_kanban_view"> |
||||
|
<field name="name"/> |
||||
|
<field name="date"/> |
||||
|
<field name="attachment"/> |
||||
|
<field name="attachment_id"/> |
||||
|
<field name="workspace_id"/> |
||||
|
<field name="content_url"/> |
||||
|
<field name="preview"/> |
||||
|
<field name="user_id"/> |
||||
|
<field name="id"/> |
||||
|
<field name="extension"/> |
||||
|
<templates> |
||||
|
<t t-name="kanban-box"> |
||||
|
<div class="o_kanban_record o_document_kanban d-flex flex-grow-1 flex-md-shrink-1 flex-shrink-0 oe_file_request"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<field name="priority" widget="priority"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<div class="o-checkbox form-check check_box"> |
||||
|
<input type="checkbox" |
||||
|
style="border-radius: 50%; |
||||
|
cursor: pointer;" |
||||
|
class="form-check-input |
||||
|
docs_check_box check_circle" |
||||
|
t-attf-id="{{record.id.value}}" |
||||
|
t-att-data-id="record.id.value"/> |
||||
|
</div> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
<div class="d-flex flex-column oe_kanban_global_area o_kanban_attachment o_documents_attachment oe_file_request" |
||||
|
t-att-data-id="record.id.value" style="justify-content: center; align-items: center;"> |
||||
|
<div class="o_kanban_image o_request_image"> |
||||
|
<div class="o_kanban_image_wrapper"> |
||||
|
<t t-value="record.extension.value" |
||||
|
t-set="Extension"/> |
||||
|
<t t-if="Extension == 'xlsx'"> |
||||
|
<img src="enhanced_document_management/static/images/xls.png" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="xlsx file"/> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'pdf'"> |
||||
|
<a t-att-href="record.content_url.value" data-fancybox="" data-caption=""> |
||||
|
<img src="enhanced_document_management/static/images/pdf.png" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="pdf file"/> |
||||
|
</a> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'txt'"> |
||||
|
<a t-att-href="record.content_url.value"> |
||||
|
<img src="enhanced_document_management/static/images/text.png" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="txt file"/> |
||||
|
</a> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'pptx'"> |
||||
|
<img src="enhanced_document_management/static/images/ppt.gif" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="pptx file"/> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'url'"> |
||||
|
<a t-att-href="record.content_url.value"> |
||||
|
<img src="enhanced_document_management/static/images/url.gif" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="url file"/> |
||||
|
</a> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'docx'"> |
||||
|
<img src="enhanced_document_management/static/images/doc.png" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="docx file"/> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'jpg'"> |
||||
|
<a t-att-href="record.content_url.value" data-fancybox="" data-caption=""> |
||||
|
<img src="enhanced_document_management/static/images/img.gif" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="jpg file"/> |
||||
|
</a> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'jpeg'"> |
||||
|
<a t-att-href="record.content_url.value" data-fancybox="" data-caption=""> |
||||
|
<img src="enhanced_document_management/static/images/img.gif" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="jpeg file"/> |
||||
|
</a> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'png'"> |
||||
|
<a t-att-href="record.content_url.value" data-fancybox="" data-caption=""> |
||||
|
<img src="enhanced_document_management/static/images/img.gif" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="png file"/> |
||||
|
</a> |
||||
|
</t> |
||||
|
<t t-elif="Extension == 'csv'"> |
||||
|
<img src="enhanced_document_management/static/images/csv.png" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="csv file"/> |
||||
|
</t> |
||||
|
<t t-else=""> |
||||
|
<img src="enhanced_document_management/static/images/file.png" |
||||
|
class="on_preview_button" |
||||
|
t-att-data-id="record.id.value" alt="other file"/> |
||||
|
</t> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="o_kanban_details flex-grow-1 flex-shrink-1 flex-auto"> |
||||
|
<div clss="o_kanban_details_wrapper"> |
||||
|
<div class="o_kanban_record_title"> |
||||
|
<field name="name"/> |
||||
|
<field name="active" invisible="1"/> |
||||
|
</div> |
||||
|
<div class="o_kanban_record_body text-muted"> |
||||
|
<field name="date"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="o_kanban_record_bottom flex-wrap"> |
||||
|
<div class="oe_kanban_bottom_left"> |
||||
|
<field name="attachment" widget="binary_widget"/> |
||||
|
</div> |
||||
|
<div class="oe_kanban_bottom_right"> |
||||
|
<field name="activity_ids" widget="kanban_activity"/> |
||||
|
<field name="user_id" widget="many2one_avatar_user"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
||||
|
</kanban> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Document Search view --> |
||||
|
<record id="document_file_view_search" model="ir.ui.view"> |
||||
|
<field name="name">document.file.view.search</field> |
||||
|
<field name="model">document.file</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Document Search"> |
||||
|
<field name="name" string="Document"/> |
||||
|
<field name="date"/> |
||||
|
<field name="workspace_id"/> |
||||
|
<filter string="Archive" name="archive" |
||||
|
domain="[('active', '=', False), ('trash', '=', False)]"/> |
||||
|
<filter string="Favourite" name="favourite" |
||||
|
domain="[('priority', '=', '1')]"/> |
||||
|
<filter string="PDF" name="filter_pdf" domain="[('extension', '=', 'pdf')]"/> |
||||
|
<filter string="XLSX" name="filter_xlsx" domain="[('extension', 'in', ['xlsx','xls'])]"/> |
||||
|
<filter string="Image" name="filter_xlsx" domain="[('extension', 'in', ['jpg','jpeg','png'])]"/> |
||||
|
<filter string="URL" name="filter_xlsx" domain="[('extension', '=', 'url')]"/> |
||||
|
<filter string="CSV" name="filter_xlsx" domain="[('extension', '=', 'csv')]"/> |
||||
|
<filter string="DOC" name="filter_xlsx" domain="[('extension', 'in', ['doc','docx'])]"/> |
||||
|
<group expand="0" string="Group By"> |
||||
|
<filter name="group_workspace" string="Workspace" |
||||
|
context="{'group_by':'workspace_id'}"/> |
||||
|
<filter name="group_extension" string="Extension" |
||||
|
context="{'group_by':'extension'}"/> |
||||
|
<filter name="group_user" string="Owner" context="{'group_by':'user_id'}"/> |
||||
|
</group> |
||||
|
<searchpanel> |
||||
|
<field name="workspace_id" icon="fa-folder" |
||||
|
hierarchize="1" expand="1" enable_counters="1" select="one"/> |
||||
|
</searchpanel> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Document form view --> |
||||
|
<record id="document_file_view_form" model="ir.ui.view"> |
||||
|
<field name="name">document.file.view.form</field> |
||||
|
<field name="model">document.file</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Upload Document" create="0" copy="0"> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="attachment" filename="name"/> |
||||
|
<field name="mimetype" invisible="1"/> |
||||
|
<field name="name" invisible="1"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="workspace_id" help="User can choose where to save the file"/> |
||||
|
<field name="company_id"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group string="History" invisible="1"> |
||||
|
<group> |
||||
|
<field name="create_uid" string="Created by"/> |
||||
|
<field name="create_date" string="Created on"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="write_uid" string="Last Updated on"/> |
||||
|
<field name="create_date" string="Last Updated by"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group string="Security" rowspan="2"> |
||||
|
<group> |
||||
|
<field name="security" widget="radio" string="Access" help="Who can access your file"/> |
||||
|
<field name="user_ids" widget="many2many_tags" |
||||
|
attrs="{'invisible':[('security','!=','specific_users')]}"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="partner_id" string="Related Partner"/> |
||||
|
<field name="auto_delete"/> |
||||
|
<field name="days" attrs="{'invisible':[('auto_delete','=',False)]}"/> |
||||
|
<field name="delete_date" attrs="{'invisible':[('auto_delete','=',False)]}"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group string="Description"> |
||||
|
<group colspan="4"> |
||||
|
<field colspan="2" name="description" nolabel="1" placeholder="Your file need..."/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
<footer> |
||||
|
<button class="oe_highlight" name="action_upload_document" type="object" |
||||
|
string="Upload"/> |
||||
|
<button special="cancel" string="Discard"/> |
||||
|
</footer> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,103 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- Inherited portal_my_home template to add documents inside portal view --> |
||||
|
<template id="portal_my_home_document" |
||||
|
name="Show Documents" customize_show="True" |
||||
|
inherit_id="portal.portal_my_home" priority="20"> |
||||
|
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside"> |
||||
|
<t t-call="portal.portal_docs_entry"> |
||||
|
<t t-set="title">Documents</t> |
||||
|
<t t-set="url" t-value="'/my/documents'"/> |
||||
|
<t t-set="placeholder_count" t-value="'document_count'"/> |
||||
|
</t> |
||||
|
<t t-call="portal.portal_docs_entry"> |
||||
|
<t t-set="title">Document Requests</t> |
||||
|
<t t-set="url" t-value="'/my/document_request'"/> |
||||
|
<t t-set="placeholder_count" t-value="'request_count'"/> |
||||
|
</t> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
<!-- Inherited portal_layout template to add documents tree view --> |
||||
|
<template id="portal_my_documents" name="My Documents"> |
||||
|
<t t-call="portal.portal_layout"> |
||||
|
<t t-set="breadcrumbs_searchbar" t-value="True"/> |
||||
|
<t t-call="portal.portal_searchbar"> |
||||
|
<t t-set="title">Documents</t> |
||||
|
</t> |
||||
|
<div id="document_portal"> |
||||
|
|
||||
|
<t t-if="not document_ids"> |
||||
|
<p>There are currently no Documents for your account.</p> |
||||
|
</t> |
||||
|
<t t-if="document_ids"> |
||||
|
<table class="table rounded mb-0 bg-white o_portal_my_doc_table"> |
||||
|
<thead> |
||||
|
<tr class="active"> |
||||
|
<th class="text-start">Document Name</th> |
||||
|
<th class="text-end">User Name</th> |
||||
|
<th class="text-end">Create Date</th> |
||||
|
<th class="text-end">Related User</th> |
||||
|
<th class="text-end">Download</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<t t-set="count" t-value="0"/> |
||||
|
<t t-foreach="extensions" t-as="extension"> |
||||
|
<thead class="table-light"> |
||||
|
<tr> |
||||
|
<th class="text-start" colspan="5" |
||||
|
style="text-transform: uppercase;"> |
||||
|
<t t-esc="extension"/> |
||||
|
</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<t t-foreach="document_ids[count]" t-as="docs"> |
||||
|
<tr> |
||||
|
<td class="text-start"> |
||||
|
<t t-esc="docs.name"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-esc="docs.user_id.name"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-esc="docs.date"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-esc="docs.partner_id.name"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-if="extension == 'url'"> |
||||
|
<i class="btn btn-outline-primary fa fa-share" t-att-data-url="docs.brochure_url"/> |
||||
|
<a class="btn btn-outline-primary fa fa-expand" |
||||
|
t-att-href="docs.content_url" |
||||
|
target="_blank"> |
||||
|
</a> |
||||
|
</t> |
||||
|
|
||||
|
<t t-else=""> |
||||
|
<i class="btn btn-outline-primary fa fa-share" t-attf-data-url="{{base_url}}{{docs.brochure_url}}"/> |
||||
|
<a class="btn btn-outline-primary fa fa-download" |
||||
|
t-attf-href="/web/content/#{docs.attachment_id.id}?download=true&access_token=" |
||||
|
target="_blank"/> |
||||
|
</t> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
<t t-set="count" t-value="count+1"/> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<div class="toast" |
||||
|
style="position:absolute;top:62px;right:10px;"> |
||||
|
<div class="toast-header"> |
||||
|
Link Copied to Clipboard |
||||
|
<button type="button" class="btn-close" data-bs-dismiss="toast"/> |
||||
|
</div> |
||||
|
<div class="toast-body text-primary"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</div> |
||||
|
</t> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,157 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- Inherited portal_breadcrumbs template to add Document Requests as breadcrumbs --> |
||||
|
<template id="portal_my_home_menu_req" name="Portal layout : Req menu" |
||||
|
inherit_id="portal.portal_breadcrumbs" priority="20"> |
||||
|
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside"> |
||||
|
<li t-if="page_name == 'document_requests'"> |
||||
|
<a t-if="document_requests" t-attf-href="/my/documents">/ Upload Request</a> |
||||
|
<t t-else="">/ Upload Request</t> |
||||
|
</li> |
||||
|
<li t-if="document_requests" class="breadcrumb-item active"> |
||||
|
/ <t t-esc="name"/> |
||||
|
</li> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
<!-- Inherited portal_layout template to add Document Requests inside portal view --> |
||||
|
<template id="portal_my_document_request" name="Document Request"> |
||||
|
<t t-call="portal.portal_layout"> |
||||
|
<t t-set="breadcrumbs_searchbar" t-value="True"/> |
||||
|
<t t-call="portal.portal_searchbar"> |
||||
|
<t t-set="title">Document Requests</t> |
||||
|
</t> |
||||
|
<div id="document_portal"> |
||||
|
<span id="req_reject_form" class="modal fade"> |
||||
|
<div class="modal-dialog modal-content" |
||||
|
style="border:none; height:fit-content; max-width:700px; |
||||
|
margin-top:2%;"> |
||||
|
<div class="modal-body" id="pop_html"> |
||||
|
<form action="/website/documents_request_reject" method="post" |
||||
|
class="oe_import"> |
||||
|
<div class="row form-group" style="padding:8px"> |
||||
|
<div class="align-middle" |
||||
|
style="margin:0 auto; width:80%;"> |
||||
|
<input type="hidden" name="csrf_token" |
||||
|
t-att-value="csrf_token"/> |
||||
|
<input type="hidden" name="req_id" |
||||
|
id="req_id"/> |
||||
|
<label for="reason">Reason </label> |
||||
|
<textarea name="reason" |
||||
|
class="form-control" |
||||
|
/> |
||||
|
<button id="submit" |
||||
|
type="submit" |
||||
|
class="btn btn-secondary" |
||||
|
style="width:200px; |
||||
|
margin-top:10px; margin-left:25%; |
||||
|
background-color:#59CE8F; |
||||
|
border:none; padding:8px; |
||||
|
font-size:16px;"> |
||||
|
Reject |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
</span> |
||||
|
<span id="req_upload_form" class="modal fade"> |
||||
|
<div class="modal-dialog modal-content" |
||||
|
style="border:none; height:fit-content; max-width:700px; |
||||
|
margin-top:2%;"> |
||||
|
<div class="modal-body" id="pop_html"> |
||||
|
<form action="/website/documents_request" method="post" |
||||
|
enctype="multipart/form-data" class="oe_import"> |
||||
|
<input type="hidden" name="csrf_token" |
||||
|
t-att-value="csrf_token"/> |
||||
|
|
||||
|
<div class="row form-group" style="padding:8px"> |
||||
|
<div class="align-middle" |
||||
|
style="margin:0 auto; width:80%;"> |
||||
|
<input type="file" name="file" |
||||
|
class="form-control" required="1"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group row" style="padding:8px"> |
||||
|
<div class="align-middle" |
||||
|
style="margin:0 auto; width:80%;"> |
||||
|
<input type="hidden" name="workspace" |
||||
|
id="workspace_id"/> |
||||
|
<input type="hidden" name="requested_by" |
||||
|
id="requested_by"/> |
||||
|
<input type="hidden" name="rec_id" |
||||
|
id="rec_id"/> |
||||
|
<input type="text" name="workspace_id" |
||||
|
id="workspace" readonly="1" |
||||
|
class="form-control"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group row" style="padding:5px"> |
||||
|
<div class="align-middle" |
||||
|
style="margin:0 auto; width:80%;"> |
||||
|
<textarea rows="6" cols="40" |
||||
|
class="form-control" |
||||
|
id="return_reason" name="reason" |
||||
|
placeholder="Description" |
||||
|
style="padding:5px; border:1px |
||||
|
solid #8879B0;"/> |
||||
|
<button id="submit" |
||||
|
type="submit" |
||||
|
class="btn btn-secondary" |
||||
|
style="width:200px; |
||||
|
margin-top:10px; margin-left:25%; |
||||
|
background-color:#59CE8F; |
||||
|
border:none; padding:8px; |
||||
|
font-size:16px;"> |
||||
|
Upload |
||||
|
</button> |
||||
|
<span id="o_website_form_result"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
</span> |
||||
|
<table class="table rounded mb-0 bg-white o_portal_my_doc_table"> |
||||
|
<thead> |
||||
|
<tr class="active"> |
||||
|
<th class="text-start">Request Date</th> |
||||
|
<th class="text-end">Requested By</th> |
||||
|
<th class="text-end">Document Needed</th> |
||||
|
<th class="text-end">Workspace</th> |
||||
|
<th class="text-end">Actions</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<t t-foreach="requests" t-as="req"> |
||||
|
<tr> |
||||
|
<td class="text-start"> |
||||
|
<t t-esc="req['date']"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-esc="req['requested_by'][1]"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-esc="req['needed_doc']"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<t t-esc="req['workspace_id'][1]"/> |
||||
|
</td> |
||||
|
<td class="text-end"> |
||||
|
<button class="btn btn-outline-primary |
||||
|
fa fa-upload re-upload" t-att-data-id="req['id']" |
||||
|
t-att-data-workspace_id="req['workspace_id'][0]" |
||||
|
t-att-data-workspace="req['workspace_id'][1]" |
||||
|
t-att-data-requested_by="req['requested_by'][0]"/> |
||||
|
<button class="btn btn-outline-danger |
||||
|
fa fa-minus-circle re-reject" |
||||
|
t-att-data-id="req['id']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</t> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,74 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Window Action to show data from document.trash module--> |
||||
|
<record id="document_trash_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Trash</field> |
||||
|
<field name="res_model">document.trash</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<!-- Document Trash tree view --> |
||||
|
<record id="document_trash_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">document.trash.view.tree</field> |
||||
|
<field name="model">document.trash</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree create="0"> |
||||
|
<field name="name" string="Document"/> |
||||
|
<field name="workspace_id" string="Workspace"/> |
||||
|
<field name="user_id" string="Owner" widget="many2one_avatar_user"/> |
||||
|
<field name="partner_id" string="Contact"/> |
||||
|
<field name="extension" string="Type"/> |
||||
|
<field name="deleted_date" string="Deleted on"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Document Trash from view --> |
||||
|
<record id="document_trash_view_form" model="ir.ui.view"> |
||||
|
<field name="name">document.trash.view.form</field> |
||||
|
<field name="model">document.trash</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Trash Document" create="0" copy="0"> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="attachment" filename="name"/> |
||||
|
<field name="mimetype" invisible="1"/> |
||||
|
<field name="name" invisible="1"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="workspace_id" help="User can choose where to save the file"/> |
||||
|
<field name="company_id"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group string="History" invisible="1"> |
||||
|
<group> |
||||
|
<field name="create_uid" string="Created by"/> |
||||
|
<field name="create_date" string="Created on"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="write_uid" string="Last Updated on"/> |
||||
|
<field name="create_date" string="Last Updated by"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group string="Security" rowspan="2"> |
||||
|
<group> |
||||
|
<field name="security" widget="radio" string="Access" help="Who can access your file"/> |
||||
|
<field name="user_ids" widget="many2many_tags" |
||||
|
attrs="{'invisible':[('security','!=','specific_users')]}"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="partner_id" string="Related Partner"/> |
||||
|
<field name="auto_delete"/> |
||||
|
<field name="days" attrs="{'invisible':[('auto_delete','=',False)]}"/> |
||||
|
<field name="delete_date" attrs="{'invisible':[('auto_delete','=',False)]}"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<group string="Description"> |
||||
|
<group colspan="4"> |
||||
|
<field colspan="2" name="description" nolabel="1" placeholder="Your file need..."/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,58 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Window Action to show data from document.workspace module--> |
||||
|
<record id="document_workspace_action" model="ir.actions.act_window"> |
||||
|
<field name="name">WorkSpace</field> |
||||
|
<field name="res_model">document.workspace</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
<field name="help" type="html"> |
||||
|
<p class="o_view_nocontent_smiling_face"> |
||||
|
Create a Workspace |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Workspace form view --> |
||||
|
<record id="document_workspace_view_form" model="ir.ui.view"> |
||||
|
<field name="name">document.workspace.view.form</field> |
||||
|
<field name="model">document.workspace</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Workspace"> |
||||
|
<sheet> |
||||
|
<div name="button_box" class="oe_button_box"> |
||||
|
<button id="button_view_document" name="action_view_document" |
||||
|
type="object" class="oe_stat_button" icon="fa-edit" attrs="{'invisible':[('document_count', '=', 0)]}"> |
||||
|
<field name="document_count" string="Documents" widget="statinfo"/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
<field name="display_name"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="company_id"/> |
||||
|
<field name="parent_id"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Description"> |
||||
|
<field name="description"/> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Workspace tree view --> |
||||
|
<record id="document_workspace_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">document.workspace.view.tree</field> |
||||
|
<field name="model">document.workspace</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree> |
||||
|
<field name="name"/> |
||||
|
<field name="company_id"/> |
||||
|
<field name="parent_id"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |