@ -0,0 +1,49 @@ |
|||
.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg |
|||
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
Document Approval |
|||
================= |
|||
This module helps to approve or reject documents. |
|||
|
|||
Configuration |
|||
============= |
|||
- No additional configuration required |
|||
|
|||
License |
|||
------- |
|||
General Public License, Version 3 (LGPL v3). |
|||
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html) |
|||
|
|||
Company |
|||
------- |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
Credits |
|||
------- |
|||
Developers: (V15) Fathima Mazlin AM, |
|||
(V17) Saneen K, |
|||
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,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM(<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/>. |
|||
# |
|||
############################################################################# |
|||
from . import models |
|||
from . import wizards |
@ -0,0 +1,50 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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 Approval", |
|||
"version": "15.0.1.0.0", |
|||
"category": "Documents Management", |
|||
"summary": "Manager can approve or reject documents", |
|||
"description": "User can create and upload various document for approvals." |
|||
"Manager can approve or reject documents.", |
|||
'author': 'Cybrosys Techno Solutions', |
|||
'company': 'Cybrosys Techno Solutions', |
|||
'maintainer': 'Cybrosys Techno Solutions', |
|||
'website': "https://www.cybrosys.com", |
|||
'depends': ['mail'], |
|||
'data': [ |
|||
'security/document_approval_security.xml', |
|||
'security/ir.model.access.csv', |
|||
'views/document_approval_menus.xml', |
|||
'views/document_approval_team_views.xml', |
|||
'views/document_approval_views.xml', |
|||
'views/res_config_settings_views.xml', |
|||
'wizards/document_approve_views.xml', |
|||
'wizards/document_reject_views.xml', |
|||
'wizards/document_approval_signature_views.xml', |
|||
], |
|||
'images': ['static/description/banner.png'], |
|||
'license': 'LGPL-3', |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': True, |
|||
} |
@ -0,0 +1,6 @@ |
|||
## Module <document_approval> |
|||
|
|||
#### 26.08.2024 |
|||
#### Version 17.0.1.0.0 |
|||
#### ADD |
|||
- Initial commit for Document Approval |
@ -0,0 +1,26 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author:Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from . import document_approval |
|||
from . import document_approval_file |
|||
from . import document_approval_step |
|||
from . import document_approval_team |
|||
from . import res_config_settings |
@ -0,0 +1,198 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import api, fields, models, _ |
|||
from odoo.exceptions import UserError, ValidationError |
|||
|
|||
|
|||
class DocumentApproval(models.Model): |
|||
""" A model for Managing the document approvals""" |
|||
_name = "document.approval" |
|||
_inherit = ["mail.thread", "mail.activity.mixin"] |
|||
_description = "Document Approvals" |
|||
|
|||
name = fields.Char(string='Name', required=True, |
|||
help='Name of the record.') |
|||
is_active = fields.Boolean(string='Active', copy=False, |
|||
help='Used to check the record active or not.') |
|||
description = fields.Text(string="Description", |
|||
help='Used to add description about the document' |
|||
' approval') |
|||
approve_initiator_id = fields.Many2one('res.users', string="Initiator", |
|||
default=lambda self: self.env.user, |
|||
help='Set who has initiated the ' |
|||
'document approval.') |
|||
team_id = fields.Many2one('document.approval.team', string="Approval Team", |
|||
required=True, |
|||
help='Set which team is approving the document.') |
|||
team_lead_id = fields.Many2one(string='Team leader', |
|||
related='team_id.team_lead_id', |
|||
help="team Leader") |
|||
method = fields.Selection(selection=[('button', 'Button'), |
|||
('sign', 'Signature')], |
|||
default='button', string="Method", |
|||
help='Set the mode of approvals.') |
|||
visibility = fields.Selection(selection=[('all_user', 'All Users'), |
|||
('followers', 'Followers & ' |
|||
'Approvers'), |
|||
('approvers', 'Approvers')], |
|||
string='Visibility', |
|||
help='Restrict the visibility of the ' |
|||
'document', default="approvers", |
|||
compute='_compute_visibility') |
|||
state = fields.Selection(selection=[('draft', 'Draft'), |
|||
('waiting', 'Waiting'), |
|||
('approved', 'Approved'), |
|||
('reject', 'Rejected')], |
|||
string='Status', default='draft', readonly=True, |
|||
tracking=True, |
|||
help='State of the document.') |
|||
company_id = fields.Many2one('res.company', string='Company', |
|||
default=lambda self: self.env.company, |
|||
help='Company of the record.') |
|||
step_ids = fields.One2many('document.approval.step', |
|||
'document_approve_id', |
|||
compute='_compute_step_ids', store=True, |
|||
help='For setting document approval steps') |
|||
file_ids = fields.One2many('document.approval.file', 'approval_id', |
|||
string='Files', |
|||
help='You can upload file and file details') |
|||
step_count = fields.Integer(string="Step", help="Current Step", |
|||
readonly=True) |
|||
approver_ids = fields.Many2many('res.users', string="Approver", |
|||
help="User to approve the document") |
|||
show_approve = fields.Boolean(string="Show Approve Button", copy=False, |
|||
help="To show the approve button to approve" |
|||
"the document", |
|||
compute="_compute_show_approve") |
|||
approval_ids = fields.Many2many('document.approval.step', |
|||
string="Approval Step", |
|||
help="Approval Step of the document") |
|||
|
|||
@api.depends('team_id') |
|||
def _compute_step_ids(self): |
|||
"""Method _compute_step_ids to compute the values to the field |
|||
step_ids""" |
|||
for rec in self: |
|||
rec.step_ids = False |
|||
for step in rec.team_id.step_ids: |
|||
rec.step_ids = [fields.Command.create({ |
|||
'steps': step.steps, |
|||
'approver_id': step.approver_id.id, |
|||
'role': step.role, |
|||
'state': step.state, |
|||
'note': step.note |
|||
})] |
|||
|
|||
@api.constrains('team_id') |
|||
def _check_team_member(self): |
|||
"""function to check whether the team has atleast one member.""" |
|||
if not self.team_id.step_ids.approver_id: |
|||
raise ValidationError( |
|||
"Your Team member should at least have one Approver.") |
|||
|
|||
@api.depends('team_id') |
|||
def _compute_show_approve(self): |
|||
"""This method _compute_show_approve to compute the valur to the field |
|||
show_approve""" |
|||
for rec in self: |
|||
rec.show_approve = True if self.env.uid in rec.approver_ids.ids \ |
|||
else False |
|||
if rec.team_id.team_lead_id.id == self.env.uid: |
|||
rec.show_approve = True |
|||
|
|||
def action_send_for_approval(self): |
|||
""" Action to sent document to approval also it changes the state |
|||
into waiting that document to be approved """ |
|||
steps = self.step_ids.mapped('steps') |
|||
unique_steps = [] |
|||
for step in steps: |
|||
if step not in unique_steps: |
|||
unique_steps.append(step) |
|||
unique_steps = sorted(unique_steps) |
|||
self.step_count = unique_steps[0] |
|||
aprroval_records = self.step_ids.search([( |
|||
'steps', '=', unique_steps[0]), ('document_approve_id', '=', |
|||
self.id)]) |
|||
self.approval_ids = aprroval_records.ids |
|||
approval_user_ids = [] |
|||
for record in aprroval_records: |
|||
approval_user_ids.append(record.approver_id.id) |
|||
record.current_state = 'pending' |
|||
self.approver_ids = approval_user_ids |
|||
self.state = "waiting" |
|||
|
|||
def action_approve(self): |
|||
""" function that return wizard to do the approval by writing note |
|||
and approver can approve the document. |
|||
Approval is done just clicking the button""" |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': 'Document Approval', |
|||
'target': 'new', |
|||
'view_mode': 'form', |
|||
'res_model': 'document.approve', |
|||
'context': { |
|||
'default_document_id': self.id |
|||
} |
|||
} |
|||
|
|||
def action_reject(self): |
|||
""" Return a wizard that to confirm rejection by adding a note""" |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': 'Document Rejection', |
|||
'target': 'new', |
|||
'view_mode': 'form', |
|||
'res_model': 'document.reject', |
|||
'context': { |
|||
'default_document_id': self.id |
|||
} |
|||
} |
|||
|
|||
def action_approve_sign(self): |
|||
""" Return a wizard that approver can ensure to give |
|||
signature and approve. Approver can add signature confirmation """ |
|||
return { |
|||
'type': 'ir.actions.act_window', |
|||
'name': 'Document Approval', |
|||
'target': 'new', |
|||
'view_mode': 'form', |
|||
'res_model': 'document.approval.signature', |
|||
'context': { |
|||
'default_document_id': self.id |
|||
} |
|||
} |
|||
|
|||
def unlink(self): |
|||
""" This function is used to ensure to there is no record of |
|||
state approved has been deleted""" |
|||
for record in self: |
|||
if record.state in ["approved", "waiting"]: |
|||
raise UserError( |
|||
_("You cannot delete record in approved or waiting state")) |
|||
return super(DocumentApproval, self).unlink() |
|||
|
|||
def _compute_visibility(self): |
|||
for rec in self: |
|||
visibility = self.env['ir.config_parameter'].sudo().get_param( |
|||
'document_approval.visibility') |
|||
rec.visibility = visibility |
@ -0,0 +1,49 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import fields, models, _ |
|||
from odoo.exceptions import UserError |
|||
|
|||
|
|||
class DocumentApprovalFiles(models.Model): |
|||
""" Manage the documents for approvals""" |
|||
_name = 'document.approval.file' |
|||
_description = "document files" |
|||
|
|||
name = fields.Char(string="Name", required=True, |
|||
help='For adding some noted about the file ') |
|||
file = fields.Binary(string="File", required=True, attachment=True, |
|||
help='For storing the file') |
|||
file_name = fields.Char(string="File Name", |
|||
help="Storing name of the file") |
|||
approval_id = fields.Many2one('document.approval', |
|||
help='Inverse fields for the document ' |
|||
'approval') |
|||
|
|||
def unlink(self): |
|||
"""Supering the method unlink of model document.approval.line to |
|||
restrict the deleting of the file""" |
|||
for rec in self: |
|||
if rec.approval_id.state != 'Draft': |
|||
raise UserError( |
|||
_(f"You cannot delete file " |
|||
f"from {rec.approval_id.state} state")) |
|||
super(DocumentApprovalFiles, rec).unlink() |
@ -0,0 +1,57 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM(<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class DocumentApprovalSteps(models.Model): |
|||
""" Document approval steps""" |
|||
_name = "document.approval.step" |
|||
_description = "Document Approvals Steps" |
|||
|
|||
steps = fields.Integer(string="Steps", |
|||
help='For counting how many steps needed') |
|||
approver_id = fields.Many2one('res.users', string="Approver", |
|||
help='The person who is responsible for ' |
|||
'the approval') |
|||
role = fields.Char(string="Role/Position", |
|||
help='To determine the position of the approver') |
|||
document_approve_id = fields.Many2one('document.approval', |
|||
string='Document Approval', |
|||
help='Inverse field from document ' |
|||
'approvals') |
|||
is_approve = fields.Boolean(string='Is Approved', copy=False, |
|||
help='Check weather it is approved or not') |
|||
document_approve_team_id = fields.Many2one('document.approval.team', |
|||
string="Approver Team", |
|||
help='The team who are ' |
|||
'responsible for the ' |
|||
'approvals') |
|||
state = fields.Selection( |
|||
selection=[('to_approve', 'To Approve'), |
|||
('approve', 'Approve')], |
|||
default="to_approve") |
|||
note = fields.Char(string='Notes', help="To add notes") |
|||
current_state = fields.Selection( |
|||
selection=[('upcoming', 'Upcoming'), ('pending', 'Pending'), |
|||
('approved', 'Approved'), ('rejected', 'Rejected')], |
|||
default="upcoming", string="Approval State", |
|||
help="THe current state of approval") |
@ -0,0 +1,45 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class DocumentApprovalTeam(models.Model): |
|||
""" Configure document approval team""" |
|||
_name = "document.approval.team" |
|||
_inherit = ["mail.thread", "mail.activity.mixin"] |
|||
_description = "Document approval team" |
|||
|
|||
name = fields.Char(string='Name', required=True, help='Name of the team', |
|||
tracking=True) |
|||
team_lead_id = fields.Many2one('res.users', string='Team Leader', |
|||
help='For setting th team lead', |
|||
tracking=True, required=True, |
|||
default=lambda self: self.env.user) |
|||
company_id = fields.Many2one('res.company', string='Company', |
|||
help='For setting the company', |
|||
default=lambda self: self.env.company) |
|||
is_active = fields.Boolean(string="Active", copy=False, |
|||
help='For checking the active status') |
|||
step_ids = fields.One2many('document.approval.step', |
|||
'document_approve_team_id', |
|||
help='For setting document approval steps for ' |
|||
'the approval team') |
@ -0,0 +1,57 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################### |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL 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 AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################### |
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class ResConfigSettings(models.TransientModel): |
|||
"""Inherit the model res.config.settings to add Additional fields""" |
|||
_inherit = 'res.config.settings' |
|||
|
|||
visibility = fields.Selection( |
|||
selection=[('all_user', 'All Users'), ( |
|||
'followers', 'Followers & Approvers'), |
|||
('approvers', 'Approvers')], string='Visibility', |
|||
help='Restrict the visibility of the document', default="approvers", |
|||
config_parameter='document_approval.visibility', required=True) |
|||
|
|||
@api.onchange('visibility') |
|||
def _onchange_visibility(self): |
|||
record_rule = self.env.ref('document_approval.' |
|||
'document_approval_rule_user') |
|||
if self.visibility == 'all_user': |
|||
record_rule.write({ |
|||
'domain_force': "[(1, '=', 1)]", |
|||
}) |
|||
elif self.visibility == 'followers': |
|||
record_rule.write({ |
|||
'domain_force': "['|','|','|',('step_ids.approver_id.id','='," |
|||
"user.id),('approve_initiator_id','='," |
|||
"user.id),('team_id.team_lead_id.id','='," |
|||
"user.id),('message_partner_ids', 'in', " |
|||
"[user.partner_id.id])]", |
|||
}) |
|||
elif self.visibility == 'approvers': |
|||
record_rule.write({ |
|||
'domain_force': "['|','|',('step_ids.approver_id.id','='," |
|||
"user.id),('approve_initiator_id','=',user.id)" |
|||
",('team_id.team_lead_id.id','=',user.id)]", |
|||
}) |
@ -0,0 +1,26 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<!-- Record rule for adding visibility to the approvers team --> |
|||
<record id="document_approval_rule_user" model="ir.rule"> |
|||
<field name="name">document approval rule user</field> |
|||
<field name="model_id" |
|||
ref="document_approval.model_document_approval"/> |
|||
<field name="domain_force"> |
|||
['|','|',('step_ids.approver_id.id','=',user.id),('approve_initiator_id','=',user.id),('team_id.team_lead_id.id','=',user.id)] |
|||
</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> |
|||
<!--Multi company rule for the model document approval--> |
|||
<record model="ir.rule" id="document_approval_multi_company_rule"> |
|||
<field name="name">Document Approval Multi Company</field> |
|||
<field name="model_id" ref="model_document_approval"/> |
|||
<field name="global" eval="True"/> |
|||
<field name="domain_force">['|', ('company_id', '=', False), |
|||
('company_id', 'in', company_ids)] |
|||
</field> |
|||
</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: 1.1 KiB |
After Width: | Height: | Size: 1.2 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: 42 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 280 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 7.7 KiB |
@ -0,0 +1,685 @@ |
|||
<div style="background-color: #714B67; height: 810px; 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/misc/cybrosys-logo.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 |
|||
style="color: #875A7B; 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>Enterprise |
|||
</div> |
|||
<div |
|||
style="color: #017E84; 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>Odoo.sh |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- END OF TITLE BAR --> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<div class="col-sm-12 col-md-12 col-lg-12"> |
|||
<!-- APP HERO --> |
|||
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;"> |
|||
Document Approval </h1> |
|||
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;"> |
|||
Approve or Reject Various Documents.</p> |
|||
<!-- END OF APP HERO --> |
|||
<img src="assets/screenshots/hero.gif" class="img-responsive" |
|||
style="width: 100%; margin-left: auto; margin-right: auto;"/> |
|||
</div> |
|||
</div> |
|||
</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 --> |
|||
|
|||
<!-- OVERVIEW 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> |
|||
This module helps to approve or reject documents. |
|||
</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"> |
|||
</div> |
|||
</div> |
|||
<!-- END OF OVERVIEW SECTION --> |
|||
|
|||
<!-- FEATURES SECTION --> |
|||
<div class="d-flex align-items-center" |
|||
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" |
|||
id="features"> |
|||
<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/features.png"/> |
|||
</div> |
|||
<h2 class="mt-2" |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
|||
Features |
|||
</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 col-md-6"> |
|||
<div class="d-flex align-items-center" |
|||
style="margin-top: 40px; margin-bottom: 40px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2"/> |
|||
<span |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Community, Enterprise &Odoo Sh |
|||
Support.</span> |
|||
</div> |
|||
<div class="d-flex align-items-center" |
|||
style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2"/> |
|||
<span |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Approve or Reject Various Documents.</span> |
|||
</div><div class="d-flex align-items-center" |
|||
style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2"/> |
|||
<span |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Set Different Team for Approvals.</span> |
|||
</div><div class="d-flex align-items-center" |
|||
style="margin-top: 30px; margin-bottom: 30px"> |
|||
<img src="assets/misc/check-box.png" class="mr-2"/> |
|||
<span |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> Signature Approval.</span> |
|||
</div> |
|||
</div> |
|||
<div class="col-sm-12 col-md-6"> |
|||
</div> |
|||
</div> |
|||
<!-- END OF FEATURES SECTION --> |
|||
|
|||
<!-- SCREENSHOTS SECTION --> |
|||
<div class="d-flex align-items-center" |
|||
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" |
|||
id="screenshots"> |
|||
<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/pictures.png"/> |
|||
</div> |
|||
<h2 class="mt-2" |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
|||
Screenshots |
|||
</h2> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12"> |
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Document Approval Menu. |
|||
</h3> |
|||
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> |
|||
|
|||
<img src="assets/screenshots/1.png" |
|||
class="img-thumbnail"> |
|||
|
|||
</div> |
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Record Access: |
|||
Configuration-> Setting -> Visibility |
|||
</h3> |
|||
<img src="assets/screenshots/2.png" |
|||
class="img-thumbnail"> |
|||
</div> |
|||
<div style="display: block; margin: 30px auto;"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Approval Team Menu |
|||
</h3> |
|||
<img src="assets/screenshots/3.png" |
|||
class="img-thumbnail"><br/> |
|||
|
|||
</div> |
|||
|
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Form view of Approval Team |
|||
</h3> |
|||
|
|||
<img src="assets/screenshots/4.png" |
|||
class="img-thumbnail"> |
|||
<br> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Document Approval |
|||
</h3> |
|||
<img src="assets/screenshots/5.png" |
|||
class="img-thumbnail"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Document Approval form view |
|||
</h3> |
|||
<p class="m-0" style="color:#718096">The approvers in an approval team can be automatically listed down when we select that approval team.'Settings' allows you to adjust which records are visible. |
|||
</p> |
|||
<img src="assets/screenshots/6.png" |
|||
class="img-thumbnail"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
'SEND FOR APPROVAL' Button for sent the request for approval. |
|||
</h3> |
|||
<img src="assets/screenshots/7.png" |
|||
class="img-thumbnail"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
Approval Request |
|||
</h3> |
|||
<p class="m-0" style="color:#718096">Selecting "approvers" as the visibility setting means that only the initiator and approvers can view the document. Clicking the "SEND FOR APPROVAL" button causes the state to change to "WAITING." While the document is being approved by each approver, the status is changed to "APPROVED."The status is changed to "REJECTED" if any one of the approvers rejects. |
|||
</p> |
|||
<img src="assets/screenshots/8.png" |
|||
class="img-thumbnail"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
APPROVE and REJECT Button |
|||
</h3> |
|||
<p class="m-0" style="color:#718096">The first approver who clicks the "APPROVE" button changes the status to "WAITING." If all approvers give their approval, the status is changed to "APPROVED". The status changes to "REJECTED" if any approver clicks the "REJECT" button. |
|||
</p> |
|||
<img src="assets/screenshots/9.png" |
|||
class="img-thumbnail"><img src="assets/screenshots/10.png" |
|||
class="img-thumbnail"><img src="assets/screenshots/11.png" |
|||
class="img-thumbnail"> |
|||
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
|||
APPROVE state |
|||
</h3> |
|||
<img src="assets/screenshots/9.png" |
|||
class="img-thumbnail"><img src="assets/screenshots/12.png" |
|||
class="img-thumbnail"> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- END OF SCREENSHOTS SECTION --> |
|||
|
|||
<!-- RELATED PRODUCTS --> |
|||
<div class="d-flex align-items-center" style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<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/categories.png"/> |
|||
</div> |
|||
<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/15.0/customer_followup_community/" |
|||
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/15.0/sales_credit_limit/" |
|||
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/15.0/odoo_contact_approval/" |
|||
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/15.0/employee_documents_expiry/" |
|||
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/15.0/gender_contact/" |
|||
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/11.0/first_last_name/" |
|||
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 --> |
|||
|
|||
<div class="d-flex align-items-center" |
|||
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<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/star.png"/> |
|||
</div> |
|||
<h2 class="mt-2" |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
|||
Our Services |
|||
</h2> |
|||
</div> |
|||
|
|||
<div class="container my-5"> |
|||
<div class="row"> |
|||
<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> |
|||
|
|||
</div> |
|||
|
|||
<!-- END OF OUR SERVICES --> |
|||
|
|||
<!-- OUR INDUSTRIES --> |
|||
|
|||
<div class="d-flex align-items-center" |
|||
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<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/corporate.png"/> |
|||
</div> |
|||
<h2 class="mt-2" |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
|||
Our |
|||
Industries |
|||
</h2> |
|||
</div> |
|||
|
|||
<div class="container my-5"> |
|||
<div class="row"> |
|||
<div class="col-lg-3"> |
|||
<div class="my-4 d-flex flex-column justify-content-center" |
|||
style="background-color: #f6f8f9 !important; border-radius: 0px; 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: 0px; 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: 0px; 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: 0px; 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: 0px; 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: 0px; 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: 0px; 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: 0px; 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> |
|||
</div> |
|||
|
|||
<!-- END OF OUR INDUSTRIES --> |
|||
|
|||
<!-- SUPPORT --> |
|||
<div class="d-flex align-items-center" |
|||
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"> |
|||
<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/customer-support.png"/> |
|||
</div> |
|||
<h2 class="mt-2" |
|||
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;"> |
|||
Support |
|||
</h2> |
|||
</div> |
|||
<div class="container mt-5"> |
|||
<div class="row"> |
|||
<div class="col-sm-12 col-md-6"> |
|||
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;"> |
|||
<div class="mr-4 d-flex justify-content-center align-items-center" |
|||
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;"> |
|||
<img src="assets/misc/support.png" height="48" width="48" |
|||
style="width: 42px; height: 42px;"/> |
|||
</div> |
|||
<div> |
|||
<h4>Need Help?</h4> |
|||
<p style="line-height: 100%;">Got questions or need help? |
|||
Get in touch.</p> |
|||
<a href="mailto:odoo@cybrosys.com"> |
|||
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;"> |
|||
odoo@cybrosys.com</p> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="col-sm-12 col-md-6"> |
|||
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;"> |
|||
<div class="mr-4 d-flex justify-content-center align-items-center" |
|||
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;"> |
|||
<img src="assets/misc/whatsapp.png" height="52" width="52" |
|||
style="width: 52px; height: 52px;"/> |
|||
</div> |
|||
<div> |
|||
<h4>WhatsApp</h4> |
|||
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p> |
|||
<a href="https://api.whatsapp.com/send?phone=918606827707"> |
|||
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;"> |
|||
+91 86068 |
|||
27707</p> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center"> |
|||
<img src="assets/misc/logo.png" width="144" height="31" |
|||
style="width:144px; height: 31px; margin-top: 40px;"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- END OF SUPPORT --> |
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<!-- Menus for document approvals --> |
|||
<menuitem id="document_approval_menu_root" name="Document Approval" |
|||
sequence="1" |
|||
web_icon="document_approval,static/description/icon.png"/> |
|||
<menuitem id="document_approval_configuration_menu" name="Configuration" |
|||
sequence="4" |
|||
parent="document_approval_menu_root"/> |
|||
|
|||
<menuitem id="document_approval_reject_reason_menu_root" |
|||
name="Approve/Reject Reason" |
|||
sequence="3" |
|||
parent="document_approval_menu_root"/> |
|||
</odoo> |
@ -0,0 +1,68 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<!-- Tree views for document approval team --> |
|||
<record id="document_approval_team_view_tree" model="ir.ui.view"> |
|||
<field name="name">document.approval.team.view.tree</field> |
|||
<field name="model">document.approval.team</field> |
|||
<field name="arch" type="xml"> |
|||
<tree> |
|||
<field name="name"/> |
|||
<field name="team_lead_id"/> |
|||
<field name="company_id"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!-- form view for document approval team --> |
|||
<record id="document_approval_team_view_form" model="ir.ui.view"> |
|||
<field name="name">document.approval.team.view.form</field> |
|||
<field name="model">document.approval.team</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<sheet> |
|||
<group> |
|||
<group> |
|||
<field name="name"/> |
|||
<field name="team_lead_id"/> |
|||
</group> |
|||
<group> |
|||
<field name="company_id"/> |
|||
</group> |
|||
</group> |
|||
<group name="approvers" string="Approvers"> |
|||
<field name="step_ids" nolabel="1" colspan="2"> |
|||
<tree editable="bottom"> |
|||
<field name="steps" |
|||
style="text-align: {left};"/> |
|||
<field name="approver_id"/> |
|||
<field name="role"/> |
|||
<field name="state"/> |
|||
<field name="note"/> |
|||
</tree> |
|||
</field> |
|||
</group> |
|||
</sheet> |
|||
<div class="oe_chatter"> |
|||
<field name="message_follower_ids"/> |
|||
<field name="message_ids"/> |
|||
<field name="activity_ids"/> |
|||
</div> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- window action for document approval team --> |
|||
<record id="document_approval_team_action" |
|||
model="ir.actions.act_window"> |
|||
<field name="name">Document Approval Team</field> |
|||
<field name="res_model">document.approval.team</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="o_view_nocontent_smiling_face"> |
|||
Create a Document Approval Team |
|||
</p> |
|||
</field> |
|||
</record> |
|||
<menuitem id="document_approval_team_menu" name="Approval Team" |
|||
sequence="18" |
|||
parent="document_approval.document_approval_configuration_menu" |
|||
action="document_approval_team_action"/> |
|||
</odoo> |
@ -0,0 +1,160 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
<!-- Tree views for document approvals --> |
|||
<record id="document_approval_view_tree" model="ir.ui.view"> |
|||
<field name="name">document.approval.view.tree</field> |
|||
<field name="model">document.approval</field> |
|||
<field name="arch" type="xml"> |
|||
<tree decoration-danger="state == 'reject'" |
|||
decoration-warning="state == 'waiting'" |
|||
decoration-primary="state == 'draft'" |
|||
decoration-success="state == 'approved'"> |
|||
<field name="name" attrs="{'readonly':[('state', '!=', 'draft')]}"/> |
|||
<field name="approve_initiator_id"/> |
|||
<field name="company_id" attrs="{'readonly':[('state', '!=', 'draft')]}"/> |
|||
<field name="state" |
|||
decoration-success="state == 'approved'" |
|||
decoration-danger="state == 'reject'" |
|||
decoration-primary="state == 'draft'" |
|||
decoration-warning="state == 'waiting'" |
|||
widget="badge" optional="show"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!-- Form views for document approvals --> |
|||
<record id="document_approval_view_form" model="ir.ui.view"> |
|||
<field name="name">document.approval.view.form</field> |
|||
<field name="model">document.approval</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<header> |
|||
<button string="Send for Approval" |
|||
name="action_send_for_approval" type="object" |
|||
states="draft" class="oe_highlight"/> |
|||
<button string="Approve" name="action_approve_sign" |
|||
type="object" |
|||
class="oe_highlight" |
|||
attrs="{'invisible':['|', '|', ('state', 'not in', ('waiting' )),('method', '=', 'button'), ('show_approve', '=', False)]}"/> |
|||
<button string="Approve" |
|||
name="action_approve" |
|||
type="object" |
|||
class="oe_highlight" |
|||
attrs="{'invisible': ['|', '|', ('state', 'not in', ('waiting' )),('method', '=', 'sign'), ('show_approve', '=', False)]}"/> |
|||
<button string="Reject" name="action_reject" |
|||
type="object" |
|||
attrs="{'invisible':['|', '|',('state', 'not in', ('waiting' )),('method', '=', False),('show_approve', '=', False)]}"/> |
|||
<field name="state" widget="statusbar" |
|||
statusbar_visible="draft,waiting,approved,reject"/> |
|||
</header> |
|||
<sheet> |
|||
<h1> |
|||
<field name="name" attrs="{'readonly':[('state', '!=', 'draft')]}"/> |
|||
</h1> |
|||
<group> |
|||
<group name="description" |
|||
string="Description"/> |
|||
<field name="description"/> |
|||
<group name="document" string="Document"> |
|||
<field name="file_ids" nolabel="1" attrs="{'readonly':[('state', '=', 'approved')]}" |
|||
colspan="4"> |
|||
<tree editable="bottom"> |
|||
<field name="name"/> |
|||
<field name="file_name" invisible="1"/> |
|||
<field name="file" widget="binary" |
|||
filename="file_name"/> |
|||
</tree> |
|||
</field> |
|||
</group> |
|||
</group> |
|||
<group> |
|||
<group name="visibility" string="Visibility"> |
|||
<field name="company_id" attrs="{'readonly':[('state', '!=', 'draft')]}"/> |
|||
<field name="visibility"/> |
|||
</group> |
|||
<group name="approval" string="Approval"> |
|||
<field name="team_id" attrs="{'readonly':[('state', '=', 'approved')]}"/> |
|||
<field name="team_lead_id"/> |
|||
<field name="method" attrs="{'readonly':[('state', '!=', 'draft')]}"/> |
|||
<field name="step_count"/> |
|||
<field name="show_approve" invisible="1"/> |
|||
<field name="approver_ids" widget="many2many_tags" |
|||
invisible="1"/> |
|||
<field name="approval_ids" widget="many2many_tags" |
|||
invisible="1"/> |
|||
</group> |
|||
</group> |
|||
<group name="approvers" string="Approvers"> |
|||
<field name="step_ids" |
|||
nolabel="1" colspan="2"> |
|||
<tree editable="bottom"> |
|||
<field name="steps"/> |
|||
<field name="approver_id"/> |
|||
<field name="role"/> |
|||
<field name="state" optional="hide"/> |
|||
<field name="current_state" |
|||
decoration-success="current_state == 'approved'" |
|||
decoration-primary="current_state == 'pending'" |
|||
decoration-warning="current_state == 'upcoming'" |
|||
attrs="{'column_invisible': [('parent.state', '=', 'draft')]}"/> |
|||
<field name="note"/> |
|||
</tree> |
|||
</field> |
|||
</group> |
|||
<group> |
|||
<field name="approve_initiator_id"/> |
|||
</group> |
|||
</sheet> |
|||
<div class="oe_chatter"> |
|||
<field name="message_follower_ids"/> |
|||
<field name="message_ids"/> |
|||
<field name="activity_ids"/> |
|||
</div> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- window action for document approvals --> |
|||
<record id="document_approval_action" model="ir.actions.act_window"> |
|||
<field name="name">Document Approval</field> |
|||
<field name="res_model">document.approval</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="o_view_nocontent_smiling_face"> |
|||
Create Document Approval |
|||
</p> |
|||
</field> |
|||
</record> |
|||
<menuitem id="document_approval_menu" name="Document" |
|||
sequence="2" |
|||
parent="document_approval.document_approval_menu_root" |
|||
action="document_approval_action"/> |
|||
<!-- Tree view for document approval steps --> |
|||
<record id="document_approval_step_view_tree" model="ir.ui.view"> |
|||
<field name="name">document.approval.step.view.tree</field> |
|||
<field name="model">document.approval.step</field> |
|||
<field name="arch" type="xml"> |
|||
<tree editable="bottom"> |
|||
<field name="steps"/> |
|||
<field name="approver_id"/> |
|||
<field name="role"/> |
|||
<field name="document_approve_id"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!--Form views for the files --> |
|||
<record id="document_approval_file_view_form" model="ir.ui.view"> |
|||
<field name="name">document.approval.file.view.form</field> |
|||
<field name="model">document.approval.file</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<group> |
|||
<field name="name" invisible="1"/> |
|||
</group> |
|||
<group> |
|||
<field name="file" filename="file_name" widget="binary"/> |
|||
</group> |
|||
</group> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,44 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<odoo> |
|||
<!-- Config Settings--> |
|||
<record id="res_config_settings_view_form" model="ir.ui.view"> |
|||
<field name="name">res.config.settings.view.form.inherit.document.approval</field> |
|||
<field name="model">res.config.settings</field> |
|||
<field name="priority" eval="15"/> |
|||
<field name="inherit_id" ref="base.res_config_settings_view_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//div[hasclass('settings')]" position="inside"> |
|||
<div class="app_settings_block" data-string="Document Approval" |
|||
string="Document Approval" |
|||
data-key="document_approval"> |
|||
<h2>Document Approval</h2> |
|||
<div class="row mt16 o_settings_container" |
|||
id="distance_amount"> |
|||
<div class="col-12 col-lg-6 o_setting_box"> |
|||
<div class="o_setting_right_pane"> |
|||
<label for="visibility"/> |
|||
<span>: |
|||
<field name="visibility"/> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
<!-- Action used in the config settings model--> |
|||
<record id="res_config_settings_action" model="ir.actions.act_window"> |
|||
<field name="name">Settings</field> |
|||
<field name="res_model">res.config.settings</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="view_id" ref="res_config_settings_view_form"/> |
|||
<field name="target">inline</field> |
|||
<field name="context">{'module' : 'document_approval','bin_size':False}</field> |
|||
</record> |
|||
<!-- Menu used in the Config Settings--> |
|||
<menuitem id="res_config_settings_menu_action" name="Settings" |
|||
parent="document_approval.document_approval_configuration_menu" |
|||
sequence="1" |
|||
action="res_config_settings_action"/> |
|||
</odoo> |
@ -0,0 +1,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from . import document_approve |
|||
from . import document_approval_signature |
|||
from . import document_reject |
@ -0,0 +1,78 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class DocumentApprovalSignature(models.TransientModel): |
|||
""" Document approval using signature confirmation""" |
|||
_name = "document.approval.signature" |
|||
_description = "Document signature approvals" |
|||
_rec_name = "document_id" |
|||
|
|||
note = fields.Text(string='Note', required=True, help='For adding notes') |
|||
signature = fields.Binary(string='Signature', required=True, |
|||
help='For writing signature') |
|||
document_id = fields.Many2one("document.approval", string="Document", |
|||
help="To track which document is get " |
|||
"approved ") |
|||
|
|||
def action_approve_signature(self): |
|||
""" Function to approve document using signature""" |
|||
if self.document_id.team_id.team_lead_id.id == self.env.uid: |
|||
self.document_id.state = "approved" |
|||
else: |
|||
if self.env.uid in self.document_id.approver_ids.ids: |
|||
self.document_id.approval_ids.write({ |
|||
'current_state': 'approved', |
|||
}) |
|||
if 'approve' in self.document_id.approval_ids.mapped('state'): |
|||
self.document_id.state = 'approved' |
|||
return True |
|||
steps = self.document_id.step_ids.mapped('steps') |
|||
unique_steps = [] |
|||
for step in steps: |
|||
if step not in unique_steps: |
|||
unique_steps.append(step) |
|||
unique_steps = sorted(unique_steps) |
|||
index_unique = unique_steps.index(self.document_id.step_count) |
|||
if index_unique < len(unique_steps) - 1: |
|||
next_number = unique_steps[index_unique + 1] |
|||
self.document_id.step_count = next_number |
|||
approval_records = self.document_id.step_ids.search( |
|||
[('steps', '=', |
|||
next_number), ( |
|||
'document_approve_id', |
|||
'=', |
|||
self.document_id.id)]) |
|||
self.document_id.approval_ids = approval_records.ids |
|||
self.document_id.approval_ids.write({ |
|||
'current_state': 'pending', |
|||
}) |
|||
users = [] |
|||
for step in approval_records: |
|||
users.append(step.approver_id.id) |
|||
self.document_id.approver_ids = users |
|||
else: |
|||
self.document_id.approval_ids.write({ |
|||
'current_state': 'approved', |
|||
}) |
|||
self.document_id.state = 'approved' |
@ -0,0 +1,70 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<!-- Wizard for document approvals using signature --> |
|||
<record id="document_approval_signature_view_form" model="ir.ui.view"> |
|||
<field name="name">document.approval.signature.view.form</field> |
|||
<field name="model">document.approval.signature</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<sheet> |
|||
<group> |
|||
<field name="note"/> |
|||
<field name="signature" widget="signature"/> |
|||
</group> |
|||
<footer> |
|||
<button name="action_approve_signature" |
|||
string="Approve" |
|||
type="object" class="oe_highlight"/> |
|||
<button string="Cancel" special="cancel"/> |
|||
</footer> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Form views for document approval using signature for the menu item --> |
|||
<record id="document_approval_signature_view_form_readonly" |
|||
model="ir.ui.view"> |
|||
<field name="name">document.approval.signature.view.form</field> |
|||
<field name="model">document.approval.signature</field> |
|||
<field name="arch" type="xml"> |
|||
<form create="0"> |
|||
<sheet> |
|||
<group> |
|||
<group> |
|||
<field name="document_id" readonly="1"/> |
|||
<field name="note" readonly="1"/> |
|||
<field name="signature" widget="signature" |
|||
readonly="1"/> |
|||
</group> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Tree views for document approval using signature --> |
|||
<record id="document_approval_signature_view_tree" model="ir.ui.view"> |
|||
<field name="name">document.approval.signature.view.tree</field> |
|||
<field name="model">document.approval.signature</field> |
|||
<field name="arch" type="xml"> |
|||
<tree create="false"> |
|||
<field name="document_id" readonly="1"/> |
|||
<field name="note" readonly="1"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!-- Action for document approval using signature description--> |
|||
<record id="document_approval_signature_action" |
|||
model="ir.actions.act_window"> |
|||
<field name="name">Document Signature Approval</field> |
|||
<field name="res_model">document.approval.signature</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="view_ids" eval="[(5, 0, 0), |
|||
(0,0,{'view_mode':'tree', 'view_id': ref('document_approval_signature_view_tree')}), |
|||
(0,0,{'view_mode':'form', 'view_id': ref('document_approval_signature_view_form_readonly')}),]"/> |
|||
</record> |
|||
<menuitem id="document_approval_signature_menu" |
|||
name="Document Signature Approval Description" |
|||
sequence="10" |
|||
parent="document_approval.document_approval_reject_reason_menu_root" |
|||
action="document_approval_signature_action"/> |
|||
</odoo> |
@ -0,0 +1,75 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM(<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class DocumentApprove(models.TransientModel): |
|||
""" Wizard for approving documents""" |
|||
_name = "document.approve" |
|||
_description = "Wizard for approving document" |
|||
_rec_name = "document_id" |
|||
|
|||
description = fields.Text(string="Description", required=True, |
|||
help='Add note which is the reason for the ' |
|||
'approval') |
|||
document_id = fields.Many2one("document.approval", string="Document", |
|||
help="To track which document is get" |
|||
" approved") |
|||
|
|||
def action_approve_document(self): |
|||
""" function to approve document""" |
|||
if self.document_id.team_id.team_lead_id.id == self.env.uid: |
|||
self.document_id.state = "approved" |
|||
else: |
|||
if self.env.uid in self.document_id.approver_ids.ids: |
|||
self.document_id.approval_ids.write({ |
|||
'current_state': 'approved', |
|||
}) |
|||
if 'approve' in self.document_id.approval_ids.mapped('state'): |
|||
self.document_id.state = 'approved' |
|||
return True |
|||
steps = self.document_id.step_ids.mapped('steps') |
|||
unique_steps = [] |
|||
for step in steps: |
|||
if step not in unique_steps: |
|||
unique_steps.append(step) |
|||
unique_steps = sorted(unique_steps) |
|||
index_unique = unique_steps.index(self.document_id.step_count) |
|||
if index_unique < len(unique_steps) - 1: |
|||
next_number = unique_steps[index_unique + 1] |
|||
self.document_id.step_count = next_number |
|||
approval_records = self.document_id.step_ids.search( |
|||
[('steps', '=', |
|||
next_number), ( |
|||
'document_approve_id', |
|||
'=', |
|||
self.document_id.id)]) |
|||
self.document_id.approval_ids = approval_records.ids |
|||
self.document_id.approval_ids.write({ |
|||
'current_state': 'pending', |
|||
}) |
|||
users = [] |
|||
for step in approval_records: |
|||
users.append(step.approver_id.id) |
|||
self.document_id.approver_ids = users |
|||
else: |
|||
self.document_id.state = 'approved' |
@ -0,0 +1,63 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<!-- wizard for document approvals --> |
|||
<record id="document_approve_view_form" model="ir.ui.view"> |
|||
<field name="name">document.approve.view.form</field> |
|||
<field name="model">document.approve</field> |
|||
<field name="arch" type="xml"> |
|||
<form create="0"> |
|||
<group> |
|||
<field name="description"/> |
|||
</group> |
|||
<footer> |
|||
<button name="action_approve_document" |
|||
string="Approve" |
|||
class="btn-primary" type="object"/> |
|||
<button string="Cancel" special="cancel"/> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Form view for document approval description for menu item --> |
|||
<record id="document_approve_view_form_readonly" model="ir.ui.view"> |
|||
<field name="name">document.approve.view.form</field> |
|||
<field name="model">document.approve</field> |
|||
<field name="arch" type="xml"> |
|||
<form create="0"> |
|||
<sheet> |
|||
<group> |
|||
<group> |
|||
<field name="document_id" readonly="1"/> |
|||
<field name="description" readonly="1"/> |
|||
</group> |
|||
</group> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Tree view for document approval description --> |
|||
<record id="document_approve_view_tree" model="ir.ui.view"> |
|||
<field name="name">document.approve.view.tree</field> |
|||
<field name="model">document.approve</field> |
|||
<field name="arch" type="xml"> |
|||
<tree create="false"> |
|||
<field name="document_id" readonly="1"/> |
|||
<field name="description" readonly="1"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!-- Action for document approval description --> |
|||
<record id="document_approve_action" |
|||
model="ir.actions.act_window"> |
|||
<field name="name">Document Approve</field> |
|||
<field name="res_model">document.approve</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="view_ids" eval="[(5, 0, 0), |
|||
(0,0,{'view_mode':'tree', 'view_id': ref('document_approve_view_tree')}), |
|||
(0,0,{'view_mode':'form', 'view_id': ref('document_approve_view_form_readonly')}),]"/> |
|||
</record> |
|||
<menuitem id="document_approve_menu" name="Document Approval Description" |
|||
sequence="12" |
|||
parent="document_approval.document_approval_reject_reason_menu_root" |
|||
action="document_approve_action"/> |
|||
</odoo> |
@ -0,0 +1,44 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# Author: Fathima Mazlin AM (<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/>. |
|||
# |
|||
############################################################################# |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class DocumentReject(models.TransientModel): |
|||
""" Wizard for rejecting documents""" |
|||
_name = "document.reject" |
|||
_description = "Wizard for document reject" |
|||
_rec_name = "document_id" |
|||
|
|||
description = fields.Text(string="Description", |
|||
help='For adding reason for the rejection') |
|||
document_id = fields.Many2one("document.approval", string="Document", |
|||
help="To track which document is get " |
|||
"approved") |
|||
|
|||
def action_reject_document(self): |
|||
""" Function to reject document""" |
|||
self.document_id.state = "reject" |
|||
for rec in self.document_id.step_ids.filtered( |
|||
lambda x: x.approver_id.id == self.env.user.id): |
|||
rec.write({ |
|||
'current_state': 'rejected', |
|||
}) |
@ -0,0 +1,46 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<odoo> |
|||
<!-- Wizard for document rejection --> |
|||
<record id="document_reject_view_form" model="ir.ui.view"> |
|||
<field name="name">document.reject.view.form</field> |
|||
<field name="model">document.reject</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<field name="document_id" readonly="1"/> |
|||
<field name="description"/> |
|||
</group> |
|||
<footer> |
|||
<button name="action_reject_document" |
|||
string="Reject" |
|||
class="btn-primary" type="object"/> |
|||
<button string="Cancel" special="cancel"/> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
<!-- Tree views for document reject reason --> |
|||
<record id="document_reject_form_view_tree" model="ir.ui.view"> |
|||
<field name="name">document.reject.view.tree</field> |
|||
<field name="model">document.reject</field> |
|||
<field name="arch" type="xml"> |
|||
<tree create="false"> |
|||
<field name="document_id" readonly="1"/> |
|||
<field name="description" readonly="1"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
<!--Action for document reject reasons --> |
|||
<record id="document_reject_action" |
|||
model="ir.actions.act_window"> |
|||
<field name="name">Document Reject</field> |
|||
<field name="res_model">document.reject</field> |
|||
<field name="view_mode">tree</field> |
|||
<field name="view_ids" eval="[(5, 0, 0), |
|||
(0,0,{'view_mode':'tree', 'view_id': ref('document_reject_form_view_tree')}),]"/> |
|||
</record> |
|||
<menuitem id="document_reject_menu" name="Document Reject Reason" |
|||
sequence="13" |
|||
parent="document_approval.document_approval_reject_reason_menu_root" |
|||
action="document_reject_action"/> |
|||
</odoo> |